diff options
author | Tim Angus <tim@ngus.net> | 2009-10-03 11:58:50 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-03 00:15:34 +0000 |
commit | ac3e5586cd56657ff1b6f5f64af7e1d7c76b410d (patch) | |
tree | b245f2cbd4e7491b948aea5c7c080be61307c950 /src/qcommon | |
parent | dc3819f1e99d8159bdb0ea1da26506b00fe78e62 (diff) |
* Merge ioq3-r1458
Diffstat (limited to 'src/qcommon')
-rw-r--r-- | src/qcommon/common.c | 26 | ||||
-rw-r--r-- | src/qcommon/files.c | 21 | ||||
-rw-r--r-- | src/qcommon/msg.c | 2 | ||||
-rw-r--r-- | src/qcommon/net_ip.c | 93 | ||||
-rw-r--r-- | src/qcommon/qcommon.h | 3 | ||||
-rw-r--r-- | src/qcommon/unzip.c | 3 | ||||
-rw-r--r-- | src/qcommon/vm_interpreted.c | 16 | ||||
-rw-r--r-- | src/qcommon/vm_x86.c | 172 | ||||
-rw-r--r-- | src/qcommon/vm_x86_64.c | 2 |
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 |