summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/cl_cin.c3
-rw-r--r--src/client/cl_keys.c12
-rw-r--r--src/client/cl_main.c7
-rw-r--r--src/client/cl_scrn.c4
-rw-r--r--src/client/libmumblelink.c14
-rw-r--r--src/client/snd_openal.c27
-rw-r--r--src/jpeg-6b/jinclude.h3
-rw-r--r--src/jpeg-6b/jmorecfg.h4
-rw-r--r--src/null/null_client.c2
-rw-r--r--src/qcommon/common.c20
-rw-r--r--src/qcommon/msg.c8
-rw-r--r--src/qcommon/net_ip.c73
-rw-r--r--src/qcommon/q_platform.h33
-rw-r--r--src/qcommon/q_shared.h2
-rw-r--r--src/qcommon/qcommon.h26
-rw-r--r--src/qcommon/vm_interpreted.c24
-rw-r--r--src/qcommon/vm_x86.c2
-rw-r--r--src/qcommon/vm_x86_64.c113
-rw-r--r--src/qcommon/vm_x86_64_assembler.c30
-rw-r--r--src/renderer/tr_model.c4
-rw-r--r--src/renderer/tr_shade_calc.c4
-rw-r--r--src/renderer/tr_shader.c37
-rw-r--r--src/sdl/sdl_glimp.c9
-rw-r--r--src/sdl/sdl_input.c16
-rw-r--r--src/server/sv_client.c2
-rw-r--r--src/server/sv_main.c4
-rw-r--r--src/sys/sys_cocoa.m40
-rw-r--r--src/sys/sys_local.h3
-rw-r--r--src/sys/sys_main.c105
-rw-r--r--src/sys/sys_unix.c251
-rw-r--r--src/sys/sys_win32.c104
-rw-r--r--src/tools/asm/cmdlib.c2
32 files changed, 713 insertions, 275 deletions
diff --git a/src/client/cl_cin.c b/src/client/cl_cin.c
index f1fde54b..6d03d40a 100644
--- a/src/client/cl_cin.c
+++ b/src/client/cl_cin.c
@@ -1653,6 +1653,9 @@ void CIN_UploadCinematic(int handle) {
if (cl_inGameVideo->integer == 0 && cinTable[handle].playonwalls == 1) {
cinTable[handle].playonwalls--;
}
+ else if (cl_inGameVideo->integer != 0 && cinTable[handle].playonwalls != 1) {
+ cinTable[handle].playonwalls = 1;
+ }
}
}
diff --git a/src/client/cl_keys.c b/src/client/cl_keys.c
index 212ac8d5..c2cda2d6 100644
--- a/src/client/cl_keys.c
+++ b/src/client/cl_keys.c
@@ -532,12 +532,14 @@ void Field_CharEvent( field_t *edit, int ch ) {
}
if ( key_overstrikeMode ) {
- if ( edit->cursor == MAX_EDIT_LINE - 1 )
+ // - 2 to leave room for the leading slash and trailing \0
+ if ( edit->cursor == MAX_EDIT_LINE - 2 )
return;
edit->buffer[edit->cursor] = ch;
edit->cursor++;
} else { // insert mode
- if ( len == MAX_EDIT_LINE - 1 ) {
+ // - 2 to leave room for the leading slash and trailing \0
+ if ( len == MAX_EDIT_LINE - 2 ) {
return; // all full
}
memmove( edit->buffer + edit->cursor + 1,
@@ -581,8 +583,10 @@ void Console_Key (int key) {
// enter finishes the line
if ( key == K_ENTER || key == K_KP_ENTER ) {
// if not in the game explicitly prepend a slash if needed
- if ( cls.state != CA_ACTIVE && g_consoleField.buffer[0] != '\\'
- && g_consoleField.buffer[0] != '/' ) {
+ if ( cls.state != CA_ACTIVE &&
+ g_consoleField.buffer[0] &&
+ g_consoleField.buffer[0] != '\\' &&
+ g_consoleField.buffer[0] != '/' ) {
char temp[MAX_EDIT_LINE-1];
Q_strncpyz( temp, g_consoleField.buffer, sizeof( temp ) );
diff --git a/src/client/cl_main.c b/src/client/cl_main.c
index 81cb98ac..a4c74c5a 100644
--- a/src/client/cl_main.c
+++ b/src/client/cl_main.c
@@ -3407,7 +3407,6 @@ void CL_Init( void ) {
// userinfo
Cvar_Get ("name", Sys_GetCurrentUser( ), CVAR_USERINFO | CVAR_ARCHIVE );
-
Cvar_Get ("rate", "25000", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("snaps", "20", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("color1", "4", CVAR_USERINFO | CVAR_ARCHIVE );
@@ -3441,7 +3440,7 @@ void CL_Init( void ) {
// just demand it. Who doesn't have at least a DSL line now, anyhow? If
// you don't, you don't need VoIP. :)
if ((cl_voip->integer) && (Cvar_VariableIntegerValue("rate") < 25000)) {
- Com_Printf("Your network rate is too slow for VoIP.\n");
+ Com_Printf(S_COLOR_YELLOW "Your network rate is too slow for VoIP.\n");
Com_Printf("Set 'Data Rate' to 'LAN/Cable/xDSL' in 'Setup/System/Network' and restart.\n");
Com_Printf("Until then, VoIP is disabled.\n");
Cvar_Set("cl_voip", "0");
@@ -3504,14 +3503,14 @@ CL_Shutdown
===============
*/
-void CL_Shutdown( void ) {
+void CL_Shutdown( char *finalmsg ) {
static qboolean recursive = qfalse;
// check whether the client is running at all.
if(!(com_cl_running && com_cl_running->integer))
return;
- Com_Printf( "----- CL_Shutdown -----\n" );
+ Com_Printf( "----- Client Shutdown (%s) -----\n", finalmsg );
if ( recursive ) {
Com_Printf( "WARNING: Recursive shutdown\n" );
diff --git a/src/client/cl_scrn.c b/src/client/cl_scrn.c
index a5769b0d..c8568472 100644
--- a/src/client/cl_scrn.c
+++ b/src/client/cl_scrn.c
@@ -549,8 +549,10 @@ void SCR_UpdateScreen( void ) {
// that case.
if( uivm || com_dedicated->integer )
{
+ // XXX
+ extern cvar_t* r_anaglyphMode;
// if running in stereo, we need to draw the frame twice
- if ( cls.glconfig.stereoEnabled || Cvar_VariableIntegerValue("r_anaglyphMode")) {
+ if ( cls.glconfig.stereoEnabled || r_anaglyphMode->integer) {
SCR_DrawScreenField( STEREO_LEFT );
SCR_DrawScreenField( STEREO_RIGHT );
} else {
diff --git a/src/client/libmumblelink.c b/src/client/libmumblelink.c
index 1b1e521e..10e90011 100644
--- a/src/client/libmumblelink.c
+++ b/src/client/libmumblelink.c
@@ -112,6 +112,7 @@ int mumble_link(const char* name)
}
close(shmfd);
#endif
+ memset(lm, 0, sizeof(LinkedMem));
mbstowcs(lm->name, name, sizeof(lm->name));
return 0;
@@ -128,12 +129,12 @@ void mumble_update_coordinates2(float fAvatarPosition[3], float fAvatarFront[3],
if (!lm)
return;
- memcpy(lm->fAvatarPosition, fAvatarPosition, sizeof(fAvatarPosition));
- memcpy(lm->fAvatarFront, fAvatarFront, sizeof(fAvatarFront));
- memcpy(lm->fAvatarTop, fAvatarTop, sizeof(fAvatarTop));
- memcpy(lm->fCameraPosition, fCameraPosition, sizeof(fCameraPosition));
- memcpy(lm->fCameraFront, fCameraFront, sizeof(fCameraFront));
- memcpy(lm->fCameraTop, fCameraTop, sizeof(fCameraTop));
+ memcpy(lm->fAvatarPosition, fAvatarPosition, sizeof(lm->fAvatarPosition));
+ memcpy(lm->fAvatarFront, fAvatarFront, sizeof(lm->fAvatarFront));
+ memcpy(lm->fAvatarTop, fAvatarTop, sizeof(lm->fAvatarTop));
+ memcpy(lm->fCameraPosition, fCameraPosition, sizeof(lm->fCameraPosition));
+ memcpy(lm->fCameraFront, fCameraFront, sizeof(lm->fCameraFront));
+ memcpy(lm->fCameraTop, fCameraTop, sizeof(lm->fCameraTop));
lm->uiVersion = 2;
lm->uiTick = GetTickCount();
}
@@ -152,6 +153,7 @@ void mumble_set_context(const unsigned char* context, size_t len)
if (!lm)
return;
len = MIN(sizeof(lm->context), len);
+ lm->context_len = len;
memcpy(lm->context, context, len);
}
diff --git a/src/client/snd_openal.c b/src/client/snd_openal.c
index b0e7cae6..6f48713f 100644
--- a/src/client/snd_openal.c
+++ b/src/client/snd_openal.c
@@ -128,6 +128,7 @@ typedef struct alSfx_s
snd_info_t info; // information for this sound like rate, sample count..
qboolean isDefault; // Couldn't be loaded - use default FX
+ qboolean isDefaultChecked; // Sound has been check if it isDefault
qboolean inMemory; // Sound is stored in memory
qboolean isLocked; // Sound is locked (can not be unloaded)
int lastUsedTime; // Time last used
@@ -294,7 +295,7 @@ static qboolean S_AL_BufferEvict( void )
S_AL_BufferLoad
=================
*/
-static void S_AL_BufferLoad(sfxHandle_t sfx)
+static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache)
{
ALenum error;
ALuint format;
@@ -302,7 +303,6 @@ static void S_AL_BufferLoad(sfxHandle_t sfx)
void *data;
snd_info_t info;
alSfx_t *curSfx = &knownSfx[sfx];
- int size_per_sec;
// Nothing?
if(curSfx->filename[0] == '\0')
@@ -313,7 +313,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx)
return;
// Already done?
- if((curSfx->inMemory) || (curSfx->isDefault))
+ if((curSfx->inMemory) || (curSfx->isDefault) || (!cache && curSfx->isDefaultChecked))
return;
// Try to load
@@ -324,9 +324,14 @@ static void S_AL_BufferLoad(sfxHandle_t sfx)
return;
}
- size_per_sec = info.rate * info.channels * info.width;
- if( size_per_sec > 0 )
- curSfx->duration = (int)(1000.0f * ((double)info.size / size_per_sec));
+ curSfx->isDefaultChecked = qtrue;
+
+ if (!cache)
+ {
+ // Don't create AL cache
+ Z_Free(data);
+ return;
+ }
format = S_AL_Format(info.width, info.channels);
@@ -402,7 +407,7 @@ void S_AL_BufferUse(sfxHandle_t sfx)
return;
if((!knownSfx[sfx].inMemory) && (!knownSfx[sfx].isDefault))
- S_AL_BufferLoad(sfx);
+ S_AL_BufferLoad(sfx, qtrue);
knownSfx[sfx].lastUsedTime = Sys_Milliseconds();
}
@@ -468,10 +473,14 @@ sfxHandle_t S_AL_RegisterSound( const char *sample, qboolean compressed )
{
sfxHandle_t sfx = S_AL_BufferFind(sample);
- if( s_alPrecache->integer && (!knownSfx[sfx].inMemory) && (!knownSfx[sfx].isDefault))
- S_AL_BufferLoad(sfx);
+ if((!knownSfx[sfx].inMemory) && (!knownSfx[sfx].isDefault))
+ S_AL_BufferLoad(sfx, s_alPrecache->integer);
knownSfx[sfx].lastUsedTime = Com_Milliseconds();
+ if (knownSfx[sfx].isDefault) {
+ return 0;
+ }
+
return sfx;
}
diff --git a/src/jpeg-6b/jinclude.h b/src/jpeg-6b/jinclude.h
index 1c5515cd..33d2cd5b 100644
--- a/src/jpeg-6b/jinclude.h
+++ b/src/jpeg-6b/jinclude.h
@@ -14,6 +14,9 @@
* JPEG library. Most applications need only include jpeglib.h.
*/
+#ifdef __WIN64__
+#include "basetsd.h"
+#endif
#ifdef _MSC_VER
diff --git a/src/jpeg-6b/jmorecfg.h b/src/jpeg-6b/jmorecfg.h
index f8020071..d677127d 100644
--- a/src/jpeg-6b/jmorecfg.h
+++ b/src/jpeg-6b/jmorecfg.h
@@ -158,9 +158,11 @@ typedef short INT16;
/* INT32 must hold at least signed 32-bit values. */
/* MinGW basetsd.h defines INT32 - don't redefine it */
-#if !(defined __MINGW32__ && defined _BASETSD_H)
+#ifndef __WIN64
+#if !(defined __MINGW32__ && (defined _BASETSD_H || defined _BASETSD_H_))
typedef long INT32;
#endif
+#endif
/* Datatype used for image dimensions. The JPEG standard only supports
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
diff --git a/src/null/null_client.c b/src/null/null_client.c
index 5c96ccb0..aca14061 100644
--- a/src/null/null_client.c
+++ b/src/null/null_client.c
@@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
cvar_t *cl_shownet;
-void CL_Shutdown( void ) {
+void CL_Shutdown( char *finalmsg ) {
}
void CL_Init( void ) {
diff --git a/src/qcommon/common.c b/src/qcommon/common.c
index d9fb4495..38902e92 100644
--- a/src/qcommon/common.c
+++ b/src/qcommon/common.c
@@ -82,6 +82,7 @@ cvar_t *com_unfocused;
cvar_t *com_maxfpsUnfocused;
cvar_t *com_minimized;
cvar_t *com_maxfpsMinimized;
+cvar_t *com_abnormalExit;
// com_speeds times
int time_game;
@@ -238,7 +239,7 @@ void QDECL Com_DPrintf( const char *fmt, ...) {
Com_Error
Both client and server can use this, and it will
-do the apropriate things.
+do the appropriate thing.
=============
*/
void QDECL Com_Error( int code, const char *fmt, ... ) {
@@ -323,7 +324,7 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
com_errorEntered = qfalse;
longjmp (abortframe, -1);
} else {
- CL_Shutdown ();
+ CL_Shutdown (va("Client fatal crashed: %s", com_errorMessage));
SV_Shutdown (va("Server fatal crashed: %s", com_errorMessage));
}
@@ -347,7 +348,7 @@ void Com_Quit_f( void ) {
char *p = Cmd_Args( );
if ( !com_errorEntered ) {
SV_Shutdown (p[0] ? p : "Server quit");
- CL_Shutdown ();
+ CL_Shutdown (p[0] ? p : "Client quit");
Com_Shutdown ();
FS_Shutdown(qtrue);
}
@@ -2616,12 +2617,25 @@ void Com_Init( char *commandLine ) {
com_maxfpsUnfocused = Cvar_Get( "com_maxfpsUnfocused", "0", CVAR_ARCHIVE );
com_minimized = Cvar_Get( "com_minimized", "0", CVAR_ROM );
com_maxfpsMinimized = Cvar_Get( "com_maxfpsMinimized", "0", CVAR_ARCHIVE );
+ com_abnormalExit = Cvar_Get( "com_abnormalExit", "0", CVAR_ROM );
s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ );
com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO );
Sys_Init();
+ if( Sys_WritePIDFile( ) ) {
+#ifndef DEDICATED
+ const char *message = "The last time " CLIENT_WINDOW_TITLE " ran, "
+ "it didn't exit properly. This may be due to inappropriate video "
+ "settings. Would you like to start with \"safe\" video settings?";
+
+ if( Sys_Dialog( DT_YES_NO, message, "Abnormal Exit" ) == DR_YES ) {
+ Cvar_Set( "com_abnormalExit", "1" );
+ }
+#endif
+ }
+
// Pick a random port value
Com_RandomBytes( (byte*)&qport, sizeof(int) );
Netchan_Init( qport & 0xffff );
diff --git a/src/qcommon/msg.c b/src/qcommon/msg.c
index c85360c4..ba956bc8 100644
--- a/src/qcommon/msg.c
+++ b/src/qcommon/msg.c
@@ -1033,6 +1033,10 @@ void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to,
numFields = sizeof(entityStateFields)/sizeof(entityStateFields[0]);
lc = MSG_ReadByte(msg);
+ if ( lc > numFields || lc < 0 ) {
+ Com_Error( ERR_DROP, "invalid entityState field count" );
+ }
+
// shownet 2/3 will interleave with other printed info, -1 will
// just print the delta records`
if ( cl_shownet->integer >= 2 || cl_shownet->integer == -1 ) {
@@ -1352,6 +1356,10 @@ void MSG_ReadDeltaPlayerstate (msg_t *msg, playerState_t *from, playerState_t *t
numFields = sizeof( playerStateFields ) / sizeof( playerStateFields[0] );
lc = MSG_ReadByte(msg);
+ if ( lc > numFields || lc < 0 ) {
+ Com_Error( ERR_DROP, "invalid playerState field count" );
+ }
+
for ( i = 0, field = playerStateFields ; i < lc ; i++, field++ ) {
fromF = (int *)( (byte *)from + field->offset );
toF = (int *)( (byte *)to + field->offset );
diff --git a/src/qcommon/net_ip.c b/src/qcommon/net_ip.c
index 2be40a86..c1e527c5 100644
--- a/src/qcommon/net_ip.c
+++ b/src/qcommon/net_ip.c
@@ -310,11 +310,11 @@ static qboolean Sys_StringToSockaddr(const char *s, struct sockaddr *sadr, int s
if(search)
{
- if(res->ai_addrlen > sadr_len)
- res->ai_addrlen = sadr_len;
+ if(search->ai_addrlen > sadr_len)
+ search->ai_addrlen = sadr_len;
- memcpy(sadr, res->ai_addr, res->ai_addrlen);
- freeaddrinfo(res);
+ memcpy(sadr, search->ai_addr, search->ai_addrlen);
+ freeaddrinfo(search);
return qtrue;
}
@@ -853,9 +853,6 @@ int NET_IPSocket( char *net_interface, int port, int *err ) {
// make it broadcast capable
if( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, (char *) &i, sizeof(i) ) == SOCKET_ERROR ) {
Com_Printf( "WARNING: NET_IPSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString() );
-
- // it is not that bad if this one fails.
-// return newsocket;
}
if( !net_interface || !net_interface[0]) {
@@ -1035,28 +1032,28 @@ void NET_JoinMulticast6(void)
if(curgroup.ipv6mr_interface)
{
if (setsockopt(multicast6_socket, IPPROTO_IPV6, IPV6_MULTICAST_IF,
- (char *) &curgroup.ipv6mr_interface, sizeof(curgroup.ipv6mr_interface)) < 0)
+ (char *) &curgroup.ipv6mr_interface, sizeof(curgroup.ipv6mr_interface)) < 0)
{
- Com_Printf("NET_JoinMulticast6: Couldn't set scope on multicast socket: %s\n", NET_ErrorString());
+ Com_Printf("NET_JoinMulticast6: Couldn't set scope on multicast socket: %s\n", NET_ErrorString());
- if(multicast6_socket != ip6_socket)
- {
- closesocket(multicast6_socket);
- multicast6_socket = INVALID_SOCKET;
- return;
+ if(multicast6_socket != ip6_socket)
+ {
+ closesocket(multicast6_socket);
+ multicast6_socket = INVALID_SOCKET;
+ return;
}
}
- }
-
- if (setsockopt(multicast6_socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *) &curgroup, sizeof(curgroup)))
- {
- Com_Printf("NET_JoinMulticast6: Couldn't join multicast group: %s\n", NET_ErrorString());
-
- if(multicast6_socket != ip6_socket)
- {
- closesocket(multicast6_socket);
- multicast6_socket = INVALID_SOCKET;
- return;
+ }
+
+ if (setsockopt(multicast6_socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *) &curgroup, sizeof(curgroup)))
+ {
+ Com_Printf("NET_JoinMulticast6: Couldn't join multicast group: %s\n", NET_ErrorString());
+
+ if(multicast6_socket != ip6_socket)
+ {
+ closesocket(multicast6_socket);
+ multicast6_socket = INVALID_SOCKET;
+ return;
}
}
}
@@ -1253,10 +1250,10 @@ void NET_OpenSocks( int port ) {
/*
=====================
-NET_GetLocalAddress
+NET_AddLocalAddress
=====================
*/
-void NET_AddLocalAddress(char *ifname, struct sockaddr *addr, struct sockaddr *netmask)
+static void NET_AddLocalAddress(char *ifname, struct sockaddr *addr, struct sockaddr *netmask)
{
int addrlen;
sa_family_t family;
@@ -1294,7 +1291,7 @@ void NET_AddLocalAddress(char *ifname, struct sockaddr *addr, struct sockaddr *n
}
#if defined(__linux__) || defined(MACOSX) || defined(__BSD__)
-void NET_GetLocalAddress(void)
+static void NET_GetLocalAddress(void)
{
struct ifaddrs *ifap, *search;
@@ -1315,10 +1312,10 @@ void NET_GetLocalAddress(void)
}
}
#else
-void NET_GetLocalAddress( void ) {
+static void NET_GetLocalAddress( void ) {
char hostname[256];
- struct addrinfo hint;
- struct addrinfo *res = NULL;
+ struct addrinfo hint;
+ struct addrinfo *res = NULL;
if(gethostname( hostname, 256 ) == SOCKET_ERROR)
return;
@@ -1334,7 +1331,7 @@ void NET_GetLocalAddress( void ) {
{
struct sockaddr_in mask4;
struct sockaddr_in6 mask6;
- struct addrinfo *search;
+ struct addrinfo *search;
/* On operating systems where it's more difficult to find out the configured interfaces, we'll just assume a
* netmask with all bits set. */
@@ -1476,27 +1473,27 @@ static qboolean NET_GetCvars( void ) {
#else
net_mcast6iface = Cvar_Get( "net_mcast6iface", "", CVAR_LATCH | CVAR_ARCHIVE );
#endif
- modified += net_mcast6iface->modified;
+ modified += net_mcast6iface->modified;
net_mcast6iface->modified = qfalse;
net_socksEnabled = Cvar_Get( "net_socksEnabled", "0", CVAR_LATCH | CVAR_ARCHIVE );
- modified += net_socksEnabled->modified;
+ modified += net_socksEnabled->modified;
net_socksEnabled->modified = qfalse;
net_socksServer = Cvar_Get( "net_socksServer", "", CVAR_LATCH | CVAR_ARCHIVE );
- modified += net_socksServer->modified;
+ modified += net_socksServer->modified;
net_socksServer->modified = qfalse;
net_socksPort = Cvar_Get( "net_socksPort", "1080", CVAR_LATCH | CVAR_ARCHIVE );
- modified += net_socksPort->modified;
+ modified += net_socksPort->modified;
net_socksPort->modified = qfalse;
net_socksUsername = Cvar_Get( "net_socksUsername", "", CVAR_LATCH | CVAR_ARCHIVE );
- modified += net_socksUsername->modified;
+ modified += net_socksUsername->modified;
net_socksUsername->modified = qfalse;
net_socksPassword = Cvar_Get( "net_socksPassword", "", CVAR_LATCH | CVAR_ARCHIVE );
- modified += net_socksPassword->modified;
+ modified += net_socksPassword->modified;
net_socksPassword->modified = qfalse;
return modified ? qtrue : qfalse;
diff --git a/src/qcommon/q_platform.h b/src/qcommon/q_platform.h
index 9405e749..4d4d2856 100644
--- a/src/qcommon/q_platform.h
+++ b/src/qcommon/q_platform.h
@@ -73,9 +73,33 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// for windows fastcall option
#define QDECL
-//================================================================= WIN32 ===
+//================================================================= WIN64/32 ===
-#ifdef _WIN32
+#if defined(_WIN64) || defined(__WIN64__)
+
+#undef QDECL
+#define QDECL __cdecl
+
+#if defined( _MSC_VER )
+#define OS_STRING "win_msvc64"
+#elif defined __MINGW64__
+#define OS_STRING "win_mingw64"
+#endif
+
+#define ID_INLINE inline
+#define PATH_SEP '\\'
+
+#if defined( __WIN64__ )
+#define ARCH_STRING "x86_64"
+#elif defined _M_ALPHA
+#define ARCH_STRING "AXP"
+#endif
+
+#define Q3_LITTLE_ENDIAN
+
+#define DLL_EXT ".dll"
+
+#elif defined(_WIN32) || defined(__WIN32__)
#undef QDECL
#define QDECL __cdecl
@@ -120,6 +144,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#elif defined __i386__
#define ARCH_STRING "x86"
#define Q3_LITTLE_ENDIAN
+#elif defined __x86_64__
+#define ARCH_STRING "x86_64"
+#define Q3_LITTLE_ENDIAN
#endif
#define DLL_EXT ".dylib"
@@ -201,7 +228,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifdef __i386__
#define ARCH_STRING "x86"
#elif defined __amd64__
-#define ARCH_STRING "x86_64"
+#define ARCH_STRING "amd64"
#elif defined __axp__
#define ARCH_STRING "alpha"
#endif
diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h
index 44685582..3f2cb9d5 100644
--- a/src/qcommon/q_shared.h
+++ b/src/qcommon/q_shared.h
@@ -184,6 +184,8 @@ typedef int clipHandle_t;
#define MAX_QINT 0x7fffffff
#define MIN_QINT (-MAX_QINT-1)
+#define ARRAY_LEN(x) (sizeof(x) / sizeof(*x))
+
// angle indexes
#define PITCH 0 // up / down
diff --git a/src/qcommon/qcommon.h b/src/qcommon/qcommon.h
index 18f4c5e5..09132159 100644
--- a/src/qcommon/qcommon.h
+++ b/src/qcommon/qcommon.h
@@ -179,7 +179,7 @@ qboolean NET_CompareBaseAdrMask(netadr_t a, netadr_t b, int netmask);
qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b);
qboolean NET_IsLocalAddress (netadr_t adr);
const char *NET_AdrToString (netadr_t a);
-const char *NET_AdrToStringwPort (netadr_t a);
+const char *NET_AdrToStringwPort (netadr_t a);
int NET_StringToAdr ( const char *s, netadr_t *a, netadrtype_t family);
qboolean NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, msg_t *net_message);
void NET_JoinMulticast6(void);
@@ -923,7 +923,7 @@ void CL_InitKeyCommands( void );
void CL_Init( void );
void CL_Disconnect( qboolean showMainMenu );
-void CL_Shutdown( void );
+void CL_Shutdown( char *finalmsg );
void CL_Frame( int msec );
qboolean CL_GameCommand( void );
void CL_KeyEvent (int key, qboolean down, unsigned time);
@@ -1072,6 +1072,7 @@ char *Sys_DefaultAppPath(void);
void Sys_SetDefaultHomePath(const char *path);
char *Sys_DefaultHomePath(void);
+const char *Sys_TempPath(void);
const char *Sys_Dirname( char *path );
const char *Sys_Basename( char *path );
char *Sys_ConsoleInput(void);
@@ -1084,6 +1085,27 @@ qboolean Sys_LowPhysicalMemory( void );
void Sys_SetEnv(const char *name, const char *value);
+typedef enum
+{
+ DR_YES = 0,
+ DR_NO = 1,
+ DR_OK = 0,
+ DR_CANCEL = 1
+} dialogResult_t;
+
+typedef enum
+{
+ DT_INFO,
+ DT_WARNING,
+ DT_ERROR,
+ DT_YES_NO,
+ DT_OK_CANCEL
+} dialogType_t;
+
+dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *title );
+
+qboolean Sys_WritePIDFile( void );
+
/* This is based on the Adaptive Huffman algorithm described in Sayood's Data
* Compression book. The ranks are not actually stored, but implicitly defined
* by the location of a node within a doubly-linked list */
diff --git a/src/qcommon/vm_interpreted.c b/src/qcommon/vm_interpreted.c
index 53357f5d..2b9ffea6 100644
--- a/src/qcommon/vm_interpreted.c
+++ b/src/qcommon/vm_interpreted.c
@@ -517,18 +517,20 @@ nextInstruction2:
//VM_LogSyscalls( (int *)&image[ programStack + 4 ] );
{
- intptr_t* argptr = (intptr_t *)&image[ programStack + 4 ];
- #if __WORDSIZE == 64
- // the vm has ints on the stack, we expect
- // longs so we have to convert it
- intptr_t argarr[16];
- int i;
- for (i = 0; i < 16; ++i) {
- argarr[i] = *(int*)&image[ programStack + 4 + 4*i ];
+ // the vm has ints on the stack, we expect
+ // pointers so we might have to convert it
+ if (sizeof(intptr_t) != sizeof(int)) {
+ intptr_t argarr[16];
+ int *imagePtr = (int *)&image[programStack];
+ int i;
+ for (i = 0; i < 16; ++i) {
+ argarr[i] = *(++imagePtr);
+ }
+ r = vm->systemCall( argarr );
+ } else {
+ intptr_t* argptr = (intptr_t *)&image[ programStack + 4 ];
+ r = vm->systemCall( argptr );
}
- argptr = argarr;
- #endif
- r = vm->systemCall( argptr );
}
#ifdef DEBUG_VM
diff --git a/src/qcommon/vm_x86.c b/src/qcommon/vm_x86.c
index dc7f5a67..41806f2a 100644
--- a/src/qcommon/vm_x86.c
+++ b/src/qcommon/vm_x86.c
@@ -37,7 +37,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
/* need this on NX enabled systems (i386 with PAE kernel or
* noexec32=on x86_64) */
-#ifdef __linux__
+#if defined(__linux__) || defined(__FreeBSD__)
#define VM_X86_MMAP
#endif
diff --git a/src/qcommon/vm_x86_64.c b/src/qcommon/vm_x86_64.c
index 93e25f6d..13c39172 100644
--- a/src/qcommon/vm_x86_64.c
+++ b/src/qcommon/vm_x86_64.c
@@ -24,11 +24,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// vm_x86_64.c -- load time compiler and execution environment for x86-64
#include "vm_local.h"
-
-#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <sys/wait.h>
#include <sys/time.h>
#include <time.h>
#include <fcntl.h>
@@ -36,6 +33,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <unistd.h>
#include <stdarg.h>
+#include <inttypes.h>
+
+#ifdef __WIN64__
+ #include <windows.h>
+ #define CROSSCALL __attribute__ ((sysv_abi))//fool the vm we're SYSV ABI
+ //#define __USE_MINGW_ANSI_STDIO 1 //very slow - avoid if possible
+#else
+ #include <sys/mman.h>
+ #include <sys/wait.h>
+ #define VM_X86_64_MMAP
+ #define CROSSCALL
+#endif
+
//#define DEBUG_VM
#ifdef DEBUG_VM
@@ -45,8 +55,6 @@ static FILE* qdasmout;
#define Dfprintf(args...)
#endif
-#define VM_X86_64_MMAP
-
void assembler_set_output(char* buf);
size_t assembler_get_code_size(void);
void assembler_init(int pass);
@@ -72,11 +80,11 @@ static void VM_Destroy_Compiled(vm_t* self);
*/
-static long callAsmCall(long callProgramStack, long callSyscallNum)
+static int64_t CROSSCALL callAsmCall(int64_t callProgramStack, int64_t callSyscallNum)
{
vm_t *savedVM;
- long ret = 0x77;
- long args[11];
+ int64_t ret = 0x77;
+ int64_t args[11];
// int iargs[11];
int i;
@@ -232,13 +240,13 @@ void emit(const char* fmt, ...)
#define CHECK_INSTR_REG(reg) \
emit("cmpl $%u, %%"#reg, header->instructionCount); \
emit("jb jmp_ok_i_%08x", instruction); \
- emit("movq $%lu, %%rax", (unsigned long)jmpviolation); \
+ emit("movq $%"PRIu64", %%rax", (uint64_t)jmpviolation); \
emit("callq *%%rax"); \
emit("jmp_ok_i_%08x:", instruction);
#define PREPARE_JMP(reg) \
CHECK_INSTR_REG(reg) \
- emit("movq $%lu, %%rbx", (unsigned long)vm->instructionPointers); \
+ emit("movq $%"PRIu64", %%rbx", (uint64_t)vm->instructionPointers); \
emit("movl (%%rbx, %%rax, 4), %%eax"); \
emit("addq %%r10, %%rax");
@@ -250,7 +258,7 @@ void emit(const char* fmt, ...)
#define JMPIARG \
CHECK_INSTR(iarg); \
- emit("movq $%lu, %%rax", vm->codeBase+vm->instructionPointers[iarg]); \
+ emit("movq $%"PRIu64", %%rax", vm->codeBase+vm->instructionPointers[iarg]); \
emit("jmpq *%%rax");
#define CONST_OPTIMIZE
@@ -340,7 +348,7 @@ void emit(const char* fmt, ...)
emit("andl $0x%x, %%ecx", vm->dataMask &~(bytes-1)); \
emit("cmpl %%" #reg ", %%ecx"); \
emit("jz rc_ok_i_%08x", instruction); \
- emit("movq $%lu, %%rax", (unsigned long)memviolation); \
+ emit("movq $%"PRIu64", %%rax", (uint64_t)memviolation); \
emit("callq *%%rax"); \
emit("rc_ok_i_%08x:", instruction);
#elif 1
@@ -364,7 +372,7 @@ static void* getentrypoint(vm_t* vm)
return vm->codeBase;
}
-static void block_copy_vm(unsigned dest, unsigned src, unsigned count)
+static void CROSSCALL block_copy_vm(unsigned dest, unsigned src, unsigned count)
{
unsigned dataMask = currentVM->dataMask;
@@ -379,20 +387,20 @@ static void block_copy_vm(unsigned dest, unsigned src, unsigned count)
memcpy(currentVM->dataBase+dest, currentVM->dataBase+src, count);
}
-static void eop(void)
+static void CROSSCALL eop(void)
{
Com_Error(ERR_DROP, "end of program reached without return!\n");
exit(1);
}
-static void jmpviolation(void)
+static void CROSSCALL jmpviolation(void)
{
Com_Error(ERR_DROP, "program tried to execute code outside VM\n");
exit(1);
}
#ifdef DEBUG_VM
-static void memviolation(void)
+static void CROSSCALL memviolation(void)
{
Com_Error(ERR_DROP, "program tried to access memory outside VM\n");
exit(1);
@@ -431,9 +439,19 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
{
compiledOfs = assembler_get_code_size();
vm->codeLength = compiledOfs;
- vm->codeBase = mmap(NULL, compiledOfs, PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
- if(vm->codeBase == (void*)-1)
- Com_Error(ERR_DROP, "VM_CompileX86: can't mmap memory");
+
+ #ifdef VM_X86_64_MMAP
+ vm->codeBase = mmap(NULL, compiledOfs, PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
+ if(vm->codeBase == (void*)-1)
+ Com_Error(ERR_DROP, "VM_CompileX86: can't mmap memory");
+ #elif __WIN64__
+ // allocate memory with write permissions under windows.
+ vm->codeBase = VirtualAlloc(NULL, compiledOfs, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
+ if(!vm->codeBase)
+ Com_Error(ERR_DROP, "VM_CompileX86: VirtualAlloc failed");
+ #else
+ vm->codeBase = malloc(compiledOfs);
+ #endif
assembler_set_output((char*)vm->codeBase);
}
@@ -474,7 +492,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
else if(op_argsize[op] == 1)
{
barg = code[pc++];
- Dfprintf(qdasmout, "%s %8hhu\n", opnames[op], barg);
+ Dfprintf(qdasmout, "%s %8hu\n", opnames[op], barg);
}
else
{
@@ -518,7 +536,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
goto emit_do_syscall;
CHECK_INSTR(const_value);
- emit("movq $%lu, %%rax", vm->codeBase+vm->instructionPointers[const_value]);
+ emit("movq $%"PRIu64", %%rax", vm->codeBase+vm->instructionPointers[const_value]);
emit("callq *%%rax");
got_const = 0;
break;
@@ -559,7 +577,7 @@ emit_do_syscall:
// first argument already in rdi
emit("movq %%rax, %%rsi"); // second argument in rsi
}
- emit("movq $%lu, %%rax", (unsigned long)callAsmCall);
+ emit("movq $%"PRIu64", %%rax", (uint64_t)callAsmCall);
emit("callq *%%rax");
emit("pop %%rbx");
emit("addq %%rbx, %%rsp");
@@ -726,7 +744,7 @@ emit_do_syscall:
MAYBE_EMIT_CONST();
emit("subq $4, %%rsi");
emit("movl 4(%%rsi), %%eax"); // get value from stack
- emit("movl $0x%hhx, %%ebx", barg);
+ emit("movl $0x%hx, %%ebx", barg);
emit("addl %%edi, %%ebx");
RANGECHECK(ebx, 4);
emit("movl %%eax, 0(%%r8,%%rbx, 1)"); // store in args space
@@ -740,11 +758,18 @@ emit_do_syscall:
emit("push %%r8");
emit("push %%r9");
emit("push %%r10");
+ emit("movq %%rsp, %%rbx"); // we need to align the stack pointer
+ emit("subq $8, %%rbx"); // |
+ emit("andq $127, %%rbx"); // |
+ emit("subq %%rbx, %%rsp"); // <-+
+ emit("push %%rbx");
emit("movl 4(%%rsi), %%edi"); // 1st argument dest
emit("movl 8(%%rsi), %%esi"); // 2nd argument src
emit("movl $%d, %%edx", iarg); // 3rd argument count
- emit("movq $%lu, %%rax", (unsigned long)block_copy_vm);
+ emit("movq $%"PRIu64", %%rax", (uint64_t)block_copy_vm);
emit("callq *%%rax");
+ emit("pop %%rbx");
+ emit("addq %%rbx, %%rsp");
emit("pop %%r10");
emit("pop %%r9");
emit("pop %%r8");
@@ -910,15 +935,25 @@ emit_do_syscall:
Com_Error(ERR_DROP, "leftover const\n");
}
- emit("movq $%lu, %%rax", (unsigned long)eop);
+ emit("movq $%"PRIu64", %%rax", (uint64_t)eop);
emit("callq *%%rax");
} // pass loop
assembler_init(0);
- if(mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC))
- Com_Error(ERR_DROP, "VM_CompileX86: mprotect failed");
+ #ifdef VM_X86_64_MMAP
+ if(mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC))
+ Com_Error(ERR_DROP, "VM_CompileX86: mprotect failed");
+ #elif __WIN64__
+ {
+ DWORD oldProtect = 0;
+
+ // remove write permissions; give exec permision
+ if(!VirtualProtect(vm->codeBase, compiledOfs, PAGE_EXECUTE_READ, &oldProtect))
+ Com_Error(ERR_DROP, "VM_CompileX86: VirtualProtect failed");
+ }
+ #endif
vm->destroy = VM_Destroy_Compiled;
@@ -935,17 +970,19 @@ emit_do_syscall:
fclose(qdasmout);
#endif
#endif
-
- if(vm->compiled)
- {
- struct timeval tvdone = {0, 0};
- struct timeval dur = {0, 0};
- Com_Printf( "VM file %s compiled to %i bytes of code (%p - %p)\n", vm->name, vm->codeLength, vm->codeBase, vm->codeBase+vm->codeLength );
- gettimeofday(&tvdone, NULL);
- timersub(&tvdone, &tvstart, &dur);
- Com_Printf( "compilation took %lu.%06lu seconds\n", dur.tv_sec, dur.tv_usec );
- }
+ #ifndef __WIN64__ //timersub and gettimeofday
+ if(vm->compiled)
+ {
+ struct timeval tvdone = {0, 0};
+ struct timeval dur = {0, 0};
+ Com_Printf( "VM file %s compiled to %i bytes of code (%p - %p)\n", vm->name, vm->codeLength, vm->codeBase, vm->codeBase+vm->codeLength );
+
+ gettimeofday(&tvdone, NULL);
+ timersub(&tvdone, &tvstart, &dur);
+ Com_Printf( "compilation took %"PRIu64".%06"PRIu64" seconds\n", dur.tv_sec, dur.tv_usec );
+ }
+ #endif
}
@@ -1035,7 +1072,7 @@ int VM_CallCompiled( vm_t *vm, int *args ) {
);
if ( opStack != &stack[1] ) {
- Com_Error( ERR_DROP, "opStack corrupted in compiled code (offset %ld)\n", (long int) ((void *) &stack[1] - opStack));
+ Com_Error( ERR_DROP, "opStack corrupted in compiled code (offset %"PRId64")\n", (int64_t) ((void *) &stack[1] - opStack));
}
if ( programStack != stackOnEntry - 48 ) {
Com_Error( ERR_DROP, "programStack corrupted in compiled code\n" );
diff --git a/src/qcommon/vm_x86_64_assembler.c b/src/qcommon/vm_x86_64_assembler.c
index 46227e6d..99d2898e 100644
--- a/src/qcommon/vm_x86_64_assembler.c
+++ b/src/qcommon/vm_x86_64_assembler.c
@@ -27,10 +27,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <string.h>
#include <stdarg.h>
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef unsigned long u64;
+#include <inttypes.h>
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
static char* out;
static unsigned compiledOfs;
@@ -79,7 +81,7 @@ static void emit1(unsigned char v)
if(fout)
writecnt = fwrite(&v, 1, 1, fout);
- debug("%02hhx ", v);
+ debug("%02hx ", v);
}
else
{
@@ -284,7 +286,7 @@ static void labelhash_free(void)
min = MIN(min, n);
max = MAX(max, n);
}
- printf("total %u, hsize %lu, zero %u, min %u, max %u\n", t, sizeof(labelhash)/sizeof(labelhash[0]), z, min, max);
+ printf("total %u, hsize %"PRIu64", zero %u, min %u, max %u\n", t, sizeof(labelhash)/sizeof(labelhash[0]), z, min, max);
memset(labelhash, 0, sizeof(labelhash));
}
@@ -310,7 +312,7 @@ static const char* argtype2str(argtype_t t)
static inline int iss8(u64 v)
{
- return (labs(v) <= 0x80);
+ return (llabs(v) <= 0x80); //llabs instead of labs required for __WIN64
}
static inline int isu8(u64 v)
@@ -320,7 +322,7 @@ static inline int isu8(u64 v)
static inline int iss16(u64 v)
{
- return (labs(v) <= 0x8000);
+ return (llabs(v) <= 0x8000);
}
static inline int isu16(u64 v)
@@ -330,7 +332,7 @@ static inline int isu16(u64 v)
static inline int iss32(u64 v)
{
- return (labs(v) <= 0x80000000);
+ return (llabs(v) <= 0x80000000);
}
static inline int isu32(u64 v)
@@ -340,7 +342,7 @@ static inline int isu32(u64 v)
static void emit_opsingle(const char* mnemonic, arg_t arg1, arg_t arg2, void* data)
{
- u8 op = (u8)((unsigned long) data);
+ u8 op = (u8)((uint64_t) data);
if(arg1.type != T_NONE || arg2.type != T_NONE)
CRAP_INVALID_ARGS;
@@ -503,7 +505,7 @@ static void maybe_emit_displacement(arg_t* arg)
/* one byte operator with register added to operator */
static void emit_opreg(const char* mnemonic, arg_t arg1, arg_t arg2, void* data)
{
- u8 op = (u8)((unsigned long) data);
+ u8 op = (u8)((uint64_t) data);
if(arg1.type != T_REGISTER || arg2.type != T_NONE)
CRAP_INVALID_ARGS;
@@ -756,7 +758,7 @@ static void emit_condjump(const char* mnemonic, arg_t arg1, arg_t arg2, void* da
{
unsigned off;
int disp;
- unsigned char opcode = (unsigned char)(((unsigned long)data)&0xFF);
+ unsigned char opcode = (unsigned char)(((uint64_t)data)&0xFF);
if(arg1.type != T_LABEL || arg2.type != T_NONE)
crap("%s: argument must be label", mnemonic);
@@ -1153,7 +1155,7 @@ static unsigned char nexttok(const char** str, char* label, u64* val)
else if(*s >= '0' && *s <= '9')
{
char* endptr = NULL;
- u64 v = strtol(s, &endptr, 0);
+ u64 v = strtoull(s, &endptr, 0);
if(endptr && (endptr-s == 0))
crap("invalid integer %s", s);
if(val) *val = v;
@@ -1274,7 +1276,7 @@ tok_memory:
}
break;
default:
- crap("invalid token %hhu in %s", *(unsigned char*)s, *str);
+ crap("invalid token %hu in %s", *(unsigned char*)s, *str);
break;
}
diff --git a/src/renderer/tr_model.c b/src/renderer/tr_model.c
index 70660583..b02d52a4 100644
--- a/src/renderer/tr_model.c
+++ b/src/renderer/tr_model.c
@@ -563,8 +563,8 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char
((float *)frame->bones)[j] = LittleFloat( ((float *)curframe->bones)[j] );
}
- curframe++;
- frame++;
+ curframe = (mdrFrame_t *) &curframe->bones[mdr->numBones];
+ frame = (mdrFrame_t *) &frame->bones[mdr->numBones];
}
}
diff --git a/src/renderer/tr_shade_calc.c b/src/renderer/tr_shade_calc.c
index c3de88cc..ba61a6df 100644
--- a/src/renderer/tr_shade_calc.c
+++ b/src/renderer/tr_shade_calc.c
@@ -360,10 +360,10 @@ static void AutospriteDeform( void ) {
vec3_t leftDir, upDir;
if ( tess.numVertexes & 3 ) {
- ri.Printf( PRINT_WARNING, "Autosprite shader %s had odd vertex count", tess.shader->name );
+ ri.Printf( PRINT_WARNING, "Autosprite shader %s had odd vertex count\n", tess.shader->name );
}
if ( tess.numIndexes != ( tess.numVertexes >> 2 ) * 6 ) {
- ri.Printf( PRINT_WARNING, "Autosprite shader %s had odd index count", tess.shader->name );
+ ri.Printf( PRINT_WARNING, "Autosprite shader %s had odd index count\n", tess.shader->name );
}
oldVerts = tess.numVertexes;
diff --git a/src/renderer/tr_shader.c b/src/renderer/tr_shader.c
index 8e86a73f..bfcd47d3 100644
--- a/src/renderer/tr_shader.c
+++ b/src/renderer/tr_shader.c
@@ -2328,11 +2328,15 @@ static char *FindShaderInShaderText( const char *shadername ) {
hash = generateHashValue(shadername, MAX_SHADERTEXT_HASH);
- for (i = 0; shaderTextHashTable[hash][i]; i++) {
- p = shaderTextHashTable[hash][i];
- token = COM_ParseExt(&p, qtrue);
- if ( !Q_stricmp( token, shadername ) ) {
- return p;
+ if(shaderTextHashTable[hash])
+ {
+ for (i = 0; shaderTextHashTable[hash][i]; i++)
+ {
+ p = shaderTextHashTable[hash][i];
+ token = COM_ParseExt(&p, qtrue);
+
+ if(!Q_stricmp(token, shadername))
+ return p;
}
}
@@ -2867,7 +2871,6 @@ void R_ShaderList_f (void) {
ri.Printf (PRINT_ALL, "------------------\n");
}
-
/*
====================
ScanAndLoadShaderFiles
@@ -2884,7 +2887,7 @@ static void ScanAndLoadShaderFiles( void )
char *p;
int numShaderFiles;
int i;
- char *oldp, *token, *hashMem;
+ char *oldp, *token, *hashMem, *textEnd;
int shaderTextHashTableSizes[MAX_SHADERTEXT_HASH], hash, size;
long sum = 0, summand;
@@ -2945,20 +2948,22 @@ static void ScanAndLoadShaderFiles( void )
// build single large buffer
s_shaderText = ri.Hunk_Alloc( sum + numShaderFiles*2, h_low );
s_shaderText[ 0 ] = '\0';
-
+ textEnd = s_shaderText;
+
// free in reverse order, so the temp files are all dumped
for ( i = numShaderFiles - 1; i >= 0 ; i-- )
{
- if(buffers[i])
- {
- p = &s_shaderText[strlen(s_shaderText)];
- strcat( s_shaderText, buffers[i] );
- ri.FS_FreeFile( buffers[i] );
- COM_Compress(p);
- strcat( s_shaderText, "\n" );
- }
+ if ( !buffers[i] )
+ continue;
+
+ strcat( textEnd, buffers[i] );
+ strcat( textEnd, "\n" );
+ textEnd += strlen( textEnd );
+ ri.FS_FreeFile( buffers[i] );
}
+ COM_Compress( s_shaderText );
+
// free up memory
ri.FS_FreeFileList( shaderFiles );
diff --git a/src/sdl/sdl_glimp.c b/src/sdl/sdl_glimp.c
index cfc10153..f065eb2d 100644
--- a/src/sdl/sdl_glimp.c
+++ b/src/sdl/sdl_glimp.c
@@ -691,6 +691,15 @@ void GLimp_Init( void )
r_allowResize = ri.Cvar_Get( "r_allowResize", "0", CVAR_ARCHIVE );
r_centerWindow = ri.Cvar_Get( "r_centerWindow", "0", CVAR_ARCHIVE );
+ if( Cvar_VariableIntegerValue( "com_abnormalExit" ) )
+ {
+ ri.Cvar_Set( "r_width", va( "%d", R_FAILSAFE_WIDTH ) );
+ ri.Cvar_Set( "r_height", va( "%d", R_FAILSAFE_HEIGHT ) );
+ ri.Cvar_Set( "r_fullscreen", "0" );
+ ri.Cvar_Set( "r_centerWindow", "0" );
+ ri.Cvar_Set( "com_abnormalExit", "0" );
+ }
+
Sys_SetEnv( "SDL_VIDEO_CENTERED", r_centerWindow->integer ? "1" : "" );
Sys_GLimpInit( );
diff --git a/src/sdl/sdl_input.c b/src/sdl/sdl_input.c
index ec96b086..0d1164fb 100644
--- a/src/sdl/sdl_input.c
+++ b/src/sdl/sdl_input.c
@@ -949,7 +949,7 @@ static void IN_ProcessEvents( void )
break;
case SDL_QUIT:
- Sys_Quit( );
+ Cbuf_ExecuteText(EXEC_NOW, "quit Closed window\n");
break;
case SDL_VIDEORESIZE:
@@ -965,6 +965,14 @@ static void IN_ProcessEvents( void )
vidRestartTime = Sys_Milliseconds() + 1000;
}
break;
+ case SDL_ACTIVEEVENT:
+ if (e.active.state & SDL_APPINPUTFOCUS) {
+ Cvar_SetValue( "com_unfocused", !e.active.gain);
+ }
+ if (e.active.state & SDL_APPACTIVE) {
+ Cvar_SetValue( "com_minimized", !e.active.gain);
+ }
+ break;
default:
break;
@@ -1034,6 +1042,8 @@ IN_Init
*/
void IN_Init( void )
{
+ int appState;
+
if( !SDL_WasInit( SDL_INIT_VIDEO ) )
{
Com_Error( ERR_FATAL, "IN_Init called before SDL_Init( SDL_INIT_VIDEO )\n" );
@@ -1071,6 +1081,10 @@ void IN_Init( void )
mouseAvailable = qfalse;
}
+ appState = SDL_GetAppState( );
+ Cvar_SetValue( "com_unfocused", !( appState & SDL_APPINPUTFOCUS ) );
+ Cvar_SetValue( "com_minimized", !( appState & SDL_APPACTIVE ) );
+
IN_InitJoystick( );
Com_DPrintf( "------------------------------------\n" );
}
diff --git a/src/server/sv_client.c b/src/server/sv_client.c
index 1448822c..815bf4db 100644
--- a/src/server/sv_client.c
+++ b/src/server/sv_client.c
@@ -1272,7 +1272,7 @@ void SV_ExecuteClientCommand( client_t *cl, const char *s, qboolean clientOK ) {
if (clientOK) {
// pass unknown strings to the game
- if (!u->name && sv.state == SS_GAME) {
+ if (!u->name && sv.state == SS_GAME && cl->state == CS_ACTIVE) {
VM_Call( gvm, GAME_CLIENT_COMMAND, cl - svs.clients );
}
}
diff --git a/src/server/sv_main.c b/src/server/sv_main.c
index 4363e532..fa009b62 100644
--- a/src/server/sv_main.c
+++ b/src/server/sv_main.c
@@ -701,7 +701,7 @@ static void SVC_RemoteCommand( netadr_t from, msg_t *msg ) {
// Prevent using rcon as an amplifier and make dictionary attacks impractical
if ( SVC_RateLimitAddress( from, 10, 1000 ) ) {
- Com_DPrintf( "SVC_Status: rate limit from %s exceeded, dropping request\n",
+ Com_DPrintf( "SVC_RemoteCommand: rate limit from %s exceeded, dropping request\n",
NET_AdrToString( from ) );
return;
}
@@ -712,7 +712,7 @@ static void SVC_RemoteCommand( netadr_t from, msg_t *msg ) {
// Make DoS via rcon impractical
if ( SVC_RateLimit( &bucket, 10, 1000 ) ) {
- Com_DPrintf( "SVC_Status: rate limit exceeded, dropping request\n" );
+ Com_DPrintf( "SVC_RemoteCommand: rate limit exceeded, dropping request\n" );
return;
}
diff --git a/src/sys/sys_cocoa.m b/src/sys/sys_cocoa.m
deleted file mode 100644
index cfc754dd..00000000
--- a/src/sys/sys_cocoa.m
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#ifndef MACOS_X
-#error This file is for Mac OS X only. You probably should not compile it.
-#endif
-
-// Please note that this file is just some Mac-specific bits. Most of the
-// Mac OS X code is shared with other Unix platforms in sys_unix.c ...
-
-#import <Cocoa/Cocoa.h>
-
-void Cocoa_MsgBox( const char *text )
-{
- NSRunInformationalAlertPanel(@"ioquake3",
- [NSString stringWithUTF8String:text],
- @"OK", nil, nil);
-}
-
-// end of sys_cocoa.m ...
-
diff --git a/src/sys/sys_local.h b/src/sys/sys_local.h
index 6017150a..9f4de9cf 100644
--- a/src/sys/sys_local.h
+++ b/src/sys/sys_local.h
@@ -55,3 +55,6 @@ void Sys_PlatformInit( void );
void Sys_SigHandler( int signal );
void Sys_ErrorDialog( const char *error );
void Sys_AnsiColorPrint( const char *msg );
+
+int Sys_PID( void );
+qboolean Sys_PIDIsRunning( int pid );
diff --git a/src/sys/sys_main.c b/src/sys/sys_main.c
index 460e8a22..53fc57fb 100644
--- a/src/sys/sys_main.c
+++ b/src/sys/sys_main.c
@@ -128,6 +128,65 @@ char *Sys_ConsoleInput(void)
return CON_Input( );
}
+#ifdef DEDICATED
+# define PID_FILENAME PRODUCT_NAME "_server.pid"
+#else
+# define PID_FILENAME PRODUCT_NAME ".pid"
+#endif
+
+/*
+=================
+Sys_PIDFileName
+=================
+*/
+static char *Sys_PIDFileName( void )
+{
+ return va( "%s/%s", Sys_TempPath( ), PID_FILENAME );
+}
+
+/*
+=================
+Sys_WritePIDFile
+
+Return qtrue if there is an existing stale PID file
+=================
+*/
+qboolean Sys_WritePIDFile( void )
+{
+ char *pidFile = Sys_PIDFileName( );
+ FILE *f;
+ qboolean stale = qfalse;
+
+ // First, check if the pid file is already there
+ if( ( f = fopen( pidFile, "r" ) ) != NULL )
+ {
+ char pidBuffer[ 64 ] = { 0 };
+ int pid;
+
+ pid = fread( pidBuffer, sizeof( char ), sizeof( pidBuffer ) - 1, f );
+ fclose( f );
+
+ if(pid > 0)
+ {
+ pid = atoi( pidBuffer );
+ if( !Sys_PIDIsRunning( pid ) )
+ stale = qtrue;
+ }
+ else
+ stale = qtrue;
+ }
+
+ if( ( f = fopen( pidFile, "w" ) ) != NULL )
+ {
+ fprintf( f, "%d", Sys_PID( ) );
+ fclose( f );
+ }
+ else
+ Com_Printf( S_COLOR_YELLOW "Couldn't write %s.\n", pidFile );
+
+ return stale;
+}
+
/*
=================
Sys_Exit
@@ -135,7 +194,7 @@ Sys_Exit
Single exit point (regular exit or in case of error)
=================
*/
-void Sys_Exit( int ex )
+static void Sys_Exit( int exitCode )
{
CON_Shutdown( );
@@ -143,13 +202,13 @@ void Sys_Exit( int ex )
SDL_Quit( );
#endif
-#ifdef NDEBUG
- exit( ex );
-#else
- // Cause a backtrace on error exits
- assert( ex == 0 );
- exit( ex );
-#endif
+ if( exitCode < 2 )
+ {
+ // Normal exit
+ remove( Sys_PIDFileName( ) );
+ }
+
+ exit( exitCode );
}
/*
@@ -159,7 +218,6 @@ Sys_Quit
*/
void Sys_Quit( void )
{
- CL_Shutdown( );
Sys_Exit( 0 );
}
@@ -288,15 +346,14 @@ void Sys_Error( const char *error, ... )
va_list argptr;
char string[1024];
- CL_Shutdown ();
-
va_start (argptr,error);
Q_vsnprintf (string, sizeof(string), error, argptr);
va_end (argptr);
+ CL_Shutdown( string );
Sys_ErrorDialog( string );
- Sys_Exit( 1 );
+ Sys_Exit( 3 );
}
/*
@@ -451,7 +508,7 @@ void Sys_ParseArgs( int argc, char **argv )
#else
fprintf( stdout, Q3_VERSION " client (%s)\n", date );
#endif
- Sys_Exit(0);
+ Sys_Exit( 0 );
}
}
}
@@ -481,14 +538,16 @@ void Sys_SigHandler( int signal )
else
{
signalcaught = qtrue;
- fprintf( stderr, "Received signal %d, exiting...\n", signal );
#ifndef DEDICATED
- CL_Shutdown();
+ CL_Shutdown( va( "Received signal %d", signal ) );
#endif
- SV_Shutdown( "Signal caught" );
+ SV_Shutdown( va( "Received signal %d", signal ) );
}
- Sys_Exit( 0 ); // Exit with 0 to avoid recursive signals
+ if( signal == SIGTERM || signal == SIGINT )
+ Sys_Exit( 1 );
+ else
+ Sys_Exit( 2 );
}
/*
@@ -520,7 +579,10 @@ int main( int argc, char **argv )
if( SDL_VERSIONNUM( ver->major, ver->minor, ver->patch ) <
SDL_VERSIONNUM( MINSDL_MAJOR, MINSDL_MINOR, MINSDL_PATCH ) )
{
- Sys_Print( "SDL version " MINSDL_VERSION " or greater required\n" );
+ Sys_Dialog( DT_ERROR, va( "SDL version " MINSDL_VERSION " or greater is required, "
+ "but only version %d.%d.%d was found. You may be able to obtain a more recent copy "
+ "from http://www.libsdl.org/.", ver->major, ver->minor, ver->patch ), "SDL Library Too Old" );
+
Sys_Exit( 1 );
}
#endif
@@ -562,13 +624,6 @@ int main( int argc, char **argv )
while( 1 )
{
-#ifndef DEDICATED
- int appState = SDL_GetAppState( );
-
- Cvar_SetValue( "com_unfocused", !( appState & SDL_APPINPUTFOCUS ) );
- Cvar_SetValue( "com_minimized", !( appState & SDL_APPACTIVE ) );
-#endif
-
IN_Frame( );
Com_Frame( );
}
diff --git a/src/sys/sys_unix.c b/src/sys/sys_unix.c
index ccff6312..5ab0f8c7 100644
--- a/src/sys/sys_unix.c
+++ b/src/sys/sys_unix.c
@@ -69,6 +69,23 @@ char *Sys_DefaultHomePath(void)
return homePath;
}
+#ifndef MACOS_X
+/*
+================
+Sys_TempPath
+================
+*/
+const char *Sys_TempPath( void )
+{
+ const char *TMPDIR = getenv( "TMPDIR" );
+
+ if( TMPDIR == NULL || TMPDIR[ 0 ] == '\0' )
+ return "/tmp";
+ else
+ return TMPDIR;
+}
+#endif
+
/*
================
Sys_Milliseconds
@@ -76,8 +93,7 @@ Sys_Milliseconds
*/
/* base time in seconds, that's our origin
timeval:tv_sec is an int:
- assuming this wraps every 0x7fffffff - ~68 years since the Epoch (1970) - we're safe till 2038
- using unsigned long data type to work right with Sys_XTimeToSysTime */
+ assuming this wraps every 0x7fffffff - ~68 years since the Epoch (1970) - we're safe till 2038 */
unsigned long sys_timeBase = 0;
/* current time in ms, using sys_timeBase as origin
NOTE: sys_timeBase*1000 + curtime -> ms since the Epoch
@@ -429,35 +445,6 @@ void Sys_FreeFileList( char **list )
Z_Free( list );
}
-#ifdef MACOS_X
-/*
-=================
-Sys_StripAppBundle
-
-Discovers if passed dir is suffixed with the directory structure of a Mac OS X
-.app bundle. If it is, the .app directory structure is stripped off the end and
-the result is returned. If not, dir is returned untouched.
-=================
-*/
-char *Sys_StripAppBundle( char *dir )
-{
- static char cwd[MAX_OSPATH];
-
- Q_strncpyz(cwd, dir, sizeof(cwd));
- if(strcmp(Sys_Basename(cwd), "MacOS"))
- return dir;
- Q_strncpyz(cwd, Sys_Dirname(cwd), sizeof(cwd));
- if(strcmp(Sys_Basename(cwd), "Contents"))
- return dir;
- Q_strncpyz(cwd, Sys_Dirname(cwd), sizeof(cwd));
- if(!strstr(Sys_Basename(cwd), ".app"))
- return dir;
- Q_strncpyz(cwd, Sys_Dirname(cwd), sizeof(cwd));
- return cwd;
-}
-#endif // MACOS_X
-
-
/*
==================
Sys_Sleep
@@ -518,39 +505,195 @@ void Sys_ErrorDialog( const char *error )
Sys_Print( va( "%s\n", error ) );
-#if defined(MACOS_X) && !DEDICATED
- /* This function has to be in a separate file, compiled as Objective-C. */
- extern void Cocoa_MsgBox( const char *text );
- if (!com_dedicated || !com_dedicated->integer)
- Cocoa_MsgBox(error);
+#ifndef DEDICATED
+ Sys_Dialog( DT_ERROR, va( "%s. See \"%s\" for details.", error, ospath ), "Error" );
#endif
- /* make sure the write path for the crashlog exists... */
+ // Make sure the write path for the crashlog exists...
if( FS_CreatePath( ospath ) ) {
Com_Printf( "ERROR: couldn't create path '%s' for crash log.\n", ospath );
return;
}
- /* we might be crashing because we maxed out the Quake MAX_FILE_HANDLES,
- which will come through here, so we don't want to recurse forever by
- calling FS_FOpenFileWrite()...use the Unix system APIs instead. */
- f = open(ospath, O_CREAT | O_TRUNC | O_WRONLY, 0640);
+ // We might be crashing because we maxed out the Quake MAX_FILE_HANDLES,
+ // which will come through here, so we don't want to recurse forever by
+ // calling FS_FOpenFileWrite()...use the Unix system APIs instead.
+ f = open( ospath, O_CREAT | O_TRUNC | O_WRONLY, 0640 );
if( f == -1 )
{
Com_Printf( "ERROR: couldn't open %s\n", fileName );
return;
}
- /* We're crashing, so we don't care much if write() or close() fails. */
+ // We're crashing, so we don't care much if write() or close() fails.
while( ( size = CON_LogRead( buffer, sizeof( buffer ) ) ) > 0 ) {
- if (write( f, buffer, size ) != size) {
+ if( write( f, buffer, size ) != size ) {
Com_Printf( "ERROR: couldn't fully write to %s\n", fileName );
break;
}
}
- close(f);
+ close( f );
+}
+
+#ifndef MACOS_X
+/*
+==============
+Sys_ZenityCommand
+==============
+*/
+static int Sys_ZenityCommand( dialogType_t type, const char *message, const char *title )
+{
+ const char *options = "";
+ char command[ 1024 ];
+
+ switch( type )
+ {
+ default:
+ case DT_INFO: options = "--info"; break;
+ case DT_WARNING: options = "--warning"; break;
+ case DT_ERROR: options = "--error"; break;
+ case DT_YES_NO: options = "--question --ok-label=\"Yes\" --cancel-label=\"No\""; break;
+ case DT_OK_CANCEL: options = "--question --ok-label=\"OK\" --cancel-label=\"Cancel\""; break;
+ }
+
+ Com_sprintf( command, sizeof( command ), "zenity %s --text=\"%s\" --title=\"%s\"",
+ options, message, title );
+
+ return system( command );
+}
+
+/*
+==============
+Sys_KdialogCommand
+==============
+*/
+static int Sys_KdialogCommand( dialogType_t type, const char *message, const char *title )
+{
+ const char *options = "";
+ char command[ 1024 ];
+
+ switch( type )
+ {
+ default:
+ case DT_INFO: options = "--msgbox"; break;
+ case DT_WARNING: options = "--sorry"; break;
+ case DT_ERROR: options = "--error"; break;
+ case DT_YES_NO: options = "--warningyesno"; break;
+ case DT_OK_CANCEL: options = "--warningcontinuecancel"; break;
+ }
+
+ Com_sprintf( command, sizeof( command ), "kdialog %s \"%s\" --title \"%s\"",
+ options, message, title );
+
+ return system( command );
+}
+
+/*
+==============
+Sys_XmessageCommand
+==============
+*/
+static int Sys_XmessageCommand( dialogType_t type, const char *message, const char *title )
+{
+ const char *options = "";
+ char command[ 1024 ];
+
+ switch( type )
+ {
+ default: options = "-buttons OK"; break;
+ case DT_YES_NO: options = "-buttons Yes:0,No:1"; break;
+ case DT_OK_CANCEL: options = "-buttons OK:0,Cancel:1"; break;
+ }
+
+ Com_sprintf( command, sizeof( command ), "xmessage -center %s \"%s\"",
+ options, message );
+
+ return system( command );
+}
+
+/*
+==============
+Sys_Dialog
+
+Display a *nix dialog box
+==============
+*/
+dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *title )
+{
+ typedef enum
+ {
+ NONE = 0,
+ ZENITY,
+ KDIALOG,
+ XMESSAGE,
+ NUM_DIALOG_PROGRAMS
+ } dialogCommandType_t;
+ typedef int (*dialogCommandBuilder_t)( dialogType_t, const char *, const char * );
+
+ const char *session = getenv( "DESKTOP_SESSION" );
+ qboolean tried[ NUM_DIALOG_PROGRAMS ] = { qfalse };
+ dialogCommandBuilder_t commands[ NUM_DIALOG_PROGRAMS ] = { NULL };
+ dialogCommandType_t preferredCommandType = NONE;
+
+ commands[ ZENITY ] = &Sys_ZenityCommand;
+ commands[ KDIALOG ] = &Sys_KdialogCommand;
+ commands[ XMESSAGE ] = &Sys_XmessageCommand;
+
+ // This may not be the best way
+ if( !Q_stricmp( session, "gnome" ) )
+ preferredCommandType = ZENITY;
+ else if( !Q_stricmp( session, "kde" ) )
+ preferredCommandType = KDIALOG;
+
+ while( 1 )
+ {
+ int i;
+ int exitCode;
+
+ for( i = NONE + 1; i < NUM_DIALOG_PROGRAMS; i++ )
+ {
+ if( preferredCommandType != NONE && preferredCommandType != i )
+ continue;
+
+ if( !tried[ i ] )
+ {
+ exitCode = commands[ i ]( type, message, title );
+
+ if( exitCode >= 0 )
+ {
+ switch( type )
+ {
+ case DT_YES_NO: return exitCode ? DR_NO : DR_YES;
+ case DT_OK_CANCEL: return exitCode ? DR_CANCEL : DR_OK;
+ default: return DR_OK;
+ }
+ }
+
+ tried[ i ] = qtrue;
+
+ // The preference failed, so start again in order
+ if( preferredCommandType != NONE )
+ {
+ preferredCommandType = NONE;
+ break;
+ }
+ }
+ }
+
+ for( i = NONE + 1; i < NUM_DIALOG_PROGRAMS; i++ )
+ {
+ if( !tried[ i ] )
+ continue;
+ }
+
+ break;
+ }
+
+ Com_DPrintf( S_COLOR_YELLOW "WARNING: failed to show a dialog\n" );
+ return DR_OK;
}
+#endif
/*
==============
@@ -612,3 +755,23 @@ void Sys_SetEnv(const char *name, const char *value)
else
unsetenv(name);
}
+
+/*
+==============
+Sys_PID
+==============
+*/
+int Sys_PID( void )
+{
+ return getpid( );
+}
+
+/*
+==============
+Sys_PIDIsRunning
+==============
+*/
+qboolean Sys_PIDIsRunning( int pid )
+{
+ return kill( pid, 0 ) == 0;
+}
diff --git a/src/sys/sys_win32.c b/src/sys/sys_win32.c
index ead428eb..ad6f18eb 100644
--- a/src/sys/sys_win32.c
+++ b/src/sys/sys_win32.c
@@ -38,10 +38,20 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <conio.h>
#include <wincrypt.h>
#include <shlobj.h>
+#include <psapi.h>
// Used to determine where to store user-specific files
static char homePath[ MAX_OSPATH ] = { 0 };
+#ifdef __WIN64__
+void Sys_SnapVector( float *v )
+{
+ v[0] = rint(v[0]);
+ v[1] = rint(v[1]);
+ v[2] = rint(v[2]);
+}
+#endif
+
/*
================
Sys_DefaultHomePath
@@ -86,6 +96,24 @@ char *Sys_DefaultHomePath( void )
/*
================
+Sys_TempPath
+================
+*/
+const char *Sys_TempPath( void )
+{
+ static TCHAR path[ MAX_PATH ];
+ DWORD length;
+
+ length = GetTempPath( sizeof( path ), path );
+
+ if( length > sizeof( path ) || length == 0 )
+ return Sys_DefaultHomePath( );
+ else
+ return path;
+}
+
+/*
+================
Sys_Milliseconds
================
*/
@@ -317,7 +345,7 @@ void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, ch
{
char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
char filename[MAX_OSPATH];
- int findhandle;
+ intptr_t findhandle;
struct _finddata_t findinfo;
if ( *numfiles >= MAX_FOUND_FILES - 1 ) {
@@ -400,7 +428,7 @@ char **Sys_ListFiles( const char *directory, const char *extension, char *filter
char **listCopy;
char *list[MAX_FOUND_FILES];
struct _finddata_t findinfo;
- int findhandle;
+ intptr_t findhandle;
int flag;
int i;
@@ -545,8 +573,8 @@ Display an error message
*/
void Sys_ErrorDialog( const char *error )
{
- if( MessageBox( NULL, va( "%s. Copy console log to clipboard?", error ),
- NULL, MB_YESNO|MB_ICONERROR ) == IDYES )
+ if( Sys_Dialog( DT_YES_NO, va( "%s. Copy console log to clipboard?", error ),
+ "Error" ) == DR_YES )
{
HGLOBAL memoryHandle;
char *clipMemory;
@@ -577,6 +605,37 @@ void Sys_ErrorDialog( const char *error )
}
}
+/*
+==============
+Sys_Dialog
+
+Display a win32 dialog box
+==============
+*/
+dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *title )
+{
+ UINT uType;
+
+ switch( type )
+ {
+ default:
+ case DT_INFO: uType = MB_ICONINFORMATION|MB_OK; break;
+ case DT_WARNING: uType = MB_ICONWARNING|MB_OK; break;
+ case DT_ERROR: uType = MB_ICONERROR|MB_OK; break;
+ case DT_YES_NO: uType = MB_ICONQUESTION|MB_YESNO; break;
+ case DT_OK_CANCEL: uType = MB_ICONWARNING|MB_OKCANCEL; break;
+ }
+
+ switch( MessageBox( NULL, message, title, uType ) )
+ {
+ default:
+ case IDOK: return DR_OK;
+ case IDCANCEL: return DR_CANCEL;
+ case IDYES: return DR_YES;
+ case IDNO: return DR_NO;
+ }
+}
+
#ifndef DEDICATED
static qboolean SDL_VIDEODRIVER_externallySet = qfalse;
#endif
@@ -660,8 +719,43 @@ Sys_SetEnv
set/unset environment variables (empty value removes it)
==============
*/
-
void Sys_SetEnv(const char *name, const char *value)
{
_putenv(va("%s=%s", name, value));
}
+
+/*
+==============
+Sys_PID
+==============
+*/
+int Sys_PID( void )
+{
+ return GetCurrentProcessId( );
+}
+
+/*
+==============
+Sys_PIDIsRunning
+==============
+*/
+qboolean Sys_PIDIsRunning( int pid )
+{
+ DWORD processes[ 1024 ];
+ DWORD numBytes, numProcesses;
+ int i;
+
+ if( !EnumProcesses( processes, sizeof( processes ), &numBytes ) )
+ return qfalse; // Assume it's not running
+
+ numProcesses = numBytes / sizeof( DWORD );
+
+ // Search for the pid
+ for( i = 0; i < numProcesses; i++ )
+ {
+ if( processes[ i ] == pid )
+ return qtrue;
+ }
+
+ return qfalse;
+}
diff --git a/src/tools/asm/cmdlib.c b/src/tools/asm/cmdlib.c
index 95fbb8c1..bf503464 100644
--- a/src/tools/asm/cmdlib.c
+++ b/src/tools/asm/cmdlib.c
@@ -64,7 +64,7 @@ char *ex_argv[MAX_EX_ARGC];
void ExpandWildcards( int *argc, char ***argv )
{
struct _finddata_t fileinfo;
- int handle;
+ intptr_t handle;
int i;
char filename[1024];
char filebase[1024];