diff options
38 files changed, 553 insertions, 335 deletions
diff --git a/build/q2pro.mk b/build/q2pro.mk index 39f7ab7..fb52702 100644 --- a/build/q2pro.mk +++ b/build/q2pro.mk @@ -82,7 +82,13 @@ ifdef USE_DINPUT SRCFILES+=in_dx.c endif -LDFLAGS+=-mwindows -lws2_32 -lwinmm +LDFLAGS+=-mwindows +ifdef WINCE +SRCFILES+=win_ascii.c +LDFLAGS+=-lwinsock -lmmtimer +else +LDFLAGS+=-lws2_32 -lwinmm +endif RESFILES=q2pro.rc diff --git a/build/q2proded.mk b/build/q2proded.mk index 0b9b684..93b66b1 100644 --- a/build/q2proded.mk +++ b/build/q2proded.mk @@ -20,7 +20,7 @@ include ../config.mk TARGET=../q2proded$(EXESUFFIX) CFLAGS+=-DUSE_CLIENT=0 -LDFLAGS+=-lm +#LDFLAGS+=-lm include $(SRCDIR)/build/common.mk @@ -30,7 +30,13 @@ include $(SRCDIR)/build/server.mk ifdef MINGW SRCFILES+=sys_win.c -LDFLAGS+=-mconsole -lws2_32 -lwinmm -ladvapi32 +LDFLAGS+=-mconsole +ifdef WINCE +SRCFILES+=win_ascii.c +LDFLAGS+=-lwinsock -lmmtimer +else +LDFLAGS+=-lws2_32 -lwinmm -ladvapi32 +endif RESFILES+=q2proded.rc else SRCFILES+=sys_unix.c @@ -54,6 +54,7 @@ cpu="" singleuser="no" asmflags="" mingw="no" +wince="no" if [ -z "$CFLAGS" ]; then CFLAGS="-O2 -g -Wall -Wstrict-prototypes" fi @@ -95,6 +96,8 @@ use_mvd_server="yes" use_mvd_client="yes" use_asm="???" use_openffa="no" +use_syscon="yes" +use_winsvc="no" # constants cfgfile="config.cfg" @@ -106,6 +109,8 @@ screenshots="screenshots" scoreshots="scoreshots" gldriver="libGL.so.1" indriver="" +vid_modelist="640x480 800x600 1024x768" +vid_geometry="640x480" #parse options for opt do @@ -120,6 +125,8 @@ for opt do ;; --enable-mingw) mingw="yes" ; sdl="no" ;; + --enable-wince) wince="yes" + ;; --cpu=*) cpu=`echo $opt | cut -d '=' -f 2` ;; --cc=*) cc=`echo $opt | cut -d '=' -f 2` @@ -276,6 +283,16 @@ if [ "$mingw" = "yes" ]; then if [ -z "$LDFLAGS" ]; then LDFLAGS="-static" fi + + if [ "$wince" = "yes" ]; then + vid_modelist="240x320" + vid_geometry="240x320" + targetos="WinCE" + use_syscon="no" + use_winsvc="no" + else + use_winsvc="yes" + fi else pathsep="/" exported="__attribute__((visibility(\"default\")))" @@ -306,6 +323,12 @@ else LDFLAGS="-Wl,--no-undefined $LDFLAGS" fi +if [ "$use_ref" = "soft" ]; then + use_tga="no" + use_png="no" + use_jpg="no" +fi + gamelib="game$cpu$libsuffix" vpath="\$(SRCDIR)/source" @@ -375,6 +398,7 @@ echo "# Generated by configure - do not modify" > $config_mk echo "// Generated by configure - do not modify" > $config_h test "$mingw" = "yes" && echo "MINGW=$mingw" >> $config_mk +test "$wince" = "yes" && echo "WINCE=$wince" >> $config_mk echo "CC=$cc" >> $config_mk echo "WINDRES=$windres" >> $config_mk echo "STRIP=$strip" >> $config_mk @@ -451,6 +475,9 @@ if [ "$use_zlib" = "yes" ]; then echo "ZLIB_LDFLAGS=-lz" >> $config_mk echo "ZLIB_CFLAGS=" >> $config_mk echo "#define USE_ZLIB 1" >> $config_h + if [ "$wince" = "yes" ]; then + echo "#define NO_ERRNO_H" >> $config_h + fi else echo "#define USE_ZLIB 0" >> $config_h fi @@ -463,6 +490,8 @@ if [ "$use_ref" != "no" ]; then echo "#define DEFAULT_OPENGL_DRIVER \"$gldriver\"" >> $config_h fi echo "#define VID_REF \"$use_ref\"" >> $config_h + echo "#define VID_MODELIST \"$vid_modelist\"" >> $config_h + echo "#define VID_GEOMETRY \"$vid_geometry\"" >> $config_h fi if [ "$use_tga" = "yes" ]; then @@ -531,6 +560,14 @@ if [ "$use_mvd_client" = "yes" ]; then echo "#define USE_MVD_CLIENT 1" >> $config_h fi +if [ "$use_syscon" = "yes" ]; then + echo "#define USE_SYSCON 1" >> $config_h +fi + +if [ "$use_winsvc" = "yes" ]; then + echo "#define USE_WINSVC !USE_CLIENT" >> $config_h +fi + echo "#define USE_MAPCHECKSUM 1" >> $config_h echo "#define USE_AUTOREPLY 1" >> $config_h diff --git a/debian/control b/debian/control index f1b9c34..cece11d 100644 --- a/debian/control +++ b/debian/control @@ -1,54 +1,54 @@ Source: q2pro Section: contrib/games -Priority: extra -Maintainer: Andrey Nazarov <skuller-vidnoe@yandex.ru> +Priority: optional +Maintainer: Andrey Nazarov <skuller@skuller.ath.cx> Build-Depends: cdbs, debhelper (>= 5), libx11-dev, libsdl1.2-dev, libpng12-dev, libjpeg62-dev, zlib1g-dev, mesa-common-dev Standards-Version: 3.7.2 Package: q2pro-client Architecture: any -Depends: ${shlibs:Depends}, q2pro-common +Depends: ${shlibs:Depends}, q2pro-common (= ${binary:Version}) Recommends: quake2-data -Description: Enhanced Quake2 engine (graphical client) - Q2PRO is a Quake2 engine modification designed for online play, +Description: Enhanced Quake 2 engine (graphical client) + Q2PRO is a Quake 2 engine modification designed for online play, fully compatible with original Quake2 clients and servers. . - Q2PRO features enhanced graphical console, support for 32-bit textures and - MD3 models, network protocol optimizations, freely resizable windows, + Q2PRO features enhanced graphical console, support for JPEG/PNG textures + and MD3 models, network protocol optimizations, freely resizable main window, increased security and overall performance, basic built-in demo editing capabilities, built-in server and demo browsers. . - This version of Q2PRO requires 3D graphics accelerator to play. + This version of Q2PRO requires a 3D graphics accelerator to play. . - Homepage: http://q2pro.sf.net/ + Homepage: http://skuller.ath.cx/q2pro/ Package: q2pro-server Architecture: any -Depends: ${shlibs:Depends}, q2pro-common +Depends: ${shlibs:Depends}, q2pro-common (= ${binary:Version}) Recommends: quake2-data -Description: Enhanced Quake2 engine (dedicated server) - Q2PRO is a Quake2 engine modification designed for online play, - fully compatible with original Quake2 clients and servers. +Description: Enhanced Quake 2 engine (dedicated server) + Q2PRO is a Quake 2 engine modification designed for online play, + fully compatible with original Quake 2 clients and servers. . Q2PRO dedicated server features multi-view demo recording capabilities, game television support, network protocol optimizations, increased security and overall performance. . This package contains streamlined server executable, with all client side - code stripped out. Use it for hosting Quake2 servers. + code stripped out. Use it for hosting Quake 2 servers. . - Homepage: http://q2pro.sf.net/ + Homepage: http://skuller.ath.cx/q2pro/ Package: q2pro-common Architecture: any Depends: ${shlibs:Depends} -Description: Enhanced Quake2 engine (common files) - This package contains common files between Q2PRO server and client. +Description: Enhanced Quake 2 engine (common files) + This package contains files common between Q2PRO server and client. Currently, OpenFFA deathmatch mod is packaged, which provides game library essential for server startup. . OpenFFA is a simple deathmatch mod for Quake2. It features familiar scoreboard, voting system, map rotation support, high scores logging. . - Homepage: http://q2pro.sf.net/ + Homepage: http://skuller.ath.cx/q2pro/ diff --git a/source/cl_demo.c b/source/cl_demo.c index 1e08789..23275f1 100644 --- a/source/cl_demo.c +++ b/source/cl_demo.c @@ -245,12 +245,6 @@ void CL_Stop_f( void ) { Com_Printf( "Stopped demo (%u bytes written).\n", msglen ); } -static const cmd_option_t o_record[] = { - { "h", "help", "display this message" }, - { "z", "gzip", "compress file with gzip" }, - { NULL } -}; - /* ==================== CL_Record_f diff --git a/source/cl_main.c b/source/cl_main.c index ab10ac7..c427fb7 100644 --- a/source/cl_main.c +++ b/source/cl_main.c @@ -2657,9 +2657,9 @@ static void CL_CheckTimeout( void ) { Com_Error( ERR_DISCONNECT, "Server connection was reset." ); } } - + delta = cl_timeout->value * 1000; - if( com_localTime - cls.netchan->last_received > delta ) { + if( delta && com_localTime - cls.netchan->last_received > delta ) { // timeoutcount saves debugger if ( ++cl.timeoutcount > 5 ) { Com_Error( ERR_DISCONNECT, "Server connection timed out." ); diff --git a/source/cl_parse.c b/source/cl_parse.c index b6c9206..b54ec7f 100644 --- a/source/cl_parse.c +++ b/source/cl_parse.c @@ -897,7 +897,9 @@ static void CL_ParseServerData( void ) { Con_Printf( "\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n" ); Con_Printf( S_COLOR_ALT "%s\n\n", levelname ); +#if USE_SYSCON Sys_Printf( "\n\n%s\n", levelname ); +#endif // make sure clientNum is in range if( cl.clientNum < 0 || cl.clientNum >= MAX_CLIENTS ) { diff --git a/source/cl_ref.c b/source/cl_ref.c index b35d92c..a107019 100644 --- a/source/cl_ref.c +++ b/source/cl_ref.c @@ -232,10 +232,10 @@ void CL_InitRefresh( void ) { // Create the video variables so we know how to start the graphics drivers vid_ref = Cvar_Get( "vid_ref", VID_REF, CVAR_ROM ); - vid_geometry = Cvar_Get( "vid_geometry", "640x480", CVAR_ARCHIVE ); vid_fullscreen = Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE ); _vid_fullscreen = Cvar_Get( "_vid_fullscreen", "1", CVAR_ARCHIVE ); - vid_modelist = Cvar_Get( "vid_modelist", "640x480 800x600 1024x768", 0 ); + vid_modelist = Cvar_Get( "vid_modelist", VID_MODELIST, CVAR_ARCHIVE ); + vid_geometry = Cvar_Get( "vid_geometry", VID_GEOMETRY, CVAR_ARCHIVE ); if( vid_fullscreen->integer ) { Cvar_Set( "_vid_fullscreen", vid_fullscreen->string ); diff --git a/source/cl_scrn.c b/source/cl_scrn.c index 18f4602..6cdfa27 100644 --- a/source/cl_scrn.c +++ b/source/cl_scrn.c @@ -205,7 +205,9 @@ SCR_DrawDemoBar ================ */ static void SCR_DrawDemoBar( void ) { +#if USE_MVD_CLIENT int percent; +#endif if( !scr_demobar->integer ) { return; diff --git a/source/com_local.h b/source/com_local.h index d940aac..2513758 100644 --- a/source/com_local.h +++ b/source/com_local.h @@ -488,6 +488,10 @@ extern time_t com_startTime; extern fileHandle_t com_logFile; +#if USE_CLIENT || USE_MVD_CLIENT || USE_MVD_SERVER +extern const cmd_option_t o_record[]; +#endif + void Qcommon_Init( int argc, char **argv ); void Qcommon_Frame( void ); void Qcommon_Shutdown( qboolean fatalError ); diff --git a/source/common.c b/source/common.c index 16b276d..21cb65c 100644 --- a/source/common.c +++ b/source/common.c @@ -295,8 +295,10 @@ void Com_Printf( const char *fmt, ... ) { Con_Print( msg ); #endif +#if USE_SYSCON // debugging console Sys_ConsoleOutput( msg ); +#endif // remote console //SV_ConsoleOutput( msg ); @@ -1100,6 +1102,7 @@ static void Com_LastError_f( void ) { } } +#ifndef __COREDLL__ static void Com_Setenv_f( void ) { int argc = Cmd_Argc(); @@ -1117,6 +1120,7 @@ static void Com_Setenv_f( void ) { Com_Printf( "Usage: %s <name> [value]\n", Cmd_Argv( 0 ) ); } } +#endif #ifdef _DEBUG @@ -1220,6 +1224,15 @@ void Com_Color_g( genctx_t *ctx ) { } #endif +#if USE_CLIENT || USE_MVD_CLIENT || USE_MVD_SERVER +const cmd_option_t o_record[] = { + { "h", "help", "display this message" }, + { "z", "gzip", "compress file with gzip" }, + { NULL } +}; +#endif + + /* =============== Com_AddEarlyCommands @@ -1367,7 +1380,9 @@ void Qcommon_Init( int argc, char **argv ) { Cmd_AddCommand ("z_stats", Z_Stats_f); +#ifndef __COREDLL__ Cmd_AddCommand( "setenv", Com_Setenv_f ); +#endif Cmd_AddMacro( "com_date", Com_Date_m ); Cmd_AddMacro( "com_time", Com_Time_m ); @@ -1387,11 +1402,15 @@ void Qcommon_Init( int argc, char **argv ) { Sys_Init(); +#if USE_SYSCON Sys_RunConsole(); +#endif FS_Init(); +#if USE_SYSCON Sys_RunConsole(); +#endif // no longer allow CVAR_NOSET modifications com_initialized = qtrue; @@ -1435,7 +1454,9 @@ void Qcommon_Init( int argc, char **argv ) { CL_Init(); #endif +#if USE_SYSCON Sys_RunConsole(); +#endif // add + commands from command line if( !Com_AddLateCommands() ) { @@ -1482,8 +1503,12 @@ Com_ProcessEvents ============== */ void Com_ProcessEvents( void ) { +#if USE_SYSCON Sys_RunConsole(); +#endif +#if USE_SERVER SV_ProcessEvents(); +#endif #if USE_CLIENT CL_ProcessEvents(); #endif diff --git a/source/files.c b/source/files.c index a8eb100..c3b78b4 100644 --- a/source/files.c +++ b/source/files.c @@ -27,7 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include <zlib.h> #include "unzip.h" #endif -#include <errno.h> /* ============================================================================= @@ -598,8 +597,8 @@ static size_t FS_FOpenFileWrite( fsFile_t *file, const char *name ) { fp = fopen( fullpath, modeStr ); if( !fp ) { - FS_DPrintf( "%s: %s: fopen(%s): %s\n", - __func__, fullpath, modeStr, strerror( errno ) ); + FS_DPrintf( "%s: %s: couldn't open\n", + __func__, fullpath ); return INVALID_LENGTH; } @@ -1030,7 +1029,7 @@ size_t FS_FOpenFile( const char *name, fileHandle_t *f, int mode ) { return ret; } - +#if USE_LOADBUF #define MAX_LOAD_BUFFER 0x100000 // 1 MiB @@ -1046,6 +1045,8 @@ static int loadStack; static int loadCount; static int loadCountStatic; +#endif // USE_LOADBUF + /* ============ FS_LoadFile @@ -1128,6 +1129,7 @@ size_t FS_LoadFile( const char *path, void **buffer ) { void *FS_AllocTempMem( size_t length ) { byte *buf; +#if USE_LOADBUF if( loadInuse + length <= MAX_LOAD_BUFFER && !( fs_restrict_mask->integer & 16 ) ) { buf = &loadBuffer[loadInuse]; loadLast = buf; @@ -1136,10 +1138,14 @@ void *FS_AllocTempMem( size_t length ) { loadInuse = ( loadInuse + 31 ) & ~31; loadStack++; loadCountStatic++; - } else { + } else +#endif + { // Com_Printf(S_COLOR_MAGENTA"alloc %d\n",length); buf = FS_Malloc( length ); +#if USE_LOADBUF loadCount++; +#endif } return buf; } @@ -1153,6 +1159,7 @@ void FS_FreeFile( void *buffer ) { if( !buffer ) { Com_Error( ERR_FATAL, "%s: NULL", __func__ ); } +#if USE_LOADBUF if( ( byte * )buffer >= loadBuffer && ( byte * )buffer < loadBuffer + MAX_LOAD_BUFFER ) { if( loadStack == 0 ) { Com_Error( ERR_FATAL, "%s: empty load stack", __func__ ); @@ -1165,7 +1172,9 @@ void FS_FreeFile( void *buffer ) { loadInuse = loadSaved; // Com_Printf(S_COLOR_MAGENTA"partial\n"); } - } else { + } else +#endif + { Z_Free( buffer ); } } @@ -2208,8 +2217,10 @@ static void FS_Stats_f( void ) { //totalHashSize += pack->hashSize; } +#if USE_LOADBUF Com_Printf( "LoadFile counter: %d\n", loadCount ); Com_Printf( "Static LoadFile counter: %d\n", loadCountStatic ); +#endif Com_Printf( "Total calls to OpenFileRead: %d\n", fs_count_read ); Com_Printf( "Total path comparsions: %d\n", fs_count_strcmp ); Com_Printf( "Total calls to fopen: %d\n", fs_count_open ); diff --git a/source/mvd_client.c b/source/mvd_client.c index 859227e..c8fb982 100644 --- a/source/mvd_client.c +++ b/source/mvd_client.c @@ -97,7 +97,6 @@ static const char *const mvd_states[MVD_NUM_STATES] = { static LIST_DECL( mvd_gtv_list ); LIST_DECL( mvd_channel_list ); -LIST_DECL( mvd_active_list ); mvd_t mvd_waitingRoom; qboolean mvd_dirty; @@ -147,7 +146,6 @@ void MVD_Free( mvd_t *mvd ) { Z_Free( mvd->delay.data ); - List_Remove( &mvd->active ); List_Remove( &mvd->entry ); Z_Free( mvd ); } @@ -156,7 +154,7 @@ void MVD_Destroy( mvd_t *mvd ) { mvd_client_t *client, *next; // update channel menus - if( !LIST_EMPTY( &mvd->active ) ) { + if( !LIST_EMPTY( &mvd->entry ) ) { mvd_dirty = qtrue; } @@ -245,31 +243,6 @@ mvd_t *MVD_SetChannel( int arg ) { return NULL; } -void MVD_CheckActive( mvd_t *mvd ) { - mvd_t *cur; - - if( mvd->state == MVD_READING || ( mvd->gtv && - mvd->gtv->state == GTV_READING ) ) - { - if( LIST_EMPTY( &mvd->active ) ) { - // sort this one into the list of active channels - LIST_FOR_EACH( mvd_t, cur, &mvd_active_list, active ) { - if( cur->id > mvd->id ) { - break; - } - } - List_Append( &cur->active, &mvd->active ); - mvd_dirty = qtrue; - } - } else { - if( !LIST_EMPTY( &mvd->active ) ) { - // delete this one from the list of active channels - List_Delete( &mvd->active ); - mvd_dirty = qtrue; - } - } -} - /* ==================================================================== @@ -324,7 +297,6 @@ static mvd_t *create_channel( gtv_t *gtv ) { mvd->min_packets = mvd_wait_delay->value * 10; List_Init( &mvd->clients ); List_Init( &mvd->entry ); - List_Init( &mvd->active ); return mvd; } @@ -677,24 +649,32 @@ static void write_message( gtv_t *gtv, gtv_clientop_t op ) { } static qboolean gtv_wait_stop( mvd_t *mvd ) { + gtv_t *gtv = mvd->gtv; int usage; + // if not connected, flush any data left + if( !gtv || gtv->state != GTV_READING ) { + goto stop; + } + // see how many frames are buffered if( mvd->num_packets >= mvd->min_packets ) { - Com_Printf( "[%s] -=- Waiting finished, reading...\n", mvd->name ); - mvd->state = MVD_READING; - return qtrue; + Com_Printf( "[%s] -=- Waiting stoped, reading...\n", mvd->name ); + goto stop; } // see how much data is buffered usage = FIFO_Percent( &mvd->delay ); if( usage >= mvd_wait_percent->value ) { - Com_Printf( "[%s] -=- Buffering finished, reading...\n", mvd->name ); - mvd->state = MVD_READING; - return qtrue; + Com_Printf( "[%s] -=- Buffering stoped, reading...\n", mvd->name ); + goto stop; } return qfalse; + +stop: + mvd->state = MVD_READING; + return qtrue; } // ran out of buffers @@ -707,36 +687,37 @@ static void gtv_wait_start( mvd_t *mvd ) { MVD_Destroyf( mvd, "End of MVD stream reached" ); } - Com_Printf( "[%s] -=- Buffering data...\n", mvd->name ); + // if connection is suspended, kill it + if( gtv->state != GTV_READING ) { + Com_Printf( "[%s] -=- Ran out of buffers.\n", mvd->name ); - mvd->state = MVD_WAITING; + gtv->mvd = NULL; + mvd->gtv = NULL; + MVD_Destroy( mvd ); - if( gtv->state == GTV_READING ) { - // oops, if this happened in the middle of the game, - // resume as quickly as possible after there is some - // data available again - mvd->min_packets = 50 + 5 * mvd->underflows; - if( mvd->min_packets > tr ) { - mvd->min_packets = tr; - } - mvd->underflows++; + longjmp( mvd_jmpbuf, -1 ); + } - // notify spectators - if( Com_IsDedicated() ) { - MVD_BroadcastPrintf( mvd, PRINT_HIGH, 0, - "[MVD] Buffering data, please wait...\n" ); - } + Com_Printf( "[%s] -=- Buffering data...\n", mvd->name ); - // send ping to force server to flush - write_message( gtv, GTC_PING ); - } else { - // channel is expected to underflow after suspend, - // reset delay to default + // oops, underflowed in the middle of the game, + // resume as quickly as possible after there is some + // data available again + mvd->min_packets = 50 + 5 * mvd->underflows; + if( mvd->min_packets > tr ) { mvd->min_packets = tr; - mvd->underflows = 0; + } + mvd->underflows++; + mvd->state = MVD_WAITING; + + // notify spectators + if( Com_IsDedicated() ) { + MVD_BroadcastPrintf( mvd, PRINT_HIGH, 0, + "[MVD] Buffering data, please wait...\n" ); } - MVD_CheckActive( mvd ); + // send ping to force server to flush + write_message( gtv, GTC_PING ); } static qboolean gtv_read_frame( mvd_t *mvd ) { @@ -923,33 +904,10 @@ static void parse_hello( gtv_t *gtv ) { } static void parse_stream_start( gtv_t *gtv ) { - mvd_t *mvd = gtv->mvd; - size_t size; - if( gtv->state != GTV_RESUMING ) { gtv_destroyf( gtv, "Unexpected stream start ack in state %u", gtv->state ); } - // create the channel - if( !mvd ) { - mvd = create_channel( gtv ); - - Cvar_ClampInteger( mvd_buffer_size, 2, 10 ); - - // allocate delay buffer - size = mvd_buffer_size->integer * MAX_MSGLEN; - mvd->delay.data = MVD_Malloc( size ); - mvd->delay.size = size; - mvd->read_frame = gtv_read_frame; - mvd->forward_cmd = gtv_forward_cmd; - - gtv->mvd = mvd; - } else { - // reset delay to default - mvd->min_packets = mvd_wait_delay->value * 10; - mvd->underflows = 0; - } - Com_Printf( "[%s] -=- Stream start ack received.\n", gtv->name ); gtv->state = GTV_READING; @@ -967,6 +925,7 @@ static void parse_stream_stop( gtv_t *gtv ) { static void parse_stream_data( gtv_t *gtv ) { mvd_t *mvd = gtv->mvd; + size_t size; if( gtv->state < GTV_WAITING ) { gtv_destroyf( gtv, "Unexpected stream data packet" ); @@ -993,8 +952,24 @@ static void parse_stream_data( gtv_t *gtv ) { gtv->state = GTV_READING; } + // create the channel, if not yet created + if( !mvd ) { + mvd = create_channel( gtv ); + + Cvar_ClampInteger( mvd_buffer_size, 2, 10 ); + + // allocate delay buffer + size = mvd_buffer_size->integer * MAX_MSGLEN; + mvd->delay.data = MVD_Malloc( size ); + mvd->delay.size = size; + mvd->read_frame = gtv_read_frame; + mvd->forward_cmd = gtv_forward_cmd; + + gtv->mvd = mvd; + } + if( !mvd->state ) { - // parse it in place + // parse it in place until we get a gamestate MVD_ParseMessage( mvd ); } else { byte *data = msg_read.data + 1; @@ -1019,8 +994,10 @@ static void parse_stream_data( gtv_t *gtv ) { } // clear entire delay buffer + // minimize the delay FIFO_Clear( &mvd->delay ); mvd->state = MVD_WAITING; + mvd->num_packets = 0; mvd->min_packets = 50; mvd->overflows++; @@ -1428,7 +1405,9 @@ void MVD_Spawn_f( void ) { Cvar_Set( "timedemo", "0" ); SV_InfoSet( "port", net_port->string ); +#if USE_SYSCON SV_SetConsoleTitle(); +#endif // generate spawncount for Waiting Room sv.spawncount = ( rand() | ( rand() << 16 ) ) ^ Sys_Milliseconds(); @@ -1515,13 +1494,16 @@ static void MVD_EmitGamestate( mvd_t *mvd ) { char *string; int i; edict_t *ent; - player_state_t *ps; + mvd_player_t *player; size_t length; - int flags, portalbytes; + int flags, extra, portalbytes; byte portalbits[MAX_MAP_AREAS/8]; + // pack MVD stream flags into extra bits + extra = mvd->flags << SVCMD_BITS; + // send the serverdata - MSG_WriteByte( mvd_serverdata ); + MSG_WriteByte( mvd_serverdata | extra ); MSG_WriteLong( PROTOCOL_VERSION_MVD ); MSG_WriteShort( PROTOCOL_VERSION_MVD_CURRENT ); MSG_WriteLong( mvd->servercount ); @@ -1549,29 +1531,28 @@ static void MVD_EmitGamestate( mvd_t *mvd ) { portalbytes = CM_WritePortalBits( &sv.cm, portalbits ); MSG_WriteByte( portalbytes ); MSG_WriteData( portalbits, portalbytes ); - + // send base player states - for( i = 0; i < mvd->maxclients; i++ ) { - ps = &mvd->players[i].ps; + for( i = 0, player = mvd->players; i < mvd->maxclients; i++, player++ ) { flags = 0; - if( !PPS_INUSE( ps ) ) { + if( !player->inuse ) { flags |= MSG_PS_REMOVE; } - MSG_WriteDeltaPlayerstate_Packet( NULL, ps, i, flags ); + MSG_WriteDeltaPlayerstate_Packet( NULL, &player->ps, i, flags ); } MSG_WriteByte( CLIENTNUM_NONE ); // send base entity states - for( i = 1; i < mvd->pool.num_edicts; i++ ) { - ent = &mvd->edicts[i]; + for( i = 1, ent = mvd->edicts + 1; i < mvd->pool.num_edicts; i++, ent++ ) { flags = 0; - if( i <= mvd->maxclients ) { - ps = &mvd->players[ i - 1 ].ps; - if( PPS_INUSE( ps ) && ps->pmove.pm_type == PM_NORMAL ) { - flags |= MSG_ES_FIRSTPERSON; + if( ent->inuse ) { + if( i <= mvd->maxclients ) { + player = &mvd->players[ i - 1 ]; + if( player->inuse && player->ps.pmove.pm_type == PM_NORMAL ) { + flags |= MSG_ES_FIRSTPERSON; + } } - } - if( !ent->inuse ) { + } else { flags |= MSG_ES_REMOVE; } MSG_WriteDeltaEntity( NULL, &ent->s, flags ); @@ -1581,8 +1562,6 @@ static void MVD_EmitGamestate( mvd_t *mvd ) { // TODO: write private layouts/configstrings } -extern const cmd_option_t o_mvdrecord[]; - void MVD_StreamedRecord_f( void ) { char buffer[MAX_OSPATH]; fileHandle_t f; @@ -1593,12 +1572,12 @@ void MVD_StreamedRecord_f( void ) { int c; size_t len; - while( ( c = Cmd_ParseOptions( o_mvdrecord ) ) != -1 ) { + while( ( c = Cmd_ParseOptions( o_record ) ) != -1 ) { switch( c ) { case 'h': - Cmd_PrintUsage( o_mvdrecord, "[/]<filename> [chanid]" ); + Cmd_PrintUsage( o_record, "[/]<filename> [chanid]" ); Com_Printf( "Begin MVD recording on the specified channel.\n" ); - Cmd_PrintHelp( o_mvdrecord ); + Cmd_PrintHelp( o_record ); return; case 'z': gzip = qtrue; @@ -2040,7 +2019,6 @@ void MVD_Shutdown( void ) { List_Init( &mvd_gtv_list ); List_Init( &mvd_channel_list ); - List_Init( &mvd_active_list ); Z_Free( mvd_clients ); mvd_clients = NULL; diff --git a/source/mvd_game.c b/source/mvd_game.c index 9fc5e5f..b891c4f 100644 --- a/source/mvd_game.c +++ b/source/mvd_game.c @@ -145,7 +145,7 @@ static void MVD_LayoutChannels( mvd_client_t *client ) { total = sizeof( header ) - 1; // FIXME: improve this - cursor = List_Count( &mvd_active_list ); + cursor = List_Count( &mvd_channel_list ); if( cursor ) { if( client->layout_cursor < 0 ) { client->layout_cursor = cursor - 1; @@ -155,7 +155,7 @@ static void MVD_LayoutChannels( mvd_client_t *client ) { y = 64; cursor = 0; - LIST_FOR_EACH( mvd_t, mvd, &mvd_active_list, active ) { + LIST_FOR_EACH( mvd_t, mvd, &mvd_channel_list, entry ) { len = Q_snprintf( buffer, sizeof( buffer ), "yv %d string%s \"%c%-12.12s %-7.7s %d/%d\" ", y, mvd == client->mvd ? "2" : "", @@ -213,7 +213,7 @@ static void MVD_LayoutMenu( mvd_client_t *client ) { "yv 120 string \"%cIgnore player FOV: %s\"" "yv 128 string \" (use 'set uf %d u' in cfg)\"" "yv 144 string2 \"%cExit menu\"" - "xv 240 yv 172 string2 " VERSION; + "%s xv 240 yv 172 string2 " VERSION; char layout[MAX_STRING_CHARS]; char cur[MENU_ITEMS]; size_t total; @@ -230,13 +230,14 @@ static void MVD_LayoutMenu( mvd_client_t *client ) { total = Q_snprintf( layout, sizeof( layout ), format, cur[0], client->target ? "Leave" : "Enter", cur[1], cur[2], List_Count( &client->mvd->clients ), - cur[3], List_Count( &mvd_active_list ), cur[4], + cur[3], List_Count( &mvd_channel_list ), cur[4], cur[5], ( client->uf & UF_MUTE_OBSERVERS ) ? YES : NO, cur[6], ( client->uf & UF_MUTE_MISC ) ? YES : NO, cur[7], ( client->uf & UF_MUTE_PLAYERS ) ? YES: NO, cur[8], ( client->uf & UF_LOCALFOV ) ? YES : NO, client->uf, - cur[9] ); + cur[9], client->mvd->state == MVD_WAITING ? + "xv 0 yv 160 cstring [BUFFERING]" : "" ); // send the layout MSG_WriteByte( svc_layout ); @@ -945,7 +946,7 @@ static void MVD_Invuse_f( mvd_client_t *client ) { } if( client->layout_type == LAYOUT_CHANNELS ) { - mvd = LIST_INDEX( mvd_t, client->layout_cursor, &mvd_active_list, active ); + mvd = LIST_INDEX( mvd_t, client->layout_cursor, &mvd_channel_list, entry ); if( mvd ) { MVD_TrySwitchChannel( client, mvd ); } else { @@ -1010,32 +1011,12 @@ static void print_channel( client_t *cl, mvd_t *mvd ) { static void mvd_channel_list_f( mvd_client_t *client ) { mvd_t *mvd; - if( Cmd_Argc() > 1 ) { - if( LIST_EMPTY( &mvd_channel_list ) ) { - SV_ClientPrintf( client->cl, PRINT_HIGH, - "No ready channels.\n" ); - return; - } - } else { - if( LIST_EMPTY( &mvd_active_list ) ) { - SV_ClientPrintf( client->cl, PRINT_HIGH, - "No active channels.\n" ); - return; - } - } - SV_ClientPrintf( client->cl, PRINT_HIGH, "id name map spc plr who is playing\n" "-- ------------ -------- --- --- --------------\n" ); - if( Cmd_Argc() > 1 ) { - LIST_FOR_EACH( mvd_t, mvd, &mvd_channel_list, entry ) { - print_channel( client->cl, mvd ); - } - } else { - LIST_FOR_EACH( mvd_t, mvd, &mvd_active_list, active ) { - print_channel( client->cl, mvd ); - } + LIST_FOR_EACH( mvd_t, mvd, &mvd_channel_list, entry ) { + print_channel( client->cl, mvd ); } } @@ -1298,9 +1279,9 @@ static qboolean MVD_GameClientConnect( edict_t *ent, char *userinfo ) { // if there is exactly one active channel, assign them to it, // otherwise, assign to Waiting Room - count = List_Count( &mvd_active_list ); + count = List_Count( &mvd_channel_list ); if( count == 1 ) { - mvd = LIST_FIRST( mvd_t, &mvd_active_list, active ); + mvd = LIST_FIRST( mvd_t, &mvd_channel_list, entry ); } else { mvd = &mvd_waitingRoom; } @@ -1548,9 +1529,6 @@ static void MVD_GameRunFrame( void ) { MVD_IntermissionStop( mvd ); } - // check for active players - MVD_CheckActive( mvd ); - // update UDP clients LIST_FOR_EACH( mvd_client_t, client, &mvd->clients, entry ) { if( client->cl->state == cs_spawned ) { @@ -1572,7 +1550,7 @@ update: MVD_UpdateLayouts( &mvd_waitingRoom ); if( mvd_dirty ) { - MVD_InfoSet( "channels", va( "%d", List_Count( &mvd_active_list ) ) ); + MVD_InfoSet( "channels", va( "%d", List_Count( &mvd_channel_list ) ) ); mvd_dirty = qfalse; } } diff --git a/source/mvd_local.h b/source/mvd_local.h index c6821a8..3e30844 100644 --- a/source/mvd_local.h +++ b/source/mvd_local.h @@ -107,7 +107,6 @@ struct gtv_s; // need to eliminate those large static arrays below... typedef struct mvd_s { list_t entry; - list_t active; mvd_state_t state; int id; @@ -157,7 +156,6 @@ typedef struct mvd_s { // extern list_t mvd_channel_list; -extern list_t mvd_active_list; extern mvd_t mvd_waitingRoom; extern qboolean mvd_dirty; @@ -167,9 +165,6 @@ extern cvar_t *mvd_shownet; void MVD_Destroyf( mvd_t *mvd, const char *fmt, ... ) q_noreturn q_printf( 2, 3 ); -void MVD_Disconnect( mvd_t *mvd ); -void MVD_BeginWaiting( mvd_t *mvd ); -void MVD_Finish( mvd_t *mvd, const char *reason ) q_noreturn; void MVD_Free( mvd_t *mvd ); void MVD_Shutdown( void ); @@ -207,5 +202,4 @@ void MVD_BroadcastPrintf( mvd_t *mvd, int level, void MVD_PrepWorldFrame( void ); void MVD_GameClientNameChanged( edict_t *ent, const char *name ); void MVD_GameClientDrop( edict_t *ent, const char *reason ); -void MVD_CheckActive( mvd_t *mvd ); diff --git a/source/mvd_parse.c b/source/mvd_parse.c index 2f6dd83..d037b64 100644 --- a/source/mvd_parse.c +++ b/source/mvd_parse.c @@ -1112,7 +1112,7 @@ static void MVD_ParseServerData( mvd_t *mvd, int extrabits ) { if( !mvd->state ) { mvd_t *cur; - // sort this one into the list of ready channels + // sort this one into the list of active channels LIST_FOR_EACH( mvd_t, cur, &mvd_channel_list, entry ) { if( cur->id > mvd->id ) { break; @@ -1121,8 +1121,7 @@ static void MVD_ParseServerData( mvd_t *mvd, int extrabits ) { List_Append( &cur->entry, &mvd->entry ); mvd->state = MVD_WAITING; - // for local client - MVD_CheckActive( mvd ); + mvd_dirty = qtrue; } // case all UDP clients to reconnect diff --git a/source/net_common.c b/source/net_common.c index 249c02b..0266172 100644 --- a/source/net_common.c +++ b/source/net_common.c @@ -32,13 +32,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sys_public.h" #include "sv_public.h" -#if defined( _WIN32 ) +#if( defined _WIN32 ) #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #define socklen_t int +#ifdef _WIN32_WCE +#define NET_GET_ERROR() ( net_error = GetLastError() ) +#else #define NET_GET_ERROR() ( net_error = WSAGetLastError() ) -#elif defined( __unix__ ) +#endif +#elif( defined __unix__ ) #include <unistd.h> #include <sys/socket.h> #include <sys/time.h> @@ -523,8 +527,8 @@ neterr_t NET_GetPacket( netsrc_t sock ) { memset( &from, 0, sizeof( from ) ); fromlen = sizeof( from ); - ret = recvfrom( udp_sockets[sock], msg_read_buffer, MAX_PACKETLEN, 0, - ( struct sockaddr * )&from, &fromlen ); + ret = recvfrom( udp_sockets[sock], ( void * )msg_read_buffer, + MAX_PACKETLEN, 0, ( struct sockaddr * )&from, &fromlen ); if( !ret ) { return NET_AGAIN; @@ -1128,7 +1132,7 @@ neterr_t NET_RunStream( netstream_t *s ) { fd_set rfd, wfd; int ret; size_t len; - byte *data; + void *data; neterr_t result = NET_AGAIN; if( s->state != NS_CONNECTED ) { @@ -1371,7 +1375,9 @@ static void NET_Restart_f( void ) { NET_Listen( qtrue ); } +#if USE_SYSCON SV_SetConsoleTitle(); +#endif } /* diff --git a/source/q_shared.c b/source/q_shared.c index f32ad5c..b97e987 100644 --- a/source/q_shared.c +++ b/source/q_shared.c @@ -1507,6 +1507,7 @@ char *Q_strchrnul( const char *s, int c ) { void Q_setenv( const char *name, const char *value ) { #ifdef _WIN32 +#ifndef __COREDLL__ if( !value ) { value = ""; } @@ -1515,6 +1516,7 @@ void Q_setenv( const char *name, const char *value ) { #else _putenv( va( "%s=%s", name, value ) ); #endif +#endif #else // _WIN32 if( value ) { setenv( name, value, 1 ); diff --git a/source/q_shared.h b/source/q_shared.h index 22b3783..8448234 100644 --- a/source/q_shared.h +++ b/source/q_shared.h @@ -33,7 +33,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include <endian.h> #endif #ifdef _WIN32 +#if HAVE_DIRECT_H #include <direct.h> +#endif #else #include <sys/stat.h> #include <sys/types.h> diff --git a/source/r_images.c b/source/r_images.c index 3f5eb50..e082629 100644 --- a/source/r_images.c +++ b/source/r_images.c @@ -1685,7 +1685,7 @@ void IMG_FreeUnused( void ) { for( image = r_images; image < last; image++ ) { if( image->registration_sequence == registration_sequence ) { #if USE_REF == REF_SOFT - Com_PageInMemory( image->pixels[0], image->width * image->height * VID_BYTES ); + Com_PageInMemory( image->pixels[0], image->width * image->height ); #endif continue; // used this sequence } diff --git a/source/snd_wave.c b/source/snd_wave.c index f036b83..084807d 100644 --- a/source/snd_wave.c +++ b/source/snd_wave.c @@ -141,9 +141,9 @@ static sndinitstat_t WAVE_Init (void) { } if (MessageBox (NULL, - __TEXT("The sound hardware is in use by another app.\n\n") - __TEXT("Select Retry to try to start sound again or Cancel to run ") __TEXT("q2pro") __TEXT(" with no sound."), - __TEXT("Sound not available"), + _T("The sound hardware is in use by another app.\n\n") + _T("Select Retry to try to start sound again or Cancel to run ") _T("q2pro") _T(" with no sound."), + _T("Sound not available"), MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY) { Com_DPrintf ("hw in use\n" ); @@ -160,10 +160,10 @@ static sndinitstat_t WAVE_Init (void) { */ Com_DPrintf ("...allocating waveform buffer: "); gSndBufSize = WAV_BUFFERS*WAV_BUFFER_SIZE; - hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, gSndBufSize); + hData = GlobalAlloc(GMEM_MOVEABLE /*| GMEM_SHARE*/, gSndBufSize); if (!hData) { - Com_DPrintf( " failed\n" ); + Com_DPrintf( " failed with error %#lx\n", GetLastError() ); WAVE_Shutdown(); return SIS_FAILURE; } @@ -173,7 +173,7 @@ static sndinitstat_t WAVE_Init (void) { lpData = GlobalLock(hData); if (!lpData) { - Com_DPrintf( " failed\n" ); + Com_DPrintf( " failed with error %#lx\n", GetLastError() ); WAVE_Shutdown(); return SIS_FAILURE; } @@ -186,12 +186,11 @@ static sndinitstat_t WAVE_Init (void) { * GMEM_SHARE flags. */ Com_DPrintf ("...allocating waveform header: "); - hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, + hWaveHdr = GlobalAlloc(GMEM_MOVEABLE /*| GMEM_SHARE*/, (DWORD) sizeof(WAVEHDR) * WAV_BUFFERS); - if (hWaveHdr == NULL) { - Com_DPrintf( "failed\n" ); + Com_DPrintf( "failed with error %#lx\n", GetLastError() ); WAVE_Shutdown(); return SIS_FAILURE; } @@ -199,10 +198,9 @@ static sndinitstat_t WAVE_Init (void) { Com_DPrintf ("...locking waveform header: "); lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr); - if (lpWaveHdr == NULL) { - Com_DPrintf( "failed\n" ); + Com_DPrintf( "failed with error %#lx\n", GetLastError() ); WAVE_Shutdown(); return SIS_FAILURE; } diff --git a/source/sv_ac.c b/source/sv_ac.c index beec6a2..01c1f8f 100644 --- a/source/sv_ac.c +++ b/source/sv_ac.c @@ -1140,7 +1140,9 @@ static qboolean AC_Flush( void ) { Com_WPrintf( "ANTICHEAT: Send buffer length exceeded, " "server may be frozen for a short while!\n" ); do { +#if USE_SYSCON Sys_RunConsole(); +#endif Sys_Sleep( 1 ); AC_Run(); if( !ac.connected ) { @@ -1375,7 +1377,9 @@ void AC_Connect( qboolean ismvd ) { AC_LoadChecks(); Com_Printf( "ANTICHEAT: Attempting to connect to %s...\n", ac_server_address->string ); +#if USE_SYSCON Sys_RunConsole(); +#endif acs.retry_backoff = AC_DEFAULT_BACKOFF; if( !AC_Reconnect() ) { @@ -1384,7 +1388,9 @@ void AC_Connect( qboolean ismvd ) { // synchronize startup for( attempts = 0; attempts < 5000; attempts++ ) { +#if USE_SYSCON Sys_RunConsole(); +#endif Sys_Sleep( 1 ); AC_Run(); if( ac.ready || !ac.stream.state ) { diff --git a/source/sv_init.c b/source/sv_init.c index 5df771f..e95210c 100644 --- a/source/sv_init.c +++ b/source/sv_init.c @@ -130,7 +130,9 @@ static void SV_SpawnServer( cm_t *cm, const char *server, const char *spawnpoint EXEC_TRIGGER( sv_changemapcmd ); +#if USE_SYSCON SV_SetConsoleTitle(); +#endif Com_Printf ("-------------------------------------\n"); } diff --git a/source/sv_main.c b/source/sv_main.c index 97dc122..9b674f1 100644 --- a/source/sv_main.c +++ b/source/sv_main.c @@ -1767,6 +1767,7 @@ void SV_UserinfoChanged( client_t *cl ) { //============================================================================ +#if USE_SYSCON void SV_SetConsoleTitle( void ) { char buffer[MAX_STRING_CHARS]; @@ -1776,6 +1777,7 @@ void SV_SetConsoleTitle( void ) { Sys_SetConsoleTitle( buffer ); } +#endif static void sv_status_limit_changed( cvar_t *self ) { SV_RateInit( &svs.ratelimit_status, self->integer, 1000 ); @@ -1786,9 +1788,11 @@ static void sv_badauth_time_changed( cvar_t *self ) { SV_RateInit( &svs.ratelimit_badrcon, 1, self->value * 1000 ); } +#if USE_SYSCON static void sv_hostname_changed( cvar_t *self ) { SV_SetConsoleTitle(); } +#endif #if USE_ZLIB voidpf SV_Zalloc OF(( voidpf opaque, uInt items, uInt size )) { @@ -1835,7 +1839,9 @@ void SV_Init( void ) { sv_maxclients = Cvar_Get( "maxclients", "8", CVAR_SERVERINFO|CVAR_LATCH ); sv_reserved_slots = Cvar_Get( "sv_reserved_slots", "0", CVAR_LATCH ); sv_hostname = Cvar_Get( "hostname", "noname", CVAR_SERVERINFO|CVAR_ARCHIVE ); +#if USE_SYSCON sv_hostname->changed = sv_hostname_changed; +#endif sv_timeout = Cvar_Get( "timeout", "90", 0 ); sv_zombietime = Cvar_Get( "zombietime", "2", 0 ); sv_ghostime = Cvar_Get( "sv_ghostime", "6", 0 ); @@ -1903,7 +1909,9 @@ void SV_Init( void ) { sv_pmp.waterfriction = 1; sv_pmp.speedMultiplier = 1; +#if USE_SYSCON SV_SetConsoleTitle(); +#endif } /* @@ -2005,7 +2013,9 @@ void SV_Shutdown( const char *finalmsg, killtype_t type ) { sv_client = NULL; sv_player = NULL; +#if USE_SYSCON SV_SetConsoleTitle(); +#endif Z_LeakTest( TAG_SERVER ); } diff --git a/source/sv_mvd.c b/source/sv_mvd.c index 93b9159..c63af6f 100644 --- a/source/sv_mvd.c +++ b/source/sv_mvd.c @@ -628,13 +628,14 @@ static void emit_gamestate( void ) { // send entity states for( i = 1, es = mvd.entities + 1; i < ge->num_edicts; i++, es++ ) { flags = 0; - if( i <= sv_maxclients->integer ) { - ps = &mvd.players[ i - 1 ]; - if( PPS_INUSE( ps ) && ps->pmove.pm_type == PM_NORMAL ) { - flags |= MSG_ES_FIRSTPERSON; + if( ( j = es->number ) != 0 ) { + if( i <= sv_maxclients->integer ) { + ps = &mvd.players[ i - 1 ]; + if( PPS_INUSE( ps ) && ps->pmove.pm_type == PM_NORMAL ) { + flags |= MSG_ES_FIRSTPERSON; + } } - } - if( ( j = es->number ) == 0 ) { + } else { flags |= MSG_ES_REMOVE; } es->number = i; @@ -2028,12 +2029,6 @@ static void rec_start( fileHandle_t demofile ) { } -const cmd_option_t o_mvdrecord[] = { - { "h", "help", "display this message" }, - { "z", "gzip", "compress file with gzip" }, - { NULL } -}; - static void SV_MvdRecord_c( genctx_t *ctx, int argnum ) { #if USE_MVD_CLIENT // TODO @@ -2070,12 +2065,12 @@ static void SV_MvdRecord_f( void ) { return; } - while( ( c = Cmd_ParseOptions( o_mvdrecord ) ) != -1 ) { + while( ( c = Cmd_ParseOptions( o_record ) ) != -1 ) { switch( c ) { case 'h': - Cmd_PrintUsage( o_mvdrecord, "[/]<filename>" ); + Cmd_PrintUsage( o_record, "[/]<filename>" ); Com_Printf( "Begin local MVD recording.\n" ); - Cmd_PrintHelp( o_mvdrecord ); + Cmd_PrintHelp( o_record ); return; case 'z': gzip = qtrue; diff --git a/source/sv_public.h b/source/sv_public.h index 48f577b..7ebdf61 100644 --- a/source/sv_public.h +++ b/source/sv_public.h @@ -37,8 +37,10 @@ void SV_ProcessEvents( void ); void SV_Init (void); void SV_Shutdown( const char *finalmsg, killtype_t type ); void SV_Frame (unsigned msec); +#if USE_SYSCON void SV_SetConsoleTitle( void ); -void SV_ConsoleOutput( const char *msg ); +#endif +//void SV_ConsoleOutput( const char *msg ); #if USE_MVD_CLIENT && USE_CLIENT int MVD_GetDemoPercent( void ); diff --git a/source/sys_public.h b/source/sys_public.h index 8dbb129..9bc02cb 100644 --- a/source/sys_public.h +++ b/source/sys_public.h @@ -44,10 +44,13 @@ void Hunk_Free( mempool_t *pool ); void Sys_Init( void ); void Sys_AddDefaultConfig( void ); +#if USE_SYSCON void Sys_RunConsole( void ); void Sys_ConsoleOutput( const char *string ); void Sys_SetConsoleTitle( const char *title ); void Sys_Printf( const char *fmt, ... ) q_printf( 1, 2 ); +#endif + void Sys_Error( const char *error, ... ) q_noreturn q_printf( 1, 2 ); void Sys_Quit( void ); diff --git a/source/sys_win.c b/source/sys_win.c index 319055d..dbbe501 100644 --- a/source/sys_win.c +++ b/source/sys_win.c @@ -23,28 +23,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "q_list.h" #include "prompt.h" #include <mmsystem.h> -#if !USE_CLIENT +#if USE_WINSVC #include <winsvc.h> #endif #include <float.h> -#define MAX_CONSOLE_INPUT_EVENTS 16 - -static HANDLE hinput = INVALID_HANDLE_VALUE; -static HANDLE houtput = INVALID_HANDLE_VALUE; - -static cvar_t *sys_viewlog; -static commandPrompt_t sys_con; -static int sys_hidden; -static CONSOLE_SCREEN_BUFFER_INFO sbinfo; -static qboolean gotConsole; -static volatile qboolean errorEntered; -static volatile qboolean shouldExit; - -#if !USE_CLIENT -static SERVICE_STATUS_HANDLE statusHandle; -#endif - HINSTANCE hGlobalInstance; qboolean iswinnt; @@ -55,6 +38,13 @@ cvar_t *sys_homedir; static char currentDirectory[MAX_OSPATH]; +#if USE_WINSVC +static SERVICE_STATUS_HANDLE statusHandle; +#endif + +static volatile qboolean errorEntered; +static volatile qboolean shouldExit; + /* =============================================================================== @@ -63,6 +53,22 @@ CONSOLE I/O =============================================================================== */ +#if USE_SYSCON + +#define MAX_CONSOLE_INPUT_EVENTS 16 + +static HANDLE hinput = INVALID_HANDLE_VALUE; +static HANDLE houtput = INVALID_HANDLE_VALUE; + +#if USE_CLIENT +static cvar_t *sys_viewlog; +#endif + +static commandPrompt_t sys_con; +static int sys_hidden; +static CONSOLE_SCREEN_BUFFER_INFO sbinfo; +static qboolean gotConsole; + static void Sys_HideInput( void ) { DWORD dummy; int i; @@ -391,6 +397,8 @@ static void Sys_ConsoleInit( void ) { sbinfo.dwSize.X, sbinfo.dwSize.Y ); } +#endif // USE_SYSCON + /* =============================================================================== @@ -399,7 +407,7 @@ SERVICE CONTROL =============================================================================== */ -#if !USE_CLIENT +#if USE_WINSVC static void Sys_InstallService_f( void ) { char servicePath[256]; @@ -530,7 +538,7 @@ fail: CloseServiceHandle( scm ); } -#endif +#endif // USE_WINSVC /* =============================================================================== @@ -597,6 +605,7 @@ MISC =============================================================================== */ +#if USE_SYSCON /* ================ Sys_Printf @@ -612,6 +621,7 @@ void Sys_Printf( const char *fmt, ... ) { Sys_ConsoleOutput( msg ); } +#endif /* ================ @@ -628,16 +638,21 @@ void Sys_Error( const char *error, ... ) { errorEntered = qtrue; +#if USE_SYSCON Sys_Printf( S_COLOR_RED "********************\n" "FATAL: %s\n" "********************\n", text ); -#if !USE_CLIENT +#endif + +#if USE_WINSVC if( !statusHandle ) #endif { +#if USE_SYSCON if( gotConsole ) { Sleep( INFINITE ); } +#endif MessageBoxA( NULL, text, APPLICATION " Fatal Error", MB_ICONERROR | MB_OK ); } @@ -653,10 +668,12 @@ void Sys_Quit( void ) { timeEndPeriod( 1 ); #if USE_CLIENT +#if USE_SYSCON if( dedicated && dedicated->integer ) { FreeConsole(); } -#else +#endif +#elif USE_WINSVC if( !statusHandle ) #endif exit( 0 ); @@ -674,7 +691,9 @@ void Sys_AddDefaultConfig( void ) { } void Sys_FixFPCW( void ) { +#ifdef __i386__ // FIXME: MSVC? _controlfp( _PC_24|_RC_NEAR, _MCW_PC|_MCW_RC ); +#endif } void Sys_Sleep( int msec ) { @@ -719,17 +738,20 @@ void Sys_Init( void ) { // specifies per-user writable directory for demos, screenshots, etc sys_homedir = Cvar_Get( "homedir", "", CVAR_NOSET ); - sys_viewlog = Cvar_Get( "sys_viewlog", "0", CVAR_NOSET ); - -#if !USE_CLIENT +#if USE_WINSVC Cmd_AddCommand( "installservice", Sys_InstallService_f ); Cmd_AddCommand( "deleteservice", Sys_DeleteService_f ); #endif +#if USE_SYSCON houtput = GetStdHandle( STD_OUTPUT_HANDLE ); - if( dedicated->integer || sys_viewlog->integer ) { +#if USE_CLIENT + sys_viewlog = Cvar_Get( "sys_viewlog", "0", CVAR_NOSET ); + + if( dedicated->integer || sys_viewlog->integer ) +#endif Sys_ConsoleInit(); - } +#endif } /* @@ -762,7 +784,7 @@ void *Sys_LoadLibrary( const char *path, const char *sym, void **handle ) { return NULL; } - entry = GetProcAddress( module, sym ); + entry = GetProcAddressA( module, sym ); if( !entry ) { Com_DPrintf( "%s failed: GetProcAddress returned %lu on %s\n", __func__, GetLastError(), path ); @@ -778,7 +800,7 @@ void *Sys_LoadLibrary( const char *path, const char *sym, void **handle ) { } void *Sys_GetProcAddress( void *handle, const char *sym ) { - return GetProcAddress( handle, sym ); + return GetProcAddressA( handle, sym ); } /* @@ -1022,15 +1044,17 @@ static int Sys_Main( int argc, char **argv ) { char *p; // fix current directory to point to the basedir - if( !GetModuleFileName( NULL, currentDirectory, sizeof( currentDirectory ) - 1 ) ) { + if( !GetModuleFileNameA( NULL, currentDirectory, sizeof( currentDirectory ) - 1 ) ) { return 1; } if( ( p = strrchr( currentDirectory, '\\' ) ) != NULL ) { *p = 0; } - if( !SetCurrentDirectory( currentDirectory ) ) { +#ifndef UNDER_CE + if( !SetCurrentDirectoryA( currentDirectory ) ) { return 1; } +#endif #if USE_DBGHELP // install our exception handler @@ -1106,19 +1130,24 @@ WinMain ================== */ -int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { +int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) { // previous instances do not exist in Win32 if( hPrevInstance ) { return 1; } hGlobalInstance = hInstance; +#ifndef UNICODE + // TODO: wince support Sys_ParseCommandLine( lpCmdLine ); +#endif return Sys_Main( sys_argc, sys_argv ); } #else // USE_CLIENT +#if USE_WINSVC + static char **sys_argv; static int sys_argc; @@ -1154,6 +1183,8 @@ static SERVICE_TABLE_ENTRY serviceTable[] = { { NULL, NULL } }; +#endif // USE_WINSVC + /* ================== main @@ -1161,10 +1192,13 @@ main ================== */ int QDECL main( int argc, char **argv ) { +#if USE_WINSVC int i; +#endif hGlobalInstance = GetModuleHandle( NULL ); +#if USE_WINSVC for( i = 1; i < argc; i++ ) { if( !strcmp( argv[i], "-service" ) ) { argv[i] = NULL; @@ -1179,6 +1213,7 @@ int QDECL main( int argc, char **argv ) { return 1; } } +#endif return Sys_Main( argc, argv ); } diff --git a/source/ui_script.c b/source/ui_script.c index 2cd4fb2..a51fbde 100644 --- a/source/ui_script.c +++ b/source/ui_script.c @@ -294,16 +294,17 @@ static void Parse_Color( void ) { } static qboolean Parse_File( const char *path, int depth ) { - char *data, *p, *cmd; + char *raw, *data, *p, *cmd; int argc; menuFrameWork_t *menu = NULL; - FS_LoadFile( path, ( void ** )&data ); - if( !data ) { + FS_LoadFile( path, ( void ** )&raw ); + if( !raw ) { Com_Printf( "Couldn't load %s\n", path ); return qfalse; } + data = raw; COM_Compress( data ); while( *data ) { @@ -415,7 +416,7 @@ static qboolean Parse_File( const char *path, int depth ) { data = p + 1; } - FS_FreeFile( data ); + FS_FreeFile( raw ); return qtrue; } diff --git a/source/vid_win.c b/source/vid_win.c index 4e0cd1a..d13492e 100644 --- a/source/vid_win.c +++ b/source/vid_win.c @@ -198,6 +198,7 @@ void Win_SetMode( void ) { } void VID_UpdateGamma( const byte *table ) { +#ifndef __COREDLL__ WORD v; int i; @@ -211,6 +212,7 @@ void VID_UpdateGamma( const byte *table ) { SetDeviceGammaRamp( win.dc, win.gamma_cust ); } +#endif } /* @@ -288,6 +290,7 @@ static void Win_Activate( WPARAM wParam ) { } } +#ifndef __COREDLL__ if( win.flags & QVF_GAMMARAMP ) { if( active == ACT_ACTIVATED ) { SetDeviceGammaRamp( win.dc, win.gamma_cust ); @@ -295,6 +298,7 @@ static void Win_Activate( WPARAM wParam ) { SetDeviceGammaRamp( win.dc, win.gamma_orig ); } } +#endif if( win.flags & QVF_FULLSCREEN ) { if( active == ACT_ACTIVATED ) { @@ -738,13 +742,21 @@ void VID_PumpEvents( void ) { } } +#ifdef __COREDLL__ +#define _WNDCLASSEX WNDCLASS +#define _RegisterClassEx RegisterClass +#else +#define _WNDCLASSEX WNDCLASSEX +#define _RegisterClassEx RegisterClassEx +#endif + /* ============ Win_Init ============ */ void Win_Init( void ) { - WNDCLASSEX wc; + _WNDCLASSEX wc; // register variables vid_flip_on_switch = Cvar_Get( "vid_flip_on_switch", "0", 0 ); @@ -758,25 +770,29 @@ void Win_Init( void ) { // register the frame class memset( &wc, 0, sizeof( wc ) ); +#ifndef __COREDLL__ wc.cbSize = sizeof( wc ); +#endif wc.lpfnWndProc = ( WNDPROC )Win_MainWndProc; wc.hInstance = hGlobalInstance; wc.hIcon = LoadImage( hGlobalInstance, MAKEINTRESOURCE( IDI_APP ), IMAGE_ICON, 32, 32, LR_CREATEDIBSECTION ); +#ifndef __COREDLL__ wc.hIconSm = LoadImage( hGlobalInstance, MAKEINTRESOURCE( IDI_APP ), IMAGE_ICON, 16, 16, LR_CREATEDIBSECTION ); +#endif wc.hCursor = LoadCursor ( NULL, IDC_ARROW ); wc.hbrBackground = GetStockObject( BLACK_BRUSH ); - wc.lpszClassName = WINDOW_CLASS_NAME; + wc.lpszClassName = _T( WINDOW_CLASS_NAME ); - if( !RegisterClassEx( &wc ) ) { + if( !_RegisterClassEx( &wc ) ) { Com_Error( ERR_FATAL, "Couldn't register main window class" ); } // create the window win.wnd = CreateWindow( - WINDOW_CLASS_NAME, - APPLICATION, + _T( WINDOW_CLASS_NAME ), + _T( APPLICATION ), 0, //style 0, 0, 0, 0, NULL, @@ -793,6 +809,7 @@ void Win_Init( void ) { Com_Error( ERR_FATAL, "Couldn't get DC of the main window" ); } +#ifndef __COREDLL__ // init gamma ramp if( vid_hwgamma->integer ) { if( GetDeviceGammaRamp( win.dc, win.gamma_orig ) ) { @@ -804,6 +821,7 @@ void Win_Init( void ) { Cvar_Set( "vid_hwgamma", "0" ); } } +#endif } /* @@ -812,15 +830,17 @@ Win_Shutdown ============ */ void Win_Shutdown( void ) { +#ifndef __COREDLL__ if( win.flags & QVF_GAMMARAMP ) { SetDeviceGammaRamp( win.dc, win.gamma_orig ); } +#endif // prevents leaving empty slots in the taskbar ShowWindow( win.wnd, SW_SHOWNORMAL ); ReleaseDC( win.wnd, win.dc ); DestroyWindow( win.wnd ); - UnregisterClass( WINDOW_CLASS_NAME, hGlobalInstance ); + UnregisterClass( _T( WINDOW_CLASS_NAME ), hGlobalInstance ); if( win.kbdHook ) { UnhookWindowsHookEx( win.kbdHook ); @@ -886,7 +906,9 @@ static void Win_AcquireMouse( void ) { SetCapture( win.wnd ); ClipCursor( &rc ); +#ifndef __COREDLL__ SetWindowText( win.wnd, "[" APPLICATION "]" ); +#endif } @@ -904,7 +926,9 @@ static void Win_DeAcquireMouse( void ) { ClipCursor( NULL ); ReleaseCapture(); +#ifndef __COREDLL__ SetWindowText( win.wnd, APPLICATION ); +#endif } static void win_xpfix_changed( cvar_t *self ) { diff --git a/source/win_ascii.c b/source/win_ascii.c new file mode 100644 index 0000000..d23dcd4 --- /dev/null +++ b/source/win_ascii.c @@ -0,0 +1,95 @@ +#include <windows.h> + +HANDLE WINAPI FindFirstFileA( LPCSTR path, LPWIN32_FIND_DATAA data ) { + WCHAR wbuffer[MAX_PATH]; + HANDLE ret; + WIN32_FIND_DATAW wdata; + + if( !MultiByteToWideChar( CP_ACP, 0, path, -1, wbuffer, MAX_PATH ) ) { + return INVALID_HANDLE_VALUE; + } + + ret = FindFirstFileW( wbuffer, &wdata ); + if( ret != INVALID_HANDLE_VALUE ) { + memcpy( data, &wdata, FIELD_OFFSET( WIN32_FIND_DATAA, cFileName ) ); + WideCharToMultiByte( CP_ACP, 0, wdata.cFileName, -1, data->cFileName, MAX_PATH, NULL, NULL ); + } + + return ret; +} + +BOOL WINAPI FindNextFileA( HANDLE handle, LPWIN32_FIND_DATAA data ) { + BOOL ret; + WIN32_FIND_DATAW wdata; + + ret = FindNextFileW( handle, &wdata ); + if( ret != FALSE ) { + memcpy( data, &wdata, FIELD_OFFSET( WIN32_FIND_DATAA, cFileName ) ); + WideCharToMultiByte( CP_ACP, 0, wdata.cFileName, -1, data->cFileName, MAX_PATH, NULL, NULL ); + } + + return ret; +} + +HINSTANCE WINAPI LoadLibraryA( LPCSTR path ) { + WCHAR wbuffer[MAX_PATH]; + + if( !MultiByteToWideChar( CP_ACP, 0, path, -1, wbuffer, MAX_PATH ) ) { + return NULL; + } + + return LoadLibraryW( wbuffer ); +} + +int WINAPI MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ) { + WCHAR wText[4096]; + WCHAR wCaption[256]; + + if( !MultiByteToWideChar( CP_ACP, 0, lpText, -1, wText, 4096 ) ) { + return 0; + } + if( !MultiByteToWideChar( CP_ACP, 0, lpCaption, -1, wCaption, 256 ) ) { + return 0; + } + + return MessageBoxW( hWnd, wText, wCaption, uType ); +} + +BOOL WINAPI CreateDirectoryA( LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes ) { + WCHAR wbuffer[MAX_PATH]; + + if( !MultiByteToWideChar( CP_ACP, 0, lpPathName, -1, wbuffer, MAX_PATH ) ) { + return FALSE; + } + + return CreateDirectoryW( wbuffer, lpSecurityAttributes ); +} + +BOOL WINAPI GetFileAttributesExA( LPCSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation ) { + WCHAR wbuffer[MAX_PATH]; + + if( !MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, wbuffer, MAX_PATH ) ) { + return FALSE; + } + + return GetFileAttributesExW( wbuffer, fInfoLevelId, lpFileInformation ); +} + +DWORD WINAPI GetModuleFileNameA( HMODULE hModule, LPSTR lpFileName, DWORD nSize ) { + WCHAR wbuffer[MAX_PATH]; + DWORD ret; + + if( nSize > MAX_PATH ) { + nSize = MAX_PATH; + } + + ret = GetModuleFileNameW( hModule, wbuffer, nSize ); + if( ret ) { + if( !WideCharToMultiByte( CP_ACP, 0, wbuffer, ret, lpFileName, ret, NULL, NULL ) ) { + return 0; + } + } + + return ret; +} + diff --git a/source/win_local.h b/source/win_local.h index 6f2e163..82aa927 100644 --- a/source/win_local.h +++ b/source/win_local.h @@ -40,6 +40,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #if USE_CLIENT +#include <tchar.h> + #define IDI_APP 100 #ifndef WM_MOUSEWHEEL @@ -67,6 +69,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. typedef const GUID *LPCGUID; #endif +#ifdef __COREDLL__ +#define ChangeDisplaySettings( mode, flags ) \ + ChangeDisplaySettingsEx( NULL, mode, NULL, flags, NULL ) +#define AdjustWindowRect( rect, style, menu ) \ + AdjustWindowRectEx( rect, style, menu, 0 ) +#endif + #define MAX_VIDEO_MODES 128 typedef struct { @@ -79,8 +88,10 @@ typedef struct { HHOOK kbdHook; vidFlags_t flags; +#ifndef __COREDLL__ SHORT gamma_cust[3][256]; SHORT gamma_orig[3][256]; +#endif vrect_t rc; byte *buffer; int pitch; diff --git a/source/win_swimp.c b/source/win_swimp.c index 0aaf245..be4edfa 100644 --- a/source/win_swimp.c +++ b/source/win_swimp.c @@ -94,9 +94,11 @@ SWimp_Shutdown System specific graphics subsystem shutdown routine. Destroys DIB surfaces as appropriate. */ -static void SWimp_Shutdown( void ) { +void VID_Shutdown( void ) { if ( sww.palettized ) { +#ifndef __COREDLL__ SetSystemPaletteUse( win.dc, SYSPAL_STATIC ); +#endif SetSysColors( NUM_SYS_COLORS, s_syspalindices, sww.oldsyscolors ); } @@ -187,7 +189,7 @@ SWimp_Init This routine is responsible for initializing the implementation specific stuff in a software rendering subsystem. */ -static qboolean SWimp_Init( void ) { +qboolean VID_Init( void ) { int i; // create the window @@ -219,11 +221,11 @@ static qboolean SWimp_Init( void ) { fail: Com_Printf( "GetLastError() = %#lx", GetLastError() ); - SWimp_Shutdown(); + VID_Shutdown(); return qfalse; } -static void SWimp_BeginFrame( void ) { +void VID_BeginFrame( void ) { } /* @@ -232,7 +234,7 @@ SWimp_EndFrame This does an implementation specific copy from the backbuffer to the front buffer. In the Win32 case it uses BitBlt if we're using DIB sections/GDI. */ -static void SWimp_EndFrame( void ) { +void VID_EndFrame( void ) { BitBlt( win.dc, 0, 0, win.rc.width, win.rc.height, sww.dibdc, 0, 0, SRCCOPY ); } @@ -249,7 +251,7 @@ G = offset 1 B = offset 2 A = offset 3 */ -static void SWimp_UpdatePalette( const byte *_pal ) { +void VID_UpdatePalette( const byte *_pal ) { const byte *pal = _pal; RGBQUAD colors[256]; int i; @@ -284,9 +286,11 @@ static void SWimp_UpdatePalette( const byte *_pal ) { identitypalette_t ipal; LOGPALETTE *pLogPal = ( LOGPALETTE * )&ipal; +#ifndef __COREDLL__ if ( SetSystemPaletteUse( win.dc, SYSPAL_NOSTATIC ) == SYSPAL_ERROR ) { Com_Error( ERR_FATAL, "DIB_SetPalette: SetSystemPaletteUse() failed\n" ); } +#endif // destroy our old palette if ( sww.pal ) { @@ -331,18 +335,4 @@ static void SWimp_UpdatePalette( const byte *_pal ) { } } -/* -@@@@@@@@@@@@ -VID_FillSWAPI -@@@@@@@@@@@@ -*/ -void VID_FillSWAPI( videoAPI_t *api ) { - api->Init = SWimp_Init; - api->Shutdown = SWimp_Shutdown; - api->UpdateGamma = Win_UpdateGamma; - api->UpdatePalette = SWimp_UpdatePalette; - api->GetProcAddr = NULL; - api->BeginFrame = SWimp_BeginFrame; - api->EndFrame = SWimp_EndFrame; -} diff --git a/wiki/contact.mdwn b/wiki/contact.mdwn index 3bb8916..9c37be6 100644 --- a/wiki/contact.mdwn +++ b/wiki/contact.mdwn @@ -8,14 +8,7 @@ There are mailing lists set up: There is also Q2PRO [forum](http://forum.quake2.com.ru/viewforum.php?f=6) available (in Russian), hosted by the [Russian Quake2 Portal](http://quake2.com.ru/). -IRC channel for Q2PRO is #q2pro at quakenet.org. +IRC channel for Q2PRO is #q2pro at irc.quakenet.org. -Q2PRO author (SkulleR) can be contacted directly in the following ways: - -* email: skuller-vidnoe at yandex.ru -* jabber/email: skuller32 at gmail.com -* IRC: skuller at quakenet.org - -Author's GPG key: - - 1024D/928FA4A2: CC6D FA00 C355 6707 6314 FE0B 9F2E C0DD 928F A4A2 +See [this](http://skuller.ath.cx/) page if you wish to contact +Q2PRO author directly. diff --git a/wiki/doc/mingw.mdwn b/wiki/doc/mingw.mdwn index 00a7266..94d762d 100644 --- a/wiki/doc/mingw.mdwn +++ b/wiki/doc/mingw.mdwn @@ -1,16 +1,16 @@ -First, download [MinGW/MSYS][mingw] packages. -Required packages are: `mingw-runtime`, `w32api`, -`binutils`, `gcc` and MSYS graphical installer. -Alternatively, [Cygwin][] packages may be used, -although the process is not described here. +As a first step, download [MinGW/MSYS][mingw] packages. Required packages are: +`mingw-runtime`, `w32api`, `binutils`, `gcc` and MSYS graphical installer. +Alternatively, [Cygwin][] installation can be used, although the process +is not described here. It is recommended to install MSYS using graphical installer first, -then uncompress each MinGW package into the `mingw/` -subdirectory of your MSYS main directory. +then uncompress each MinGW package into the `mingw/` subdirectory +of your MSYS main directory. You also need to build [zlib][] and install appropriate headers and libraries into your MinGW tree. By adding `--disable-zlib` option to -configure script you may disable linking with zlib, but this is not recommended. +configure script you can disable linking with zlib, but this is not +a good idea as this will likely break network compatibility. If you wish to include support for DirectSound and DirectInput drivers into the client executable, you also need to get `dsound.h` and `dinput.h` files @@ -18,38 +18,29 @@ from MS DirectX SDK and place them into your include path. No extra libraries are required. Then add the following options to configure script: `--enable-dsound --enable-dinput`. -If you wish to include support for 32bit textures into OpenGL refresh library, -you need to build [jpeglib][] and [pnglib][] and install appropriate headers -and libraries into your MinGW tree. Then add the following options to -configure script: `--enable-jpeg --enable-png`. +If you wish to include support for 32 bit textures, you need to build +[libjpeg][] and [libpng][] and install appropriate headers and libraries +into your MinGW tree. Then add the following options to configure script: +`--enable-jpeg --enable-png`. [mingw]: http://mingw.org/download.shtml [cygwin]: http://www.cygwin.com/ [zlib]: http://www.zlib.net/ -[jpeglib]: http://www.ijg.org/ -[pnglib]: http://www.libpng.org/pub/png/ +[libjpeg]: http://www.ijg.org/ +[libpng]: http://www.libpng.org/pub/png/ Enter the following commands at MSYS prompt: - cd q2pro + cd /path/to/q2pro/source/tree ./configure [options] make -This should build the following files in the root direcory: +This should build the following files in the current direcory: -* q2pro.exe - client executable +* q2pro.exe - graphical client (with built-in OpenGL renderer) * q2proded.exe - dedicated server -* ref_gl.dll - OpenGL refresh library -* ref_soft.dll - software refresh library -Do not run `make install` as it will not do what you want. -On Windows, Q2PRO is not designed to run shared between users and you have to -install it manually into your Quake2 directory. - -Install Q2PRO as follows, assuming `c:\quake2` is your Quake2 directory: - - c:\quake2\q2pro.exe - c:\quake2\q2proded.exe - c:\quake2\baseq2pro\ref_gl.dll - c:\quake2\baseq2pro\ref_soft.dll +On Windows, `install` target is not supported as Q2PRO is not designed to +run shared between users there. You need to manually move executables into +your Quake 2 directory. diff --git a/wiki/download.mdwn b/wiki/download.mdwn index 96f855a..01fbd63 100644 --- a/wiki/download.mdwn +++ b/wiki/download.mdwn @@ -1,14 +1,31 @@ -Stable releases +Windows ---------------- OpenGL-only client for Win32: [q2pro-r179ac-win32.zip](http://skuller.ath.cx/q2pro/releases/q2pro-r179ac-win32.zip). This binary is supported by r1ch.net [anticheat](http://antiche.at/) module. +_Keep in mind this version is quite outdated and is known to contain bugs. +If something does not work as expected, please try a nightly build below._ + +Debian GNU/Linux +---------------- +Those running stable Debian destribution (currently Etch) on i386 +architecture can conveniently install pre-built Q2PRO packages from +skuller.ath.cx Debian [repository](http://skuller.ath.cx/debian/). +Just add the following line(s) into your `/etc/apt/sources.list` +and run `aptitude update`: + + deb http://skuller.ath.cx/debian/ etch q2pro + deb-src http://skuller.ath.cx/debian/ etch q2pro + +Users of Secure APT may need to import the repository signing key first: + + wget -O - http://skuller.ath.cx/debian/archive.key | apt-key add - Nightly builds ---------------- Binary builds and source snapshots from SVN trunk are [available](http://skuller.ath.cx/q2pro/nightly/). They are regenerated -automatically on nightly basis. You may also find SVN +automatically on nightly basis. You can also find SVN [changelog](http://q2pro.svn.sourceforge.net/viewvc/q2pro?view=log) useful. Source code @@ -20,7 +37,7 @@ the `q2pro` directory: svn co https://q2pro.svn.sourceforge.net/svnroot/q2pro/trunk q2pro If you are looking for the source code snapshot corresponding to -a particular binary release, try the following command, replacing XXX +a stable binary release, try the following command, replacing XXX with release number: svn co https://q2pro.svn.sourceforge.net/svnroot/q2pro/tags/rXXX q2pro-rXXX diff --git a/wiki/index.mdwn b/wiki/index.mdwn index 0c83955..af497d4 100644 --- a/wiki/index.mdwn +++ b/wiki/index.mdwn @@ -2,9 +2,19 @@ Introduction ----------------- Q2PRO is a [Quake 2][q2] engine modification, based on source code released -under the GPL by id Software. This is not a standalone game as it does not -provide own media content, but rather an enhancement over original Quake 2 -release designed for multiplayer use. +under the terms of GPL by id Software. This is not a standalone game as it +does not provide any media content, but rather a backwards compatible +enhancement over original Quake 2 release designed for multiplayer use. + + +Important news +----------------- +* __2008-Oct-30:__ Q2PRO server versions from [r307 and up][dl] now implement + improved MVD/GTV protocol capable of automatic connection recovery and + feature special "suspension mode" for additional bandwidth savings in + case there are no players/spectators on a channel. + +[dl]: http://skuller.ath.cx/q2pro/nightly/ Feature highlights diff --git a/wiki/shots.mdwn b/wiki/shots.mdwn deleted file mode 100644 index 52bb5d5..0000000 --- a/wiki/shots.mdwn +++ /dev/null @@ -1,11 +0,0 @@ -Site dedicated to game engine missing a screenshots page? -It is impossible :) - -* Transparent console with digital clock and custom rail trail - in background. [JPG](shot00.jpg) -* Server browser in action. [PNG](shot01.png) -* Q2PRO running in one of the tiled frames under control of the [Ion3][] - window manager, and an open manpage. [PNG](shot02.png) - -[ion3]: http://modeemi.fi/~tuomov/ion/ - |