summaryrefslogtreecommitdiff
path: root/src/qcommon
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2009-10-03 11:58:50 +0000
committerTim Angus <tim@ngus.net>2013-01-03 00:15:34 +0000
commitac3e5586cd56657ff1b6f5f64af7e1d7c76b410d (patch)
treeb245f2cbd4e7491b948aea5c7c080be61307c950 /src/qcommon
parentdc3819f1e99d8159bdb0ea1da26506b00fe78e62 (diff)
* Merge ioq3-r1458
Diffstat (limited to 'src/qcommon')
-rw-r--r--src/qcommon/common.c26
-rw-r--r--src/qcommon/files.c21
-rw-r--r--src/qcommon/msg.c2
-rw-r--r--src/qcommon/net_ip.c93
-rw-r--r--src/qcommon/qcommon.h3
-rw-r--r--src/qcommon/unzip.c3
-rw-r--r--src/qcommon/vm_interpreted.c16
-rw-r--r--src/qcommon/vm_x86.c172
-rw-r--r--src/qcommon/vm_x86_64.c2
9 files changed, 172 insertions, 166 deletions
diff --git a/src/qcommon/common.c b/src/qcommon/common.c
index 586c334c..f16234c2 100644
--- a/src/qcommon/common.c
+++ b/src/qcommon/common.c
@@ -81,7 +81,9 @@ cvar_t *sv_packetdelay;
cvar_t *com_cameraMode;
cvar_t *com_ansiColor;
cvar_t *com_unfocused;
+cvar_t *com_maxfpsUnfocused;
cvar_t *com_minimized;
+cvar_t *com_maxfpsMinimized;
// com_speeds times
int time_game;
@@ -2481,7 +2483,9 @@ void Com_Init( char *commandLine ) {
com_ansiColor = Cvar_Get( "com_ansiColor", "0", CVAR_ARCHIVE );
com_unfocused = Cvar_Get( "com_unfocused", "0", CVAR_ROM );
+ 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 );
if ( com_developer && com_developer->integer ) {
Cmd_AddCommand ("error", Com_Error_f);
@@ -2696,12 +2700,30 @@ void Com_Frame( void ) {
}
// we may want to spin here if things are going too fast
- if ( !com_dedicated->integer && com_maxfps->integer > 0 && !com_timedemo->integer ) {
- minMsec = 1000 / com_maxfps->integer;
+ if ( !com_dedicated->integer && !com_timedemo->integer ) {
+ if( com_minimized->integer && com_maxfpsMinimized->integer > 0 ) {
+ minMsec = 1000 / com_maxfpsMinimized->integer;
+ } else if( com_unfocused->integer && com_maxfpsUnfocused->integer > 0 ) {
+ minMsec = 1000 / com_maxfpsUnfocused->integer;
+ } else if( com_maxfps->integer > 0 ) {
+ minMsec = 1000 / com_maxfps->integer;
+ } else {
+ minMsec = 1;
+ }
} else {
minMsec = 1;
}
+
+ msec = minMsec;
do {
+ int timeRemaining = minMsec - msec;
+
+ // The existing Sys_Sleep implementations aren't really
+ // precise enough to be of use beyond 100fps
+ // FIXME: implement a more precise sleep (RDTSC or something)
+ if( timeRemaining >= 10 )
+ Sys_Sleep( timeRemaining );
+
com_frameTime = Com_EventLoop();
if ( lastTime > com_frameTime ) {
lastTime = com_frameTime; // possible on first frame
diff --git a/src/qcommon/files.c b/src/qcommon/files.c
index 53385244..6b407c20 100644
--- a/src/qcommon/files.c
+++ b/src/qcommon/files.c
@@ -299,6 +299,11 @@ char lastValidGame[MAX_OSPATH];
FILE* missingFiles = NULL;
#endif
+/* C99 defines __func__ */
+#ifndef __func__
+#define __func__ "(unknown)"
+#endif
+
/*
==============
FS_Initialized
@@ -527,7 +532,7 @@ static void FS_CopyFile( char *fromOSPath, char *toOSPath ) {
Com_Printf( "copy %s to %s\n", fromOSPath, toOSPath );
- FS_FilenameIsExecutable( toOSPath, __FUNCTION__ );
+ FS_FilenameIsExecutable( toOSPath, __func__ );
if (strstr(fromOSPath, "journal.dat") || strstr(fromOSPath, "journaldata.dat")) {
Com_Printf( "Ignoring journal files\n");
@@ -570,7 +575,7 @@ FS_Remove
===========
*/
void FS_Remove( const char *osPath ) {
- FS_FilenameIsExecutable( osPath, __FUNCTION__ );
+ FS_FilenameIsExecutable( osPath, __func__ );
remove( osPath );
}
@@ -582,7 +587,7 @@ FS_HomeRemove
===========
*/
void FS_HomeRemove( const char *homePath ) {
- FS_FilenameIsExecutable( homePath, __FUNCTION__ );
+ FS_FilenameIsExecutable( homePath, __func__ );
remove( FS_BuildOSPath( fs_homepath->string,
fs_gamedir, homePath ) );
@@ -661,7 +666,7 @@ fileHandle_t FS_SV_FOpenFileWrite( const char *filename ) {
Com_Printf( "FS_SV_FOpenFileWrite: %s\n", ospath );
}
- FS_FilenameIsExecutable( ospath, __FUNCTION__ );
+ FS_FilenameIsExecutable( ospath, __func__ );
if( FS_CreatePath( ospath ) ) {
return 0;
@@ -772,7 +777,7 @@ void FS_SV_Rename( const char *from, const char *to ) {
Com_Printf( "FS_SV_Rename: %s --> %s\n", from_ospath, to_ospath );
}
- FS_FilenameIsExecutable( to_ospath, __FUNCTION__ );
+ FS_FilenameIsExecutable( to_ospath, __func__ );
if (rename( from_ospath, to_ospath )) {
// Failed, try copying it and deleting the original
@@ -806,7 +811,7 @@ void FS_Rename( const char *from, const char *to ) {
Com_Printf( "FS_Rename: %s --> %s\n", from_ospath, to_ospath );
}
- FS_FilenameIsExecutable( to_ospath, __FUNCTION__ );
+ FS_FilenameIsExecutable( to_ospath, __func__ );
if (rename( from_ospath, to_ospath )) {
// Failed, try copying it and deleting the original
@@ -869,7 +874,7 @@ fileHandle_t FS_FOpenFileWrite( const char *filename ) {
Com_Printf( "FS_FOpenFileWrite: %s\n", ospath );
}
- FS_FilenameIsExecutable( ospath, __FUNCTION__ );
+ FS_FilenameIsExecutable( ospath, __func__ );
if( FS_CreatePath( ospath ) ) {
return 0;
@@ -917,7 +922,7 @@ fileHandle_t FS_FOpenFileAppend( const char *filename ) {
Com_Printf( "FS_FOpenFileAppend: %s\n", ospath );
}
- FS_FilenameIsExecutable( ospath, __FUNCTION__ );
+ FS_FilenameIsExecutable( ospath, __func__ );
if( FS_CreatePath( ospath ) ) {
return 0;
diff --git a/src/qcommon/msg.c b/src/qcommon/msg.c
index d98b6a78..37c61c31 100644
--- a/src/qcommon/msg.c
+++ b/src/qcommon/msg.c
@@ -994,8 +994,6 @@ If the delta removes the entity, entityState_t->number will be set to MAX_GENTIT
Can go from either a baseline or a previous packet_entity
==================
*/
-extern cvar_t *cl_shownet;
-
void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to,
int number) {
int i, lc;
diff --git a/src/qcommon/net_ip.c b/src/qcommon/net_ip.c
index 9ecd5e9e..baf70a17 100644
--- a/src/qcommon/net_ip.c
+++ b/src/qcommon/net_ip.c
@@ -24,61 +24,68 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/qcommon.h"
#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#if WINVER < 0x501
-#include <wspiapi.h>
-#else
-#include <ws2spi.h>
-#endif
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# if WINVER < 0x501
+# ifdef __MINGW32__
+ // wspiapi.h isn't available on MinGW, so if it's
+ // present it's because the end user has added it
+ // and we should look for it in our tree
+# include "wspiapi.h"
+# else
+# include <wspiapi.h>
+# endif
+# else
+# include <ws2spi.h>
+# endif
typedef int socklen_t;
-#ifdef ADDRESS_FAMILY
-#define sa_family_t ADDRESS_FAMILY
-#else
+# ifdef ADDRESS_FAMILY
+# define sa_family_t ADDRESS_FAMILY
+# else
typedef unsigned short sa_family_t;
-#endif
+# endif
-#define EAGAIN WSAEWOULDBLOCK
-#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
-#define EAFNOSUPPORT WSAEAFNOSUPPORT
-#define ECONNRESET WSAECONNRESET
-#define socketError WSAGetLastError( )
+# define EAGAIN WSAEWOULDBLOCK
+# define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+# define EAFNOSUPPORT WSAEAFNOSUPPORT
+# define ECONNRESET WSAECONNRESET
+# define socketError WSAGetLastError( )
static WSADATA winsockdata;
static qboolean winsockInitialized = qfalse;
#else
-#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- // needed for socklen_t on OSX 10.2
-# define _BSD_SOCKLEN_T_
-#endif
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#if !defined(__sun) && !defined(__sgi)
-#include <ifaddrs.h>
-#endif
-
-#ifdef __sun
-#include <sys/filio.h>
-#endif
+# if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ // needed for socklen_t on OSX 10.2
+# define _BSD_SOCKLEN_T_
+# endif
+
+# include <arpa/inet.h>
+# include <errno.h>
+# include <netdb.h>
+# include <netinet/in.h>
+# include <sys/socket.h>
+# include <net/if.h>
+# include <sys/ioctl.h>
+# include <sys/types.h>
+# include <sys/time.h>
+# include <unistd.h>
+# if !defined(__sun) && !defined(__sgi)
+# include <ifaddrs.h>
+# endif
+
+# ifdef __sun
+# include <sys/filio.h>
+# endif
typedef int SOCKET;
-#define INVALID_SOCKET -1
-#define SOCKET_ERROR -1
-#define closesocket close
-#define ioctlsocket ioctl
-#define socketError errno
+# define INVALID_SOCKET -1
+# define SOCKET_ERROR -1
+# define closesocket close
+# define ioctlsocket ioctl
+# define socketError errno
#endif
diff --git a/src/qcommon/qcommon.h b/src/qcommon/qcommon.h
index 62012914..d6f7ea03 100644
--- a/src/qcommon/qcommon.h
+++ b/src/qcommon/qcommon.h
@@ -588,7 +588,6 @@ fileHandle_t FS_FOpenFileWrite( const char *qpath );
fileHandle_t FS_FOpenFileAppend( const char *filename );
// will properly create any needed paths and deal with seperater character issues
-int FS_filelength( fileHandle_t f );
fileHandle_t FS_SV_FOpenFileWrite( const char *filename );
int FS_SV_FOpenFileRead( const char *filename, fileHandle_t *fp );
void FS_SV_Rename( const char *from, const char *to );
@@ -790,7 +789,9 @@ extern cvar_t *com_journal;
extern cvar_t *com_cameraMode;
extern cvar_t *com_ansiColor;
extern cvar_t *com_unfocused;
+extern cvar_t *com_maxfpsUnfocused;
extern cvar_t *com_minimized;
+extern cvar_t *com_maxfpsMinimized;
extern cvar_t *com_altivec;
// both client and server must agree to pause
diff --git a/src/qcommon/unzip.c b/src/qcommon/unzip.c
index 7daf271b..90f5354d 100644
--- a/src/qcommon/unzip.c
+++ b/src/qcommon/unzip.c
@@ -7,7 +7,8 @@
*
*****************************************************************************/
-#include "../client/client.h"
+#include "../qcommon/q_shared.h"
+#include "../qcommon/qcommon.h"
#include "unzip.h"
/* unzip.h -- IO for uncompress .zip files using zlib
diff --git a/src/qcommon/vm_interpreted.c b/src/qcommon/vm_interpreted.c
index f9071669..eb14e94b 100644
--- a/src/qcommon/vm_interpreted.c
+++ b/src/qcommon/vm_interpreted.c
@@ -481,7 +481,7 @@ nextInstruction2:
case OP_BLOCK_COPY:
{
int *src, *dest;
- int i, count, srci, desti;
+ int count, srci, desti;
count = r2;
// MrE: copy range check
@@ -490,16 +490,10 @@ nextInstruction2:
count = ((srci + count) & dataMask) - srci;
count = ((desti + count) & dataMask) - desti;
- src = (int *)&image[ r0&dataMask ];
- dest = (int *)&image[ r1&dataMask ];
- if ( ( (intptr_t)src | (intptr_t)dest | count ) & 3 ) {
- // happens in westernq3
- Com_Printf( S_COLOR_YELLOW "Warning: OP_BLOCK_COPY not dword aligned\n");
- }
- count >>= 2;
- for ( i = count-1 ; i>= 0 ; i-- ) {
- dest[i] = src[i];
- }
+ src = (int *)&image[ srci ];
+ dest = (int *)&image[ desti ];
+
+ memcpy(dest, src, count);
programCounter += 4;
opStack -= 2;
}
diff --git a/src/qcommon/vm_x86.c b/src/qcommon/vm_x86.c
index 5eb49b0b..64af7d11 100644
--- a/src/qcommon/vm_x86.c
+++ b/src/qcommon/vm_x86.c
@@ -54,7 +54,6 @@ static void VM_Destroy_Compiled(vm_t* self);
*/
-// TTimo: initialised the statics, this fixes a crash when entering a compiled VM
static byte *buf = NULL;
static byte *jused = NULL;
static int compiledOfs = 0;
@@ -72,9 +71,6 @@ int _ftol( float );
static int ftolPtr = (int)_ftol;
#endif
-void AsmCall( void );
-static int asmCallPtr = (int)AsmCall;
-
#else // _MSC_VER
#if defined( FTOL_PTR )
@@ -89,10 +85,11 @@ int qftol0F7F( void );
static int ftolPtr = (int)qftol0F7F;
#endif // FTOL_PTR
-void doAsmCall( void );
-static int asmCallPtr = (int)doAsmCall;
#endif
+void AsmCall(void);
+static void (*const asmCallPtr)(void) = AsmCall;
+
static int callMask = 0;
@@ -125,7 +122,7 @@ vm_t* savedVM;
__asm {
mov eax, dword ptr [edi]
sub edi, 4
- or eax,eax
+ test eax,eax
jl systemCall
// calling another vm function
shl eax,2
@@ -138,8 +135,7 @@ systemCall:
// convert negative num to system call number
// and store right before the first arg
- neg eax
- dec eax
+ not eax
push ebp
mov ebp, esp
@@ -181,68 +177,58 @@ _asm {
#else //!_MSC_VER
#if defined(__MINGW32__) || defined(MACOS_X) // _ is prepended to compiled symbols
-#define CMANG(sym) "_"#sym
+# define CMANG(sym) "_"#sym
#else
-#define CMANG(sym) #sym
+# define CMANG(sym) #sym
#endif
-static int callProgramStack;
-static int *callOpStack;
-static int callSyscallNum;
-
-void callAsmCall(void)
+static void __attribute__((cdecl, used)) CallAsmCall(int const syscallNum,
+ int const programStack, int* const opStack)
{
- vm_t *savedVM;
- int *callOpStack2;
-
- savedVM = currentVM;
- callOpStack2 = callOpStack;
+ vm_t *const vm = currentVM;
+ intptr_t *const data = (intptr_t*)(vm->dataBase + programStack + 4);
// save the stack to allow recursive VM entry
- currentVM->programStack = callProgramStack - 4;
- *(int *)((byte *)currentVM->dataBase + callProgramStack + 4) = callSyscallNum;
- //VM_LogSyscalls((int *)((byte *)currentVM->dataBase + callProgramStack + 4) );
- *(callOpStack2+1) = currentVM->systemCall( (intptr_t *)((byte *)currentVM->dataBase + callProgramStack + 4) );
+ vm->programStack = programStack - 4;
+ *data = syscallNum;
+ opStack[1] = vm->systemCall(data);
- currentVM = savedVM;
+ currentVM = vm;
}
-// Note the C space function AsmCall is never actually called, and is in fact
-// arbitrarily named (though this is not true for the MSC version). When a vm
-// makes a system call, control jumps straight to the doAsmCall label.
-void AsmCall( void ) {
- __asm__( CMANG(doAsmCall) ": \n\t" \
- " movl (%%edi),%%eax \n\t" \
- " subl $4,%%edi \n\t" \
- " orl %%eax,%%eax \n\t" \
- " jl systemCall \n\t" \
- " shll $2,%%eax \n\t" \
- " addl %3,%%eax \n\t" \
- " call *(%%eax) \n\t" \
- " movl (%%edi),%%eax \n\t" \
- " andl " CMANG(callMask) ", %%eax \n\t" \
- " jmp doret \n\t" \
- "systemCall: \n\t" \
- " negl %%eax \n\t" \
- " decl %%eax \n\t" \
- " movl %%eax,%0 \n\t" \
- " movl %%esi,%1 \n\t" \
- " movl %%edi,%2 \n\t" \
- " pushl %%ecx \n\t" \
- " pushl %%esi \n\t" \
- " pushl %%edi \n\t" \
- " call " CMANG(callAsmCall) " \n\t" \
- " popl %%edi \n\t" \
- " popl %%esi \n\t" \
- " popl %%ecx \n\t" \
- " addl $4,%%edi \n\t" \
- "doret: \n\t" \
- " ret \n\t" \
- : "=rm" (callSyscallNum), "=rm" (callProgramStack), "=rm" (callOpStack) \
- : "m" (instructionPointers) \
- : "ax", "di", "si", "cx" \
- );
-}
+__asm__(
+ ".text\n\t"
+ ".p2align 4,,15\n\t"
+#if defined __ELF__
+ ".type " CMANG(AsmCall) ", @function\n"
+#endif
+ CMANG(AsmCall) ":\n\t"
+ "movl (%edi), %eax\n\t"
+ "subl $4, %edi\n\t"
+ "testl %eax, %eax\n\t"
+ "jl 0f\n\t"
+ "shll $2, %eax\n\t"
+ "addl " CMANG(instructionPointers) ", %eax\n\t"
+ "call *(%eax)\n\t"
+ "movl (%edi), %eax\n\t"
+ "andl " CMANG(callMask) ", %eax\n\t"
+ "ret\n"
+ "0:\n\t" // system call
+ "notl %eax\n\t"
+ "pushl %ecx\n\t"
+ "pushl %edi\n\t" // opStack
+ "pushl %esi\n\t" // programStack
+ "pushl %eax\n\t" // syscallNum
+ "call " CMANG(CallAsmCall) "\n\t"
+ "addl $12, %esp\n\t"
+ "popl %ecx\n\t"
+ "addl $4, %edi\n\t"
+ "ret\n\t"
+#if defined __ELF__
+ ".size " CMANG(AsmCall)", .-" CMANG(AsmCall)
+#endif
+);
+
#endif
static int Constant4( void ) {
@@ -1124,7 +1110,7 @@ void VM_Destroy_Compiled(vm_t* self)
#ifdef VM_X86_MMAP
munmap(self->codeBase, self->codeLength);
#elif _WIN32
- VirtualFree(self->codeBase, self->codeLength, MEM_RELEASE);
+ VirtualFree(self->codeBase, 0, MEM_RELEASE);
#else
free(self->codeBase);
#endif
@@ -1143,7 +1129,6 @@ int VM_CallCompiled( vm_t *vm, int *args ) {
int programStack;
int stackOnEntry;
byte *image;
- void *entryPoint;
void *opStack;
int *oldInstructionPointers;
@@ -1182,45 +1167,38 @@ int VM_CallCompiled( vm_t *vm, int *args ) {
*(int *)&image[ programStack ] = -1; // will terminate the loop on return
// off we go into generated code...
- entryPoint = vm->codeBase;
opStack = &stack;
+ {
#ifdef _MSC_VER
- __asm {
- pushad
- mov esi, programStack;
- mov edi, opStack
- call entryPoint
- mov programStack, esi
- mov opStack, edi
- popad
- }
+ void *entryPoint = vm->codeBase;
+
+ __asm {
+ pushad
+ mov esi, programStack
+ mov edi, opStack
+ call entryPoint
+ mov programStack, esi
+ mov opStack, edi
+ popad
+ }
#else
- {
- static int memProgramStack;
- static void *memOpStack;
- static void *memEntryPoint;
-
- memProgramStack = programStack;
- memOpStack = opStack;
- memEntryPoint = entryPoint;
-
- __asm__(" pushal \n" \
- " movl %0,%%esi \n" \
- " movl %1,%%edi \n" \
- " call *%2 \n" \
- " movl %%esi,%0 \n" \
- " movl %%edi,%1 \n" \
- " popal \n" \
- : "=m" (memProgramStack), "=m" (memOpStack) \
- : "m" (memEntryPoint), "m" (memProgramStack), "m" (memOpStack) \
- : "si", "di" \
+ /* These registers are used as scratch registers and are destroyed after the
+ * call. Do not use clobber, so they can be used as input for the asm. */
+ unsigned eax;
+ unsigned ebx;
+ unsigned ecx;
+ unsigned edx;
+
+ __asm__ volatile(
+ "call *%6"
+ : "+S" (programStack), "+D" (opStack),
+ "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+ : "mr" (vm->codeBase)
+ : "cc", "memory"
);
-
- programStack = memProgramStack;
- opStack = memOpStack;
- }
#endif
+ }
if ( opStack != &stack[1] ) {
Com_Error( ERR_DROP, "opStack corrupted in compiled code" );
diff --git a/src/qcommon/vm_x86_64.c b/src/qcommon/vm_x86_64.c
index 0eb79306..09a9c6d1 100644
--- a/src/qcommon/vm_x86_64.c
+++ b/src/qcommon/vm_x86_64.c
@@ -1041,7 +1041,7 @@ void VM_Destroy_Compiled(vm_t* self)
#ifdef USE_GAS
munmap(self->codeBase, self->codeLength);
#elif _WIN32
- VirtualFree(self->codeBase, self->codeLength, MEM_RELEASE);
+ VirtualFree(self->codeBase, 0, MEM_RELEASE);
#else
munmap(self->codeBase, self->codeLength);
#endif