From 2fa56dc951335dbe4bdb0b3187932708c924ad8b Mon Sep 17 00:00:00 2001 From: g-cont Date: Tue, 4 Sep 2007 00:00:00 +0400 Subject: [PATCH] 04 Sep 2007 --- changelog.log | 8 + editor/editor.h | 5 +- editor/editor.plg | 34 +-- editor/guiforms.c | 11 +- editor/guiutils.c | 12 + engine/client/cl_input.c | 27 +- engine/client/cl_main.c | 33 +- engine/client/cl_parse.c | 9 +- engine/client/cl_scrn.c | 21 +- engine/client/cl_view.c | 7 - engine/common.h | 34 +-- engine/common/cmd.c | 9 +- engine/common/common.c | 73 +++-- engine/common/net_chan.c | 33 +- engine/common/net_wins.c | 55 ++-- engine/engine.dsp | 4 - engine/engine.h | 42 ++- engine/engine.plg | 16 +- engine/host.c | 93 +++--- engine/in_win.c | 8 +- engine/prvm/vm_cmds.c | 16 +- engine/prvm/vm_edict.c | 45 +-- engine/prvm/vm_exec.c | 626 ++++++++++++++++++++++++++++++++++--- engine/prvm/vm_exec.h | 628 -------------------------------------- engine/server/server.h | 2 +- engine/server/sv_ccmds.c | 15 +- engine/server/sv_init.c | 7 +- engine/server/sv_main.c | 28 +- engine/server/sv_phys.c | 8 +- engine/server/sv_save.c | 2 +- engine/server/sv_send.c | 13 +- engine/server/sv_user.c | 2 +- engine/server/sv_world.c | 26 +- engine/snd_dma.c | 6 +- engine/snd_win.c | 172 +++++------ engine/system.c | 10 +- engine/vid_dll.c | 50 ++- launcher/console.c | 15 +- launcher/launcher.c | 22 +- launcher/launcher.h | 23 +- launcher/launcher.plg | 16 + launcher/utils.c | 15 +- platform/baseutils.c | 6 +- platform/bsplib/portals.c | 4 +- platform/bsplib/shaders.c | 2 +- platform/filesystem.c | 24 +- platform/platform.c | 2 +- platform/platform.plg | 16 + public/const.h | 26 -- public/ref_system.h | 25 +- renderer/gl_rmain.c | 59 ++-- renderer/r_texture.c | 18 +- resource/server.dat | Bin 0 -> 62108 bytes 53 files changed, 1165 insertions(+), 1298 deletions(-) delete mode 100644 engine/prvm/vm_exec.h create mode 100644 launcher/launcher.plg create mode 100644 platform/platform.plg create mode 100644 resource/server.dat diff --git a/changelog.log b/changelog.log index 2a7d2aa2..45a78c94 100644 --- a/changelog.log +++ b/changelog.log @@ -1,5 +1,12 @@ Разработать концепцию языка VirtualC\VirtualC++ (базируется на QuakeC) +Quake1 Quake2 +SV_MoveBounds SV_TraceBounds +SV_Move SV_Trace +SV_ClipMoveToEntity CM_BoxTrace +SV_ClipToLinks SV_ClipMoveToEntities + + //================================================== // FIXME //================================================== @@ -9,6 +16,7 @@ //================================================== // то, что уже готово //================================================== ++добавлены кастомные названия окна для различных инстанций (studiomdl, bsplib итд) +исправлен баг с кодом возвращаемой ошибки +исправлен баг с выводом сообщений в консоль кварка\хаммера +исправлены баги со studiomdl diff --git a/editor/editor.h b/editor/editor.h index 8e39ada0..14dcbcfd 100644 --- a/editor/editor.h +++ b/editor/editor.h @@ -27,10 +27,13 @@ void EditorMain ( void ); void FreeEditor ( void ); extern int com_argc; +extern int dev_mode; extern bool debug_mode; extern platform_exp_t *pi; extern char *com_argv[MAX_NUM_ARGVS]; int CheckParm (const char *parm); +bool _GetParmFromCmdLine( char *parm, char *out, size_t size ); +#define GetParmFromCmdLine( parm, out ) _GetParmFromCmdLine( parm, out, sizeof(out)) /* =========================================== @@ -38,7 +41,7 @@ System Events =========================================== */ void GUI_Msg( const char *pMsg, ... ); -void GUI_MsgDev( const char *pMsg, ... ); +void GUI_MsgDev( int level, const char *pMsg, ... ); void GUI_MsgWarn( const char *pMsg, ... ); extern stdinout_api_t std; diff --git a/editor/editor.plg b/editor/editor.plg index fff17474..cb2e0b18 100644 --- a/editor/editor.plg +++ b/editor/editor.plg @@ -3,41 +3,9 @@
 

Build Log

---------------------Configuration: editor - Win32 Debug-------------------- +--------------------Configuration: editor - Win32 Release--------------------

Command Lines

-Creating temporary file "C:\Temp\RSP2FD7.tmp" with contents -[ -/nologo /MTd /W3 /Gm /Gi /GX /ZI /Od /I "../public" /I "../platform/formats" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\editor\!debug/" /Fo"..\temp\editor\!debug/" /Fd"..\temp\editor\!debug/" /FD /GZ /c -"D:\XASH3D\src_main\!source\editor\editor.c" -"D:\XASH3D\src_main\!source\editor\guiutils.c" -"D:\XASH3D\src_main\!source\editor\guiforms.c" -] -Creating command line "cl.exe @C:\Temp\RSP2FD7.tmp" -Creating temporary file "C:\Temp\RSP2FD8.tmp" with contents -[ -kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib /nologo /dll /incremental:yes /pdb:"..\temp\editor\!debug/editor.pdb" /debug /machine:I386 /out:"..\temp\editor\!debug/editor.dll" /implib:"..\temp\editor\!debug/editor.lib" /pdbtype:sept -"\XASH3D\src_main\!source\temp\editor\!debug\editor.obj" -"\XASH3D\src_main\!source\temp\editor\!debug\guiutils.obj" -"\XASH3D\src_main\!source\temp\editor\!debug\guiforms.obj" -"\XASH3D\src_main\!source\temp\editor\!debug\editor.res" -] -Creating command line "link.exe @C:\Temp\RSP2FD8.tmp" -Creating temporary file "C:\Temp\RSP2FD9.bat" with contents -[ -@echo off -copy \XASH3D\src_main\!source\temp\editor\!debug\editor.dll "D:\Xash3D\bin\editor.dll" -] -Creating command line "C:\Temp\RSP2FD9.bat" -Compiling... -editor.c -guiutils.c -guiforms.c -Generating Code... -Linking... -

Output Window

-Performing Custom Build Step on \XASH3D\src_main\!source\temp\editor\!debug\editor.dll -‘Є®ЇЁа®ў ­® д ©«®ў: 1. diff --git a/editor/guiforms.c b/editor/guiforms.c index e5feda6b..88a4c2f2 100644 --- a/editor/guiforms.c +++ b/editor/guiforms.c @@ -418,8 +418,13 @@ GUI Acellerators void GUI_ResetWndOptions( void ) { + char dev_level[4]; + //get info about debug mode if(CheckParm ("-debug")) debug_mode = true; + if(GetParmFromCmdLine("-dev", dev_level )) + dev_mode = atoi(dev_level); + s_gui.gHinst = (HINSTANCE) GetModuleHandle( NULL ); //reset options @@ -646,12 +651,12 @@ void GUI_Msg( const char *pMsg, ... ) std.print( text ); } -void GUI_MsgDev( const char *pMsg, ... ) +void GUI_MsgDev( int level, const char *pMsg, ... ) { va_list argptr; char text[MAX_INPUTLINE]; - if(debug_mode) + if(dev_mode >= level) { va_start (argptr, pMsg); vsprintf (text, pMsg, argptr); @@ -1010,7 +1015,7 @@ void InitEditor ( char *funcname, int argc, char **argv ) //end of all initializations ShowWindow(s_gui.hWnd, SW_SHOWDEFAULT); - MsgDev("------- Xash Recource Editor ver. %g initialized -------\n", EDITOR_VERSION ); + MsgDev(D_INFO, "------- Xash Recource Editor ver. %g initialized -------\n", EDITOR_VERSION ); } void EditorMain ( void ) diff --git a/editor/guiutils.c b/editor/guiutils.c index 8c043ea3..9b8cc7bb 100644 --- a/editor/guiutils.c +++ b/editor/guiutils.c @@ -6,6 +6,7 @@ #include "editor.h" bool debug_mode = false; +int dev_mode = 0; int com_argc; char *com_argv[MAX_NUM_ARGVS]; /* @@ -29,6 +30,17 @@ int CheckParm (const char *parm) return 0; } +bool _GetParmFromCmdLine( char *parm, char *out, size_t size ) +{ + int argc = CheckParm( parm ); + + if(!argc) return false; + if(!out) return false; + + strncpy( out, com_argv[argc+1], size ); + return true; +} + // search case-insensitive for string2 in string char *stristr( const char *string, const char *string2 ) { diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 13af5f33..c1f72fa9 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -23,7 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cvar_t *cl_nodelta; -extern unsigned sys_frame_time; unsigned frame_msec; unsigned old_sys_frame_time; @@ -94,7 +93,7 @@ void KeyDown (kbutton_t *b) c = Cmd_Argv(2); b->downtime = atoi(c); if (!b->downtime) - b->downtime = (uint)sys_frame_time - 0.1; + b->downtime = host.cl_timer - 100; b->state |= 1 + 2; // down + impulse down } @@ -194,8 +193,8 @@ float CL_KeyState (kbutton_t *key) if (key->state) { // still down - msec += sys_frame_time - key->downtime; - key->downtime = sys_frame_time; + msec += host.cl_timer - key->downtime; + key->downtime = host.cl_timer; } #if 0 @@ -206,10 +205,8 @@ float CL_KeyState (kbutton_t *key) #endif val = (float)msec / frame_msec; - if (val < 0) - val = 0; - if (val > 1) - val = 1; + if (val < 0) val = 0; + if (val > 1) val = 1; return val; } @@ -377,11 +374,9 @@ usercmd_t CL_CreateCmd (void) { usercmd_t cmd; - frame_msec = sys_frame_time - old_sys_frame_time; - if (frame_msec < 1) - frame_msec = 1; - if (frame_msec > 200) - frame_msec = 200; + frame_msec = host.cl_timer - old_sys_frame_time; + if (frame_msec < 1) frame_msec = 1; + if (frame_msec > 200) frame_msec = 200; // get basic movement from keyboard CL_BaseMove (&cmd); @@ -391,9 +386,9 @@ usercmd_t CL_CreateCmd (void) CL_FinishMove (&cmd); - old_sys_frame_time = sys_frame_time; + old_sys_frame_time = host.cl_timer; -//cmd.impulse = cls.framecount; + //cmd.impulse = cls.framecount; return cmd; } @@ -482,7 +477,7 @@ void CL_SendCmd (void) if ( cls.state == ca_connected) { - if (cls.netchan.message.cursize || curtime - cls.netchan.last_sent > 1.0f ) + if (cls.netchan.message.cursize || host.realtime - cls.netchan.last_sent > 1.0f ) Netchan_Transmit (&cls.netchan, 0, buf.data); return; } diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index ca6f693b..260314c6 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -462,7 +462,7 @@ void CL_CheckForResend (void) if (cls.state != ca_connecting) return; - if (cls.realtime - cls.connect_time < 3000) + if (cls.realtime - cls.connect_time < 3.0f) return; if (!NET_StringToAdr (cls.servername, &adr)) @@ -616,15 +616,6 @@ void CL_Disconnect (void) if (cls.state == ca_disconnected) return; - if (cl_timedemo && cl_timedemo->value) - { - float time; - - time = Sys_DoubleTime() - cl.timedemo_start; - if (time > 0) - Msg ("%i frames, %3.1f seconds: %3.1f fps\n", cl.timedemo_frames, time, cl.timedemo_frames / time); - } - VectorClear (cl.refdef.blend); re->CinematicSetPalette(NULL); @@ -726,8 +717,7 @@ void CL_Changing_f (void) { //ZOID //if we are downloading, we don't change! This so we don't suddenly stop downloading a map - if (cls.download) - return; + if (cls.download) return; SCR_BeginLoadingPlaque (); cls.state = ca_connected; // not active anymore, but not disconnected @@ -761,7 +751,7 @@ void CL_Reconnect_f (void) if (*cls.servername) { if (cls.state >= ca_connected) { CL_Disconnect(); - cls.connect_time = cls.realtime - 1500; + cls.connect_time = cls.realtime - 1.5f; } else cls.connect_time = -99999; // fire immediately @@ -1411,7 +1401,8 @@ CL_InitLocal void CL_InitLocal (void) { cls.state = ca_disconnected; - cls.realtime = Sys_DoubleTime(); + cls.realtime = 1.0f; + CL_InitInput (); adr0 = Cvar_Get( "adr0", "", CVAR_ARCHIVE ); @@ -1424,9 +1415,9 @@ void CL_InitLocal (void) adr7 = Cvar_Get( "adr7", "", CVAR_ARCHIVE ); adr8 = Cvar_Get( "adr8", "", CVAR_ARCHIVE ); -// -// register our variables -// + // + // register our variables + // cl_stereo_separation = Cvar_Get( "cl_stereo_separation", "0.4", CVAR_ARCHIVE ); cl_stereo = Cvar_Get( "cl_stereo", "0", 0 ); @@ -1681,7 +1672,7 @@ void CL_Frame (float time) static float extratime; static float lasttimecalled; - if (dedicated->value) return; + if (host.type == HOST_DEDICATED) return; extratime += time; @@ -1722,9 +1713,7 @@ void CL_Frame (float time) CL_PrepRefresh (); // update the screen - if (host_speeds->value) time_before_ref = Sys_DoubleTime(); SCR_UpdateScreen (); - if (host_speeds->value) time_after_ref = Sys_DoubleTime(); // update audio S_Update (cl.refdef.vieworg, cl.v_forward, cl.v_right, cl.v_up); @@ -1748,8 +1737,8 @@ CL_Init */ void CL_Init (void) { - if (dedicated->value) - return; // nothing running on the client + // nothing running on the client + if (host.type == HOST_DEDICATED) return; // all archived variables will now be loaded diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index a6cfbd50..ef346871 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -296,14 +296,13 @@ void CL_ParseServerData (void) char *str; int i; - MsgDev ("Serverdata packet received.\n"); -// -// wipe the client_state_t struct -// + MsgDev (D_INFO, "Serverdata packet received.\n"); + + // wipe the client_state_t struct CL_ClearState (); cls.state = ca_connected; -// parse protocol version number + // parse protocol version number i = MSG_ReadLong (&net_message); cls.serverProtocol = i; diff --git a/engine/client/cl_scrn.c b/engine/client/cl_scrn.c index 90499f4f..988493a6 100644 --- a/engine/client/cl_scrn.c +++ b/engine/client/cl_scrn.c @@ -570,20 +570,19 @@ SCR_BeginLoadingPlaque void SCR_BeginLoadingPlaque (void) { S_StopAllSounds (); - cl.sound_prepped = false; // don't play ambients + cl.sound_prepped = false; // don't play ambients if (cls.disable_screen) return; - if (developer->value) - return; - if (cls.state == ca_disconnected) - return; // if at console, don't bring up the plaque + if (host.developer) return; + + if (cls.state == ca_disconnected) return; // if at console, don't bring up the plaque if (cls.key_dest == key_console) return; if (cl.cinematictime > 0) - scr_draw_loading = 2; // clear to black first - else - scr_draw_loading = 1; - SCR_UpdateScreen (); - cls.disable_screen = Sys_DoubleTime(); + scr_draw_loading = 2; // clear to black first + else scr_draw_loading = 1; + SCR_UpdateScreen(); + + cls.disable_screen = cls.realtime; cls.disable_servercount = cl.servercount; } @@ -1269,7 +1268,7 @@ void SCR_UpdateScreen (void) // do nothing at all if (cls.disable_screen) { - if (Sys_DoubleTime() - cls.disable_screen > 120.0f) + if (cls.realtime - cls.disable_screen > 120.0f) { cls.disable_screen = 0; Msg ("Loading plaque timed out.\n"); diff --git a/engine/client/cl_view.c b/engine/client/cl_view.c index 02ec7506..4ec3398b 100644 --- a/engine/client/cl_view.c +++ b/engine/client/cl_view.c @@ -445,13 +445,6 @@ void V_RenderView( float stereo_separation ) if (!cl.refresh_prepped) return; // still loading - if (cl_timedemo->value) - { - if (!cl.timedemo_start) - cl.timedemo_start = Sys_DoubleTime(); - cl.timedemo_frames++; - } - // an invalid frame will just use the exact previous refdef // we can't use the old frame if the video mode has changed, though... if ( cl.frame.valid && (cl.force_refdef || !cl_paused->value) ) diff --git a/engine/common.h b/engine/common.h index 3d51e3cc..031c36fe 100644 --- a/engine/common.h +++ b/engine/common.h @@ -136,10 +136,9 @@ void MSG_ReadData (sizebuf_t *sb, void *buffer, int size); //============================================================================ -int COM_Argc (void); +int COM_Argc (void); char *COM_Argv (int arg); // range and null checked void COM_ClearArgv (int arg); -int COM_CheckParm (char *parm); void COM_Init (void); void COM_InitArgv (int argc, char **argv); @@ -628,20 +627,17 @@ MISC #define EXEC_INSERT 1 // insert at current position, but don't run yet #define EXEC_APPEND 2 // add to end of the command buffer -#define PRINT_ALL 0 -#define PRINT_DEVELOPER 1 // only print when "developer 1" +void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush)); +void Com_EndRedirect (void); +void Com_Printf (char *fmt, ...); +void Com_DPrintf (int level, char *fmt, ...); +void Com_DWarnf (char *fmt, ...); +void Com_Error (int code, char *fmt, ...); +void Com_Error_f ( void ); +void Com_Quit (void); -void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush)); -void Com_EndRedirect (void); -void Com_Printf (char *fmt, ...); -void Com_DPrintf (char *fmt, ...); -void Com_DWarnf (char *fmt, ...); -void Com_Error (int code, char *fmt, ...); -void Com_Error_f ( void ); -void Com_Quit (void); - -int Com_ServerState (void); // this should have just been a cvar... -void Com_SetServerState (int state); +int Com_ServerState (void); // this should have just been a cvar... +void Com_SetServerState (int state); unsigned Com_BlockChecksum (void *buffer, int length); byte COM_BlockSequenceCRCByte (byte *base, int length, int sequence); @@ -649,16 +645,8 @@ byte COM_BlockSequenceCRCByte (byte *base, int length, int sequence); float frand(void); // 0 to 1 float crand(void); // -1 to 1 -extern cvar_t *developer; -extern cvar_t *dedicated; extern cvar_t *host_speeds; -// host_speeds times -extern float time_before_game; -extern float time_after_game; -extern float time_before_ref; -extern float time_after_ref; - #define NUMVERTEXNORMALS 162 extern vec3_t bytedirs[NUMVERTEXNORMALS]; diff --git a/engine/common/cmd.c b/engine/common/cmd.c index c7c91beb..ed1da89a 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -234,7 +234,7 @@ void Cbuf_Execute (void) memmove (text, text+i, cmd_text.cursize); } -// execute the command line + // execute the command line Cmd_ExecuteString (line); if (cmd_wait) @@ -301,7 +301,7 @@ bool Cbuf_AddLateCommands (void) int argc; bool ret; -// build the combined string to parse from + // build the combined string to parse from s = 0; argc = COM_Argc(); for (i=1 ; i 0 ================ */ -void Com_DPrintf (char *fmt, ...) +void Com_DPrintf (int level, char *fmt, ...) { va_list argptr; char msg[MAXPRINTMSG]; - if (!host_debug) return; // don't confuse non-developers with techie stuff... - - va_start (argptr,fmt); - vsprintf (msg,fmt,argptr); - va_end (argptr); + // don't confuse non-developers with techie stuff... + if(host.developer >= level) + { + va_start (argptr,fmt); + vsprintf (msg,fmt,argptr); + va_end (argptr); - Msg ("%s", msg); + Msg ("%s", msg); + } } /* @@ -200,7 +194,8 @@ void Com_DWarnf (char *fmt, ...) va_list argptr; char msg[MAXPRINTMSG]; - if (!host_debug) return; // don't confuse non-developers with techie stuff... + // don't confuse non-developers with techie stuff... + if (!host.debug) return; va_start (argptr,fmt); vsprintf (msg,fmt,argptr); @@ -249,27 +244,36 @@ void Com_SetServerState (int state) /* ================ -COM_CheckParm +CheckParm Returns the position (1 to argc-1) in the program's argument list where the given parameter apears, or 0 if not present ================ */ -int COM_CheckParm (char *parm) +int CheckParm (const char *parm) { - int i; - - for (i=1 ; i MAX_NUM_ARGVS) { @@ -312,6 +317,12 @@ void COM_InitArgv (int argc, char **argv) com_argv[i] = ""; else com_argv[i] = argv[i]; } + + // determine debug and developer mode + if (CheckParm ("-debug")) host.debug = true; + + if(GetParmFromCmdLine("-dev", dev_level )) + host.developer = atoi(dev_level); } char *CopyString (const char *in) diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index 0af0e874..cf86bff1 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -158,7 +158,7 @@ void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t adr, int qport) chan->sock = sock; chan->remote_address = adr; chan->qport = qport; - chan->last_received = curtime; + chan->last_received = host.realtime; chan->incoming_sequence = 0; chan->outgoing_sequence = 1; @@ -238,14 +238,14 @@ void Netchan_Transmit (netchan_t *chan, int length, byte *data) } -// write the packet header + // write the packet header SZ_Init (&send, send_buf, sizeof(send_buf)); w1 = ( chan->outgoing_sequence & ~(1<<31) ) | (send_reliable<<31); w2 = ( chan->incoming_sequence & ~(1<<31) ) | (chan->incoming_reliable_sequence<<31); chan->outgoing_sequence++; - chan->last_sent = curtime; + chan->last_sent = host.realtime; MSG_WriteLong (&send, w1); MSG_WriteLong (&send, w2); @@ -352,22 +352,19 @@ bool Netchan_Process (netchan_t *chan, sizebuf_t *msg) if (chan->dropped > 0) { if (showdrop->value) - Msg ("%s:Dropped %i packets at %i\n" - , NET_AdrToString (chan->remote_address) - , chan->dropped - , sequence); + Msg ("%s:Dropped %i packets at %i\n", NET_AdrToString (chan->remote_address), chan->dropped, sequence); } -// -// if the current outgoing reliable message has been acknowledged -// clear the buffer to make way for the next -// + // + // if the current outgoing reliable message has been acknowledged + // clear the buffer to make way for the next + // if (reliable_ack == chan->reliable_sequence) chan->reliable_length = 0; // it has been received -// -// if this message contains a reliable message, bump incoming_reliable_sequence -// + // + // if this message contains a reliable message, bump incoming_reliable_sequence + // chan->incoming_sequence = sequence; chan->incoming_acknowledged = sequence_ack; chan->incoming_reliable_acknowledged = reliable_ack; @@ -376,10 +373,10 @@ bool Netchan_Process (netchan_t *chan, sizebuf_t *msg) chan->incoming_reliable_sequence ^= 1; } -// -// the message can now be read from the current message pointer -// - chan->last_received = curtime; + // + // the message can now be read from the current message pointer + // + chan->last_received = host.realtime; return true; } diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index ccc8dfb5..edbb86fa 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -367,12 +367,9 @@ bool NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) continue; } - if (dedicated->value) // let dedicated servers continue after errors - Msg ("NET_GetPacket: %s from %s\n", NET_ErrorString(), - NET_AdrToString(*net_from)); - else - Com_Error (ERR_DROP, "NET_GetPacket: %s from %s", - NET_ErrorString(), NET_AdrToString(*net_from)); + if (host.type == HOST_DEDICATED) // let dedicated servers continue after errors + Msg ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from)); + else Com_Error (ERR_DROP, "NET_GetPacket: %s from %s", NET_ErrorString(), NET_AdrToString(*net_from)); continue; } @@ -444,10 +441,9 @@ void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to) if ((err == WSAEADDRNOTAVAIL) && ((to.type == NA_BROADCAST) || (to.type == NA_BROADCAST_IPX))) return; - if (dedicated->value) // let dedicated servers continue after errors + if (host.type == HOST_DEDICATED) // let dedicated servers continue after errors { - Msg ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(), - NET_AdrToString (to)); + Msg ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(), NET_AdrToString (to)); } else { @@ -533,13 +529,10 @@ NET_OpenIP void NET_OpenIP (void) { cvar_t *ip; - int port; - int dedicated; + int port; ip = Cvar_Get ("ip", "localhost", CVAR_NOSET); - dedicated = Cvar_VariableValue ("dedicated"); - if (!ip_sockets[NS_SERVER]) { port = Cvar_Get("ip_hostport", "0", CVAR_NOSET)->value; @@ -552,12 +545,13 @@ void NET_OpenIP (void) } } ip_sockets[NS_SERVER] = NET_IPSocket (ip->string, port); - if (!ip_sockets[NS_SERVER] && dedicated) Sys_Error("Couldn't allocate dedicated server IP port"); + if (!ip_sockets[NS_SERVER] && host.type == HOST_DEDICATED) + Sys_Error("Couldn't allocate dedicated server IP port"); } // dedicated servers don't need client ports - if (dedicated) return; + if (host.type == HOST_DEDICATED) return; if (!ip_sockets[NS_CLIENT]) { @@ -636,9 +630,6 @@ NET_OpenIPX void NET_OpenIPX (void) { int port; - int dedicated; - - dedicated = Cvar_VariableValue ("dedicated"); if (!ipx_sockets[NS_SERVER]) { @@ -655,8 +646,7 @@ void NET_OpenIPX (void) } // dedicated servers don't need client ports - if (dedicated) - return; + if (host.type == HOST_DEDICATED) return; if (!ipx_sockets[NS_CLIENT]) { @@ -681,7 +671,7 @@ NET_Config A single player game will only use the loopback code ==================== */ -void NET_Config (bool multiplayer) +void NET_Config (bool multiplayer) { int i; static bool old_config; @@ -719,24 +709,23 @@ void NET_Config (bool multiplayer) // sleeps msec or until net socket is ready void NET_Sleep(float time) { - struct timeval timeout; - fd_set fdset; - extern cvar_t *dedicated; - int i; - - if (!dedicated || !dedicated->value) - return; // we're not a server, just run full speed + struct timeval timeout; + fd_set fdset; + int i = 0; + // we're not a server, just run full speed + if (host.type == HOST_NORMAL) return; FD_ZERO(&fdset); - i = 0; - if (ip_sockets[NS_SERVER]) { + + if (ip_sockets[NS_SERVER]) + { FD_SET(ip_sockets[NS_SERVER], &fdset); // network socket i = ip_sockets[NS_SERVER]; } - if (ipx_sockets[NS_SERVER]) { + if (ipx_sockets[NS_SERVER]) + { FD_SET(ipx_sockets[NS_SERVER], &fdset); // network socket - if (ipx_sockets[NS_SERVER] > i) - i = ipx_sockets[NS_SERVER]; + if (ipx_sockets[NS_SERVER] > i) i = ipx_sockets[NS_SERVER]; } timeout.tv_sec = time; timeout.tv_usec = fmod(time, 1.0f) * 1.0f; diff --git a/engine/engine.dsp b/engine/engine.dsp index 927bb526..8d025685 100644 --- a/engine/engine.dsp +++ b/engine/engine.dsp @@ -408,10 +408,6 @@ SOURCE=.\common\vid.h SOURCE=.\prvm\vm_cmds.h # End Source File -# Begin Source File - -SOURCE=.\prvm\vm_exec.h -# End Source File # End Group # End Target # End Project diff --git a/engine/engine.h b/engine/engine.h index 609d946b..64655acd 100644 --- a/engine/engine.h +++ b/engine/engine.h @@ -34,7 +34,47 @@ extern jmp_buf abortframe; extern int host_debug; -int Sys_Milliseconds (void); +typedef enum +{ + HOST_INIT, // initalize operations + HOST_FRAME, // host running + HOST_SHUTDOWN, // shutdown operations + HOST_ERROR, // host stopped by error + HOST_SLEEP, // sleeped by different reason, e.g. minimize window + HOST_NOFOCUS, // same as HOST_FRAME, but disable mouse and joy + +} host_state; + +typedef enum +{ + HOST_OFFLINE, // host not running + HOST_NORMAL, // normal mode + HOST_DEDICATED, // dedicated mode +} host_mode; + +typedef struct host_parm_s +{ + host_state state; // global host state + host_mode type; // running at + + bool debug; // show all warnings mode + int developer; // show all developer's message + + bool paused; // freeze server + + dword framecount; // global framecount + double realtime; // host realtime + uint sv_timer; // SV_Input msg time + uint cl_timer; // CL_Input msg time + + uint maxclients; // host max clients + +} host_parm_t; + +extern host_parm_t host; + +bool _GetParmFromCmdLine( char *parm, char *out, size_t size ); +#define GetParmFromCmdLine( parm, out ) _GetParmFromCmdLine( parm, out, sizeof(out)) /* =========================================== diff --git a/engine/engine.plg b/engine/engine.plg index 8cf436f0..0f104c2e 100644 --- a/engine/engine.plg +++ b/engine/engine.plg @@ -6,13 +6,13 @@ --------------------Configuration: engine - Win32 Debug--------------------

Command Lines

-Creating temporary file "C:\Temp\RSP31BD.tmp" with contents +Creating temporary file "C:\Temp\RSP199.tmp" with contents [ /nologo /MTd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "prvm" /I "common" /I "server" /I "client" /I "../public" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\engine\!debug/" /Fo"..\temp\engine\!debug/" /Fd"..\temp\engine\!debug/" /FD /c -"D:\XASH3D\src_main\!source\engine\system.c" +"D:\XASH3D\src_main\!source\engine\server\sv_phys.c" ] -Creating command line "cl.exe @C:\Temp\RSP31BD.tmp" -Creating temporary file "C:\Temp\RSP31BE.tmp" with contents +Creating command line "cl.exe @C:\Temp\RSP199.tmp" +Creating temporary file "C:\Temp\RSP19A.tmp" with contents [ gdi32.lib winmm.lib kernel32.lib user32.lib wsock32.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\engine\!debug/engine.pdb" /debug /machine:I386 /out:"..\temp\engine\!debug/engine.dll" /implib:"..\temp\engine\!debug/engine.lib" /pdbtype:sept "\XASH3D\src_main\!source\temp\engine\!debug\cl_cin.obj" @@ -66,15 +66,15 @@ gdi32.lib winmm.lib kernel32.lib user32.lib wsock32.lib /nologo /subsystem:windo "\XASH3D\src_main\!source\temp\engine\!debug\vm_edict.obj" "\XASH3D\src_main\!source\temp\engine\!debug\vm_exec.obj" ] -Creating command line "link.exe @C:\Temp\RSP31BE.tmp" -Creating temporary file "C:\Temp\RSP31BF.bat" with contents +Creating command line "link.exe @C:\Temp\RSP19A.tmp" +Creating temporary file "C:\Temp\RSP19B.bat" with contents [ @echo off copy \XASH3D\src_main\!source\temp\engine\!debug\engine.dll "D:\Xash3D\bin\engine.dll" ] -Creating command line "C:\Temp\RSP31BF.bat" +Creating command line "C:\Temp\RSP19B.bat" Compiling... -system.c +sv_phys.c Linking...

Output Window

Performing Custom Build Step on \XASH3D\src_main\!source\temp\engine\!debug\engine.dll diff --git a/engine/host.c b/engine/host.c index 3c63d4cd..8de85df0 100644 --- a/engine/host.c +++ b/engine/host.c @@ -9,15 +9,13 @@ #include "engine.h" #include "progsvm.h" -platform_exp_t *pi; //fundamental callbacks +platform_exp_t *pi; // fundamental callbacks +host_parm_t host; // host parms byte *zonepool; int ActiveApp; -bool Minimized; -bool is_dedicated; -extern uint sys_msg_time; -dword host_framecount = 0; +// host params void Key_Init (void); void SCR_EndLoadingPlaque (void); @@ -29,17 +27,11 @@ cvar_t *timescale; cvar_t *fixedtime; cvar_t *showtrace; -int host_debug; - void Host_InitPlatform( char *funcname, int argc, char **argv ) { stdinout_api_t pistd; platform_t CreatePlat; - //platform dll - COM_InitArgv (argc, argv); - if (COM_CheckParm ("-debug")) host_debug = 1; - //make callbacks pistd.printf = Msg; pistd.dprintf = MsgDev; @@ -86,19 +78,23 @@ void Host_Init (char *funcname, int argc, char **argv) { char *s; + host.state = HOST_INIT; //initialzation started + global_hInstance = (HINSTANCE)GetModuleHandle( NULL ); - if(!strcmp(funcname, "host_dedicated"))is_dedicated = true; + + if(!strcmp(funcname, "host_dedicated")) host.type = HOST_DEDICATED; + else if(!strcmp(funcname, "host_shared")) host.type = HOST_NORMAL; + else host.type = HOST_OFFLINE; // launcher can loading engine for some reasons + + COM_InitArgv (argc, argv); // init host.debug & host.developer here Host_InitPlatform( funcname, argc, argv ); - Msg("------- Loading bin/engine.dll [%g] -------\n", ENGINE_VERSION ); + MsgDev(D_INFO, "------- Loading bin/engine.dll [%g] -------\n", ENGINE_VERSION ); - Cbuf_Init (); - - Cmd_Init (); - Cvar_Init (); - - Key_Init (); - + Cbuf_Init(); + Cmd_Init(); + Cvar_Init(); + Key_Init(); PRVM_Init(); // we need to add the early commands twice, because @@ -117,17 +113,17 @@ void Host_Init (char *funcname, int argc, char **argv) Cmd_AddCommand ("error", Com_Error_f); host_speeds = Cvar_Get ("host_speeds", "0", 0); - developer = Cvar_Get ("developer", "0", 0); timescale = Cvar_Get ("timescale", "1", 0); fixedtime = Cvar_Get ("fixedtime", "0", 0); showtrace = Cvar_Get ("showtrace", "0", 0); - if(is_dedicated) dedicated = Cvar_Get ("dedicated", "1", CVAR_NOSET); - else dedicated = Cvar_Get ("dedicated", "0", CVAR_NOSET); s = va("%4.2f %s %s %s", VERSION, "x86", __DATE__, BUILDSTRING); Cvar_Get ("version", s, CVAR_SERVERINFO|CVAR_NOSET); - if (dedicated->value) Cmd_AddCommand ("quit", Com_Quit); + if (host.type == HOST_DEDICATED) + { + Cmd_AddCommand ("quit", Com_Quit); + } Sys_Init(); @@ -138,10 +134,10 @@ void Host_Init (char *funcname, int argc, char **argv) CL_Init(); // add + commands from command line - if (!Cbuf_AddLateCommands ()) + if (!Cbuf_AddLateCommands()) { // if the user didn't give any commands, run default action - if (!dedicated->value) Cbuf_AddText ("d1\n"); + if(host.type == HOST_NORMAL) Cbuf_AddText ("d1\n"); else Cbuf_AddText ("dedicated_start\n"); Cbuf_Execute (); } @@ -160,7 +156,6 @@ Host_Frame void Host_Frame (double time) { char *s; - static double time_before, time_between, time_after; if (setjmp (abortframe) ) return; // an ERR_DROP was thrown @@ -182,29 +177,10 @@ void Host_Frame (double time) } while (s); Cbuf_Execute (); - if (host_speeds->value) time_before = Sys_DoubleTime(); - SV_Frame (time); - - if (host_speeds->value) time_between = Sys_DoubleTime(); - CL_Frame (time); - if (host_speeds->value) time_after = Sys_DoubleTime(); - - if (host_speeds->value) - { - double all, sv, gm, cl, rf; - - all = time_after - time_before; - sv = time_between - time_before; - cl = time_after - time_between; - gm = time_after_game - time_before_game; - rf = time_after_ref - time_before_ref; - sv -= gm; - cl -= rf; - Msg ("all:%.3f sv:%.3f gm:%.3f cl:%.3f rf:%.3f\n", all, sv, gm, cl, rf); - } + host.framecount++; } /* @@ -214,32 +190,34 @@ Host_Main */ void Host_Main( void ) { - MSG msg; - float oldtime, newtime; + MSG msg; + static double oldtime, newtime; + host.state = HOST_FRAME; oldtime = Sys_DoubleTime(); //first call // main window message loop - while (1) + while (host.type != HOST_OFFLINE) { // if at a full screen console, don't update unless needed - if (Minimized || (dedicated && dedicated->value) ) + if (host.type == HOST_DEDICATED ) { - Sleep(1); + Sleep( 1 ); } - + else if(host.state == HOST_SLEEP) Sleep( 100 ); + while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage (&msg, NULL, 0, 0)) Com_Quit (); - sys_msg_time = msg.time; + host.sv_timer = msg.time; TranslateMessage (&msg); DispatchMessage (&msg); } newtime = Sys_DoubleTime(); - curtime = newtime - oldtime; + host.realtime = newtime - oldtime; - Host_Frame (curtime); + Host_Frame (host.realtime); oldtime = newtime; } } @@ -252,6 +230,9 @@ Host_Shutdown */ void Host_Free (void) { + host.state = HOST_SHUTDOWN; + + SV_Shutdown ("Server shutdown\n", false); CL_Shutdown (); Host_FreePlatform(); } \ No newline at end of file diff --git a/engine/in_win.c b/engine/in_win.c index 286e9837..85313429 100644 --- a/engine/in_win.c +++ b/engine/in_win.c @@ -24,9 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "engine.h" #include "./client/client.h" -extern unsigned sys_msg_time; extern HWND cl_hwnd; -extern bool ActiveApp, Minimized; // joystick defines and variables // where should defines be moved? @@ -251,13 +249,13 @@ void IN_MouseEvent (int mstate) if ( (mstate & (1<value) + if (host.debug) { VM_VarString(0, string, sizeof(string)); Msg("%s", string); @@ -705,12 +705,12 @@ void VM_remove (void) ed = PRVM_G_EDICT(OFS_PARM0); if( PRVM_NUM_FOR_EDICT(ed) <= prog->reserved_edicts ) { - if (developer->value >= 1) + if (host.developer >= D_INFO) VM_Warning( "VM_remove: tried to remove the null entity or a reserved entity!\n" ); } else if( ed->priv.ed->free ) { - if (developer->value >= 1) + if (host.developer >= D_INFO) VM_Warning( "VM_remove: tried to remove an already freed entity!\n" ); } else @@ -1486,13 +1486,13 @@ void VM_fopen(void) if (prog->openfiles[filenum] == NULL) { PRVM_G_FLOAT(OFS_RETURN) = -1; - if (developer->value >= 100) + if (host.developer >= D_WARN) VM_Warning("VM_fopen: %s: %s mode %s failed\n", PRVM_NAME, filename, modestring); } else { PRVM_G_FLOAT(OFS_RETURN) = filenum; - if (developer->value >= 100) + if (host.developer >= D_WARN) Msg("VM_fopen: %s: %s mode %s opened as #%i\n", PRVM_NAME, filename, modestring, filenum); } } @@ -1524,7 +1524,7 @@ void VM_fclose(void) } FS_Close(prog->openfiles[filenum]); prog->openfiles[filenum] = NULL; - if (developer->value >= 100) + if (host.developer >= D_WARN) Msg("VM_fclose: %s: #%i closed\n", PRVM_NAME, filenum); } @@ -1558,7 +1558,7 @@ void VM_fgets(void) c = FS_Gets (prog->openfiles[filenum], string, VM_STRINGTEMP_LENGTH ); - if (developer->value >= 100) Msg("fgets: %s: %s\n", PRVM_NAME, string); + if (host.developer >= D_WARN) Msg("fgets: %s: %s\n", PRVM_NAME, string); if (c >= 0) PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(string); else PRVM_G_INT(OFS_RETURN) = 0; @@ -1594,7 +1594,7 @@ void VM_fputs(void) VM_VarString(1, string, sizeof(string)); if ((stringlength = (int)strlen(string))) FS_Write(prog->openfiles[filenum], string, stringlength); - if (developer->value >= 100) + if (host.developer >= D_WARN) Msg("fputs: %s: %s\n", PRVM_NAME, string); } diff --git a/engine/prvm/vm_edict.c b/engine/prvm/vm_edict.c index 1736e2b1..565e15bc 100644 --- a/engine/prvm/vm_edict.c +++ b/engine/prvm/vm_edict.c @@ -759,7 +759,7 @@ For debugging ============= */ // 2 possibilities : 1. just displaying the active edict count -// 2. making a function pointer [x] +// 2. making a function pointer [x] void PRVM_ED_Count_f (void) { int i; @@ -866,7 +866,7 @@ void PRVM_ED_ParseGlobals (const char *data) key = PRVM_ED_FindGlobal (keyname); if (!key) { - MsgDev("'%s' is not a global on %s\n", keyname, PRVM_NAME); + MsgDev(D_INFO, "'%s' is not a global on %s\n", keyname, PRVM_NAME); continue; } @@ -946,7 +946,7 @@ bool PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s) s++; i = atoi(s); if (i >= prog->limit_edicts) - Msg("PRVM_ED_ParseEpair: ev_entity reference too large (edict %u >= MAX_EDICTS %u) on %s\n", (unsigned int)i, (unsigned int)MAX_EDICTS, PRVM_NAME); + MsgDev(D_WARN, "PRVM_ED_ParseEpair: ev_entity reference too large (edict %u >= MAX_EDICTS %u) on %s\n", (uint)i, (uint)MAX_EDICTS, PRVM_NAME); while (i >= prog->max_edicts) PRVM_MEM_IncreaseEdicts(); //SV_IncreaseEdicts(); @@ -960,7 +960,7 @@ bool PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s) def = PRVM_ED_FindField(s); if (!def) { - MsgDev("PRVM_ED_ParseEpair: Can't find field %s in %s\n", s, PRVM_NAME); + MsgDev(D_WARN, "PRVM_ED_ParseEpair: Can't find field %s in %s\n", s, PRVM_NAME); return false; } val->_int = def->ofs; @@ -970,14 +970,14 @@ bool PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s) func = PRVM_ED_FindFunction(s); if (!func) { - Msg("PRVM_ED_ParseEpair: Can't find function %s in %s\n", s, PRVM_NAME); + MsgDev(D_WARN, "PRVM_ED_ParseEpair: Can't find function %s in %s\n", s, PRVM_NAME); return false; } val->function = func - prog->functions; break; default: - Msg("PRVM_ED_ParseEpair: Unknown key->type %i for key \"%s\" on %s\n", key->type, PRVM_GetString(key->s_name), PRVM_NAME); + MsgDev(D_WARN, "PRVM_ED_ParseEpair: Unknown key->type %i for key \"%s\" on %s\n", key->type, PRVM_GetString(key->s_name), PRVM_NAME); return false; } return true; @@ -1011,9 +1011,8 @@ void PRVM_ED_EdictSet_f(void) ed = PRVM_EDICT_NUM(atoi(Cmd_Argv(2))); if((key = PRVM_ED_FindField(Cmd_Argv(3))) == 0) - Msg("Key %s not found !\n", Cmd_Argv(3)); - else - PRVM_ED_ParseEpair(ed, key, Cmd_Argv(4)); + MsgWarn("Key %s not found !\n", Cmd_Argv(3)); + else PRVM_ED_ParseEpair(ed, key, Cmd_Argv(4)); PRVM_End; } @@ -1036,14 +1035,14 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent) init = false; -// go through all the dictionary pairs + // go through all the dictionary pairs while (1) { // parse key if (!COM_Parse(&data)) PRVM_ERROR ("PRVM_ED_ParseEdict: EOF without closing brace"); - MsgDev("Key: \"%s\"", COM_Token()); + MsgDev(D_INFO, "Key: \"%s\"", COM_Token()); if (COM_Token()[0] == '}') break; strncpy (keyname, COM_Token(), sizeof(keyname)); @@ -1059,7 +1058,7 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent) // parse value if (!COM_Parse(&data)) PRVM_ERROR ("PRVM_ED_ParseEdict: EOF without closing brace"); - MsgDev(" \"%s\"\n", COM_Token()); + MsgDev(D_INFO, " \"%s\"\n", COM_Token()); if (COM_Token()[0] == '}') PRVM_ERROR ("PRVM_ED_ParseEdict: closing brace without data"); @@ -1077,7 +1076,7 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent) key = PRVM_ED_FindField (keyname); if (!key) { - MsgDev("%s: '%s' is not a field\n", PRVM_NAME, keyname); + MsgDev(D_INFO, "%s: '%s' is not a field\n", PRVM_NAME, keyname); continue; } @@ -1157,8 +1156,11 @@ void PRVM_ED_LoadFromFile (const char *data) string_t handle = *(string_t*)&((unsigned char*)ent->fields.vp)[PRVM_ED_FindFieldOffset("classname")]; if (!handle) { - Con_Print("No classname for:\n"); - PRVM_ED_Print(ent); + if(host.debug) + { + MsgWarn("No classname for:\n"); + PRVM_ED_Print(ent); + } PRVM_ED_Free (ent); continue; } @@ -1168,9 +1170,9 @@ void PRVM_ED_LoadFromFile (const char *data) if (!func) { - if (1) // don't confuse non-developers with errors + if(host.debug) { - Msg("No spawn function for:\n"); + MsgWarn("No spawn function for:\n"); PRVM_ED_Print(ent); } PRVM_ED_Free (ent); @@ -1187,7 +1189,7 @@ void PRVM_ED_LoadFromFile (const char *data) died++; } - MsgDev("%s: %i new entities parsed, %i new inhibited, %i (%i new) spawned (whereas %i removed self, %i stayed)\n", PRVM_NAME, parsed, inhibited, prog->num_edicts, spawned, died, spawned - died); + MsgDev(D_INFO, "%s: %i new entities parsed, %i new inhibited, %i (%i new) spawned (whereas %i removed self, %i stayed)\n", PRVM_NAME, parsed, inhibited, prog->num_edicts, spawned, died, spawned - died); } /* @@ -1273,7 +1275,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu if (prog->progs == NULL || filesize < (fs_offset_t)sizeof(dprograms_t)) PRVM_ERROR ("PRVM_LoadProgs: couldn't load %s for %s", filename, PRVM_NAME); - MsgDev("%s programs occupy %iK.\n", PRVM_NAME, filesize/1024); + MsgDev(D_INFO, "%s programs occupy %iK.\n", PRVM_NAME, filesize/1024); prog->filecrc = CRC_Block((unsigned char *)prog->progs, filesize); @@ -1481,7 +1483,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME); break; default: - MsgDev("PRVM_LoadProgs: unknown opcode %d at statement %d in %s\n", st->op, i, PRVM_NAME); + MsgDev(D_WARN, "PRVM_LoadProgs: unknown opcode %d at statement %d in %s\n", st->op, i, PRVM_NAME); break; } } @@ -1900,8 +1902,7 @@ int PRVM_SetEngineString(const char *s) if (prog->knownstrings[i] == s) return -1 - i; // new unknown engine string - if (developer->value >= 100) - Msg("new engine string %p\n", s); + MsgDev(D_WARN, "new engine string %p\n", s); for (i = prog->firstfreeknownstring;i < prog->numknownstrings;i++) if (!prog->knownstrings[i]) break; diff --git a/engine/prvm/vm_exec.c b/engine/prvm/vm_exec.c index 9fc1bdf8..e83d7836 100644 --- a/engine/prvm/vm_exec.c +++ b/engine/prvm/vm_exec.c @@ -478,14 +478,15 @@ PRVM_ExecuteProgram ==================== */ // LordHavoc: optimized -#define OPA ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->a]) -#define OPB ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->b]) -#define OPC ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->c]) +#define OPA ((prvm_eval_t *)&prog->globals.generic[(word) st->a]) +#define OPB ((prvm_eval_t *)&prog->globals.generic[(word) st->b]) +#define OPC ((prvm_eval_t *)&prog->globals.generic[(word) st->c]) extern cvar_t *prvm_boundscheck; extern cvar_t *prvm_traceqc; extern cvar_t *prvm_statementprofiling; -extern int PRVM_ED_FindFieldOffset (const char *field); -extern ddef_t* PRVM_ED_FindGlobal(const char *name); +extern int PRVM_ED_FindFieldOffset (const char *field); +extern ddef_t* PRVM_ED_FindGlobal(const char *name); + void PRVM_ExecuteProgram (func_t fnum, const char *errormessage) { dstatement_t *st, *startst; @@ -521,68 +522,599 @@ void PRVM_ExecuteProgram (func_t fnum, const char *errormessage) chooseexecprogram: cachedpr_trace = prog->trace; - if (prvm_statementprofiling->value) + + while (1) { -#define PRVMSTATEMENTPROFILING 1 - if (prvm_boundscheck->value) + st++; + + if (prog->trace) PRVM_PrintStatement(st); + if (prvm_statementprofiling->value) prog->statement_profile[st - prog->statements]++; + + switch (st->op) { -#define PRVMBOUNDSCHECK 1 - if (prog->trace) + case OP_ADD_F: + OPC->_float = OPA->_float + OPB->_float; + break; + case OP_ADD_V: + OPC->vector[0] = OPA->vector[0] + OPB->vector[0]; + OPC->vector[1] = OPA->vector[1] + OPB->vector[1]; + OPC->vector[2] = OPA->vector[2] + OPB->vector[2]; + break; + case OP_SUB_F: + OPC->_float = OPA->_float - OPB->_float; + break; + case OP_SUB_V: + OPC->vector[0] = OPA->vector[0] - OPB->vector[0]; + OPC->vector[1] = OPA->vector[1] - OPB->vector[1]; + OPC->vector[2] = OPA->vector[2] - OPB->vector[2]; + break; + case OP_MUL_F: + OPC->_float = OPA->_float * OPB->_float; + break; + case OP_MUL_V: + OPC->_float = OPA->vector[0]*OPB->vector[0] + OPA->vector[1]*OPB->vector[1] + OPA->vector[2]*OPB->vector[2]; + break; + case OP_MUL_FV: + OPC->vector[0] = OPA->_float * OPB->vector[0]; + OPC->vector[1] = OPA->_float * OPB->vector[1]; + OPC->vector[2] = OPA->_float * OPB->vector[2]; + break; + case OP_MUL_VF: + OPC->vector[0] = OPB->_float * OPA->vector[0]; + OPC->vector[1] = OPB->_float * OPA->vector[1]; + OPC->vector[2] = OPB->_float * OPA->vector[2]; + break; + case OP_DIV_F: + if( OPB->_float != 0.0f ) { -#define PRVMTRACE 1 -#include "vm_exec.h" -#undef PRVMTRACE + OPC->_float = OPA->_float / OPB->_float; } else { -#include "vm_exec.h" + if( host.developer >= D_WARN ) + { + prog->xfunction->profile += (st - startst); + startst = st; + prog->xstatement = st - prog->statements; + VM_Warning( "Attempted division by zero in %s\n", PRVM_NAME ); + } + OPC->_float = 0.0f; } -#undef PRVMBOUNDSCHECK - } - else - { - if (prog->trace) + break; + case OP_BITAND: + OPC->_float = (int)OPA->_float & (int)OPB->_float; + break; + case OP_BITOR: + OPC->_float = (int)OPA->_float | (int)OPB->_float; + break; + case OP_GE: + OPC->_float = OPA->_float >= OPB->_float; + break; + case OP_LE: + OPC->_float = OPA->_float <= OPB->_float; + break; + case OP_GT: + OPC->_float = OPA->_float > OPB->_float; + break; + case OP_LT: + OPC->_float = OPA->_float < OPB->_float; + break; + case OP_AND: + OPC->_float = OPA->_float && OPB->_float; + break; + case OP_OR: + OPC->_float = OPA->_float || OPB->_float; + break; + case OP_NOT_F: + OPC->_float = !OPA->_float; + break; + case OP_NOT_V: + OPC->_float = !OPA->vector[0] && !OPA->vector[1] && !OPA->vector[2]; + break; + case OP_NOT_S: + OPC->_float = !OPA->string || !*PRVM_GetString(OPA->string); + break; + case OP_NOT_FNC: + OPC->_float = !OPA->function; + break; + case OP_NOT_ENT: + OPC->_float = (OPA->edict == 0); + break; + case OP_EQ_F: + OPC->_float = OPA->_float == OPB->_float; + break; + case OP_EQ_V: + OPC->_float = (OPA->vector[0] == OPB->vector[0]) && (OPA->vector[1] == OPB->vector[1]) && (OPA->vector[2] == OPB->vector[2]); + break; + case OP_EQ_S: + OPC->_float = !strcmp(PRVM_GetString(OPA->string),PRVM_GetString(OPB->string)); + break; + case OP_EQ_E: + OPC->_float = OPA->_int == OPB->_int; + break; + case OP_EQ_FNC: + OPC->_float = OPA->function == OPB->function; + break; + case OP_NE_F: + OPC->_float = OPA->_float != OPB->_float; + break; + case OP_NE_V: + OPC->_float = (OPA->vector[0] != OPB->vector[0]) || (OPA->vector[1] != OPB->vector[1]) || (OPA->vector[2] != OPB->vector[2]); + break; + case OP_NE_S: + OPC->_float = strcmp(PRVM_GetString(OPA->string),PRVM_GetString(OPB->string)); + break; + case OP_NE_E: + OPC->_float = OPA->_int != OPB->_int; + break; + case OP_NE_FNC: + OPC->_float = OPA->function != OPB->function; + break; + + case OP_STORE_F: + case OP_STORE_ENT: + case OP_STORE_FLD: // integers + case OP_STORE_S: + case OP_STORE_FNC: // pointers + OPB->_int = OPA->_int; + break; + case OP_STORE_V: + OPB->ivector[0] = OPA->ivector[0]; + OPB->ivector[1] = OPA->ivector[1]; + OPB->ivector[2] = OPA->ivector[2]; + break; + + case OP_STOREP_F: + case OP_STOREP_ENT: + case OP_STOREP_FLD: // integers + case OP_STOREP_S: + case OP_STOREP_FNC: // pointers + if(prvm_boundscheck->value && (OPB->_int < 0 || OPB->_int + 4 > prog->edictareasize)) { -#define PRVMTRACE 1 -#include "vm_exec.h" -#undef PRVMTRACE + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, OPB->_int); + return; + } + ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int); + ptr->_int = OPA->_int; + break; + + case OP_STOREP_V: + if (prvm_boundscheck->value && (OPB->_int < 0 || OPB->_int + 12 > prog->edictareasize)) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, OPB->_int); + return; + } + ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int); + ptr->vector[0] = OPA->vector[0]; + ptr->vector[1] = OPA->vector[1]; + ptr->vector[2] = OPA->vector[2]; + break; + + case OP_ADDRESS: + if (prvm_boundscheck->value && ((uint)(OPB->_int) >= (uint)(prog->progs->entityfields))) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR("%s attempted to address an invalid field (%i) in an edict", PRVM_NAME, OPB->_int); + return; + } + if (OPA->edict == 0 && !prog->allowworldwrites) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR("forbidden assignment to null/world entity in %s", PRVM_NAME); + return; + } + ed = PRVM_PROG_TO_EDICT(OPA->edict); + OPC->_int = (unsigned char *)((int *)ed->fields.vp + OPB->_int) - (unsigned char *)prog->edictsfields; + break; + + case OP_LOAD_F: + case OP_LOAD_FLD: + case OP_LOAD_ENT: + case OP_LOAD_S: + case OP_LOAD_FNC: + if (prvm_boundscheck->value && ((uint)(OPB->_int) >= (uint)(prog->progs->entityfields))) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)", PRVM_NAME, OPB->_int); + return; + } + ed = PRVM_PROG_TO_EDICT(OPA->edict); + OPC->_int = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->_int; + break; + + case OP_LOAD_V: + if (prvm_boundscheck->value && (OPB->_int < 0 || OPB->_int + 2 >= prog->progs->entityfields)) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)", PRVM_NAME, OPB->_int); + return; + } + ed = PRVM_PROG_TO_EDICT(OPA->edict); + OPC->vector[0] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[0]; + OPC->vector[1] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[1]; + OPC->vector[2] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[2]; + break; + + case OP_IFNOT: + if (!OPA->_int) + { + prog->xfunction->profile += (st - startst); + st += st->b - 1; // offset the s++ + startst = st; + if (++jumpcount == 10000000) + { + prog->xstatement = st - prog->statements; + PRVM_Profile(1<<30, 1000000); + PRVM_ERROR("runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", jumpcount, PRVM_NAME); + } + } + break; + + case OP_IF: + if (OPA->_int) + { + prog->xfunction->profile += (st - startst); + st += st->b - 1; // offset the s++ + startst = st; + if (++jumpcount == 10000000) + { + prog->xstatement = st - prog->statements; + PRVM_Profile(1<<30, 1000000); + PRVM_ERROR("runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", jumpcount, PRVM_NAME); + } + } + break; + + case OP_GOTO: + prog->xfunction->profile += (st - startst); + st += st->a - 1; // offset the s++ + startst = st; + if (++jumpcount == 10000000) + { + prog->xstatement = st - prog->statements; + PRVM_Profile(1<<30, 1000000); + PRVM_ERROR("runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", jumpcount, PRVM_NAME); + } + break; + case OP_CALL0: + case OP_CALL1: + case OP_CALL2: + case OP_CALL3: + case OP_CALL4: + case OP_CALL5: + case OP_CALL6: + case OP_CALL7: + case OP_CALL8: + prog->xfunction->profile += (st - startst); + startst = st; + prog->xstatement = st - prog->statements; + prog->argc = st->op - OP_CALL0; + if (!OPA->function) PRVM_ERROR("NULL function in %s", PRVM_NAME); + + newf = &prog->functions[OPA->function]; + newf->callcount++; + + if (newf->first_statement < 0) + { + // negative statements are built in functions + int builtinnumber = -newf->first_statement; + prog->xfunction->builtinsprofile++; + if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber]) + prog->builtins[builtinnumber](); + else PRVM_ERROR("No such builtin #%i in %s", builtinnumber, PRVM_NAME); + } + else st = prog->statements + PRVM_EnterFunction(newf); + startst = st; + break; + + case OP_DONE: + case OP_RETURN: + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + + prog->globals.generic[OFS_RETURN+0] = prog->globals.generic[(word) st->a+0]; + prog->globals.generic[OFS_RETURN+1] = prog->globals.generic[(word) st->a+1]; + prog->globals.generic[OFS_RETURN+2] = prog->globals.generic[(word) st->a+2]; + + st = prog->statements + PRVM_LeaveFunction(); + startst = st; + if (prog->depth <= exitdepth) + return; // all done + if (prog->trace != cachedpr_trace) + goto chooseexecprogram; + break; + + case OP_STATE: + if(prog->flag & PRVM_OP_STATE) + { + ed = PRVM_PROG_TO_EDICT(PRVM_G_INT(prog->self->ofs)); + PRVM_E_FLOAT(ed, PRVM_ED_FindField ("nextthink")->ofs) = *prog->time + 0.1; + PRVM_E_FLOAT(ed, PRVM_ED_FindField ("frame")->ofs) = OPA->_float; + *(func_t *)((float*)ed->fields.vp + PRVM_ED_FindField ("think")->ofs) = OPB->function; } else { -#include "vm_exec.h" + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR("OP_STATE not supported by %s", PRVM_NAME); } - } -#undef PRVMSTATEMENTPROFILING - } - else - { - if (prvm_boundscheck->value) - { -#define PRVMBOUNDSCHECK 1 - if (prog->trace) + break; + +// LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized +#if 0 + case OP_ADD_I: + OPC->_int = OPA->_int + OPB->_int; + break; + case OP_ADD_IF: + OPC->_int = OPA->_int + (int) OPB->_float; + break; + case OP_ADD_FI: + OPC->_float = OPA->_float + (float) OPB->_int; + break; + case OP_SUB_I: + OPC->_int = OPA->_int - OPB->_int; + break; + case OP_SUB_IF: + OPC->_int = OPA->_int - (int) OPB->_float; + break; + case OP_SUB_FI: + OPC->_float = OPA->_float - (float) OPB->_int; + break; + case OP_MUL_I: + OPC->_int = OPA->_int * OPB->_int; + break; + case OP_MUL_IF: + OPC->_int = OPA->_int * (int) OPB->_float; + break; + case OP_MUL_FI: + OPC->_float = OPA->_float * (float) OPB->_int; + break; + case OP_MUL_VI: + OPC->vector[0] = (float) OPB->_int * OPA->vector[0]; + OPC->vector[1] = (float) OPB->_int * OPA->vector[1]; + OPC->vector[2] = (float) OPB->_int * OPA->vector[2]; + break; + case OP_DIV_VF: { -#define PRVMTRACE 1 -#include "vm_exec.h" -#undef PRVMTRACE + float temp = 1.0f / OPB->_float; + OPC->vector[0] = temp * OPA->vector[0]; + OPC->vector[1] = temp * OPA->vector[1]; + OPC->vector[2] = temp * OPA->vector[2]; } - else + break; + case OP_DIV_I: + OPC->_int = OPA->_int / OPB->_int; + break; + case OP_DIV_IF: + OPC->_int = OPA->_int / (int) OPB->_float; + break; + case OP_DIV_FI: + OPC->_float = OPA->_float / (float) OPB->_int; + break; + case OP_CONV_ITOF: + OPC->_float = OPA->_int; + break; + case OP_CONV_FTOI: + OPC->_int = OPA->_float; + break; + case OP_BITAND_I: + OPC->_int = OPA->_int & OPB->_int; + break; + case OP_BITOR_I: + OPC->_int = OPA->_int | OPB->_int; + break; + case OP_BITAND_IF: + OPC->_int = OPA->_int & (int)OPB->_float; + break; + case OP_BITOR_IF: + OPC->_int = OPA->_int | (int)OPB->_float; + break; + case OP_BITAND_FI: + OPC->_float = (int)OPA->_float & OPB->_int; + break; + case OP_BITOR_FI: + OPC->_float = (int)OPA->_float | OPB->_int; + break; + case OP_GE_I: + OPC->_float = OPA->_int >= OPB->_int; + break; + case OP_LE_I: + OPC->_float = OPA->_int <= OPB->_int; + break; + case OP_GT_I: + OPC->_float = OPA->_int > OPB->_int; + break; + case OP_LT_I: + OPC->_float = OPA->_int < OPB->_int; + break; + case OP_AND_I: + OPC->_float = OPA->_int && OPB->_int; + break; + case OP_OR_I: + OPC->_float = OPA->_int || OPB->_int; + break; + case OP_GE_IF: + OPC->_float = (float)OPA->_int >= OPB->_float; + break; + case OP_LE_IF: + OPC->_float = (float)OPA->_int <= OPB->_float; + break; + case OP_GT_IF: + OPC->_float = (float)OPA->_int > OPB->_float; + break; + case OP_LT_IF: + OPC->_float = (float)OPA->_int < OPB->_float; + break; + case OP_AND_IF: + OPC->_float = (float)OPA->_int && OPB->_float; + break; + case OP_OR_IF: + OPC->_float = (float)OPA->_int || OPB->_float; + break; + case OP_GE_FI: + OPC->_float = OPA->_float >= (float)OPB->_int; + break; + case OP_LE_FI: + OPC->_float = OPA->_float <= (float)OPB->_int; + break; + case OP_GT_FI: + OPC->_float = OPA->_float > (float)OPB->_int; + break; + case OP_LT_FI: + OPC->_float = OPA->_float < (float)OPB->_int; + break; + case OP_AND_FI: + OPC->_float = OPA->_float && (float)OPB->_int; + break; + case OP_OR_FI: + OPC->_float = OPA->_float || (float)OPB->_int; + break; + case OP_NOT_I: + OPC->_float = !OPA->_int; + break; + case OP_EQ_I: + OPC->_float = OPA->_int == OPB->_int; + break; + case OP_EQ_IF: + OPC->_float = (float)OPA->_int == OPB->_float; + break; + case OP_EQ_FI: + OPC->_float = OPA->_float == (float)OPB->_int; + break; + case OP_NE_I: + OPC->_float = OPA->_int != OPB->_int; + break; + case OP_NE_IF: + OPC->_float = (float)OPA->_int != OPB->_float; + break; + case OP_NE_FI: + OPC->_float = OPA->_float != (float)OPB->_int; + break; + case OP_STORE_I: + OPB->_int = OPA->_int; + break; + case OP_STOREP_I: + if (prvm_boundscheck->value && (OPB->_int < 0 || OPB->_int + 4 > prog->edictareasize)) { -#include "vm_exec.h" + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR ("%s Progs attempted to write to an out of bounds edict", PRVM_NAME); + return; } -#undef PRVMBOUNDSCHECK - } - else - { - if (prog->trace) + ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int); + ptr->_int = OPA->_int; + break; + case OP_LOAD_I: + if (prvm_boundscheck->value && (OPA->edict < 0 || OPA->edict >= prog->edictareasize)) { -#define PRVMTRACE 1 -#include "vm_exec.h" -#undef PRVMTRACE + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR ("%s Progs attempted to read an out of bounds edict number", PRVM_NAME); + return; } - else + if (OPB->_int < 0 || OPB->_int >= prog->progs->entityfields) { -#include "vm_exec.h" + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR ("%s Progs attempted to read an invalid field in an edict", PRVM_NAME); + return; } + ed = PRVM_PROG_TO_EDICT(OPA->edict); + OPC->_int = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->_int; + break; + + case OP_GSTOREP_I: + case OP_GSTOREP_F: + case OP_GSTOREP_ENT: + case OP_GSTOREP_FLD: // integers + case OP_GSTOREP_S: + case OP_GSTOREP_FNC: // pointers + if (prvm_boundscheck->value && (OPB->_int < 0 || OPB->_int >= (uint)prog->progs->numglobaldefs)) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR ("%s Progs attempted to write to an invalid indexed global", PRVM_NAME); + return; + } + prog->globals.generic[OPB->_int] = OPA->_float; + break; + + case OP_GSTOREP_V: + if (prvm_boundscheck->value && (OPB->_int < 0 || OPB->_int + 2 >= (uint)prog->progs->numglobaldefs)) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR ("%s Progs attempted to write to an invalid indexed global", PRVM_NAME); + return; + } + prog->globals.generic[OPB->_int+0] = OPA->vector[0]; + prog->globals.generic[OPB->_int+1] = OPA->vector[1]; + prog->globals.generic[OPB->_int+2] = OPA->vector[2]; + break; + + case OP_GLOBALADDRESS: + i = OPA->_int + (int)OPB->_float; + if (prvm_boundscheck->value && (i < 0 || i >= (uint)prog->progs->numglobaldefs)) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR ("%s Progs attempted to address an out of bounds global", PRVM_NAME); + return; + } + OPC->_float = prog->globals.generic[i]; + break; + + case OP_LOADA_I: + case OP_LOADA_F: + case OP_LOADA_FLD: + case OP_LOADA_ENT: + case OP_LOADA_S: + case OP_LOADA_FNC: + if (prvm_boundscheck->value && (OPA->_int < 0 || OPA->_int >= (uint)prog->progs->numglobaldefs)) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR ("%s Progs attempted to read an invalid indexed global", PRVM_NAME); + return; + } + OPC->_float = prog->globals.generic[OPA->_int]; + break; + + case OP_LOADA_V: + if (prvm_boundscheck->value && (OPA->_int < 0 || OPA->_int + 2 >= (uint)prog->progs->numglobaldefs)) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR ("%s Progs attempted to read an invalid indexed global", PRVM_NAME); + return; + } + OPC->vector[0] = prog->globals.generic[OPA->_int+0]; + OPC->vector[1] = prog->globals.generic[OPA->_int+1]; + OPC->vector[2] = prog->globals.generic[OPA->_int+2]; + break; + + case OP_BOUNDCHECK: + if (OPA->_int < 0 || OPA->_int >= st->b) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR ("%s Progs boundcheck failed at line number %d, value is < 0 or >= %d", PRVM_NAME, st->b, st->c); + return; + } + break; +#endif + default: + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR ("Bad opcode %i in %s", st->op, PRVM_NAME); } } } diff --git a/engine/prvm/vm_exec.h b/engine/prvm/vm_exec.h deleted file mode 100644 index c232999b..00000000 --- a/engine/prvm/vm_exec.h +++ /dev/null @@ -1,628 +0,0 @@ - -// This code isn't #ifdef/#define protectable, don't try. - - while (1) - { - st++; - -#if PRVMTRACE - PRVM_PrintStatement(st); -#endif -#if PRVMSTATEMENTPROFILING - prog->statement_profile[st - prog->statements]++; -#endif - - switch (st->op) - { - case OP_ADD_F: - OPC->_float = OPA->_float + OPB->_float; - break; - case OP_ADD_V: - OPC->vector[0] = OPA->vector[0] + OPB->vector[0]; - OPC->vector[1] = OPA->vector[1] + OPB->vector[1]; - OPC->vector[2] = OPA->vector[2] + OPB->vector[2]; - break; - case OP_SUB_F: - OPC->_float = OPA->_float - OPB->_float; - break; - case OP_SUB_V: - OPC->vector[0] = OPA->vector[0] - OPB->vector[0]; - OPC->vector[1] = OPA->vector[1] - OPB->vector[1]; - OPC->vector[2] = OPA->vector[2] - OPB->vector[2]; - break; - case OP_MUL_F: - OPC->_float = OPA->_float * OPB->_float; - break; - case OP_MUL_V: - OPC->_float = OPA->vector[0]*OPB->vector[0] + OPA->vector[1]*OPB->vector[1] + OPA->vector[2]*OPB->vector[2]; - break; - case OP_MUL_FV: - OPC->vector[0] = OPA->_float * OPB->vector[0]; - OPC->vector[1] = OPA->_float * OPB->vector[1]; - OPC->vector[2] = OPA->_float * OPB->vector[2]; - break; - case OP_MUL_VF: - OPC->vector[0] = OPB->_float * OPA->vector[0]; - OPC->vector[1] = OPB->_float * OPA->vector[1]; - OPC->vector[2] = OPB->_float * OPA->vector[2]; - break; - case OP_DIV_F: - if( OPB->_float != 0.0f ) - { - OPC->_float = OPA->_float / OPB->_float; - } - else - { - if( developer->value >= 1 ) - { - prog->xfunction->profile += (st - startst); - startst = st; - prog->xstatement = st - prog->statements; - VM_Warning( "Attempted division by zero in %s\n", PRVM_NAME ); - } - OPC->_float = 0.0f; - } - break; - case OP_BITAND: - OPC->_float = (int)OPA->_float & (int)OPB->_float; - break; - case OP_BITOR: - OPC->_float = (int)OPA->_float | (int)OPB->_float; - break; - case OP_GE: - OPC->_float = OPA->_float >= OPB->_float; - break; - case OP_LE: - OPC->_float = OPA->_float <= OPB->_float; - break; - case OP_GT: - OPC->_float = OPA->_float > OPB->_float; - break; - case OP_LT: - OPC->_float = OPA->_float < OPB->_float; - break; - case OP_AND: - OPC->_float = OPA->_float && OPB->_float; - break; - case OP_OR: - OPC->_float = OPA->_float || OPB->_float; - break; - case OP_NOT_F: - OPC->_float = !OPA->_float; - break; - case OP_NOT_V: - OPC->_float = !OPA->vector[0] && !OPA->vector[1] && !OPA->vector[2]; - break; - case OP_NOT_S: - OPC->_float = !OPA->string || !*PRVM_GetString(OPA->string); - break; - case OP_NOT_FNC: - OPC->_float = !OPA->function; - break; - case OP_NOT_ENT: - OPC->_float = (OPA->edict == 0); - break; - case OP_EQ_F: - OPC->_float = OPA->_float == OPB->_float; - break; - case OP_EQ_V: - OPC->_float = (OPA->vector[0] == OPB->vector[0]) && (OPA->vector[1] == OPB->vector[1]) && (OPA->vector[2] == OPB->vector[2]); - break; - case OP_EQ_S: - OPC->_float = !strcmp(PRVM_GetString(OPA->string),PRVM_GetString(OPB->string)); - break; - case OP_EQ_E: - OPC->_float = OPA->_int == OPB->_int; - break; - case OP_EQ_FNC: - OPC->_float = OPA->function == OPB->function; - break; - case OP_NE_F: - OPC->_float = OPA->_float != OPB->_float; - break; - case OP_NE_V: - OPC->_float = (OPA->vector[0] != OPB->vector[0]) || (OPA->vector[1] != OPB->vector[1]) || (OPA->vector[2] != OPB->vector[2]); - break; - case OP_NE_S: - OPC->_float = strcmp(PRVM_GetString(OPA->string),PRVM_GetString(OPB->string)); - break; - case OP_NE_E: - OPC->_float = OPA->_int != OPB->_int; - break; - case OP_NE_FNC: - OPC->_float = OPA->function != OPB->function; - break; - - //================== - case OP_STORE_F: - case OP_STORE_ENT: - case OP_STORE_FLD: // integers - case OP_STORE_S: - case OP_STORE_FNC: // pointers - OPB->_int = OPA->_int; - break; - case OP_STORE_V: - OPB->ivector[0] = OPA->ivector[0]; - OPB->ivector[1] = OPA->ivector[1]; - OPB->ivector[2] = OPA->ivector[2]; - break; - - case OP_STOREP_F: - case OP_STOREP_ENT: - case OP_STOREP_FLD: // integers - case OP_STOREP_S: - case OP_STOREP_FNC: // pointers -#if PRVMBOUNDSCHECK - if (OPB->_int < 0 || OPB->_int + 4 > prog->edictareasize) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, OPB->_int); - return; - } -#endif - ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int); - ptr->_int = OPA->_int; - break; - case OP_STOREP_V: -#if PRVMBOUNDSCHECK - if (OPB->_int < 0 || OPB->_int + 12 > prog->edictareasize) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, OPB->_int); - return; - } -#endif - ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int); - ptr->vector[0] = OPA->vector[0]; - ptr->vector[1] = OPA->vector[1]; - ptr->vector[2] = OPA->vector[2]; - break; - - case OP_ADDRESS: -#if PRVMBOUNDSCHECK - if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->progs->entityfields)) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR("%s attempted to address an invalid field (%i) in an edict", PRVM_NAME, OPB->_int); - return; - } -#endif - if (OPA->edict == 0 && !prog->allowworldwrites) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR("forbidden assignment to null/world entity in %s", PRVM_NAME); - return; - } - ed = PRVM_PROG_TO_EDICT(OPA->edict); - OPC->_int = (unsigned char *)((int *)ed->fields.vp + OPB->_int) - (unsigned char *)prog->edictsfields; - break; - - case OP_LOAD_F: - case OP_LOAD_FLD: - case OP_LOAD_ENT: - case OP_LOAD_S: - case OP_LOAD_FNC: -#if PRVMBOUNDSCHECK - if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->progs->entityfields)) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)", PRVM_NAME, OPB->_int); - return; - } -#endif - ed = PRVM_PROG_TO_EDICT(OPA->edict); - OPC->_int = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->_int; - break; - - case OP_LOAD_V: -#if PRVMBOUNDSCHECK - if (OPB->_int < 0 || OPB->_int + 2 >= prog->progs->entityfields) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)", PRVM_NAME, OPB->_int); - return; - } -#endif - ed = PRVM_PROG_TO_EDICT(OPA->edict); - OPC->vector[0] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[0]; - OPC->vector[1] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[1]; - OPC->vector[2] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[2]; - break; - - //================== - - case OP_IFNOT: - if (!OPA->_int) - { - prog->xfunction->profile += (st - startst); - st += st->b - 1; // offset the s++ - startst = st; - if (++jumpcount == 10000000) - { - prog->xstatement = st - prog->statements; - PRVM_Profile(1<<30, 1000000); - PRVM_ERROR("runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", jumpcount, PRVM_NAME); - } - } - break; - - case OP_IF: - if (OPA->_int) - { - prog->xfunction->profile += (st - startst); - st += st->b - 1; // offset the s++ - startst = st; - if (++jumpcount == 10000000) - { - prog->xstatement = st - prog->statements; - PRVM_Profile(1<<30, 1000000); - PRVM_ERROR("runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", jumpcount, PRVM_NAME); - } - } - break; - - case OP_GOTO: - prog->xfunction->profile += (st - startst); - st += st->a - 1; // offset the s++ - startst = st; - if (++jumpcount == 10000000) - { - prog->xstatement = st - prog->statements; - PRVM_Profile(1<<30, 1000000); - PRVM_ERROR("runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", jumpcount, PRVM_NAME); - } - break; - case OP_CALL0: - case OP_CALL1: - case OP_CALL2: - case OP_CALL3: - case OP_CALL4: - case OP_CALL5: - case OP_CALL6: - case OP_CALL7: - case OP_CALL8: - prog->xfunction->profile += (st - startst); - startst = st; - prog->xstatement = st - prog->statements; - prog->argc = st->op - OP_CALL0; - if (!OPA->function) PRVM_ERROR("NULL function in %s", PRVM_NAME); - - newf = &prog->functions[OPA->function]; - newf->callcount++; - - if (newf->first_statement < 0) - { - // negative statements are built in functions - int builtinnumber = -newf->first_statement; - prog->xfunction->builtinsprofile++; - if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber]) - prog->builtins[builtinnumber](); - else PRVM_ERROR("No such builtin #%i in %s", builtinnumber, PRVM_NAME); - } - else st = prog->statements + PRVM_EnterFunction(newf); - startst = st; - break; - case OP_DONE: - case OP_RETURN: - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - - prog->globals.generic[OFS_RETURN+0] = prog->globals.generic[(word) st->a+0]; - prog->globals.generic[OFS_RETURN+1] = prog->globals.generic[(word) st->a+1]; - prog->globals.generic[OFS_RETURN+2] = prog->globals.generic[(word) st->a+2]; - - st = prog->statements + PRVM_LeaveFunction(); - startst = st; - if (prog->depth <= exitdepth) - return; // all done - if (prog->trace != cachedpr_trace) - goto chooseexecprogram; - break; - - case OP_STATE: - if(prog->flag & PRVM_OP_STATE) - { - ed = PRVM_PROG_TO_EDICT(PRVM_G_INT(prog->self->ofs)); - PRVM_E_FLOAT(ed, PRVM_ED_FindField ("nextthink")->ofs) = *prog->time + 0.1; - PRVM_E_FLOAT(ed, PRVM_ED_FindField ("frame")->ofs) = OPA->_float; - *(func_t *)((float*)ed->fields.vp + PRVM_ED_FindField ("think")->ofs) = OPB->function; - } - else - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR("OP_STATE not supported by %s", PRVM_NAME); - } - break; - -// LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized -/* - case OP_ADD_I: - OPC->_int = OPA->_int + OPB->_int; - break; - case OP_ADD_IF: - OPC->_int = OPA->_int + (int) OPB->_float; - break; - case OP_ADD_FI: - OPC->_float = OPA->_float + (float) OPB->_int; - break; - case OP_SUB_I: - OPC->_int = OPA->_int - OPB->_int; - break; - case OP_SUB_IF: - OPC->_int = OPA->_int - (int) OPB->_float; - break; - case OP_SUB_FI: - OPC->_float = OPA->_float - (float) OPB->_int; - break; - case OP_MUL_I: - OPC->_int = OPA->_int * OPB->_int; - break; - case OP_MUL_IF: - OPC->_int = OPA->_int * (int) OPB->_float; - break; - case OP_MUL_FI: - OPC->_float = OPA->_float * (float) OPB->_int; - break; - case OP_MUL_VI: - OPC->vector[0] = (float) OPB->_int * OPA->vector[0]; - OPC->vector[1] = (float) OPB->_int * OPA->vector[1]; - OPC->vector[2] = (float) OPB->_int * OPA->vector[2]; - break; - case OP_DIV_VF: - { - float temp = 1.0f / OPB->_float; - OPC->vector[0] = temp * OPA->vector[0]; - OPC->vector[1] = temp * OPA->vector[1]; - OPC->vector[2] = temp * OPA->vector[2]; - } - break; - case OP_DIV_I: - OPC->_int = OPA->_int / OPB->_int; - break; - case OP_DIV_IF: - OPC->_int = OPA->_int / (int) OPB->_float; - break; - case OP_DIV_FI: - OPC->_float = OPA->_float / (float) OPB->_int; - break; - case OP_CONV_IF: - OPC->_float = OPA->_int; - break; - case OP_CONV_FI: - OPC->_int = OPA->_float; - break; - case OP_BITAND_I: - OPC->_int = OPA->_int & OPB->_int; - break; - case OP_BITOR_I: - OPC->_int = OPA->_int | OPB->_int; - break; - case OP_BITAND_IF: - OPC->_int = OPA->_int & (int)OPB->_float; - break; - case OP_BITOR_IF: - OPC->_int = OPA->_int | (int)OPB->_float; - break; - case OP_BITAND_FI: - OPC->_float = (int)OPA->_float & OPB->_int; - break; - case OP_BITOR_FI: - OPC->_float = (int)OPA->_float | OPB->_int; - break; - case OP_GE_I: - OPC->_float = OPA->_int >= OPB->_int; - break; - case OP_LE_I: - OPC->_float = OPA->_int <= OPB->_int; - break; - case OP_GT_I: - OPC->_float = OPA->_int > OPB->_int; - break; - case OP_LT_I: - OPC->_float = OPA->_int < OPB->_int; - break; - case OP_AND_I: - OPC->_float = OPA->_int && OPB->_int; - break; - case OP_OR_I: - OPC->_float = OPA->_int || OPB->_int; - break; - case OP_GE_IF: - OPC->_float = (float)OPA->_int >= OPB->_float; - break; - case OP_LE_IF: - OPC->_float = (float)OPA->_int <= OPB->_float; - break; - case OP_GT_IF: - OPC->_float = (float)OPA->_int > OPB->_float; - break; - case OP_LT_IF: - OPC->_float = (float)OPA->_int < OPB->_float; - break; - case OP_AND_IF: - OPC->_float = (float)OPA->_int && OPB->_float; - break; - case OP_OR_IF: - OPC->_float = (float)OPA->_int || OPB->_float; - break; - case OP_GE_FI: - OPC->_float = OPA->_float >= (float)OPB->_int; - break; - case OP_LE_FI: - OPC->_float = OPA->_float <= (float)OPB->_int; - break; - case OP_GT_FI: - OPC->_float = OPA->_float > (float)OPB->_int; - break; - case OP_LT_FI: - OPC->_float = OPA->_float < (float)OPB->_int; - break; - case OP_AND_FI: - OPC->_float = OPA->_float && (float)OPB->_int; - break; - case OP_OR_FI: - OPC->_float = OPA->_float || (float)OPB->_int; - break; - case OP_NOT_I: - OPC->_float = !OPA->_int; - break; - case OP_EQ_I: - OPC->_float = OPA->_int == OPB->_int; - break; - case OP_EQ_IF: - OPC->_float = (float)OPA->_int == OPB->_float; - break; - case OP_EQ_FI: - OPC->_float = OPA->_float == (float)OPB->_int; - break; - case OP_NE_I: - OPC->_float = OPA->_int != OPB->_int; - break; - case OP_NE_IF: - OPC->_float = (float)OPA->_int != OPB->_float; - break; - case OP_NE_FI: - OPC->_float = OPA->_float != (float)OPB->_int; - break; - case OP_STORE_I: - OPB->_int = OPA->_int; - break; - case OP_STOREP_I: -#if PRBOUNDSCHECK - if (OPB->_int < 0 || OPB->_int + 4 > pr_edictareasize) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR ("%s Progs attempted to write to an out of bounds edict", PRVM_NAME); - return; - } -#endif - ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int); - ptr->_int = OPA->_int; - break; - case OP_LOAD_I: -#if PRBOUNDSCHECK - if (OPA->edict < 0 || OPA->edict >= pr_edictareasize) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR ("%s Progs attempted to read an out of bounds edict number", PRVM_NAME); - return; - } - if (OPB->_int < 0 || OPB->_int >= progs->entityfields) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR ("%s Progs attempted to read an invalid field in an edict", PRVM_NAME); - return; - } -#endif - ed = PRVM_PROG_TO_EDICT(OPA->edict); - OPC->_int = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->_int; - break; - - case OP_GSTOREP_I: - case OP_GSTOREP_F: - case OP_GSTOREP_ENT: - case OP_GSTOREP_FLD: // integers - case OP_GSTOREP_S: - case OP_GSTOREP_FNC: // pointers -#if PRBOUNDSCHECK - if (OPB->_int < 0 || OPB->_int >= pr_globaldefs) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR ("%s Progs attempted to write to an invalid indexed global", PRVM_NAME); - return; - } -#endif - pr_globals[OPB->_int] = OPA->_float; - break; - case OP_GSTOREP_V: -#if PRBOUNDSCHECK - if (OPB->_int < 0 || OPB->_int + 2 >= pr_globaldefs) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR ("%s Progs attempted to write to an invalid indexed global", PRVM_NAME); - return; - } -#endif - pr_globals[OPB->_int ] = OPA->vector[0]; - pr_globals[OPB->_int+1] = OPA->vector[1]; - pr_globals[OPB->_int+2] = OPA->vector[2]; - break; - - case OP_GADDRESS: - i = OPA->_int + (int) OPB->_float; -#if PRBOUNDSCHECK - if (i < 0 || i >= pr_globaldefs) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR ("%s Progs attempted to address an out of bounds global", PRVM_NAME); - return; - } -#endif - OPC->_float = pr_globals[i]; - break; - - case OP_GLOAD_I: - case OP_GLOAD_F: - case OP_GLOAD_FLD: - case OP_GLOAD_ENT: - case OP_GLOAD_S: - case OP_GLOAD_FNC: -#if PRBOUNDSCHECK - if (OPA->_int < 0 || OPA->_int >= pr_globaldefs) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR ("%s Progs attempted to read an invalid indexed global", PRVM_NAME); - return; - } -#endif - OPC->_float = pr_globals[OPA->_int]; - break; - - case OP_GLOAD_V: -#if PRBOUNDSCHECK - if (OPA->_int < 0 || OPA->_int + 2 >= pr_globaldefs) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR ("%s Progs attempted to read an invalid indexed global", PRVM_NAME); - return; - } -#endif - OPC->vector[0] = pr_globals[OPA->_int ]; - OPC->vector[1] = pr_globals[OPA->_int+1]; - OPC->vector[2] = pr_globals[OPA->_int+2]; - break; - - case OP_BOUNDCHECK: - if (OPA->_int < 0 || OPA->_int >= st->b) - { - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR ("%s Progs boundcheck failed at line number %d, value is < 0 or >= %d", PRVM_NAME, st->b, st->c); - return; - } - break; - -*/ - - default: - prog->xfunction->profile += (st - startst); - prog->xstatement = st - prog->statements; - PRVM_ERROR ("Bad opcode %i in %s", st->op, PRVM_NAME); - } - } - diff --git a/engine/server/server.h b/engine/server/server.h index e4935cc8..aa8c1132 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -362,7 +362,7 @@ int SV_PointContents (vec3_t p); trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, prvm_edict_t *passedict, int contentmask); trace_t SV_TraceToss (prvm_edict_t *tossent, prvm_edict_t *ignore); -trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int contentsmask); +trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int contentsmask); // mins and maxs are relative diff --git a/engine/server/sv_ccmds.c b/engine/server/sv_ccmds.c index 037691ad..f53db5ad 100644 --- a/engine/server/sv_ccmds.c +++ b/engine/server/sv_ccmds.c @@ -43,7 +43,7 @@ void SV_SetMaster_f (void) int i, slot; // only dedicated servers send heartbeats - if (!dedicated->value) + if (host.type == HOST_NORMAL) { Msg ("Only dedicated servers use masters.\n"); return; @@ -52,11 +52,11 @@ void SV_SetMaster_f (void) // make sure the server is listed public Cvar_Set ("public", "1"); - for (i=1 ; ivalue ) Cmd_AddCommand ("say", SV_ConSay_f); + if (host.type == HOST_DEDICATED) + { + Cmd_AddCommand ("say", SV_ConSay_f); + } Cmd_AddCommand ("serverrecord", SV_ServerRecord_f); Cmd_AddCommand ("serverstop", SV_ServerStop_f); diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 3975f401..0e537eee 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -291,7 +291,7 @@ void SV_SpawnServer (char *server, char *spawnpoint, char *savename, server_stat if (attractloop) Cvar_Set ("paused", "0"); Msg("------- Server Initialization -------\n"); - MsgDev ("SpawnServer: %s\n", server); + MsgDev (D_INFO, "SpawnServer: %s\n", server); if (sv.demofile) FS_Close (sv.demofile); svs.spawncount++; // any partially connected client will be restarted @@ -467,10 +467,9 @@ void SV_InitGame (void) // dedicated servers are can't be single player and are usually DM // so unless they explicity set coop, force it to deathmatch - if (dedicated->value) + if (host.type == HOST_DEDICATED) { - if (!Cvar_VariableValue ("coop")) - Cvar_FullSet ("deathmatch", "1", CVAR_SERVERINFO | CVAR_LATCH); + if (!Cvar_VariableValue ("coop")) Cvar_FullSet ("deathmatch", "1", CVAR_SERVERINFO | CVAR_LATCH); } // init clients diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 73547307..f7ae22e0 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -252,7 +252,7 @@ void SVC_GetChallenge (void) // overwrite the oldest svs.challenges[oldest].challenge = rand() & 0x7fff; svs.challenges[oldest].adr = net_from; - svs.challenges[oldest].time = curtime; + svs.challenges[oldest].time = host.realtime; i = oldest; } @@ -282,7 +282,7 @@ void SVC_DirectConnect (void) adr = net_from; - MsgDev ("SVC_DirectConnect()\n"); + MsgDev (D_INFO, "SVC_DirectConnect()\n"); version = atoi(Cmd_Argv(1)); if (version != PROTOCOL_VERSION) @@ -368,7 +368,7 @@ void SVC_DirectConnect (void) if (!newcl) { Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nServer is full.\n"); - MsgDev("SVC_DirectConnect: Rejected a connection.\n"); + MsgDev(D_INFO, "SVC_DirectConnect: Rejected a connection.\n"); return; } @@ -711,8 +711,6 @@ SV_RunGameFrame */ void SV_RunGameFrame (void) { - if (host_speeds->value) time_before_game = Sys_DoubleTime(); - // we always need to bump framenum, even if we // don't run the world, otherwise the delta // compression can get confused when a client @@ -734,8 +732,6 @@ void SV_RunGameFrame (void) svs.realtime = sv.time; } } - - if (host_speeds->value) time_after_game = Sys_DoubleTime(); } /* @@ -746,8 +742,6 @@ SV_Frame */ void SV_Frame (float time) { - time_before_game = time_after_game = 0; - // if server is not active, do nothing if (!svs.initialized) return; @@ -819,9 +813,8 @@ void Master_Heartbeat (void) char *string; int i; - // pgm post3.19 change, cvar pointer not validated before dereferencing - if (!dedicated || !dedicated->value) - return; // only dedicated servers send heartbeats + // only dedicated servers send heartbeats + if (host.type == HOST_NORMAL) return; // pgm post3.19 change, cvar pointer not validated before dereferencing if (!public_server || !public_server->value) @@ -861,22 +854,21 @@ void Master_Shutdown (void) { int i; - // pgm post3.19 change, cvar pointer not validated before dereferencing - if (!dedicated && !dedicated->value) - return; // only dedicated servers send heartbeats + if (host.type == HOST_NORMAL) return; // only dedicated servers send heartbeats // pgm post3.19 change, cvar pointer not validated before dereferencing if (!public_server || !public_server->value) return; // a private dedicated game // send to group master - for (i=0 ; i 0) - Msg ("Sending heartbeat to %s\n", NET_AdrToString (master_adr[i])); + if (i > 0) Msg ("Sending heartbeat to %s\n", NET_AdrToString (master_adr[i])); Netchan_OutOfBandPrint (NS_SERVER, master_adr[i], "shutdown"); } + } } //============================================================================ diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 30a61f91..a55604b1 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -66,7 +66,7 @@ trace_t SV_TraceToss (prvm_edict_t *tossent, prvm_edict_t *ignore) VectorMA (tossent->fields.sv->angles, 0.05, tossent->fields.sv->avelocity, tossent->fields.sv->angles); VectorScale (tossent->fields.sv->velocity, 0.05, move); VectorAdd (tossent->fields.sv->origin, move, end); - trace = SV_Trace(tossent->fields.sv->origin, tossent->fields.sv->mins, tossent->fields.sv->maxs, end, tossent, MASK_ALL ); + trace = SV_Trace(tossent->fields.sv->origin, tossent->fields.sv->mins, tossent->fields.sv->maxs, end, tossent, MASK_SOLID ); VectorCopy (trace.endpos, tossent->fields.sv->origin); if (trace.fraction < 1) break; @@ -89,7 +89,7 @@ returns true if the entity is in solid currently */ int SV_TestEntityPosition (prvm_edict_t *ent) { - trace_t trace = SV_Trace(ent->fields.sv->origin, ent->fields.sv->mins, ent->fields.sv->maxs, ent->fields.sv->origin, ent, MASK_ALL); + trace_t trace = SV_Trace(ent->fields.sv->origin, ent->fields.sv->mins, ent->fields.sv->maxs, ent->fields.sv->origin, ent, MASK_SOLID); if (trace.contents & MASK_SOLID) return true; @@ -233,7 +233,7 @@ int SV_FlyMove (prvm_edict_t *ent, float time, float *stepnormal) break; VectorMA(ent->fields.sv->origin, time_left, ent->fields.sv->velocity, end); - trace = SV_Trace(ent->fields.sv->origin, ent->fields.sv->mins, ent->fields.sv->maxs, end, ent, 0); + trace = SV_Trace(ent->fields.sv->origin, ent->fields.sv->mins, ent->fields.sv->maxs, end, ent, MASK_SOLID); // break if it moved the entire distance if (trace.fraction == 1) @@ -389,7 +389,7 @@ trace_t SV_PushEntity (prvm_edict_t *ent, vec3_t push, bool failonbmodelstartsol VectorAdd (ent->fields.sv->origin, push, end); - trace = SV_Trace(ent->fields.sv->origin, ent->fields.sv->mins, ent->fields.sv->maxs, end, ent, 0 ); + trace = SV_Trace(ent->fields.sv->origin, ent->fields.sv->mins, ent->fields.sv->maxs, end, ent, MASK_SOLID ); if (trace.startstuck && failonbmodelstartsolid) return trace; VectorCopy (trace.endpos, ent->fields.sv->origin); diff --git a/engine/server/sv_save.c b/engine/server/sv_save.c index 0a877ff7..c881b68f 100644 --- a/engine/server/sv_save.c +++ b/engine/server/sv_save.c @@ -148,7 +148,7 @@ void SV_WriteSaveFile( char *name ) return; } - MsgDev ("Saving game... %s\n", name ); + MsgDev (D_INFO, "Saving game... %s\n", name ); sprintf (comment, "%s - %s", sv.configstrings[CS_NAME], SV_CurTime()); header = (dsavehdr_t *)Z_Malloc( sizeof(dsavehdr_t)); diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index e9869316..2457c950 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -99,19 +99,20 @@ void SV_BroadcastPrintf (int level, char *fmt, ...) va_end (argptr); // echo to console - if (dedicated->value) + if (host.type == HOST_DEDICATED) { char copy[1024]; int i; // mask off high bits - for (i=0 ; i<1023 && string[i] ; i++) - copy[i] = string[i]&127; - copy[i] = 0; + for (i = 0; i < 1023 && string[i]; i++) + copy[i] = string[i] & 127; + + copy[i] = 0; //write null terminator Msg ("%s", copy); } - for (i=0, cl = svs.clients ; ivalue; i++, cl++) + for (i = 0, cl = svs.clients; i < maxclients->value; i++, cl++) { if (level < cl->messagelevel) continue; @@ -551,7 +552,7 @@ void SV_SendClientMessages (void) else { // just update reliable if needed - if (c->netchan.message.cursize || curtime - c->netchan.last_sent > 1.0f) + if (c->netchan.message.cursize || host.realtime - c->netchan.last_sent > 1.0f) Netchan_Transmit (&c->netchan, 0, NULL); } } diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 91cdbea8..ac29bdbd 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -356,7 +356,7 @@ void SV_BeginDownload_f(void) } SV_NextDownload_f (); - MsgDev ("Downloading %s to %s\n", name, sv_client->name); + MsgDev(D_INFO, "Downloading %s to %s\n", name, sv_client->name); } diff --git a/engine/server/sv_world.c b/engine/server/sv_world.c index b7f66f44..e4e4d157 100644 --- a/engine/server/sv_world.c +++ b/engine/server/sv_world.c @@ -580,28 +580,8 @@ trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, prvm_edict return clip.trace; } -trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int contentsmask) +trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int contentsmask) { - moveclip_t clip; - - memset( &clip, 0, sizeof(moveclip_t)); - - clip.passedict = ent; - clip.contentmask = contentsmask; - - VectorCopy(start, clip.start); - VectorCopy(end, clip.end); - - VectorCopy(mins, clip.mins); - VectorCopy(maxs, clip.maxs); - VectorCopy(mins, clip.mins2); - VectorCopy(maxs, clip.maxs2); - - // create the bounding box of the entire move - SV_TraceBounds ( clip.start, clip.mins2, clip.maxs2, clip.end, clip.boxmins, clip.boxmaxs ); - - // all prepares finished - SV_ClipMoveToEntities( &clip ); - - return clip.trace; + // correct ?? + return CM_BoxTrace(start, end, mins, maxs, ent->priv.sv->headnode, contentsmask); } \ No newline at end of file diff --git a/engine/snd_dma.c b/engine/snd_dma.c index ec711d4d..530b2f28 100644 --- a/engine/snd_dma.c +++ b/engine/snd_dma.c @@ -1104,8 +1104,8 @@ void GetSoundtime(void) void S_Update_(void) { - unsigned endtime; - int samps; + uint endtime; + int samps; if (!sound_started) return; @@ -1121,7 +1121,7 @@ void S_Update_(void) // check to make sure that we haven't overshot if (paintedtime < soundtime) { - MsgWarn("S_Update_: overflow\n"); + MsgWarn("S_Update_: overflow [%g]\n", soundtime - paintedtime); paintedtime = soundtime; } diff --git a/engine/snd_win.c b/engine/snd_win.c index cc51eb0e..2edffaef 100644 --- a/engine/snd_win.c +++ b/engine/snd_win.c @@ -115,16 +115,16 @@ static bool DS_CreateBuffers( void ) format.cbSize = 0; format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; - Msg( "Creating DS buffers\n" ); + MsgDev(D_INFO, "Creating DS buffers\n" ); - MsgDev("...setting EXCLUSIVE coop level: " ); + MsgDev(D_INFO, "...setting EXCLUSIVE coop level: " ); if ( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, cl_hwnd, DSSCL_EXCLUSIVE ) ) { - Msg ("failed\n"); + MsgDev(D_INFO, "failed\n"); FreeSound (); return false; } - MsgDev("ok\n" ); + MsgDev(D_INFO, "ok\n" ); // get access to the primary buffer, if possible, so we can set the // sound hardware format @@ -138,31 +138,31 @@ static bool DS_CreateBuffers( void ) dsbcaps.dwSize = sizeof(dsbcaps); primary_format_set = false; - MsgDev( "...creating primary buffer: " ); + MsgDev(D_INFO, "...creating primary buffer: " ); if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSPBuf, NULL)) { pformat = format; - MsgDev( "ok\n" ); + MsgDev(D_INFO, "ok\n" ); if (DS_OK != pDSPBuf->lpVtbl->SetFormat (pDSPBuf, &pformat)) { if (snd_firsttime) - MsgDev ("...setting primary sound format: failed\n"); + MsgDev (D_INFO, "...setting primary sound format: failed\n"); } else { if (snd_firsttime) - MsgDev ("...setting primary sound format: ok\n"); + MsgDev (D_INFO, "...setting primary sound format: ok\n"); primary_format_set = true; } } else - Msg( "failed\n" ); + MsgDev(D_INFO, "failed\n" ); if ( !primary_format_set || !s_primary->value) { - // create the secondary buffer we'll actually work with + // create the secondary buffer we'll actually work with memset (&dsbuf, 0, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE; @@ -172,14 +172,14 @@ static bool DS_CreateBuffers( void ) memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); - MsgDev( "...creating secondary buffer: " ); + MsgDev( D_INFO, "...creating secondary buffer: " ); if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) { - Msg( "failed\n" ); + MsgDev(D_INFO, "failed\n" ); FreeSound (); return false; } - MsgDev( "ok\n" ); + MsgDev(D_INFO, "ok\n" ); dma.channels = format.nChannels; dma.samplebits = format.wBitsPerSample; @@ -187,29 +187,29 @@ static bool DS_CreateBuffers( void ) if (DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps)) { - Msg ("*** GetCaps failed ***\n"); + MsgDev(D_WARN, "*** GetCaps failed ***\n"); FreeSound (); return false; } - Msg ("...using secondary sound buffer\n"); + MsgDev (D_INFO, "...using secondary sound buffer\n"); } else { - Msg( "...using primary buffer\n" ); + MsgDev(D_INFO, "...using primary buffer\n" ); - MsgDev( "...setting WRITEPRIMARY coop level: " ); + MsgDev(D_INFO, "...setting WRITEPRIMARY coop level: " ); if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, cl_hwnd, DSSCL_WRITEPRIMARY)) { - Msg( "failed\n" ); + MsgDev( D_INFO, "failed\n" ); FreeSound (); return false; } - MsgDev( "ok\n" ); + MsgDev(D_INFO, "ok\n" ); if (DS_OK != pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps)) { - Msg ("*** GetCaps failed ***\n"); + MsgDev (D_WARN, "*** GetCaps failed ***\n"); return false; } @@ -220,10 +220,7 @@ static bool DS_CreateBuffers( void ) pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); if (snd_firsttime) - Msg(" %d channel(s)\n" - " %d bits/sample\n" - " %d bytes/sec\n", - dma.channels, dma.samplebits, dma.speed); + Msg(" %d channel(s)\n"" %d bits/sample\n"" %d bytes/sec\n", dma.channels, dma.samplebits, dma.speed); gSndBufSize = dsbcaps.dwBufferBytes; @@ -248,16 +245,16 @@ static bool DS_CreateBuffers( void ) */ static void DS_DestroyBuffers( void ) { - MsgDev( "Destroying DS buffers\n" ); + MsgDev(D_INFO, "Destroying DS buffers\n" ); if ( pDS ) { - MsgDev( "...setting NORMAL coop level\n" ); + MsgDev(D_INFO, "...setting NORMAL coop level\n" ); pDS->lpVtbl->SetCooperativeLevel( pDS, cl_hwnd, DSSCL_NORMAL ); } if ( pDSBuf ) { - MsgDev( "...stopping and releasing sound buffer\n" ); + MsgDev(D_INFO, "...stopping and releasing sound buffer\n" ); pDSBuf->lpVtbl->Stop( pDSBuf ); pDSBuf->lpVtbl->Release( pDSBuf ); } @@ -265,7 +262,7 @@ static void DS_DestroyBuffers( void ) // only release primary buffer if it's not also the mixing buffer we just released if ( pDSPBuf && ( pDSBuf != pDSPBuf ) ) { - MsgDev( "...releasing primary buffer\n" ); + MsgDev(D_INFO, "...releasing primary buffer\n" ); pDSPBuf->lpVtbl->Release( pDSPBuf ); } pDSBuf = NULL; @@ -283,36 +280,36 @@ void FreeSound (void) { int i; - MsgDev( "Shutting down sound system\n" ); + MsgDev(D_INFO, "Shutting down sound system\n" ); if ( pDS ) DS_DestroyBuffers(); if ( hWaveOut ) { - MsgDev( "...resetting waveOut\n" ); + MsgDev(D_INFO, "...resetting waveOut\n" ); waveOutReset (hWaveOut); if (lpWaveHdr) { - MsgDev( "...unpreparing headers\n" ); + MsgDev(D_INFO, "...unpreparing headers\n" ); for (i=0 ; i< WAV_BUFFERS ; i++) waveOutUnprepareHeader (hWaveOut, lpWaveHdr+i, sizeof(WAVEHDR)); } - MsgDev( "...closing waveOut\n" ); + MsgDev(D_INFO, "...closing waveOut\n" ); waveOutClose (hWaveOut); if (hWaveHdr) { - MsgDev( "...freeing WAV header\n" ); + MsgDev(D_INFO, "...freeing WAV header\n" ); GlobalUnlock(hWaveHdr); GlobalFree(hWaveHdr); } if (hData) { - MsgDev( "...freeing WAV buffer\n" ); + MsgDev(D_INFO, "...freeing WAV buffer\n" ); GlobalUnlock(hData); GlobalFree(hData); } @@ -321,13 +318,13 @@ void FreeSound (void) if ( pDS ) { - MsgDev( "...releasing DS object\n" ); + MsgDev(D_INFO, "...releasing DS object\n" ); pDS->lpVtbl->Release( pDS ); } if ( hInstDS ) { - MsgDev( "...freeing DSOUND.DLL\n" ); + MsgDev(D_INFO, "...freeing DSOUND.DLL\n" ); FreeLibrary( hInstDS ); hInstDS = NULL; } @@ -370,57 +367,53 @@ sndinitstat SNDDMA_InitDirect (void) if ( !hInstDS ) { - MsgDev( "...loading dsound.dll: " ); + MsgDev(D_INFO, "...loading dsound.dll: " ); hInstDS = LoadLibrary("dsound.dll"); if (hInstDS == NULL) { - Msg ("failed\n"); + MsgDev (D_INFO, "failed\n"); return SIS_FAILURE; } - MsgDev ("ok\n"); + MsgDev (D_INFO, "ok\n"); pDirectSoundCreate = (void *)GetProcAddress(hInstDS,"DirectSoundCreate"); if (!pDirectSoundCreate) { - Msg ("*** couldn't get DS proc addr ***\n"); + MsgDev (D_ERROR, "*** couldn't get DS proc addr ***\n"); return SIS_FAILURE; } } - MsgDev( "...creating DS object: " ); + MsgDev(D_INFO, "...creating DS object: " ); while ( ( hresult = iDirectSoundCreate( NULL, &pDS, NULL ) ) != DS_OK ) { if (hresult != DSERR_ALLOCATED) { - Msg( "failed\n" ); + MsgDev(D_INFO, "failed\n" ); return SIS_FAILURE; } - if (MessageBox (NULL, - "The sound hardware is in use by another app.\n\n" - "Select Retry to try to start sound again or Cancel to run Quake with no sound.", - "Sound not available", - MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY) + if (MessageBox (NULL,"The sound hardware is in use by another app.\n\n" "Select Retry to try to start sound again or Cancel to run Quake with no sound.","Sound not available", MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY) { - Msg ("failed, hardware already in use\n" ); + MsgDev(D_INFO, "failed, hardware already in use\n" ); return SIS_NOTAVAIL; } } - MsgDev( "ok\n" ); + MsgDev(D_INFO, "ok\n" ); dscaps.dwSize = sizeof(dscaps); if ( DS_OK != pDS->lpVtbl->GetCaps( pDS, &dscaps ) ) { - Msg ("*** couldn't get DS caps ***\n"); + MsgDev(D_WARN, "*** couldn't get DS caps ***\n"); } if ( dscaps.dwFlags & DSCAPS_EMULDRIVER ) { - MsgDev ("...no DSound driver found\n" ); + MsgDev (D_ERROR, "...no DSound driver found\n" ); FreeSound(); return SIS_FAILURE; } @@ -430,7 +423,7 @@ sndinitstat SNDDMA_InitDirect (void) dsound_init = true; - MsgDev("...completed successfully\n" ); + MsgDev(D_INFO, "...completed successfully\n" ); return SIS_SUCCESS; } @@ -449,7 +442,7 @@ bool SNDDMA_InitWav (void) int i; HRESULT hr; - Msg( "Initializing wave sound\n" ); + MsgDev(D_INFO, "Initializing wave sound\n" ); snd_sent = 0; snd_completed = 0; @@ -475,29 +468,23 @@ bool SNDDMA_InitWav (void) format.nAvgBytesPerSec = format.nSamplesPerSec *format.nBlockAlign; - /* Open a waveform device for output using window callback. */ - MsgDev ("...opening waveform device: "); - while ((hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, - &format, - 0, 0L, CALLBACK_NULL)) != MMSYSERR_NOERROR) + // Open a waveform device for output using window callback. + MsgDev (D_INFO, "...opening waveform device: "); + while ((hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, &format, 0, 0L, CALLBACK_NULL)) != MMSYSERR_NOERROR) { if (hr != MMSYSERR_ALLOCATED) { - Msg ("failed\n"); + MsgDev(D_INFO, "failed\n"); return false; } - if (MessageBox (NULL, - "The sound hardware is in use by another app.\n\n" - "Select Retry to try to start sound again or Cancel to run game with no sound.", - "Sound not available", - MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY) + if (MessageBox (NULL, "The sound hardware is in use by another app.\n\n""Select Retry to try to start sound again or Cancel to run game with no sound.","Sound not available", MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY) { - Msg ("hw in use\n" ); + MsgDev(D_INFO, "hw in use\n" ); return false; } } - MsgDev( "ok\n" ); + MsgDev(D_INFO, "ok\n" ); /* * Allocate and lock memory for the waveform data. The memory @@ -505,59 +492,58 @@ bool SNDDMA_InitWav (void) * GMEM_MOVEABLE and GMEM_SHARE flags. */ - MsgDev ("...allocating waveform buffer: "); + MsgDev (D_INFO, "...allocating waveform buffer: "); gSndBufSize = WAV_BUFFERS*WAV_BUFFER_SIZE; hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, gSndBufSize); if (!hData) { - Msg( " failed\n" ); + MsgDev(D_INFO, " failed\n" ); FreeSound (); return false; } - MsgDev( "ok\n" ); + MsgDev(D_INFO, "ok\n" ); - MsgDev ("...locking waveform buffer: "); + MsgDev (D_INFO, "...locking waveform buffer: "); lpData = GlobalLock(hData); if (!lpData) { - Msg( " failed\n" ); + MsgDev(D_INFO, " failed\n" ); FreeSound (); return false; } memset (lpData, 0, gSndBufSize); - MsgDev( "ok\n" ); + MsgDev(D_INFO, "ok\n" ); /* * Allocate and lock memory for the header. This memory must * also be globally allocated with GMEM_MOVEABLE and * GMEM_SHARE flags. */ - MsgDev ("...allocating waveform header: "); - hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, - (DWORD) sizeof(WAVEHDR) * WAV_BUFFERS); + MsgDev (D_INFO, "...allocating waveform header: "); + hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD) sizeof(WAVEHDR) * WAV_BUFFERS); if (hWaveHdr == NULL) { - Msg( "failed\n" ); + MsgDev(D_INFO, "failed\n" ); FreeSound (); return false; } - MsgDev( "ok\n" ); + MsgDev(D_INFO, "ok\n" ); - MsgDev ("...locking waveform header: "); + MsgDev (D_INFO, "...locking waveform header: "); lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr); if (lpWaveHdr == NULL) { - Msg( "failed\n" ); + MsgDev(D_INFO, "failed\n" ); FreeSound (); return false; } memset (lpWaveHdr, 0, sizeof(WAVEHDR) * WAV_BUFFERS); - MsgDev( "ok\n" ); + MsgDev(D_INFO, "ok\n" ); /* After allocation, set up and prepare headers. */ - MsgDev ("...preparing headers: "); + MsgDev (D_INFO, "...preparing headers: "); for (i=0 ; ilpVtbl->GetStatus (pDSBuf, &dwStatus) != DS_OK) - Msg ("Couldn't get sound buffer status\n"); + MsgDev(D_INFO, "Couldn't get sound buffer status\n"); if (dwStatus & DSBSTATUS_BUFFERLOST) pDSBuf->lpVtbl->Restore (pDSBuf); @@ -737,7 +723,7 @@ void SNDDMA_BeginPainting (void) { if (hresult != DSERR_BUFFERLOST) { - Msg( "S_TransferStereo16: Lock failed with error '%s'\n", DSoundError( hresult ) ); + MsgDev(D_ERROR,"S_TransferStereo16: Lock failed with error '%s'\n", DSoundError( hresult ) ); S_Shutdown (); return; } @@ -782,7 +768,7 @@ void SNDDMA_Submit(void) { if ( snd_completed == snd_sent ) { - MsgDev ("Sound overrun\n"); + MsgDev (D_WARN, "Sound overrun\n"); break; } @@ -794,7 +780,6 @@ void SNDDMA_Submit(void) snd_completed++; // this buffer has been played } -//Msg ("completed %i\n", snd_completed); // // submit a few new sound blocks // @@ -803,7 +788,6 @@ void SNDDMA_Submit(void) h = lpWaveHdr + ( snd_sent&WAV_MASK ); if (paintedtime/256 <= snd_sent) break; // Msg ("submit overrun\n"); -//Msg ("send %i\n", snd_sent); snd_sent++; /* * Now the data block can be sent to the output device. The @@ -814,7 +798,7 @@ void SNDDMA_Submit(void) if (wResult != MMSYSERR_NOERROR) { - Msg ("Failed to write block to device\n"); + MsgDev(D_WARN, "Failed to write block to device\n"); FreeSound (); return; } diff --git a/engine/system.c b/engine/system.c index 8ce23113..70bd429e 100644 --- a/engine/system.c +++ b/engine/system.c @@ -27,9 +27,6 @@ extern HWND cl_hwnd; //engine builddate char *buildstring = __TIME__ " " __DATE__; stdinout_api_t std; -uint sys_msg_time; -float sys_frame_time; -double curtime; /* =============================================================================== @@ -97,17 +94,18 @@ Send Key_Event calls */ void Sys_SendKeyEvents (void) { - MSG msg; + MSG msg; while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage (&msg, NULL, 0, 0)) Sys_Quit (); - sys_msg_time = msg.time; + host.sv_timer = msg.time; TranslateMessage (&msg); DispatchMessage (&msg); } + // grab frame time - sys_frame_time = Sys_DoubleTime(); + host.cl_timer = timeGetTime(); // FIXME: should this be at start? } diff --git a/engine/vid_dll.c b/engine/vid_dll.c index 0265bb60..335974a2 100644 --- a/engine/vid_dll.c +++ b/engine/vid_dll.c @@ -28,7 +28,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. renderer_exp_t *re; extern HWND cl_hwnd; -extern bool ActiveApp, Minimized; extern HINSTANCE global_hInstance; #ifndef WM_MOUSEWHEEL @@ -55,9 +54,6 @@ HWND cl_hwnd; // Main window handle for life of program LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); - -extern unsigned sys_msg_time; - /* ========================================================================== @@ -183,29 +179,25 @@ int MapKey (int key) } } -void AppActivate(BOOL fActive, BOOL minimize) +void AppActivate(bool fActive, bool fMinimize) { - Minimized = minimize; + if(fActive && !fMinimize) host.state = HOST_FRAME; + else if(fMinimize) host.state = HOST_SLEEP; + else host.state = HOST_NOFOCUS; Key_ClearStates(); - // we don't want to act like we're active if we're minimized - if (fActive && !Minimized) - ActiveApp = true; - else - ActiveApp = false; - // minimize/restore mouse-capture on demand - if (!ActiveApp) - { - IN_Activate (false); - S_Activate (false); - } - else + if(host.state == HOST_FRAME) { IN_Activate (true); S_Activate (true); } + else + { + IN_Activate (false); + S_Activate (false); + } } /* @@ -223,13 +215,13 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if ( ( ( int ) wParam ) > 0 ) { - Key_Event( K_MWHEELUP, true, sys_msg_time ); - Key_Event( K_MWHEELUP, false, sys_msg_time ); + Key_Event( K_MWHEELUP, true, host.sv_timer ); + Key_Event( K_MWHEELUP, false, host.sv_timer ); } else { - Key_Event( K_MWHEELDOWN, true, sys_msg_time ); - Key_Event( K_MWHEELDOWN, false, sys_msg_time ); + Key_Event( K_MWHEELDOWN, true, host.sv_timer ); + Key_Event( K_MWHEELDOWN, false, host.sv_timer ); } return DefWindowProc (hWnd, uMsg, wParam, lParam); } @@ -243,13 +235,13 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) */ if ( ( short ) HIWORD( wParam ) > 0 ) { - Key_Event( K_MWHEELUP, true, sys_msg_time ); - Key_Event( K_MWHEELUP, false, sys_msg_time ); + Key_Event( K_MWHEELUP, true, host.sv_timer ); + Key_Event( K_MWHEELUP, false, host.sv_timer ); } else { - Key_Event( K_MWHEELDOWN, true, sys_msg_time ); - Key_Event( K_MWHEELDOWN, false, sys_msg_time ); + Key_Event( K_MWHEELDOWN, true, host.sv_timer ); + Key_Event( K_MWHEELDOWN, false, host.sv_timer ); } break; @@ -305,7 +297,7 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) Cvar_SetValue( "vid_ypos", yPos + r.top); vid_xpos->modified = false; vid_ypos->modified = false; - if (ActiveApp) + if (host.state == HOST_FRAME) IN_Activate (true); } } @@ -351,11 +343,11 @@ LONG WINAPI MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } // fall through case WM_KEYDOWN: - Key_Event( MapKey( lParam ), true, sys_msg_time); + Key_Event( MapKey( lParam ), true, host.sv_timer); break; case WM_SYSKEYUP: case WM_KEYUP: - Key_Event( MapKey( lParam ), false, sys_msg_time); + Key_Event( MapKey( lParam ), false, host.sv_timer); break; default: // pass all unhandled messages to DefWindowProc return DefWindowProc (hWnd, uMsg, wParam, lParam); diff --git a/launcher/console.c b/launcher/console.c index e66b1eb5..a388224e 100644 --- a/launcher/console.c +++ b/launcher/console.c @@ -260,8 +260,8 @@ print into cmd32 console */ void Sys_PrintA(const char *pMsg) { - fprintf (stdout, pMsg ); - fflush (stdout); //refresh message + fprintf(stdout, pMsg ); + fflush(stdout); //refresh message } /* @@ -283,12 +283,12 @@ void Sys_MsgW( const char *pMsg, ... ) Sys_Print( text ); } -void Sys_MsgDevW( const char *pMsg, ... ) +void Sys_MsgDevW( int level, const char *pMsg, ... ) { va_list argptr; char text[MAX_INPUTLINE]; - if(debug_mode) + if(dev_mode >= level) { va_start (argptr, pMsg); vsprintf (text, pMsg, argptr); @@ -318,7 +318,7 @@ Sys_CreateConsoleW create win32 console ================ */ -void Sys_CreateConsoleW( void ) +void Sys_CreateConsoleW( const char *caption ) { HDC hDC; WNDCLASS wc; @@ -351,7 +351,6 @@ void Sys_CreateConsoleW( void ) rect.right = 536; rect.top = 0; rect.bottom = 280; - strcpy(Title, "" ); strcpy(FontName, "Arial" ); fontsize = 16; } @@ -361,7 +360,6 @@ void Sys_CreateConsoleW( void ) rect.right = 536; rect.top = 0; rect.bottom = 364; - strcpy(Title, "Xash Console" ); strcpy(FontName, "Fixedsys" ); fontsize = 8; } @@ -371,10 +369,11 @@ void Sys_CreateConsoleW( void ) rect.right = 540; rect.top = 0; rect.bottom = 392; - strcpy(Title, "Xash Dedicated Console" ); strcpy(FontName, "Fixedsys" ); fontsize = 8; } + + strcpy(Title, caption ); AdjustWindowRect( &rect, DEDSTYLE, FALSE ); hDC = GetDC( GetDesktopWindow() ); diff --git a/launcher/launcher.c b/launcher/launcher.c index 4b8969d5..12f8005e 100644 --- a/launcher/launcher.c +++ b/launcher/launcher.c @@ -13,6 +13,7 @@ bool show_always = true; bool about_mode = false; bool sys_error = false; char dllname[64]; +char caption[64]; const char *show_credits = "\n\n\n\n\tCopyright XashXT Group 2007 ©\n\t All Rights Reserved\n\n\t Visit www.xash.ru\n"; @@ -70,6 +71,7 @@ void LookupInstance( const char *funcname ) if(!debug_mode) show_always = false; strcpy(dllname, "bin/engine.dll" ); strcpy(log_path, "engine.log" ); // xash3d root directory + strcpy(caption, va("Xash3D ver.%g", CalcEngineVersion())); } else if(!strcmp(progname, "host_dedicated")) { @@ -77,6 +79,7 @@ void LookupInstance( const char *funcname ) console_read_only = false; strcpy(dllname, "bin/engine.dll" ); strcpy(log_path, "engine.log" ); // xash3d root directory + strcpy(caption, va("Xash3D Dedicated Server ver.%g", CalcEngineVersion())); } else if(!strcmp(progname, "host_editor")) { @@ -86,35 +89,41 @@ void LookupInstance( const char *funcname ) if(!debug_mode) show_always = false; strcpy(dllname, "bin/editor.dll" ); strcpy(log_path, "editor.log" ); // xash3d root directory + strcpy(caption, va("Xash3D Editor ver.%g", CalcEditorVersion())); } else if(!strcmp(progname, "bsplib")) { app_name = BSPLIB; strcpy(dllname, "bin/platform.dll" ); strcpy(log_path, "bsplib.log" ); // xash3d root directory + strcpy(caption, "Xash3D BSP Compiler"); } else if(!strcmp(progname, "qcclib")) { app_name = QCCLIB; strcpy(dllname, "bin/platform.dll" ); sprintf(log_path, "%s/compile.log", sys_rootdir ); // same as .exe file + strcpy(caption, "Xash3D QuakeC Compiler"); } else if(!strcmp(progname, "sprite")) { app_name = SPRITE; strcpy(dllname, "bin/platform.dll" ); sprintf(log_path, "%s/spritegen.log", sys_rootdir ); // same as .exe file + strcpy(caption, "Xash3D Sprite Compiler"); } else if(!strcmp(progname, "studio")) { app_name = STUDIO; strcpy(dllname, "bin/platform.dll" ); sprintf(log_path, "%s/studiomdl.log", sys_rootdir ); // same as .exe file + strcpy(caption, "Xash3D Studio Models Compiler"); } else if(!strcmp(progname, "credits")) //easter egg { app_name = CREDITS; about_mode = true; + strcpy(caption, "About"); } else app_name = DEFAULT; } @@ -263,7 +272,7 @@ void CreateInstance( void ) std.input = Sys_Input; // first text message into console or log - if(app_name != CREDITS) Msg("------- Loading bin/launcher.dll [%g] -------\n", LAUNCHER_VERSION ); + if(app_name != CREDITS) MsgDev(D_INFO, "------- Loading bin/launcher.dll [%g] -------\n", LAUNCHER_VERSION ); switch(app_name) { @@ -325,7 +334,7 @@ void HOST_MakeStubs( void ) void API_Reset( void ) { - Sys_InitConsole = NullVoid; + Sys_InitConsole = NullVoidWithName; Sys_FreeConsole = NullVoid; Sys_ShowConsole = NullVoidWithArg; @@ -333,7 +342,7 @@ void API_Reset( void ) Sys_Error = NullVarArgs; Msg = NullVarArgs; - MsgDev = NullVarArgs; + MsgDev = NullVarArgs2; MsgWarn = NullVarArgs; } @@ -361,7 +370,8 @@ void API_SetConsole( void ) void InitLauncher( char *funcname ) { - HANDLE hStdout; + HANDLE hStdout; + char dev_level[4]; API_Reset();//filled stdinout api @@ -375,6 +385,8 @@ void InitLauncher( char *funcname ) if(CheckParm ("-log")) log_active = true; if(abs((short)hStdout) < 100) hooked_out = false; else hooked_out = true; + if(GetParmFromCmdLine("-dev", dev_level )) + dev_mode = atoi(dev_level); UpdateEnvironmentVariables(); // set working directory @@ -382,7 +394,7 @@ void InitLauncher( char *funcname ) LookupInstance( funcname ); HOST_MakeStubs();//make sure what all functions are filled API_SetConsole(); //initialize system console - Sys_InitConsole(); + Sys_InitConsole( caption ); CreateInstance(); diff --git a/launcher/launcher.h b/launcher/launcher.h index a464bdef..cc353d57 100644 --- a/launcher/launcher.h +++ b/launcher/launcher.h @@ -19,9 +19,9 @@ typedef int bool; char *(*Sys_Input ) ( void ); void ( *Msg )( char *msg, ... ); void ( *Sys_Print )( char *msg ); -void ( *Sys_InitConsole )( void ); +void ( *Sys_InitConsole )( const char *caption ); void ( *Sys_FreeConsole )( void ); -void ( *MsgDev )( char *msg, ... ); +void ( *MsgDev )( int level, char *msg, ... ); void ( *MsgWarn )( char *msg, ... ); void ( *Sys_Error )( char *msg, ... ); void ( *Sys_ShowConsole )( bool show ); @@ -37,6 +37,7 @@ extern HINSTANCE linked_dll; extern bool debug_mode; extern bool log_active; extern bool hooked_out; +extern int dev_mode; extern int com_argc; extern char *com_argv[MAX_NUM_ARGVS]; extern char sys_rootdir[ MAX_SYSPATH ]; @@ -47,19 +48,27 @@ extern bool about_mode; extern bool sys_error; char *va(const char *format, ...); +// +// utils.c +// const char* Log_Timestamp( void ); int CheckParm (const char *parm); void ParseCommandLine (LPSTR lpCmdLine); void UpdateEnvironmentVariables( void ); -bool GetParmFromCmdLine( char *parm, char *out ); +bool _GetParmFromCmdLine( char *parm, char *out, size_t size ); +#define GetParmFromCmdLine( parm, out ) _GetParmFromCmdLine( parm, out, sizeof(out)) +float CalcEngineVersion( void ); +float CalcEditorVersion( void ); -//win32 console +// +// console.c +// void Sys_PrintA(const char *pMsg); void Sys_PrintW(const char *pMsg); void Sys_MsgW( const char *pMsg, ... ); -void Sys_MsgDevW( const char *pMsg, ... ); +void Sys_MsgDevW( int level, const char *pMsg, ... ); void Sys_MsgWarnW( const char *pMsg, ... ); -void Sys_CreateConsoleW( void ); +void Sys_CreateConsoleW( const char *caption ); void Sys_DestroyConsoleW( void ); void Sys_ShowConsoleW( bool show ); char *Sys_InputW( void ); @@ -69,7 +78,9 @@ void Sys_ErrorW(char *error, ...); __inline void NullVoid( void ) {} __inline void NullVoidWithArg( bool parm ) {} __inline void NullVarArgs( char *parm, ... ) {} +__inline void NullVarArgs2( int level, char *parm, ... ) {} __inline char *NullChar( void ) { return NULL; } +__inline void NullVoidWithName( const char *caption ) {} __inline void NullInit ( char *funcname, int argc, char **argv ) {} //memory manager diff --git a/launcher/launcher.plg b/launcher/launcher.plg new file mode 100644 index 00000000..0d49e7f5 --- /dev/null +++ b/launcher/launcher.plg @@ -0,0 +1,16 @@ + + +
+

Build Log

+

+--------------------Configuration: launcher - Win32 Release-------------------- +

+

Command Lines

+ + + +

Results

+launcher.dll - 0 error(s), 0 warning(s) +
+ + diff --git a/launcher/utils.c b/launcher/utils.c index 212e2c59..dc8ef6c9 100644 --- a/launcher/utils.c +++ b/launcher/utils.c @@ -9,6 +9,7 @@ char sys_rootdir[ MAX_SYSPATH ]; bool debug_mode = false; bool console_read_only = true; +int dev_mode = 0; /* ==================== @@ -31,6 +32,16 @@ const char* Log_Timestamp( void ) return timestamp; } +float CalcEngineVersion( void ) +{ + return LAUNCHER_VERSION + PLATFORM_VERSION + RENDERER_VERSION + ENGINE_VERSION; +} + +float CalcEditorVersion( void ) +{ + return LAUNCHER_VERSION + PLATFORM_VERSION + RENDERER_VERSION + EDITOR_VERSION; +} + /* ================== ParseCommandLine @@ -87,14 +98,14 @@ int CheckParm (const char *parm) return 0; } -bool GetParmFromCmdLine( char *parm, char *out ) +bool _GetParmFromCmdLine( char *parm, char *out, size_t size ) { int argc = CheckParm( parm ); if(!argc) return false; if(!out) return false; - strcpy( out, com_argv[argc+1]); + strncpy( out, com_argv[argc+1], size ); return true; } diff --git a/platform/baseutils.c b/platform/baseutils.c index 47db2471..fc0adb10 100644 --- a/platform/baseutils.c +++ b/platform/baseutils.c @@ -1161,15 +1161,15 @@ void Plat_InitCPU( void ) szFeatureString[strlen(szFeatureString)-1] = '\0'; // Dump CPU information: - if( cpu.m_usNumLogicCore == 1 ) Msg( "CPU: %s [1 core]. Frequency: %.01f %s\n", cpu.m_szCPUID, fFrequency, szFrequencyDenomination ); + if( cpu.m_usNumLogicCore == 1 ) MsgDev( D_INFO, "CPU: %s [1 core]. Frequency: %.01f %s\n", cpu.m_szCPUID, fFrequency, szFrequencyDenomination ); else { char buffer[256] = ""; if( cpu.m_usNumPhysCore != cpu.m_usNumLogicCore ) sprintf(buffer, " (%i physical)", (int) cpu.m_usNumPhysCore ); - Msg( "CPU: %s [%i core's %s]. Frequency: %.01f %s\n ", cpu.m_szCPUID, (int)cpu.m_usNumLogicCore, buffer, fFrequency, szFrequencyDenomination ); + MsgDev(D_INFO, "CPU: %s [%i core's %s]. Frequency: %.01f %s\n ", cpu.m_szCPUID, (int)cpu.m_usNumLogicCore, buffer, fFrequency, szFrequencyDenomination ); } - MsgDev("CPU Features: %s\n", szFeatureString ); + MsgDev(D_INFO, "CPU Features: %s\n", szFeatureString ); } /* diff --git a/platform/bsplib/portals.c b/platform/bsplib/portals.c index 16740ec7..65700f51 100644 --- a/platform/bsplib/portals.c +++ b/platform/bsplib/portals.c @@ -867,8 +867,8 @@ void EmitAreaPortals (node_t *headnode) dareas[i].numareaportals = numareaportals - dareas[i].firstareaportal; } - MsgDev("%5i numareas\n", numareas); - MsgDev("%5i numareaportals\n", numareaportals); + MsgDev(D_INFO, "%5i numareas\n", numareas); + MsgDev(D_INFO, "%5i numareaportals\n", numareaportals); } /* diff --git a/platform/bsplib/shaders.c b/platform/bsplib/shaders.c index b13b5729..bd6ffb21 100644 --- a/platform/bsplib/shaders.c +++ b/platform/bsplib/shaders.c @@ -123,7 +123,7 @@ static void ParseShaderFile( char *filename ) if( load ) { FS_FileBase( filename, name ); - MsgDev("Adding shader: %s.txt\n", name ); + MsgDev(D_INFO, "Adding shader: %s.txt\n", name ); } while ( load ) diff --git a/platform/filesystem.c b/platform/filesystem.c index 7e412f33..f755413f 100644 --- a/platform/filesystem.c +++ b/platform/filesystem.c @@ -353,7 +353,7 @@ pack_t *FS_LoadPackPK3 (const char *packfile) return NULL; } - MsgDev("Adding packfile %s (%i files)\n", packfile, real_nb_files); + MsgDev(D_INFO, "Adding packfile %s (%i files)\n", packfile, real_nb_files); return pack; } @@ -612,11 +612,11 @@ void FS_Path (void) { searchpath_t *s; - MsgDev("Current search path:\n"); - for (s=fs_searchpaths ; s ; s=s->next) + MsgDev(D_INFO, "Current search path:\n"); + for (s = fs_searchpaths; s; s = s->next) { - if (s->pack) MsgDev("%s (%i files)\n", s->pack->filename, s->pack->numfiles); - else MsgDev("%s\n", s->filename); + if (s->pack) MsgDev(D_INFO, "%s (%i files)\n", s->pack->filename, s->pack->numfiles); + else MsgDev(D_INFO, "%s\n", s->filename); } } @@ -733,7 +733,7 @@ pack_t *FS_LoadPackPAK (const char *packfile) } Free(info); - MsgDev("Adding packfile %s (%i files)\n", packfile, numpackfiles); + MsgDev(D_INFO, "Adding packfile %s (%i files)\n", packfile, numpackfiles); return pack; } @@ -1426,7 +1426,7 @@ static searchpath_t *FS_FindFile (const char *name, int* index, bool quiet) // Found it if (!diff) { - if (!quiet) MsgDev("FS_FindFile: %s in %s\n", pak->files[middle].name, pak->filename); + if (!quiet) MsgDev(D_INFO, "FS_FindFile: %s in %s\n", pak->files[middle].name, pak->filename); if (index != NULL) *index = middle; return search; } @@ -1442,14 +1442,14 @@ static searchpath_t *FS_FindFile (const char *name, int* index, bool quiet) sprintf(netpath, "%s%s", search->filename, name); if (FS_SysFileExists(netpath)) { - if (!quiet) MsgDev("FS_FindFile: %s\n", netpath); + if (!quiet) MsgDev(D_INFO, "FS_FindFile: %s\n", netpath); if (index != NULL) *index = -1; return search; } } } - if (!quiet) MsgDev("FS_FindFile: can't find %s\n", name); + if (!quiet) MsgDev(D_WARN, "FS_FindFile: can't find %s\n", name); if (index != NULL) *index = -1; return NULL; @@ -1860,7 +1860,7 @@ int FS_Gets (file_t* file, byte *string, size_t bufsize ) c = FS_Getc(file); if (c != '\n') FS_UnGetc(file, (byte)c); } - MsgDev("FS_Gets: %s\n", string); + MsgDev(D_INFO, "FS_Gets: %s\n", string); return c; } @@ -2193,7 +2193,7 @@ static search_t *_FS_Search(const char *pattern, int caseinsensitive, int quiet if (resultlistindex == resultlist.numstrings) { stringlistappend(&resultlist, temp); - if (!quiet) MsgDev("SearchPackFile: %s : %s\n", pak->filename, temp); + if (!quiet) MsgDev(D_INFO, "SearchPackFile: %s : %s\n", pak->filename, temp); } } // strip off one path element at a time until empty @@ -2229,7 +2229,7 @@ static search_t *_FS_Search(const char *pattern, int caseinsensitive, int quiet if (resultlistindex == resultlist.numstrings) { stringlistappend(&resultlist, temp); - if (!quiet) MsgDev("SearchDirFile: %s\n", temp); + if (!quiet) MsgDev(D_INFO, "SearchDirFile: %s\n", temp); } } } diff --git a/platform/platform.c b/platform/platform.c index e48ba9ac..92e66168 100644 --- a/platform/platform.c +++ b/platform/platform.c @@ -18,7 +18,7 @@ gameinfo_t Plat_GameInfo( void ) bool InitPlatform ( int argc, char **argv ) { - Msg("------- Loading bin/platform.dll [%g] -------\n", PLATFORM_VERSION ); + MsgDev(D_INFO, "------- Loading bin/platform.dll [%g] -------\n", PLATFORM_VERSION ); InitMemory(); Plat_InitCPU(); diff --git a/platform/platform.plg b/platform/platform.plg new file mode 100644 index 00000000..a2428a54 --- /dev/null +++ b/platform/platform.plg @@ -0,0 +1,16 @@ + + +
+

Build Log

+

+--------------------Configuration: platform - Win32 Release-------------------- +

+

Command Lines

+ + + +

Results

+platform.dll - 0 error(s), 0 warning(s) +
+ + diff --git a/public/const.h b/public/const.h index a41997be..df652a07 100644 --- a/public/const.h +++ b/public/const.h @@ -217,34 +217,8 @@ void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ); void PerpendicularVector( vec3_t dst, const vec3_t src ); void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ); - - void Com_PageInMemory (byte *buffer, int size); -//============================================= - -// -// key / value info strings -// -char *Info_ValueForKey (char *s, char *key); -void Info_RemoveKey (char *s, char *key); -void Info_SetValueForKey (char *s, char *key, char *value); -bool Info_Validate (char *s); - -/* -============================================================== - -SYSTEM SPECIFIC - -============================================================== -*/ - -extern double curtime; - -void Sys_Error (char *error, ...); -void Com_Printf (char *msg, ...); -void Com_DPrintf (char *fmt, ...); - /* ============================================================== diff --git a/public/ref_system.h b/public/ref_system.h index 2351f3bb..630cc283 100644 --- a/public/ref_system.h +++ b/public/ref_system.h @@ -84,7 +84,14 @@ typedef enum MSG_PVS_R, } msgtype_t; -//format info table +enum dev_level +{ + D_INFO = 1, // "-developer 1", shows various system messages + D_WARN, // "-developer 2", shows not critical system warnings, same as MsgWarn + D_ERROR, // "-developer 3", shows critical warnings +}; + +// format info table typedef struct { int format; // pixelformat @@ -465,16 +472,16 @@ STDIO SYSTEM INTERFACE typedef struct stdinout_api_s { //interface validator - size_t api_size; // must matched with sizeof(stdinout_api_t) + size_t api_size; // must matched with sizeof(stdinout_api_t) //base events - void (*print)( char *msg ); // basic text message - void (*printf)( char *msg, ... ); // normal text message - void (*dprintf)( char *msg, ... ); // developer text message - void (*wprintf)( char *msg, ... ); // warning text message - void (*error)( char *msg, ... ); // abnormal termination with message - void (*exit)( void ); // normal silent termination - char *(*input)( void ); // system console input + void (*print)( char *msg ); // basic text message + void (*printf)( char *msg, ... ); // normal text message + void (*dprintf)( int level, char *msg, ... ); // developer text message + void (*wprintf)( char *msg, ... ); // warning text message + void (*error)( char *msg, ... ); // abnormal termination with message + void (*exit)( void ); // normal silent termination + char *(*input)( void ); // system console input } stdinout_api_t; diff --git a/renderer/gl_rmain.c b/renderer/gl_rmain.c index 66e37db2..166259e3 100644 --- a/renderer/gl_rmain.c +++ b/renderer/gl_rmain.c @@ -1002,7 +1002,7 @@ bool R_SetMode (void) if ( vid_fullscreen->modified && !gl_config.allow_cds ) { - Msg("R_SetMode() - CDS not allowed with this driver\n" ); + MsgWarn("R_SetMode: CDS not allowed with this driver\n" ); ri.Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value ); vid_fullscreen->modified = false; } @@ -1022,7 +1022,7 @@ bool R_SetMode (void) { ri.Cvar_SetValue( "vid_fullscreen", 0); vid_fullscreen->modified = false; - Msg("R_SetMode() - fullscreen unavailable in this mode\n" ); + MsgWarn("R_SetMode: fullscreen unavailable in this mode\n" ); if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, false ) ) == rserr_ok ) return true; } @@ -1030,13 +1030,13 @@ bool R_SetMode (void) { ri.Cvar_SetValue( "gl_mode", gl_state.prev_mode ); gl_mode->modified = false; - Msg("R_SetMode() - invalid mode\n" ); + MsgWarn("R_SetMode: invalid mode\n" ); } // try setting it back to something safe if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_state.prev_mode, false ) ) != rserr_ok ) { - Msg("R_SetMode() - could not revert to safe mode\n" ); + MsgWarn("R_SetMode: could not revert to safe mode\n" ); return false; } } @@ -1091,18 +1091,18 @@ int R_Init( void *hinstance, void *hWnd ) return false; } - Msg("------- Loading bin/renderer.dll [%g] -------\n", RENDERER_VERSION ); + MsgDev(D_INFO, "------- Loading bin/renderer.dll [%g] -------\n", RENDERER_VERSION ); ri.Vid_MenuInit(); //get our various GL strings gl_config.vendor_string = qglGetString (GL_VENDOR); - MsgDev("GL_VENDOR: %s\n", gl_config.vendor_string ); + MsgDev(D_INFO, "GL_VENDOR: %s\n", gl_config.vendor_string ); gl_config.renderer_string = qglGetString (GL_RENDERER); - MsgDev("GL_RENDERER: %s\n", gl_config.renderer_string ); + MsgDev(D_INFO, "GL_RENDERER: %s\n", gl_config.renderer_string ); gl_config.version_string = qglGetString (GL_VERSION); - MsgDev("GL_VERSION: %s\n", gl_config.version_string ); + MsgDev(D_INFO, "GL_VERSION: %s\n", gl_config.version_string ); gl_config.extensions_string = qglGetString (GL_EXTENSIONS); - MsgDev("GL_EXTENSIONS: %s\n", gl_config.extensions_string ); + MsgDev(D_INFO, "GL_EXTENSIONS: %s\n", gl_config.extensions_string ); strcpy( renderer_buffer, gl_config.renderer_string ); strlwr( renderer_buffer ); @@ -1125,20 +1125,20 @@ int R_Init( void *hinstance, void *hWnd ) */ if ( strstr( gl_config.extensions_string, "GL_EXT_compiled_vertex_array" ) || strstr( gl_config.extensions_string, "GL_SGI_compiled_vertex_array" ) ) { - MsgDev("...enabling GL_EXT_compiled_vertex_array\n" ); + MsgDev(D_INFO, "...enabling GL_EXT_compiled_vertex_array\n" ); qglLockArraysEXT = ( void * ) qwglGetProcAddress( "glLockArraysEXT" ); qglUnlockArraysEXT = ( void * ) qwglGetProcAddress( "glUnlockArraysEXT" ); } - else MsgDev("...GL_EXT_compiled_vertex_array not found\n" ); + else MsgDev(D_WARN, "...GL_EXT_compiled_vertex_array not found\n" ); if ( strstr( gl_config.extensions_string, "WGL_EXT_swap_control" ) ) { qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" ); - Msg("...enabling WGL_EXT_swap_control\n" ); + MsgDev(D_INFO, "...enabling WGL_EXT_swap_control\n" ); } else { - Msg("...WGL_EXT_swap_control not found\n" ); + MsgDev(D_WARN, "...WGL_EXT_swap_control not found\n" ); } if (strstr( gl_config.extensions_string, "GL_ARB_texture_compression" )) @@ -1160,23 +1160,23 @@ int R_Init( void *hinstance, void *hWnd ) { qglPointParameterfEXT = ( void (APIENTRY *)( GLenum, GLfloat ) ) qwglGetProcAddress( "glPointParameterfEXT" ); qglPointParameterfvEXT = ( void (APIENTRY *)( GLenum, const GLfloat * ) ) qwglGetProcAddress( "glPointParameterfvEXT" ); - Msg("...using GL_EXT_point_parameters\n" ); + MsgDev(D_INFO, "...using GL_EXT_point_parameters\n" ); } else { - Msg("...ignoring GL_EXT_point_parameters\n" ); + MsgDev(D_INFO, "...ignoring GL_EXT_point_parameters\n" ); } } else { - Msg("...GL_EXT_point_parameters not found\n" ); + MsgDev(D_WARN, "...GL_EXT_point_parameters not found\n" ); } if ( strstr( gl_config.extensions_string, "GL_ARB_multitexture" ) ) { if ( gl_ext_multitexture->value ) { - MsgDev("...using GL_ARB_multitexture\n" ); + MsgDev(D_INFO, "...using GL_ARB_multitexture\n" ); qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMultiTexCoord2fARB" ); qglActiveTextureARB = ( void * ) qwglGetProcAddress( "glActiveTextureARB" ); qglClientActiveTextureARB = ( void * ) qwglGetProcAddress( "glClientActiveTextureARB" ); @@ -1185,33 +1185,33 @@ int R_Init( void *hinstance, void *hWnd ) } else { - MsgDev("...ignoring GL_ARB_multitexture\n" ); + MsgDev(D_INFO, "...ignoring GL_ARB_multitexture\n" ); } } else { - Msg("...GL_ARB_multitexture not found\n" ); + MsgDev(D_WARN, "...GL_ARB_multitexture not found\n" ); } if ( strstr( gl_config.extensions_string, "GL_NV_texture_rectangle" ) ) { - Msg("...using GL_NV_texture_rectangle\n"); + MsgDev(D_INFO, "...using GL_NV_texture_rectangle\n"); gl_state.nv_tex_rectangle = true; } else { - Msg("...GL_NV_texture_rectangle not found\n"); + MsgDev(D_WARN, "...GL_NV_texture_rectangle not found\n"); gl_state.nv_tex_rectangle = false; } if ( strstr( gl_config.extensions_string, "GL_EXT_texture_rectangle" ) ) { - Msg("...using GL_EXT_texture_rectangle\n"); + MsgDev(D_INFO, "...using GL_EXT_texture_rectangle\n"); gl_state.ati_tex_rectangle = true; } else { - Msg("...GL_EXT_texture_rectangle not found\n"); + MsgDev(D_WARN, "...GL_EXT_texture_rectangle not found\n"); gl_state.ati_tex_rectangle = false; } @@ -1219,11 +1219,11 @@ int R_Init( void *hinstance, void *hWnd ) { if ( qglActiveTextureARB ) { - Msg("...GL_SGIS_multitexture deprecated in favor of ARB_multitexture\n" ); + MsgDev(D_INFO, "...GL_SGIS_multitexture deprecated in favor of ARB_multitexture\n" ); } else if ( gl_ext_multitexture->value ) { - Msg("...using GL_SGIS_multitexture\n" ); + MsgDev(D_INFO, "...using GL_SGIS_multitexture\n" ); qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMTexCoord2fSGIS" ); qglSelectTextureSGIS = ( void * ) qwglGetProcAddress( "glSelectTextureSGIS" ); GL_TEXTURE0 = GL_TEXTURE0_SGIS; @@ -1231,21 +1231,18 @@ int R_Init( void *hinstance, void *hWnd ) } else { - Msg("...ignoring GL_SGIS_multitexture\n" ); + MsgDev(D_INFO, "...ignoring GL_SGIS_multitexture\n" ); } } else { - Msg("...GL_SGIS_multitexture not found\n" ); + MsgDev(D_WARN, "...GL_SGIS_multitexture not found\n" ); } GL_SetDefaultState(); // draw our stereo patterns - -#if 0 // commented out until H3D pays us the money they owe us GL_DrawStereoPattern(); -#endif R_InitTextures(); Mod_Init (); @@ -1254,7 +1251,7 @@ int R_Init( void *hinstance, void *hWnd ) R_StudioInit(); err = qglGetError(); - if ( err != GL_NO_ERROR ) Msg("glGetError() = 0x%x\n", err); + if ( err != GL_NO_ERROR ) MsgWarn("glGetError = 0x%x\n", err); return 1; } diff --git a/renderer/r_texture.c b/renderer/r_texture.c index 6d68bc9d..c58d4f6f 100644 --- a/renderer/r_texture.c +++ b/renderer/r_texture.c @@ -563,7 +563,7 @@ void GL_GenerateMipmaps( void ) if( image_desc.flags & IMAGE_GEN_MIPS ) { qglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); - if(qglGetError()) MsgWarn("R_LoadTexImage: can't create mip levels\n"); + if(qglGetError()) MsgDev(D_WARN, "R_LoadTexImage: can't create mip levels\n"); } } @@ -961,7 +961,7 @@ bool qrsCompressedTexImage2D( uint target, int level, int internalformat, uint w } break; default: - MsgWarn("qrsCompressedTexImage2D: invalid compression type: %s\n", PixelFormatDescription[internalformat].name ); + MsgDev(D_WARN, "qrsCompressedTexImage2D: invalid compression type: %s\n", PixelFormatDescription[internalformat].name ); return false; } @@ -1227,7 +1227,7 @@ bool qrsDecompressImageATI( uint target, int level, int internalformat, uint wid } break; default: - MsgWarn("qrsDecompressImageATI: invalid compression type: %s\n", PixelFormatDescription[internalformat].name ); + MsgDev(D_WARN, "qrsDecompressImageATI: invalid compression type: %s\n", PixelFormatDescription[internalformat].name ); return false; } @@ -1326,7 +1326,7 @@ bool R_StoreImageARGB( uint target, int level, uint width, uint height, uint ima } else { - MsgWarn("R_StoreImageARGB: can't get RGBA bitmask\n" ); + MsgDev(D_ERROR, "R_StoreImageARGB: can't get RGBA bitmask\n" ); return false; } @@ -1429,7 +1429,7 @@ bool R_LoadImage32 (byte *data ) if (s&3) { - MsgWarn("R_LoadImage32: s&3\n"); + MsgDev(D_ERROR, "R_LoadImage32: s&3\n"); return false; } for (i = 0; i < s; i++ ) @@ -1528,7 +1528,7 @@ bool R_LoadImage24(byte *data ) { if (s&3) { - MsgWarn("R_LoadImage24: s&3\n"); + MsgDev(D_ERROR, "R_LoadImage24: s&3\n"); return false; } if(image_desc.pal) @@ -1615,14 +1615,14 @@ image_t *R_LoadImage(char *name, rgbdata_t *pic, imagetype_t type ) { if (numgltextures == MAX_GLTEXTURES) { - MsgWarn("R_LoadImage: gl_textures limit is out\n"); + MsgDev(D_ERROR, "R_LoadImage: gl_textures limit is out\n"); return NULL; } numgltextures++; } image = &gltextures[i]; - if (strlen(name) >= sizeof(image->name)) MsgWarn( "R_LoadImage: \"%s\" is too long", name); + if (strlen(name) >= sizeof(image->name)) MsgDev( D_WARN, "R_LoadImage: \"%s\" is too long", name); strncpy (image->name, name, sizeof(image->name)); image->registration_sequence = registration_sequence; @@ -1646,7 +1646,7 @@ image_t *R_LoadImage(char *name, rgbdata_t *pic, imagetype_t type ) R_SetPixelFormat( image_desc.width, image_desc.height, image_desc.numLayers ); offset = image_desc.SizeOfFile;// move pointer - // MsgDev("loading %s [%s] \n", name, PixelFormatDescription[image_desc.format].name ); + MsgDev(D_INFO, "loading %s [%s] \n", name, PixelFormatDescription[image_desc.format].name ); switch(pic->type) { diff --git a/resource/server.dat b/resource/server.dat new file mode 100644 index 0000000000000000000000000000000000000000..81e3b2255469b4a134422f60bb4f721d6dd37f9a GIT binary patch literal 62108 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 UPZ8|xjP7CZUW8ybFw*7xA2;4yPyhe` literal 0 HcmV?d00001