|
ORTS
|
00001 // $Id: replayer_main.C 5279 2007-06-23 02:49:08Z mburo $ 00002 00003 // This is an ORTS file (c) Michael Buro, licensed under the GPL 00004 00005 #include "Options.H" 00006 #include "GfxModule.H" 00007 #include "ShutDown.H" 00008 #include "SDLinit.H" 00009 #include "SoundMixer.H" 00010 #include "LoopFunctor.H" 00011 #include "Game.H" 00012 #include "GameChanges.H" 00013 00014 #include "ClientState.H" 00015 #include "TerrainModule.H" 00016 00017 #include "Replayer.H" 00018 #include "VCRWidget.H" 00019 00020 using namespace std; 00021 00022 00023 const char *ORTSG_VERSION = "GfxClient version 0.91 (2005-Apr-10)"; 00024 00025 #define USE_EFENCE 0 00026 00027 extern int EF_PROTECT_FREE, EF_FILL, EF_PROTECT_BELOW, EF_ALLOW_MALLOC_0; 00028 00029 00030 static bool just_drew = false; 00031 sint4 speed; 00032 sint4 last_frame; 00033 00034 struct GfxEventHandler : public EventHandler 00035 { 00036 GfxEventHandler() {} 00037 00038 bool handle_event(const Event& e) 00039 { 00040 if (e.get_what() == VCRWidget::SET_SPEED) { 00041 const VCREvent *ve = dynamic_cast<const VCREvent*>(&e); 00042 assert(ve && "VCR Event"); 00043 speed = ve->get_speed(); 00044 return true; 00045 } 00046 return false; 00047 } 00048 }; 00049 00050 00051 class ortsgLooper : public LoopFunctor 00052 { 00053 private: 00054 GfxModule *gfxm; 00055 ViewReplayer *rep; 00056 bool refresh; 00057 00058 public: 00059 00060 ortsgLooper(GfxModule *g, ViewReplayer *r) : gfxm(g), rep(r) 00061 { 00062 ::Options::get("-refresh", refresh); 00063 last_frame = 0; 00064 speed = 1000; 00065 } 00066 00067 void loop() const { 00068 00069 sint4 now = SDL_GetTicks(); 00070 if (now - last_frame > speed) { 00071 last_frame = now; 00072 rep->tick(); 00073 gfxm->process_changes(); 00074 00075 const Game &game = gfxm->get_game(); 00076 sint4 vf = game.get_view_frame(); 00077 sint4 ai = game.get_action_frame(); 00078 sint4 sk = game.get_skipped_actions(); 00079 sint4 md = game.get_merged_actions(); 00080 00081 if (vf != ai || sk || md > 1) { 00082 00083 cout << "frame " << vf; 00084 if (ai < 0) cout << " [no action]"; 00085 else if (vf != ai) cout << " [behind by " << (vf - ai) << " frame(s)]"; 00086 if (sk) cout << " [skipped " << sk << "]"; 00087 if (md > 1) cout << " [merged " << md << "]"; 00088 cout << endl; 00089 } 00090 00091 // don't draw if we are far behind 00092 if (abs(vf-ai) < 10) { 00093 gfxm->draw(); 00094 } 00095 just_drew = true; 00096 } 00097 00098 if (gfxm->get_quit()) exit(0); 00099 00100 if (refresh) { 00101 00102 if (!just_drew) // allow some waiting time after a message 00103 gfxm->draw(); 00104 else 00105 just_drew = false; 00106 } 00107 } 00108 }; 00109 00110 int main(int argc, char **argv) 00111 { 00112 char mydir[81]; 00113 getcwd(mydir, 80); 00114 glutInit(&argc, argv); 00115 chdir(mydir); 00116 00117 try { 00118 #if USE_EFENCE 00119 // aggressive efence checks 00120 EF_PROTECT_FREE = 1; 00121 EF_FILL = 0xee; 00122 EF_PROTECT_BELOW = 1; 00123 EF_ALLOW_MALLOC_0 = 1; 00124 #endif 00125 00126 signals_shut_down(true); 00127 atexit(SDL_Quit); 00128 00129 // populate opt with options from various modules 00130 00131 GfxModule::Options::add(); 00132 00133 // process command line arguments 00134 if (Options::process(argc, argv, cerr, ORTSG_VERSION)) exit(20); 00135 00136 00137 // change seed value to time(0) if 0 00138 sint4 seed; 00139 Options::get("-seed", seed); 00140 if (!seed) seed = time(0); 00141 Options::set("-seed", seed); 00142 cout << "seed=" << seed << endl; 00143 00144 srand48(seed); // used by STL, fixme: avoid (global) 00145 00146 SDLinit::video_init(); 00147 SDLinit::network_init(); 00148 00149 // populate option objects with command line values 00150 // and create modules 00151 00152 GfxModule::Options gfxmo; 00153 GfxModule gfxm; 00154 00155 // ortsg event handler 00156 GfxEventHandler gev; 00157 00158 //===================================== 00159 00160 GameChanges gc; 00161 ActionChanges ac; 00162 00163 ViewReplayer rep; 00164 ViewReplayer::Options repo; 00165 rep.init(repo); 00166 00167 VCRWidget vcr; 00168 vcr.add_handler(&gev); 00169 00170 gfxm.init(rep.get_game(), gc, ac, gfxmo); 00171 00172 // gfx loop (should become a thread) 00173 ortsgLooper l(&gfxm, &rep); 00174 00175 cout << "start loop" << endl; 00176 00177 gfxm.start_loop(&l); 00178 00179 } 00180 catch (ExitException& ee) 00181 { 00182 errstr << std::endl << *(ee.get_reason()) << std::endl; 00183 #ifdef GCC 00184 abort(); 00185 #else 00186 ABORT; 00187 #endif 00188 exit(20); 00189 } 00190 return 0; 00191 }