#include "precompiled.h" #include #include #include #include #include // Alan: For some reason if this gets included after anything else some // compile time errors get thrown up todo with javascript internal typedefs #include "scripting/ScriptingHost.h" #include "sdl.h" #include "ogl.h" #include "detect.h" #include "timer.h" #include "input.h" #include "lib.h" #include "res/res.h" #include "res/file.h" #ifdef _M_IX86 #include "sysdep/ia32.h" #endif #include "ps/CConsole.h" #include "Config.h" #include "MapReader.h" #include "Terrain.h" #include "TextureManager.h" #include "ObjectManager.h" #include "SkeletonAnimManager.h" #include "Renderer.h" #include "Model.h" #include "UnitManager.h" #include "BaseEntityCollection.h" #include "Entity.h" #include "EntityHandles.h" #include "EntityManager.h" #include "PathfindEngine.h" #ifndef NO_GUI #include "gui/GUI.h" #endif CConsole* g_Console = 0; extern bool conInputHandler(const SDL_Event& ev); u32 game_ticks; bool keys[SDLK_LAST]; bool mouseButtons[5]; // Globals int g_xres, g_yres; int g_bpp; int g_freq; // flag to disable extended GL extensions until fix found - specifically, crashes // using VBOs on laptop Radeon cards static bool g_NoGLVBO=false; // flag to switch on shadows static bool g_Shadows=false; // flag to switch off pbuffers static bool g_NoPBuffer=false; static bool g_VSync = false; static bool g_EntGraph = false; static float g_Gamma = 1.0f; // mapfile to load or null for no map (and to use default terrain) static const char* g_MapFile=0; static Handle font; extern CCamera g_Camera; extern void terr_init(); extern void terr_update(float time); extern bool terr_handler(const SDL_Event& ev); extern int allow_reload(); extern int dir_add_watch(const char* const dir, bool watch_subdirs); void Testing (void) { g_Console->InsertMessage("Testing Function Registration"); } static int write_sys_info() { get_gfx_info(); struct utsname un; uname(&un); FILE* const f = fopen("../logs/system_info.txt", "w"); if(!f) return -1; // .. OS fprintf(f, "%s %s (%s)\n", un.sysname, un.release, un.version); // .. CPU fprintf(f, "%s, %s", un.machine, cpu_type); if(cpus > 1) fprintf(f, " (x%d)", cpus); if(cpu_freq != 0.0f) { if(cpu_freq < 1e9) fprintf(f, ", %.2f MHz\n", cpu_freq*1e-6); else fprintf(f, ", %.2f GHz\n", cpu_freq*1e-9); } else fprintf(f, "\n"); // .. memory fprintf(f, "%lu MB RAM; %lu MB free\n", tot_mem/MB, avl_mem/MB); // .. graphics card fprintf(f, "%s\n", gfx_card); fprintf(f, "%s\n", gfx_drv_ver); fprintf(f, "%dx%d:%d@%d\n", g_xres, g_yres, g_bpp, g_freq); // .. network name / ips char hostname[100]; // possibly nodename != hostname gethostname(hostname, sizeof(hostname)); fprintf(f, "%s\n", hostname); hostent* host = gethostbyname(hostname); if(host) { struct in_addr** ips = (struct in_addr**)host->h_addr_list; for(int i = 0; ips && ips[i]; i++) fprintf(f, "%s ", inet_ntoa(*ips[i])); fprintf(f, "\n"); } fclose(f); return 0; } // error before GUI is initialized: display message, and quit // TODO: localization static void display_startup_error(const wchar_t* msg) { const wchar_t* caption = L"0ad startup problem"; write_sys_info(); wdisplay_msg(caption, msg); exit(1); } // error before GUI is initialized: display message, and quit // TODO: localization static void display_startup_error(const char* msg) { const char* caption = "0ad startup problem"; write_sys_info(); display_msg(caption, msg); exit(1); } static int set_vmode(int w, int h, int bpp) { SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if(!SDL_SetVideoMode(w, h, bpp, SDL_OPENGL|SDL_FULLSCREEN)) return -1; glViewport(0, 0, w, h); #ifndef NO_GUI g_GUI.UpdateResolution(); #endif oglInit(); // required after each mode change return 0; } // break out of main loop static bool quit = false; static bool handler(const SDL_Event& ev) { int c; switch(ev.type) { case SDL_KEYDOWN: c = ev.key.keysym.sym; keys[c] = true; switch(c) { case SDLK_ESCAPE: quit = true; break; } break; case SDL_KEYUP: c = ev.key.keysym.sym; keys[c] = false; break; case SDL_MOUSEBUTTONDOWN: c = ev.button.button; if( c < 5 ) mouseButtons[c] = true; break; case SDL_MOUSEBUTTONUP: c = ev.button.button; if( c < 5 ) mouseButtons[c] = false; break; } return 0; } ////////////////////////////////////////////////////////////////////////////////////////////////// // RenderTerrain: iterate through all terrain patches and submit all patches in viewing frustum to // the renderer void RenderTerrain() { CFrustum frustum=g_Camera.GetFustum(); u32 patchesPerSide=g_Terrain.GetPatchesPerSide(); for (uint j=0; jGetBounds())) { g_Renderer.Submit(patch); } } } } ////////////////////////////////////////////////////////////////////////////////////////////////// // SubmitModelRecursive: recurse down given model, submitting it and all its descendents to the // renderer void SubmitModelRecursive(CModel* model) { g_Renderer.Submit(model); const std::vector& props=model->GetProps(); for (uint i=0;i& units=g_UnitMan.GetUnits(); for (uint i=0;iGetModel()->GetBounds())) { SubmitModelRecursive(units[i]->GetModel()); } } } ///////////////////////////////////////////////////////////////////////////////////////////// // RenderNoCull: render absolutely everything to a blank frame to force renderer // to load required assets void RenderNoCull() { g_Renderer.BeginFrame(); g_Renderer.SetCamera(g_Camera); uint i,j; const std::vector& units=g_UnitMan.GetUnits(); for (i=0;iGetModel()); } u32 patchesPerSide=g_Terrain.GetPatchesPerSide(); for (j=0; jRender(); // restore glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); g_Renderer.EndFrame(); } static void do_tick() { } ////////////////////////////////////////////////////////////////////////////////////////////// // UpdateWorld: update time dependent data in the world to account for changes over // the given time (in s) void UpdateWorld(float time) { const std::vector& units=g_UnitMan.GetUnits(); for (uint i=0;iGetModel()->Update(time); } g_EntityManager.updateAll( time ); } void ParseArgs(int argc, char* argv[]) { for (int i=1;iRegisterFunc(Testing, "Testing"); // fixed timestep main loop const double TICK_TIME = 30e-3; // [s] double time0 = get_time(); // g_Config.Update(); while(!quit) { //g_Config.Update(); //// allow_reload(); // TODO: limiter in case simulation can't keep up? #if 0 double time1 = get_time(); while((time1-time0) > TICK_TIME) { game_ticks++; in_get_events(); do_tick(); time0 += TICK_TIME; } UpdateWorld(float(time1-time0)); terr_update(float(time1-time0)); Render(); SDL_GL_SwapBuffers(); calc_fps(); #else double time1 = get_time(); mouseButtons[SDL_BUTTON_WHEELUP] = false; mouseButtons[SDL_BUTTON_WHEELDOWN] = false; float TimeSinceLastFrame = (float)(time1-time0); in_get_events(); UpdateWorld(TimeSinceLastFrame); terr_update(TimeSinceLastFrame); g_Console->Update(TimeSinceLastFrame); Render(); SDL_GL_SwapBuffers(); calc_fps(); time0=time1; #endif } #ifndef NO_GUI g_GUI.Destroy(); delete CGUI::GetSingletonPtr(); #endif delete &g_ScriptingHost; /// delete &g_Config; delete &g_Pathfinder; delete &g_EntityManager; delete &g_EntityTemplateCollection; // destroy actor related stuff delete CUnitManager::GetSingletonPtr(); delete CObjectManager::GetSingletonPtr(); delete CSkeletonAnimManager::GetSingletonPtr(); // destroy terrain related stuff delete CTextureManager::GetSingletonPtr(); // destroy renderer delete CRenderer::GetSingletonPtr(); //shut down FMOD - needs adding to the atexit calls above FSOUND_Close(); exit(0); return 0; }