summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2008-11-13 18:58:41 +0000
committerAndrey Nazarov <skuller@skuller.net>2008-11-13 18:58:41 +0000
commitbbefa87db18f5b76dc67efa00b7cc798361480f3 (patch)
treeefc130fe3b4fe22f111154a8720491b756daa7bd
parentd65e02496cd9873f5bb0297661b19762b44ddfec (diff)
Hacked the source to get it compile on Windows Mobile using CeGCC toolchain.
Fixed nasty memory corruption bug in UI scripts loading code. Fixed software refresh compilation issues on Windows. Inactive MVD channels are now completely destroyed and recreated once they are active again, and they are no longer allowed to stay in waiting state forever. Fixed delay buffer overflow resulting in fatal connection error. Preserve MVD stream flags in demos recorded on GTV server, and handle `inuse' flag correctly on players when writing gamestate. Updated documentation and Debian package descriptions.
-rw-r--r--build/q2pro.mk8
-rw-r--r--build/q2proded.mk10
-rwxr-xr-xconfigure37
-rw-r--r--debian/control36
-rw-r--r--source/cl_demo.c6
-rw-r--r--source/cl_main.c4
-rw-r--r--source/cl_parse.c2
-rw-r--r--source/cl_ref.c4
-rw-r--r--source/cl_scrn.c2
-rw-r--r--source/com_local.h4
-rw-r--r--source/common.c25
-rw-r--r--source/files.c23
-rw-r--r--source/mvd_client.c186
-rw-r--r--source/mvd_game.c46
-rw-r--r--source/mvd_local.h6
-rw-r--r--source/mvd_parse.c5
-rw-r--r--source/net_common.c16
-rw-r--r--source/q_shared.c2
-rw-r--r--source/q_shared.h2
-rw-r--r--source/r_images.c2
-rw-r--r--source/snd_wave.c20
-rw-r--r--source/sv_ac.c6
-rw-r--r--source/sv_init.c2
-rw-r--r--source/sv_main.c10
-rw-r--r--source/sv_mvd.c25
-rw-r--r--source/sv_public.h4
-rw-r--r--source/sys_public.h3
-rw-r--r--source/sys_win.c99
-rw-r--r--source/ui_script.c9
-rw-r--r--source/vid_win.c36
-rw-r--r--source/win_ascii.c95
-rw-r--r--source/win_local.h11
-rw-r--r--source/win_swimp.c30
-rw-r--r--wiki/contact.mdwn13
-rw-r--r--wiki/doc/mingw.mdwn49
-rw-r--r--wiki/download.mdwn23
-rw-r--r--wiki/index.mdwn16
-rw-r--r--wiki/shots.mdwn11
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
diff --git a/configure b/configure
index 2b0d86b..42ab376 100755
--- a/configure
+++ b/configure
@@ -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/
-