diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cl_pred.c | 7 | ||||
-rw-r--r-- | src/cl_ref.c | 2 | ||||
-rw-r--r-- | src/common.c | 5 | ||||
-rw-r--r-- | src/fpu.c | 44 | ||||
-rw-r--r-- | src/fpu.h | 56 | ||||
-rw-r--r-- | src/sv_game.c | 2 | ||||
-rw-r--r-- | src/sv_init.c | 5 | ||||
-rw-r--r-- | src/sv_local.h | 1 | ||||
-rw-r--r-- | src/sv_main.c | 6 | ||||
-rw-r--r-- | src/sv_user.c | 5 | ||||
-rw-r--r-- | src/sys_public.h | 2 | ||||
-rw-r--r-- | src/sys_unix.c | 23 | ||||
-rw-r--r-- | src/sys_win.c | 7 |
13 files changed, 128 insertions, 37 deletions
diff --git a/src/cl_pred.c b/src/cl_pred.c index 744eb33..2a87b08 100644 --- a/src/cl_pred.c +++ b/src/cl_pred.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "cl_local.h" - +#include "fpu.h" /* =================== @@ -213,6 +213,9 @@ void CL_PredictMovement( void ) { return; } + X86_PUSH_FPCW; + X86_SINGLE_FPCW; + // copy current state to pmove memset( &pm, 0, sizeof( pm ) ); pm.trace = CL_Trace; @@ -246,6 +249,8 @@ void CL_PredictMovement( void ) { } else { frame = current - 1; } + + X86_POP_FPCW; oldz = cl.predicted_origins[cl.predicted_step_frame & CMD_MASK][2]; step = pm.s.origin[2] - oldz; diff --git a/src/cl_ref.c b/src/cl_ref.c index 771ca99..c51beb9 100644 --- a/src/cl_ref.c +++ b/src/cl_ref.c @@ -273,7 +273,7 @@ void CL_InitRefresh( void ) { SCR_RegisterMedia(); Con_RegisterMedia(); - + cvar_modified &= ~(CVAR_FILES|CVAR_REFRESH); } diff --git a/src/common.c b/src/common.c index 84e144c..086a6b9 100644 --- a/src/common.c +++ b/src/common.c @@ -38,6 +38,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "q_field.h" #include "prompt.h" #include "io_sleep.h" +#include "fpu.h" #include <setjmp.h> #if USE_ZLIB #include <zlib.h> @@ -472,6 +473,8 @@ void Com_Error( error_type_t code, const char *fmt, ... ) { // abort any console redirects Com_AbortRedirect(); + + X86_POP_FPCW; if( code == ERR_DISCONNECT || code == ERR_SILENT ) { Com_WPrintf( "%s\n", com_errorMsg ); @@ -1832,6 +1835,8 @@ void Qcommon_Init( int argc, char **argv ) { Com_SetLastError( NULL ); + X86_SetFPCW(); + // prepare enough of the subsystems to handle // cvar and command buffer management Z_Init(); diff --git a/src/fpu.c b/src/fpu.c new file mode 100644 index 0000000..9e21130 --- /dev/null +++ b/src/fpu.c @@ -0,0 +1,44 @@ +/* +Copyright (C) 2011 skuller.net + +This program 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. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "common.h" +#include "fpu.h" + +#if (defined __i386__) || (defined _M_IX86) + +uint16_t pushed_cw, single_cw, full_cw, chop_cw, ceil_cw; + +void X86_SetFPCW( void ) { + uint16_t cw; + + // save the control word into pushed_cw + X86_PUSH_FPCW; + + // mask off RC and PC bits + cw = pushed_cw & 0xf0ff; + + single_cw = cw; // round mode, 24-bit precision + full_cw = cw | 0x300; // round mode, 64-bit precision + chop_cw = cw | 0xc00; // chop mode, 24-bit precision + ceil_cw = cw | 0x800; // ceil mode, 24-bit precision +} + +#endif + diff --git a/src/fpu.h b/src/fpu.h new file mode 100644 index 0000000..62125bc --- /dev/null +++ b/src/fpu.h @@ -0,0 +1,56 @@ +/* +Copyright (C) 2011 skuller.net + +This program 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. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#if (defined __i386__) || (defined _M_IX86) + +#ifdef _MSC_VER +#define X86_STORE_FPCW(x) __asm fnstcw x +#define X86_LOAD_FPCW(x) __asm fldcw x +#else +#define X86_STORE_FPCW(x) __asm__ __volatile__( "fnstcw %0" : "=m" (x) ) +#define X86_LOAD_FPCW(x) __asm__ __volatile__( "fldcw %0" : : "m" (x) ) +#endif + +#define X86_PUSH_FPCW X86_STORE_FPCW(pushed_cw) +#define X86_POP_FPCW X86_LOAD_FPCW(pushed_cw) + +#define X86_SINGLE_FPCW X86_LOAD_FPCW(single_cw) +#define X86_FULL_FPCW X86_LOAD_FPCW(full_cw) +#define X86_CHOP_FPCW X86_LOAD_FPCW(chop_cw) +#define X86_CEIL_FPCW X86_LOAD_FPCW(ceil_cw) + +extern uint16_t pushed_cw, single_cw, full_cw, chop_cw, ceil_cw; + +void X86_SetFPCW( void ); + +#else + +#define X86_PUSH_FPCW +#define X86_POP_FPCW + +#define X86_SINGLE_FPCW +#define X86_FULL_FPCW +#define X86_CHOP_FPCW +#define X86_CEIL_FPCW + +#define X86_SetFPCW() + +#endif + diff --git a/src/sv_game.c b/src/sv_game.c index 04f4642..2408942 100644 --- a/src/sv_game.c +++ b/src/sv_game.c @@ -882,7 +882,5 @@ void SV_InitGameProgs ( void ) { if( ge->max_edicts <= sv_maxclients->integer || ge->max_edicts > MAX_EDICTS ) { Com_Error (ERR_DROP, "Game DLL returned bad number of max_edicts"); } - - Sys_FixFPCW(); } diff --git a/src/sv_init.c b/src/sv_init.c index fbe7740..033b3dd 100644 --- a/src/sv_init.c +++ b/src/sv_init.c @@ -149,6 +149,9 @@ static void SV_SpawnServer( cm_t *cm, const char *server, const char *spawnpoint // map initialization sv.state = ss_loading; + X86_PUSH_FPCW; + X86_SINGLE_FPCW; + // load and spawn all other entities ge->SpawnEntities ( sv.name, cm->cache->entitystring, spawnpoint ); @@ -156,6 +159,8 @@ static void SV_SpawnServer( cm_t *cm, const char *server, const char *spawnpoint ge->RunFrame (); ge->RunFrame (); + X86_POP_FPCW; + // make sure maxclients string is correct sprintf( sv.configstrings[CS_MAXCLIENTS], "%d", sv_maxclients->integer ); diff --git a/src/sv_local.h b/src/sv_local.h index 9289d4f..5e7ea79 100644 --- a/src/sv_local.h +++ b/src/sv_local.h @@ -40,6 +40,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mvd_public.h" #endif #include "io_sleep.h" +#include "fpu.h" #if USE_ZLIB #include <zlib.h> #endif diff --git a/src/sv_main.c b/src/sv_main.c index d6ff9b2..fbbcdde 100644 --- a/src/sv_main.c +++ b/src/sv_main.c @@ -1499,8 +1499,13 @@ static void SV_RunGameFrame( void ) { time_before_game = Sys_Milliseconds(); #endif + X86_PUSH_FPCW; + X86_SINGLE_FPCW; + ge->RunFrame(); + X86_POP_FPCW; + #if USE_CLIENT if( host_speeds->integer ) time_after_game = Sys_Milliseconds(); @@ -1517,7 +1522,6 @@ static void SV_RunGameFrame( void ) { // save the entire world state if recording a serverdemo SV_MvdEndFrame(); #endif - } /* diff --git a/src/sv_user.c b/src/sv_user.c index b4ba1be..31ee6e6 100644 --- a/src/sv_user.c +++ b/src/sv_user.c @@ -1193,6 +1193,9 @@ void SV_ExecuteClientMessage( client_t *client ) { int net_drop; size_t len; + X86_PUSH_FPCW; + X86_SINGLE_FPCW; + sv_client = client; sv_player = sv_client->edict; @@ -1358,5 +1361,7 @@ void SV_ExecuteClientMessage( client_t *client ) { sv_client = NULL; sv_player = NULL; + + X86_POP_FPCW; } diff --git a/src/sys_public.h b/src/sys_public.h index 0122b11..6b9b507 100644 --- a/src/sys_public.h +++ b/src/sys_public.h @@ -63,8 +63,6 @@ char *Sys_GetCurrentDirectory( void ); void Sys_DebugBreak( void ); -void Sys_FixFPCW( void ); - #if USE_AC_CLIENT qboolean Sys_GetAntiCheatAPI( void ); #endif diff --git a/src/sys_unix.c b/src/sys_unix.c index 1ff2370..4d3ab0c 100644 --- a/src/sys_unix.c +++ b/src/sys_unix.c @@ -604,27 +604,6 @@ qboolean Sys_GetAntiCheatAPI( void ) { } #endif -void Sys_FixFPCW( void ) { -#ifdef __i386__ - uint16_t cw; - - __asm__ __volatile__( "fnstcw %0" : "=m" (cw) ); - - Com_DPrintf( "FPU control word: %x\n", cw ); - - if( cw & 0x300 ) { - Com_DPrintf( "Setting FPU to single precision mode\n" ); - cw &= ~0x300; - } - if( cw & 0xC00 ) { - Com_DPrintf( "Setting FPU to round to nearest mode\n" ); - cw &= ~0xC00; - } - - __asm__ __volatile__( "fldcw %0" : : "m" (cw) ); -#endif -} - static void hup_handler( int signum ) { Com_FlushLogs(); } @@ -726,8 +705,6 @@ void Sys_Init( void ) { signal( SIGFPE, kill_handler ); signal( SIGTRAP, kill_handler ); } - - Sys_FixFPCW(); } #if USE_SYSCON diff --git a/src/sys_win.c b/src/sys_win.c index 4ca0a6c..6630dca 100644 --- a/src/sys_win.c +++ b/src/sys_win.c @@ -26,7 +26,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #if USE_WINSVC #include <winsvc.h> #endif -#include <float.h> HINSTANCE hGlobalInstance; @@ -674,12 +673,6 @@ unsigned Sys_Milliseconds( void ) { void Sys_AddDefaultConfig( void ) { } -void Sys_FixFPCW( void ) { -#ifdef __i386__ // FIXME: MSVC? - _controlfp( _PC_24|_RC_NEAR, _MCW_PC|_MCW_RC ); -#endif -} - void Sys_Sleep( int msec ) { Sleep( msec ); } |