2004-06-03 20:38:14 +02:00
# include "precompiled.h"
2004-05-24 22:25:48 +02:00
# include <cstdio>
# include <cstring>
# include <cstdlib>
2004-06-03 03:43:33 +02:00
# include <cmath>
2004-07-12 18:50:46 +02:00
# include <stdarg.h>
2004-06-03 03:43:33 +02:00
2004-05-28 15:07:54 +02:00
2004-05-24 22:25:48 +02:00
# include "sdl.h"
# include "ogl.h"
# include "detect.h"
# include "timer.h"
# include "input.h"
# include "lib.h"
2004-10-06 16:25:36 +02:00
# include "lib/res/res.h"
# include "lib/res/tex.h"
# include "lib/res/hotload.h"
2004-05-24 22:25:48 +02:00
# ifdef _M_IX86
2004-07-12 18:50:46 +02:00
# include "sysdep/ia32.h" // _control87
2004-05-24 22:25:48 +02:00
# endif
2004-07-24 21:38:12 +02:00
# include "lib/res/cursor.h"
2004-06-02 22:39:21 +02:00
2004-08-28 00:08:30 +02:00
# include "ps/Font.h"
2004-06-02 22:39:21 +02:00
# include "ps/CConsole.h"
2004-07-27 23:00:53 +02:00
# include "ps/Game.h"
2004-05-29 23:04:18 +02:00
# include "Config.h"
2004-05-24 22:25:48 +02:00
# include "MapReader.h"
# include "Terrain.h"
2004-05-29 23:04:18 +02:00
# include "TextureManager.h"
# include "ObjectManager.h"
# include "SkeletonAnimManager.h"
2004-05-24 22:25:48 +02:00
# include "Renderer.h"
2004-08-05 15:07:51 +02:00
# include "LightEnv.h"
2004-05-24 22:25:48 +02:00
# include "Model.h"
# include "UnitManager.h"
2004-09-23 07:21:18 +02:00
# include "MaterialManager.h"
2004-05-24 22:25:48 +02:00
2004-07-20 21:30:35 +02:00
# include "Interact.h"
2004-07-21 18:34:07 +02:00
# include "Hotkey.h"
2004-05-24 22:25:48 +02:00
# include "BaseEntityCollection.h"
# include "Entity.h"
# include "EntityHandles.h"
# include "EntityManager.h"
2004-05-29 05:32:33 +02:00
# include "PathfindEngine.h"
2004-07-20 21:30:35 +02:00
# include "Scheduler.h"
2004-05-24 22:25:48 +02:00
2004-07-12 18:50:46 +02:00
# include "scripting/ScriptingHost.h"
2004-06-11 00:24:03 +02:00
# include "scripting/JSInterface_Entity.h"
# include "scripting/JSInterface_BaseEntity.h"
# include "scripting/JSInterface_Vector3D.h"
2004-08-03 01:14:54 +02:00
# include "scripting/JSInterface_Camera.h"
# include "scripting/JSInterface_Selection.h"
# include "scripting/JSInterface_Console.h"
2004-10-07 21:23:35 +02:00
# include "scripting/JSCollection.h"
2004-07-08 17:22:09 +02:00
# include "gui/scripting/JSInterface_IGUIObject.h"
# include "gui/scripting/JSInterface_GUITypes.h"
2004-06-09 16:10:31 +02:00
2004-06-11 00:24:03 +02:00
# include "ConfigDB.h"
2004-06-09 16:10:31 +02:00
# include "CLogger.h"
2004-05-28 15:07:54 +02:00
2004-08-21 13:45:01 +02:00
# include "ps/i18n.h"
2004-08-15 22:57:31 +02:00
# define LOG_CATEGORY "main"
2004-05-24 22:25:48 +02:00
# ifndef NO_GUI
# include "gui/GUI.h"
# endif
2004-07-28 13:36:16 +02:00
# include "sound/CMusicPlayer.h"
2004-09-19 17:58:13 +02:00
# include "lib/res/snd.h"
2004-08-16 17:19:17 +02:00
# include "Network/SessionManager.h"
# include "Network/Server.h"
2004-07-28 13:36:16 +02:00
2004-09-19 17:58:13 +02:00
2004-06-02 22:39:21 +02:00
CConsole * g_Console = 0 ;
2004-06-26 00:13:48 +02:00
extern int conInputHandler ( const SDL_Event * ev ) ;
2004-06-02 22:39:21 +02:00
2004-07-20 21:30:35 +02:00
// Globals
2004-05-24 22:25:48 +02:00
u32 game_ticks ;
bool keys [ SDLK_LAST ] ;
2004-05-26 00:02:57 +02:00
bool mouseButtons [ 5 ] ;
2004-07-20 21:30:35 +02:00
int mouse_x = 50 , mouse_y = 50 ;
2004-05-24 22:25:48 +02:00
2004-06-03 03:43:33 +02:00
int g_xres , g_yres ;
int g_bpp ;
int g_freq ;
2004-07-12 18:50:46 +02:00
bool g_active = true ;
2004-05-24 22:25:48 +02:00
// flag to disable extended GL extensions until fix found - specifically, crashes
// using VBOs on laptop Radeon cards
static bool g_NoGLVBO = false ;
2004-05-29 23:04:18 +02:00
// flag to switch on shadows
static bool g_Shadows = false ;
// flag to switch off pbuffers
2004-06-07 21:51:52 +02:00
static bool g_NoPBuffer = true ;
// flag to switch on fixed frame timing (RC: I'm using this for profiling purposes)
static bool g_FixedFrameTiming = false ;
2004-05-24 22:25:48 +02:00
static bool g_VSync = false ;
2004-10-07 21:23:35 +02:00
extern CLightEnv g_LightEnv ;
2004-08-05 15:07:51 +02:00
2004-05-29 05:32:33 +02:00
static bool g_EntGraph = false ;
2004-05-24 22:25:48 +02:00
static float g_Gamma = 1.0f ;
2004-07-27 23:00:53 +02:00
CGameAttributes g_GameAttributes ;
2004-07-31 17:57:18 +02:00
extern int game_view_handler ( const SDL_Event * ev ) ;
2004-05-24 22:25:48 +02:00
2004-07-28 13:36:16 +02:00
static CMusicPlayer MusicPlayer ;
2004-07-31 14:45:30 +02:00
CStr g_CursorName = " test " ;
2004-07-28 13:36:16 +02:00
2004-09-22 16:01:50 +02:00
2004-05-24 22:25:48 +02:00
extern int allow_reload ( ) ;
extern int dir_add_watch ( const char * const dir , bool watch_subdirs ) ;
2004-07-12 18:50:46 +02:00
extern void sle ( int ) ;
2004-07-27 23:00:53 +02:00
extern size_t frameCount ;
2004-07-12 18:50:46 +02:00
static bool quit = false ; // break out of main loop
const wchar_t * HardcodedErrorString ( int err )
{
2004-07-14 14:26:49 +02:00
# define E(sym) case sym: return L ## #sym;
2004-07-12 18:50:46 +02:00
switch ( err )
{
E ( ERR_NO_MEM )
E ( ERR_FILE_NOT_FOUND )
E ( ERR_INVALID_HANDLE )
E ( ERR_INVALID_PARAM )
E ( ERR_EOF )
E ( ERR_PATH_NOT_FOUND )
E ( ERR_VFS_PATH_LENGTH )
default :
return 0 ;
}
}
const wchar_t * ErrorString ( int err )
{
// language file not available (yet)
if ( 1 )
return HardcodedErrorString ( err ) ;
// TODO: load from language file
}
static int write_sys_info ( ) ;
2004-07-19 21:03:33 +02:00
ERROR_GROUP ( System ) ;
ERROR_TYPE ( System , SDLInitFailed ) ;
ERROR_TYPE ( System , VmodeFailed ) ;
ERROR_TYPE ( System , RequiredExtensionsMissing ) ;
2004-07-12 18:50:46 +02:00
2004-06-02 22:39:21 +02:00
void Testing ( void )
{
2004-06-16 17:44:24 +02:00
g_Console - > InsertMessage ( L " Testing Function Registration " ) ;
}
void TestingUnicode ( void )
{
// This looks really broken in my IDE's font
g_Console - > InsertMessage ( L " Ai! lauri� lantar lassi s�rinen, " ) ;
g_Console - > InsertMessage ( L " y�ni �n�tim� ve r�mar aldaron! " ) ;
g_Console - > InsertMessage ( L " Y�ni ve lint� yuldar av�nier " ) ;
g_Console - > InsertMessage ( L " mi oromardi liss�-miruv�reva " ) ;
g_Console - > InsertMessage ( L " And�n� pella, Vardo tellumar " ) ;
g_Console - > InsertMessage ( L " nu luini yassen tintilar i eleni " ) ;
g_Console - > InsertMessage ( L " �maryo airet�ri-l�rinen. " ) ;
2004-06-02 22:39:21 +02:00
}
2004-05-24 22:25:48 +02:00
static int write_sys_info ( )
{
get_gfx_info ( ) ;
struct utsname un ;
uname ( & un ) ;
2004-05-27 02:29:54 +02:00
FILE * const f = fopen ( " ../logs/system_info.txt " , " w " ) ;
2004-05-24 22:25:48 +02:00
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 ) ;
2004-05-26 01:16:21 +02:00
fprintf ( f , " %s \n " , gfx_drv_ver ) ;
2004-07-19 21:03:33 +02:00
2004-06-01 19:34:12 +02:00
fprintf ( f , " %dx%d:%d@%d \n " , g_xres , g_yres , g_bpp , g_freq ) ;
2004-05-24 22:25:48 +02:00
// .. network name / ips
2004-07-12 18:50:46 +02:00
// note: can't use un.nodename because it is for an
// "implementation-defined communications network".
char hostname [ 128 ] ;
2004-06-16 17:44:24 +02:00
if ( gethostname ( hostname , sizeof ( hostname ) ) = = 0 ) // make sure it succeeded
2004-05-24 22:25:48 +02:00
{
2004-06-16 17:44:24 +02:00
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 " ) ;
}
2004-05-24 22:25:48 +02:00
}
2004-06-07 21:51:52 +02:00
2004-07-19 21:03:33 +02:00
// Write extensions last, because there are lots of them
const char * exts = oglExtList ( ) ;
if ( ! exts ) exts = " {unknown} " ;
fprintf ( f , " \n Supported extensions: %s \n " , exts ) ;
2004-05-24 22:25:48 +02:00
fclose ( f ) ;
return 0 ;
}
2004-07-10 23:33:31 +02:00
static int set_vmode ( int w , int h , int bpp , bool fullscreen )
2004-05-24 22:25:48 +02:00
{
2004-09-23 14:42:37 +02:00
SDL_GL_SetAttribute ( SDL_GL_DEPTH_SIZE , 24 ) ;
SDL_GL_SetAttribute ( SDL_GL_DOUBLEBUFFER , 1 ) ;
2004-05-24 22:25:48 +02:00
2004-07-10 23:33:31 +02:00
if ( ! SDL_SetVideoMode ( w , h , bpp , SDL_OPENGL | ( fullscreen ? SDL_FULLSCREEN : 0 ) ) )
2004-05-24 22:25:48 +02:00
return - 1 ;
glViewport ( 0 , 0 , w , h ) ;
# ifndef NO_GUI
g_GUI . UpdateResolution ( ) ;
# endif
oglInit ( ) ; // required after each mode change
2004-07-12 18:50:46 +02:00
if ( SDL_SetGamma ( g_Gamma , g_Gamma , g_Gamma ) < 0 )
debug_warn ( " SDL_SetGamma failed " ) ;
2004-05-24 22:25:48 +02:00
return 0 ;
}
2004-09-23 14:42:37 +02:00
// use_bmp is for when you want high-speed output at the expense of huge files
2004-07-17 13:13:21 +02:00
static void WriteScreenshot ( bool use_bmp = false )
2004-06-26 00:13:48 +02:00
{
2004-07-09 04:04:30 +02:00
// determine next screenshot number.
//
// current approach: increment number until that file doesn't yet exist.
// this is fairly slow, but it's typically only done once, since the last
// number is cached. binary search shouldn't be necessary.
//
// known bug: after program restart, holes in the number series are
// filled first. example: add 1st and 2nd; [exit] delete 1st; [restart]
// add 3rd -> it gets number 1, not 3.
// could fix via enumerating all files, but it's not worth it ATM.
char fn [ VFS_MAX_PATH ] ;
2004-07-17 13:13:21 +02:00
2004-09-23 14:42:37 +02:00
const char * file_format =
use_bmp ? " screenshots/screenshot%04d.bmp "
: " screenshots/screenshot%04d.png " ;
2004-07-17 13:13:21 +02:00
2004-07-09 04:04:30 +02:00
static int next_num = 1 ;
do
2004-07-17 13:13:21 +02:00
sprintf ( fn , file_format , next_num + + ) ;
2004-07-09 04:04:30 +02:00
while ( vfs_exists ( fn ) ) ;
const int w = g_xres , h = g_yres ;
const int bpp = 24 ;
const size_t size = w * h * bpp ;
void * img = mem_alloc ( size ) ;
2004-07-17 13:13:21 +02:00
glReadPixels ( 0 , 0 , w , h , use_bmp ? GL_BGR : GL_RGB , GL_UNSIGNED_BYTE , img ) ;
2004-07-09 04:04:30 +02:00
2004-07-17 13:13:21 +02:00
if ( tex_write ( fn , w , h , bpp , use_bmp ? TEX_BGR : 0 , img ) < 0 )
2004-07-09 04:04:30 +02:00
debug_warn ( " WriteScreenshot: tex_write failed " ) ;
mem_free ( img ) ;
2004-06-26 00:13:48 +02:00
}
2004-05-24 22:25:48 +02:00
2004-07-09 14:44:12 +02:00
// HACK: Let code from other files (i.e. the scripting system) quit
void kill_mainloop ( )
{
quit = true ;
}
2004-06-26 00:13:48 +02:00
static int handler ( const SDL_Event * ev )
2004-05-24 22:25:48 +02:00
{
int c ;
2004-06-26 00:13:48 +02:00
switch ( ev - > type )
2004-05-24 22:25:48 +02:00
{
2004-07-10 23:33:31 +02:00
case SDL_ACTIVEEVENT :
2004-07-12 18:50:46 +02:00
g_active = ev - > active . gain ! = 0 ;
2004-06-21 16:14:12 +02:00
break ;
2004-07-20 21:30:35 +02:00
case SDL_MOUSEMOTION :
mouse_x = ev - > motion . x ;
mouse_y = ev - > motion . y ;
break ;
2004-05-24 22:25:48 +02:00
case SDL_KEYDOWN :
2004-06-26 00:13:48 +02:00
c = ev - > key . keysym . sym ;
2004-05-24 22:25:48 +02:00
keys [ c ] = true ;
2004-07-21 18:34:07 +02:00
break ;
case SDL_HOTKEYDOWN :
2004-06-02 22:39:21 +02:00
2004-07-21 18:34:07 +02:00
switch ( ev - > user . code )
2004-05-24 22:25:48 +02:00
{
2004-07-21 18:34:07 +02:00
case HOTKEY_EXIT :
2004-05-24 22:25:48 +02:00
quit = true ;
break ;
2004-06-26 00:13:48 +02:00
2004-07-21 18:34:07 +02:00
case HOTKEY_SCREENSHOT :
2004-07-09 04:04:30 +02:00
WriteScreenshot ( ) ;
2004-06-26 00:13:48 +02:00
break ;
2004-07-21 18:34:07 +02:00
2004-07-28 13:36:16 +02:00
case HOTKEY_PLAYMUSIC :
2004-09-19 17:58:13 +02:00
{
// MusicPlayer.open("audio/music/germanic peace 3.ogg");
// MusicPlayer.play();
2004-10-05 15:14:03 +02:00
Handle hs = snd_open (
2004-09-22 16:01:50 +02:00
//"audio/music/germanic peace 3.ogg"
2004-10-05 15:14:34 +02:00
" audio/voice/hellenes/citizensoldier/Attack-ZeusSaviourandVictory-Zeus-soter-kai-nike.ogg "
2004-09-22 16:01:50 +02:00
//"audio/voice/hellenes/citizensoldier/Stance-HoldYourPosition-Kataschete-ten-taxin.ogg"
//"audio/voice/hellenes/citizensoldier/Econ-Chop-Kopto.ogg"
2004-10-05 15:14:03 +02:00
//"audio/lead_em.wav"
//"audio/nike.wav"
2004-10-05 15:14:34 +02:00
//"audio/nike.ogg"
2004-10-05 15:14:03 +02:00
//"audio/1111_Warcraft 2 - Orc Defeat.ogg"
2004-09-22 16:01:50 +02:00
) ;
2004-10-05 15:14:03 +02:00
snd_play ( hs ) ;
2004-09-19 17:58:13 +02:00
}
2004-07-28 13:36:16 +02:00
break ;
2004-07-21 18:34:07 +02:00
default :
return ( EV_PASS ) ;
2004-05-24 22:25:48 +02:00
}
2004-07-21 18:34:07 +02:00
return ( EV_HANDLED ) ;
2004-05-24 22:25:48 +02:00
case SDL_KEYUP :
2004-06-26 00:13:48 +02:00
c = ev - > key . keysym . sym ;
2004-05-24 22:25:48 +02:00
keys [ c ] = false ;
break ;
2004-05-26 00:02:57 +02:00
case SDL_MOUSEBUTTONDOWN :
2004-06-26 00:13:48 +02:00
c = ev - > button . button ;
2004-05-26 00:02:57 +02:00
if ( c < 5 )
mouseButtons [ c ] = true ;
2004-06-21 16:14:12 +02:00
else
debug_warn ( " SDL mouse button defs changed; fix mouseButton array def " ) ;
2004-05-26 00:02:57 +02:00
break ;
case SDL_MOUSEBUTTONUP :
2004-06-26 00:13:48 +02:00
c = ev - > button . button ;
2004-05-26 00:02:57 +02:00
if ( c < 5 )
mouseButtons [ c ] = false ;
2004-06-21 16:14:12 +02:00
else
debug_warn ( " SDL mouse button defs changed; fix mouseButton array def " ) ;
2004-05-26 00:02:57 +02:00
break ;
2004-05-24 22:25:48 +02:00
}
2004-06-26 00:13:48 +02:00
return EV_PASS ;
2004-05-24 22:25:48 +02:00
}
2004-08-05 15:07:51 +02:00
void EndGame ( )
{
delete g_Game ;
g_Game = NULL ;
}
2004-05-24 22:25:48 +02:00
/////////////////////////////////////////////////////////////////////////////////////////////
// RenderNoCull: render absolutely everything to a blank frame to force renderer
2004-06-07 21:51:52 +02:00
// to load required assets
2004-05-24 22:25:48 +02:00
void RenderNoCull ( )
{
g_Renderer . BeginFrame ( ) ;
2004-07-31 17:57:18 +02:00
2004-08-05 15:07:51 +02:00
if ( g_Game )
g_Game - > GetView ( ) - > RenderNoCull ( ) ;
2004-05-24 22:25:48 +02:00
g_Renderer . FlushFrame ( ) ;
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
g_Renderer . EndFrame ( ) ;
}
static void Render ( )
{
2004-07-15 21:12:54 +02:00
MICROLOG ( L " begin frame " ) ;
2004-08-06 17:01:23 +02:00
oglCheck ( ) ;
2004-05-24 22:25:48 +02:00
// start new frame
g_Renderer . BeginFrame ( ) ;
// switch on wireframe for terrain if we want it
2004-06-16 17:44:24 +02:00
//g_Renderer.SetTerrainRenderMode( SOLID ); // (PT: If this is done here, the W key doesn't work)
2004-07-27 23:00:53 +02:00
2004-08-06 17:01:23 +02:00
oglCheck ( ) ;
2004-08-05 15:07:51 +02:00
if ( g_Game )
2004-05-29 05:32:33 +02:00
{
2004-08-05 15:07:51 +02:00
g_Game - > GetView ( ) - > Render ( ) ;
2004-05-26 22:57:25 +02:00
2004-08-06 17:01:23 +02:00
oglCheck ( ) ;
2004-08-05 15:07:51 +02:00
MICROLOG ( L " flush frame " ) ;
g_Renderer . FlushFrame ( ) ;
2004-05-24 22:25:48 +02:00
2004-08-05 15:07:51 +02:00
glPushAttrib ( GL_ENABLE_BIT ) ;
glDisable ( GL_LIGHTING ) ;
glDisable ( GL_TEXTURE_2D ) ;
glDisable ( GL_DEPTH_TEST ) ;
if ( g_EntGraph )
{
glColor3f ( 1.0f , 0.0f , 1.0f ) ;
2004-07-20 21:30:35 +02:00
2004-08-05 15:07:51 +02:00
MICROLOG ( L " render entities " ) ;
g_EntityManager . renderAll ( ) ; // <-- collision outlines, pathing routes
}
g_Mouseover . renderSelectionOutlines ( ) ;
g_Selection . renderSelectionOutlines ( ) ;
glPopAttrib ( ) ;
}
else
g_Renderer . FlushFrame ( ) ;
2004-07-20 21:30:35 +02:00
2004-08-06 17:01:23 +02:00
oglCheck ( ) ;
2004-07-15 21:12:54 +02:00
MICROLOG ( L " render fonts " ) ;
2004-05-24 22:25:48 +02:00
// overlay mode
glPushAttrib ( GL_ENABLE_BIT ) ;
2004-06-16 17:44:24 +02:00
glEnable ( GL_TEXTURE_2D ) ;
2004-05-24 22:25:48 +02:00
glDisable ( GL_CULL_FACE ) ;
2004-06-07 21:51:52 +02:00
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
2004-05-24 22:25:48 +02:00
glEnable ( GL_BLEND ) ;
glMatrixMode ( GL_PROJECTION ) ;
glPushMatrix ( ) ;
glLoadIdentity ( ) ;
glOrtho ( 0.f , ( float ) g_xres , 0.f , ( float ) g_yres , - 1.f , 1000.f ) ;
glMatrixMode ( GL_MODELVIEW ) ;
glPushMatrix ( ) ;
2004-08-06 17:01:23 +02:00
oglCheck ( ) ;
2004-07-17 19:51:04 +02:00
# ifndef NO_GUI
// Temp GUI message GeeTODO
glLoadIdentity ( ) ;
MICROLOG ( L " render GUI " ) ;
g_GUI . Draw ( ) ;
# endif
2004-08-06 17:01:23 +02:00
oglCheck ( ) ;
2004-07-17 19:51:04 +02:00
// Text:
2004-05-24 22:25:48 +02:00
2004-06-16 17:44:24 +02:00
// Use the GL_ALPHA texture as the alpha channel with a flat colouring
glDisable ( GL_ALPHA_TEST ) ;
glTexEnvi ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE ) ;
2004-09-03 07:49:20 +02:00
// Added --
glEnable ( GL_TEXTURE_2D ) ;
// -- GL
2004-06-16 17:44:24 +02:00
2004-08-06 17:01:23 +02:00
oglCheck ( ) ;
2004-08-28 00:08:30 +02:00
{
glLoadIdentity ( ) ;
MICROLOG ( L " render console " ) ;
CFont font ( " console " ) ;
font . Bind ( ) ;
g_Console - > Render ( ) ;
}
2004-05-26 22:57:25 +02:00
2004-08-06 17:01:23 +02:00
oglCheck ( ) ;
2004-08-05 15:07:51 +02:00
if ( g_Game )
{
g_Mouseover . renderOverlays ( ) ;
g_Selection . renderOverlays ( ) ;
}
2004-07-20 21:30:35 +02:00
2004-08-06 17:01:23 +02:00
oglCheck ( ) ;
2004-07-24 21:38:12 +02:00
// Draw the cursor (or set the Windows cursor, on Windows)
2004-07-31 14:45:30 +02:00
cursor_draw ( g_CursorName ) ;
2004-07-24 21:38:12 +02:00
2004-05-24 22:25:48 +02:00
// restore
glMatrixMode ( GL_PROJECTION ) ;
glPopMatrix ( ) ;
glMatrixMode ( GL_MODELVIEW ) ;
glPopMatrix ( ) ;
glPopAttrib ( ) ;
2004-07-15 21:12:54 +02:00
MICROLOG ( L " end frame " ) ;
2004-05-24 22:25:48 +02:00
g_Renderer . EndFrame ( ) ;
2004-08-06 17:01:23 +02:00
oglCheck ( ) ;
2004-05-24 22:25:48 +02:00
}
2004-08-05 15:07:51 +02:00
static void InitDefaultGameAttributes ( )
{
2004-08-16 17:19:17 +02:00
g_GameAttributes . SetValue ( " mapFile " , L " test01.pmp " ) ;
2004-08-05 15:07:51 +02:00
}
2004-08-02 14:53:49 +02:00
static void ParseArgs ( int argc , char * argv [ ] )
2004-05-24 22:25:48 +02:00
{
2004-08-02 14:53:49 +02:00
for ( int i = 1 ; i < argc ; i + + )
{
// this arg isn't an option; skip
if ( argv [ i ] [ 0 ] ! = ' - ' )
continue ;
2004-05-29 23:04:18 +02:00
2004-08-02 14:53:49 +02:00
char * name = argv [ i ] + 1 ; // no leading '-'
2004-06-07 21:51:52 +02:00
2004-08-02 14:53:49 +02:00
// switch first letter of option name
switch ( argv [ i ] [ 1 ] )
{
case ' c ' :
if ( strcmp ( name , " conf " ) = = 0 )
{
if ( argc - i > = 1 ) // at least one arg left
{
i + + ;
char * arg = argv [ i ] ;
char * equ = strchr ( arg , ' = ' ) ;
if ( equ )
{
* equ = 0 ;
g_ConfigDB . CreateValue ( CFG_SYSTEM , arg )
- > m_String = ( equ + 1 ) ;
2004-06-09 16:10:31 +02:00
}
2004-08-02 14:53:49 +02:00
}
2004-05-24 22:25:48 +02:00
}
2004-08-02 14:53:49 +02:00
break ;
case ' e ' :
g_EntGraph = true ;
break ;
case ' f ' :
if ( strncmp ( name , " fixedframe " , 10 ) = = 0 )
g_FixedFrameTiming = true ;
break ;
case ' g ' :
if ( strncmp ( name , " g= " , 2 ) = = 0 )
{
g_Gamma = ( float ) atof ( argv [ i ] + 3 ) ;
if ( g_Gamma = = 0.0f )
g_Gamma = 1.0f ;
}
break ;
case ' m ' :
if ( strncmp ( name , " m= " , 2 ) = = 0 )
2004-08-16 17:19:17 +02:00
g_GameAttributes . SetValue ( " mapFile " , CStr ( argv [ i ] + 3 ) ) ;
2004-08-02 14:53:49 +02:00
break ;
case ' n ' :
if ( strncmp ( name , " novbo " , 5 ) = = 0 )
g_ConfigDB . CreateValue ( CFG_SYSTEM , " novbo " ) - > m_String = " true " ;
else if ( strncmp ( name , " nopbuffer " , 9 ) = = 0 )
g_NoPBuffer = true ;
break ;
case ' s ' :
if ( strncmp ( name , " shadows " , 7 ) = = 0 )
g_ConfigDB . CreateValue ( CFG_SYSTEM , " shadows " ) - > m_String = " true " ;
break ;
case ' v ' :
g_ConfigDB . CreateValue ( CFG_SYSTEM , " vsync " ) - > m_String = " true " ;
break ;
case ' x ' :
if ( strncmp ( name , " xres= " , 6 ) = = 0 )
g_ConfigDB . CreateValue ( CFG_SYSTEM , " xres " ) - > m_String = argv [ i ] + 6 ;
break ;
case ' y ' :
if ( strncmp ( name , " yres= " , 6 ) = = 0 )
g_ConfigDB . CreateValue ( CFG_SYSTEM , " yres " ) - > m_String = argv [ i ] + 6 ;
break ;
} // switch
2004-05-24 22:25:48 +02:00
}
2004-08-02 14:53:49 +02:00
2004-06-09 16:10:31 +02:00
CConfigValue * val ;
2004-07-24 16:04:40 +02:00
if ( ( val = g_ConfigDB . GetValue ( CFG_SYSTEM , " xres " ) ) )
2004-06-09 16:10:31 +02:00
val - > GetInt ( g_xres ) ;
2004-07-24 16:04:40 +02:00
if ( ( val = g_ConfigDB . GetValue ( CFG_SYSTEM , " yres " ) ) )
2004-06-09 16:10:31 +02:00
val - > GetInt ( g_yres ) ;
2004-07-07 20:47:11 +02:00
2004-07-24 16:04:40 +02:00
if ( ( val = g_ConfigDB . GetValue ( CFG_SYSTEM , " vsync " ) ) )
2004-07-07 20:47:11 +02:00
val - > GetBool ( g_VSync ) ;
2004-07-24 16:04:40 +02:00
if ( ( val = g_ConfigDB . GetValue ( CFG_SYSTEM , " novbo " ) ) )
2004-07-07 20:47:11 +02:00
val - > GetBool ( g_NoGLVBO ) ;
2004-07-24 16:04:40 +02:00
if ( ( val = g_ConfigDB . GetValue ( CFG_SYSTEM , " shadows " ) ) )
2004-07-07 20:47:11 +02:00
val - > GetBool ( g_Shadows ) ;
2004-06-09 16:10:31 +02:00
2004-08-15 22:57:31 +02:00
LOG ( NORMAL , LOG_CATEGORY , " g_x/yres is %dx%d " , g_xres , g_yres ) ;
2004-05-24 22:25:48 +02:00
}
2004-06-08 22:41:28 +02:00
2004-07-12 18:50:46 +02:00
static void InitScripting ( )
{
// Create the scripting host. This needs to be done before the GUI is created.
new ScriptingHost ;
2004-07-20 21:30:35 +02:00
// It would be nice for onLoad code to be able to access the setTimeout() calls.
new CScheduler ;
2004-07-12 18:50:46 +02:00
// Register the JavaScript interfaces with the runtime
2004-10-07 21:23:35 +02:00
CEntity : : ScriptingInit ( ) ;
CBaseEntity : : ScriptingInit ( ) ;
2004-07-12 18:50:46 +02:00
JSI_IGUIObject : : init ( ) ;
JSI_GUITypes : : init ( ) ;
JSI_Vector3D : : init ( ) ;
2004-10-07 21:23:35 +02:00
// JSI_Selection::init();
EntityCollection : : Init ( " EntityCollection " ) ;
CJSPropertyAccessor < CEntity > : : ScriptingInit ( ) ; // <-- Doesn't really matter which we use, but we know CJSPropertyAccessor<T> is already being compiled for T = CEntity.
2004-08-03 01:14:54 +02:00
JSI_Camera : : init ( ) ;
JSI_Console : : init ( ) ;
2004-07-12 18:50:46 +02:00
}
2004-08-02 14:53:49 +02:00
2004-07-12 18:50:46 +02:00
static void InitVfs ( char * argv0 )
{
// set current directory to "$game_dir/data".
// this is necessary because it is otherwise unknown,
// especially if run from a shortcut / symlink.
//
// "../data" is relative to the executable (in "$game_dir/system").
//
// rationale for data/ being root: untrusted scripts must not be
// allowed to overwrite critical game (or worse, OS) files.
// the VFS prevents any accesses to files above this directory.
int err = file_rel_chdir ( argv0 , " ../data " ) ;
if ( err < 0 )
throw err ;
/ / display_startup_error ( L " error setting current directory. \n " \
// L"argv[0] is probably incorrect. please start the game via command-line.");
vfs_mount ( " " , " mods/official " , 0 ) ;
vfs_mount ( " screenshots " , " screenshots " , 0 ) ;
}
2004-06-21 16:14:12 +02:00
static void psInit ( )
{
2004-09-22 16:01:50 +02:00
// console
2004-08-28 00:08:30 +02:00
{
2004-09-22 16:01:50 +02:00
float ConsoleHeight = g_yres * 0.6f ;
g_Console - > SetSize ( 0 , g_yres - ConsoleHeight , ( float ) g_xres , ConsoleHeight ) ;
2004-08-28 00:08:30 +02:00
// Calculate and store the line spacing
CFont font ( " console " ) ;
g_Console - > m_iFontHeight = font . GetLineSpacing ( ) ;
// Offset by an arbitrary amount, to make it fit more nicely
g_Console - > m_iFontOffset = 9 ;
}
2004-06-21 16:14:12 +02:00
2004-09-06 13:13:36 +02:00
CConfigValue * val = g_ConfigDB . GetValue ( CFG_SYSTEM , " language " ) ;
std : : string lang = " english " ;
if ( val )
val - > GetString ( lang ) ;
I18n : : LoadLanguage ( lang . c_str ( ) ) ;
2004-08-21 13:45:01 +02:00
2004-07-22 18:18:12 +02:00
loadHotkeys ( ) ;
2004-06-21 16:14:12 +02:00
# ifndef NO_GUI
// GUI uses VFS, so this must come after VFS init.
g_GUI . Initialize ( ) ;
2004-07-08 17:22:09 +02:00
2004-08-31 04:10:40 +02:00
g_GUI . LoadXMLFile ( " gui/test/setup.xml " ) ;
2004-07-08 17:22:09 +02:00
g_GUI . LoadXMLFile ( " gui/test/styles.xml " ) ;
g_GUI . LoadXMLFile ( " gui/test/hello.xml " ) ;
g_GUI . LoadXMLFile ( " gui/test/sprite1.xml " ) ;
2004-06-21 16:14:12 +02:00
# endif
}
static void psShutdown ( )
{
# ifndef NO_GUI
g_GUI . Destroy ( ) ;
delete & g_GUI ;
# endif
delete g_Console ;
2004-07-24 21:38:12 +02:00
// disable the special Windows cursor, or free textures for OGL cursors
cursor_draw ( NULL ) ;
2004-07-08 17:22:09 +02:00
// close down Xerces if it was loaded
CXeromyces : : Terminate ( ) ;
2004-07-28 13:36:16 +02:00
MusicPlayer . release ( ) ;
2004-08-21 13:45:01 +02:00
2004-08-24 13:32:32 +02:00
// Unload the real language (since it depends on the scripting engine,
// which is going to be killed later) and use the English fallback messages
I18n : : LoadLanguage ( NULL ) ;
2004-06-21 16:14:12 +02:00
}
2004-07-12 18:50:46 +02:00
2004-06-21 16:14:12 +02:00
extern u64 PREVTSC ;
2004-07-12 18:50:46 +02:00
static void Shutdown ( )
{
psShutdown ( ) ; // Must delete g_GUI before g_ScriptingHost
2004-08-05 15:07:51 +02:00
if ( g_Game )
delete g_Game ;
2004-08-21 13:45:01 +02:00
2004-07-20 21:30:35 +02:00
delete & g_Scheduler ;
2004-08-16 17:19:17 +02:00
delete & g_SessionManager ;
2004-07-20 21:30:35 +02:00
delete & g_Mouseover ;
delete & g_Selection ;
2004-07-12 18:50:46 +02:00
delete & g_Pathfinder ;
2004-08-05 15:07:51 +02:00
// Managed by CWorld
// delete &g_EntityManager;
2004-10-07 21:23:35 +02:00
2004-07-12 18:50:46 +02:00
delete & g_EntityTemplateCollection ;
2004-10-07 21:23:35 +02:00
delete & g_ScriptingHost ;
2004-07-12 18:50:46 +02:00
// destroy actor related stuff
delete & g_UnitMan ;
delete & g_ObjMan ;
delete & g_SkelAnimMan ;
2004-09-23 14:42:37 +02:00
delete & g_MaterialManager ;
2004-07-12 18:50:46 +02:00
// destroy terrain related stuff
delete & g_TexMan ;
// destroy renderer
delete & g_Renderer ;
delete & g_ConfigDB ;
2004-08-24 13:32:32 +02:00
// Really shut down the i18n system. Any future calls
// to translate() will crash.
I18n : : Shutdown ( ) ;
2004-07-12 18:50:46 +02:00
}
static void Init ( int argc , char * argv [ ] )
2004-05-24 22:25:48 +02:00
{
2004-07-15 21:12:54 +02:00
MICROLOG ( L " In init " ) ;
2004-07-10 16:14:36 +02:00
// If you ever want to catch a particular allocation:
2004-08-24 13:32:32 +02:00
//_CrtSetBreakAlloc(7239);
2004-07-10 16:14:36 +02:00
2004-06-08 22:41:28 +02:00
# ifdef _MSC_VER
u64 TSC = rdtsc ( ) ;
debug_out (
" ---------------------------------------- \n " \
" MAIN (elapsed = %f ms) \n " \
" ---------------------------------------- \n " , ( TSC - PREVTSC ) / 2e9 * 1e3 ) ;
PREVTSC = TSC ;
# endif
2004-07-15 21:12:54 +02:00
MICROLOG ( L " init lib " ) ;
2004-05-27 19:30:06 +02:00
lib_init ( ) ;
2004-08-24 13:32:32 +02:00
// Call LoadLanguage(NULL) to initialise the I18n system, but
// without loading an actual language file - translate() will
// just show the English key text, which is better than crashing
// from a null pointer when attempting to translate e.g. error messages.
// Real languages can only be loaded when the scripting system has
// been initialised.
MICROLOG ( L " init i18n " ) ;
I18n : : LoadLanguage ( NULL ) ;
2004-05-27 19:30:06 +02:00
// set 24 bit (float) FPU precision for faster divides / sqrts
# ifdef _M_IX86
_control87 ( _PC_24 , _MCW_PC ) ;
# endif
2004-07-19 21:03:33 +02:00
// Do this as soon as possible, because it chdirs
// and will mess up the error reporting if anything
// crashes before the working directory is set.
MICROLOG ( L " init vfs " ) ;
InitVfs ( argv [ 0 ] ) ;
2004-07-11 18:03:26 +02:00
// Set up the console early, so that debugging
// messages can be logged to it. (The console's size
// and fonts are set later in psInit())
g_Console = new CConsole ( ) ;
2004-07-15 21:12:54 +02:00
MICROLOG ( L " detect " ) ;
2004-05-27 19:30:06 +02:00
detect ( ) ;
2004-07-15 21:12:54 +02:00
MICROLOG ( L " init sdl " ) ;
2004-05-27 19:30:06 +02:00
// init SDL
if ( SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE ) < 0 )
2004-07-19 21:03:33 +02:00
{
2004-08-15 22:57:31 +02:00
LOG ( ERROR , LOG_CATEGORY , " SDL library initialization failed: %s " , SDL_GetError ( ) ) ;
2004-07-19 21:03:33 +02:00
throw PSERROR_System_SDLInitFailed ( ) ;
}
2004-05-27 19:30:06 +02:00
atexit ( SDL_Quit ) ;
SDL_EnableUNICODE ( 1 ) ;
2004-06-09 16:10:31 +02:00
// preferred video mode = current desktop settings
// (command line params may override these)
get_cur_vmode ( & g_xres , & g_yres , & g_bpp , & g_freq ) ;
2004-05-27 19:30:06 +02:00
2004-07-15 21:12:54 +02:00
MICROLOG ( L " init scripting " ) ;
2004-07-12 18:50:46 +02:00
InitScripting ( ) ; // before GUI
2004-07-14 14:26:49 +02:00
2004-07-15 21:12:54 +02:00
MICROLOG ( L " init config " ) ;
2004-06-09 16:10:31 +02:00
new CConfigDB ;
g_ConfigDB . SetConfigFile ( CFG_SYSTEM , false , " config/system.cfg " ) ;
g_ConfigDB . Reload ( CFG_SYSTEM ) ;
2004-06-21 16:14:12 +02:00
2004-06-09 16:10:31 +02:00
g_ConfigDB . SetConfigFile ( CFG_MOD , true , " config/mod.cfg " ) ;
// No point in reloading mod.cfg here - we haven't mounted mods yet
g_ConfigDB . SetConfigFile ( CFG_USER , true , " config/user.cfg " ) ;
// Same thing here; we haven't even started up yet - this will wait until
// the profile dir is VFS mounted (or we will do a new SetConfigFile with
// a generated profile path)
2004-08-05 15:07:51 +02:00
// We init the defaults here; command line options might want to override
InitDefaultGameAttributes ( ) ;
2004-05-24 22:25:48 +02:00
ParseArgs ( argc , argv ) ;
2004-07-09 04:04:30 +02:00
//g_xres = 800;
//g_yres = 600;
2004-05-24 22:25:48 +02:00
// GUI is notified in set_vmode, so this must come before that.
# ifndef NO_GUI
new CGUI ;
# endif
2004-07-10 23:33:31 +02:00
CConfigValue * val = g_ConfigDB . GetValue ( CFG_SYSTEM , " windowed " ) ;
bool windowed = false ;
if ( val ) val - > GetBool ( windowed ) ;
2004-07-14 14:26:49 +02:00
# ifdef _WIN32
2004-07-12 18:50:46 +02:00
sle ( 11340106 ) ;
2004-07-14 14:26:49 +02:00
# endif
2004-07-12 18:50:46 +02:00
2004-07-15 21:12:54 +02:00
MICROLOG ( L " set vmode " ) ;
2004-07-12 18:50:46 +02:00
if ( set_vmode ( g_xres , g_yres , 32 , ! windowed ) < 0 )
2004-07-19 21:03:33 +02:00
{
2004-08-15 22:57:31 +02:00
LOG ( ERROR , LOG_CATEGORY , " Could not set %dx%d graphics mode: %s " , g_xres , g_yres , SDL_GetError ( ) ) ;
2004-07-19 21:03:33 +02:00
throw PSERROR_System_VmodeFailed ( ) ;
}
2004-07-28 13:36:16 +02:00
SDL_WM_SetCaption ( " 0 A.D. " , " 0 A.D. " ) ;
2004-07-19 21:03:33 +02:00
write_sys_info ( ) ;
2004-05-24 22:25:48 +02:00
2004-08-25 13:44:11 +02:00
if ( ! oglExtAvail ( " GL_ARB_multitexture " ) | | ! oglExtAvail ( " GL_ARB_texture_env_combine " ) | |
! glActiveTexture ) // prevent crashing later if multitexture support is falsely
// advertised (janwas 2004-08-25, for bug #18)
2004-07-19 21:03:33 +02:00
{
2004-08-15 22:57:31 +02:00
LOG ( ERROR , LOG_CATEGORY , " Required ARB_multitexture or ARB_texture_env_combine extension not available " ) ;
2004-07-19 21:03:33 +02:00
throw PSERROR_System_RequiredExtensionsMissing ( ) ;
}
2004-05-24 22:25:48 +02:00
// enable/disable VSync
// note: "GL_EXT_SWAP_CONTROL" is "historical" according to dox.
if ( oglExtAvail ( " WGL_EXT_swap_control " ) )
wglSwapIntervalEXT ( g_VSync ? 1 : 0 ) ;
2004-05-30 02:46:58 +02:00
2004-05-24 22:25:48 +02:00
2004-06-11 20:02:57 +02:00
# ifdef _MSC_VER
u64 CURTSC = rdtsc ( ) ;
debug_out (
" ---------------------------------------- \n " \
2004-07-12 18:50:46 +02:00
" low-level ready (elapsed = %f ms) \n " \
2004-06-11 20:02:57 +02:00
" ---------------------------------------- \n " , ( CURTSC - PREVTSC ) / 2e9 * 1e3 ) ;
PREVTSC = CURTSC ;
# endif
2004-07-15 21:12:54 +02:00
MICROLOG ( L " init ps " ) ;
2004-06-21 16:14:12 +02:00
psInit ( ) ;
2004-06-02 22:39:21 +02:00
2004-05-29 23:04:18 +02:00
// create renderer
new CRenderer ;
2004-05-24 22:25:48 +02:00
// set renderer options from command line options - NOVBO must be set before opening the renderer
2004-05-29 23:04:18 +02:00
g_Renderer . SetOptionBool ( CRenderer : : OPT_NOVBO , g_NoGLVBO ) ;
g_Renderer . SetOptionBool ( CRenderer : : OPT_SHADOWS , g_Shadows ) ;
g_Renderer . SetOptionBool ( CRenderer : : OPT_NOPBUFFER , g_NoPBuffer ) ;
// create terrain related stuff
new CTextureManager ;
2004-09-23 14:42:37 +02:00
// create the material manager
new CMaterialManager ;
2004-09-23 06:00:56 +02:00
2004-05-29 23:04:18 +02:00
// create actor related stuff
new CSkeletonAnimManager ;
new CObjectManager ;
new CUnitManager ;
2004-05-24 22:25:48 +02:00
2004-07-15 21:12:54 +02:00
MICROLOG ( L " init renderer " ) ;
2004-06-03 03:43:33 +02:00
g_Renderer . Open ( g_xres , g_yres , g_bpp ) ;
2004-07-28 21:27:35 +02:00
2004-08-05 15:07:51 +02:00
// Setup default lighting environment. Since the Renderer accesses the
// lighting environment through a pointer, this has to be done before
// the first Frame.
g_LightEnv . m_SunColor = RGBColor ( 1 , 1 , 1 ) ;
g_LightEnv . m_Rotation = DEGTORAD ( 270 ) ;
g_LightEnv . m_Elevation = DEGTORAD ( 45 ) ;
g_LightEnv . m_TerrainAmbientColor = RGBColor ( 0 , 0 , 0 ) ;
g_LightEnv . m_UnitsAmbientColor = RGBColor ( 0.4f , 0.4f , 0.4f ) ;
g_Renderer . SetLightEnv ( & g_LightEnv ) ;
// I haven't seen the camera affecting GUI rendering and such, but the
// viewport has to be updated according to the video mode
SViewPort vp ;
vp . m_X = 0 ;
vp . m_Y = 0 ;
vp . m_Width = g_xres ;
vp . m_Height = g_yres ;
g_Renderer . SetViewport ( vp ) ;
2004-05-24 22:25:48 +02:00
// This needs to be done after the renderer has loaded all its actors...
new CBaseEntityCollection ;
2004-08-05 15:07:51 +02:00
// CEntityManager is managed by CWorld
//new CEntityManager;
2004-05-29 05:32:33 +02:00
new CPathfindEngine ;
2004-07-20 21:30:35 +02:00
new CSelectedEntities ;
new CMouseoverEntities ;
2004-05-24 22:25:48 +02:00
2004-08-16 17:19:17 +02:00
new CSessionManager ;
// Register a few Game/Network JS globals
g_ScriptingHost . SetGlobal ( " g_NetServerAttributes " , OBJECT_TO_JSVAL ( g_NetServerAttributes . GetJSObject ( ) ) ) ;
g_ScriptingHost . SetGlobal ( " g_GameAttributes " , OBJECT_TO_JSVAL ( g_GameAttributes . GetJSObject ( ) ) ) ;
2004-07-21 14:28:23 +02:00
// Check for heap corruption after every allocation. Very, very slowly.
// (And it highlights the allocation just after the one you care about,
// so you need to run it again and tell it to break on the one before.)
/*
extern void memory_debug_extreme_turbo_plus ( ) ;
memory_debug_extreme_turbo_plus ( ) ;
_CrtSetBreakAlloc ( 36367 ) ;
//*/
2004-05-24 22:25:48 +02:00
// Initialize entities
2004-05-26 05:14:33 +02:00
in_add_handler ( handler ) ;
2004-07-31 17:57:18 +02:00
in_add_handler ( game_view_handler ) ;
2004-05-24 22:25:48 +02:00
2004-07-20 21:30:35 +02:00
in_add_handler ( interactInputHandler ) ;
# ifndef NO_GUI
in_add_handler ( gui_handler ) ;
# endif
2004-07-22 18:18:12 +02:00
in_add_handler ( conInputHandler ) ;
2004-07-21 18:34:07 +02:00
2004-07-22 18:18:12 +02:00
in_add_handler ( hotkeyInputHandler ) ; // <- Leave this one until after all the others.
2004-06-02 22:39:21 +02:00
2004-07-15 21:12:54 +02:00
MICROLOG ( L " render blank " ) ;
2004-05-24 22:25:48 +02:00
// render everything to a blank frame to force renderer to load everything
RenderNoCull ( ) ;
2004-06-07 21:51:52 +02:00
if ( g_FixedFrameTiming ) {
2004-07-31 17:57:18 +02:00
CCamera & g_Camera = * g_Game - > GetView ( ) - > GetCamera ( ) ;
2004-06-07 21:51:52 +02:00
#if 0 // TOPDOWN
g_Camera . SetProjection ( 1.0f , 10000.0f , DEGTORAD ( 90 ) ) ;
g_Camera . m_Orientation . SetIdentity ( ) ;
g_Camera . m_Orientation . RotateX ( DEGTORAD ( 90 ) ) ;
g_Camera . m_Orientation . Translate ( CELL_SIZE * 250 * 0.5 , 250 , CELL_SIZE * 250 * 0.5 ) ;
# else // std view
g_Camera . SetProjection ( 1.0f , 10000.0f , DEGTORAD ( 20 ) ) ;
g_Camera . m_Orientation . SetXRotation ( DEGTORAD ( 30 ) ) ;
g_Camera . m_Orientation . RotateY ( DEGTORAD ( - 45 ) ) ;
g_Camera . m_Orientation . Translate ( 350 , 350 , - 275 ) ;
# endif
g_Camera . UpdateFrustum ( ) ;
}
2004-06-16 17:44:24 +02:00
g_Console - > RegisterFunc ( Testing , L " Testing " ) ;
{
wchar_t t [ ] = { ' T ' , 0xE9 , ' s ' , ' t ' , ' i ' , ' n ' , ' g ' , 0 } ;
g_Console - > RegisterFunc ( TestingUnicode , t ) ;
}
2004-06-02 22:39:21 +02:00
2004-06-08 22:41:28 +02:00
# ifdef _MSC_VER
2004-06-11 20:02:57 +02:00
{
2004-06-08 22:41:28 +02:00
u64 CURTSC = rdtsc ( ) ;
debug_out (
" ---------------------------------------- \n " \
" READY (elapsed = %f ms) \n " \
" ---------------------------------------- \n " , ( CURTSC - PREVTSC ) / 2e9 * 1e3 ) ;
PREVTSC = CURTSC ;
2004-06-11 20:02:57 +02:00
}
2004-06-08 22:41:28 +02:00
# endif
2004-07-12 18:50:46 +02:00
}
2004-05-24 22:25:48 +02:00
2004-07-12 18:50:46 +02:00
static void Frame ( )
{
2004-07-15 21:12:54 +02:00
MICROLOG ( L " In frame " ) ;
2004-07-28 13:36:16 +02:00
MusicPlayer . update ( ) ;
2004-10-05 15:14:03 +02:00
snd_update ( 0 , 0 , 0 ) ;
2004-07-28 13:36:16 +02:00
2004-07-12 18:50:46 +02:00
static double last_time ;
const double time = get_time ( ) ;
const float TimeSinceLastFrame = ( float ) ( time - last_time ) ;
last_time = time ;
ONCE ( return ) ;
2004-07-17 13:13:21 +02:00
// first call: set last_time and return
2004-07-12 18:50:46 +02:00
assert ( TimeSinceLastFrame > = 0.0f ) ;
2004-05-24 22:25:48 +02:00
2004-07-15 21:12:54 +02:00
MICROLOG ( L " reload files " ) ;
2004-07-12 18:50:46 +02:00
res_reload_changed_files ( ) ;
2004-05-24 22:25:48 +02:00
2004-07-15 21:12:54 +02:00
MICROLOG ( L " input " ) ;
2004-07-12 18:50:46 +02:00
in_get_events ( ) ;
2004-08-16 17:19:17 +02:00
g_SessionManager . Poll ( ) ;
2004-07-20 21:30:35 +02:00
2004-09-21 16:40:43 +02:00
if ( g_Game & & g_Game - > IsGameStarted ( ) )
2004-08-05 15:07:51 +02:00
{
g_Game - > Update ( TimeSinceLastFrame ) ;
if ( ! g_FixedFrameTiming )
g_Game - > GetView ( ) - > Update ( float ( TimeSinceLastFrame ) ) ;
2004-07-21 18:34:07 +02:00
2004-08-05 15:07:51 +02:00
// TODO Where does GameView end and other things begin?
g_Mouseover . update ( TimeSinceLastFrame ) ;
g_Selection . update ( ) ;
}
2004-07-21 18:34:07 +02:00
2004-07-20 21:30:35 +02:00
g_Console - > Update ( TimeSinceLastFrame ) ;
// ugly, but necessary. these are one-shot events, have to be reset.
2004-07-21 18:34:07 +02:00
// Spoof mousebuttonup events for the hotkey system
SDL_Event spoof ;
spoof . type = SDL_MOUSEBUTTONUP ;
spoof . button . button = SDL_BUTTON_WHEELUP ;
if ( mouseButtons [ SDL_BUTTON_WHEELUP ] )
hotkeyInputHandler ( & spoof ) ;
spoof . button . button = SDL_BUTTON_WHEELDOWN ;
if ( mouseButtons [ SDL_BUTTON_WHEELDOWN ] )
hotkeyInputHandler ( & spoof ) ;
2004-07-20 21:30:35 +02:00
mouseButtons [ SDL_BUTTON_WHEELUP ] = false ;
mouseButtons [ SDL_BUTTON_WHEELDOWN ] = false ;
2004-06-18 15:11:58 +02:00
2004-07-12 18:50:46 +02:00
if ( g_active )
{
2004-07-15 21:12:54 +02:00
MICROLOG ( L " render " ) ;
2004-07-12 18:50:46 +02:00
Render ( ) ;
2004-07-15 21:12:54 +02:00
MICROLOG ( L " swap buffers " ) ;
2004-07-12 18:50:46 +02:00
SDL_GL_SwapBuffers ( ) ;
2004-07-15 21:12:54 +02:00
MICROLOG ( L " finished render " ) ;
2004-07-12 18:50:46 +02:00
}
// inactive; relinquish CPU for a little while
// don't use SDL_WaitEvent: don't want the main loop to freeze until app focus is restored
else
SDL_Delay ( 10 ) ;
2004-07-08 17:22:09 +02:00
2004-07-12 18:50:46 +02:00
calc_fps ( ) ;
if ( g_FixedFrameTiming & & frameCount = = 100 ) quit = true ;
}
2004-05-24 22:25:48 +02:00
2004-07-15 21:12:54 +02:00
2004-08-24 13:32:32 +02:00
// Choose when to override the standard exception handling behaviour
// (opening the debugger when available, or crashing when not) with
// code that generates a crash log/dump.
2004-07-22 15:22:28 +02:00
# if defined(_WIN32) && ( defined(NDEBUG) || defined(TESTING) )
# define CUSTOM_EXCEPTION_HANDLER
2004-07-15 21:12:54 +02:00
# endif
2004-07-22 15:22:28 +02:00
2004-07-15 21:12:54 +02:00
# ifdef CUSTOM_EXCEPTION_HANDLER
# include <excpt.h>
# endif
2004-07-12 18:50:46 +02:00
int main ( int argc , char * argv [ ] )
{
2004-07-15 21:12:54 +02:00
MICROLOG ( L " In main " ) ;
# ifdef CUSTOM_EXCEPTION_HANDLER
__try
2004-07-12 18:50:46 +02:00
{
2004-07-15 21:12:54 +02:00
# endif
MICROLOG ( L " Init " ) ;
2004-07-12 18:50:46 +02:00
Init ( argc , argv ) ;
2004-06-13 17:35:08 +02:00
2004-07-12 18:50:46 +02:00
while ( ! quit )
2004-07-15 21:12:54 +02:00
{
2004-07-20 21:30:35 +02:00
MICROLOG ( L " (Simulation) Frame " ) ;
2004-07-12 18:50:46 +02:00
Frame ( ) ;
2004-07-15 21:12:54 +02:00
}
2004-06-13 17:35:08 +02:00
2004-09-05 13:27:23 +02:00
//_CrtMemDumpAllObjectsSince(NULL);
2004-07-15 21:12:54 +02:00
MICROLOG ( L " Shutdown " ) ;
2004-07-12 18:50:46 +02:00
Shutdown ( ) ;
2004-07-15 21:12:54 +02:00
# ifdef CUSTOM_EXCEPTION_HANDLER
2004-07-12 18:50:46 +02:00
}
2004-07-15 21:12:54 +02:00
__except ( debug_main_exception_filter ( GetExceptionCode ( ) , GetExceptionInformation ( ) ) )
2004-07-12 18:50:46 +02:00
{
}
2004-07-15 21:12:54 +02:00
# endif
2004-07-10 16:14:36 +02:00
2004-06-01 19:34:12 +02:00
exit ( 0 ) ;
2004-05-24 22:25:48 +02:00
}