From 3d4e7f87b8b1234fb658f0f6b47d7b55e6544688 Mon Sep 17 00:00:00 2001 From: Spoike Date: Mon, 24 Aug 2015 15:47:40 +0000 Subject: [PATCH] fix possible infinite loop. fix viewmodel animations not adhering to sv_gamespeed. actually fix -watchdog, at least for msvc. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4972 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_ents.c | 15 +++++++++------ engine/client/sys_win.c | 6 +++--- engine/common/sys_win_threads.c | 32 +++++++++++++++++++++++--------- engine/server/sv_send.c | 14 ++++++++------ engine/server/sv_sys_win.c | 6 +++--- 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index b29079ade..1ba8b2c43 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -4859,7 +4859,10 @@ void CL_LinkViewModel(void) ent.model = cl.model_precache[pv->stats[STAT_WEAPONMODELI]]; if (!ent.model) + { + pv->vm.oldmodel = NULL; return; + } #ifdef HLCLIENT if (!CLHL_AnimateViewEntity(&ent)) @@ -4870,7 +4873,7 @@ void CL_LinkViewModel(void) { pv->vm.oldmodel = ent.model; pv->vm.oldframe = pv->vm.prevframe = pv->stats[STAT_WEAPONFRAME]; - pv->vm.oldlerptime = pv->vm.lerptime = realtime; + pv->vm.oldlerptime = pv->vm.lerptime = cl.time; pv->vm.frameduration = 0.1; } //if the frame changed, update the oldframe to lerp into the new frame @@ -4880,19 +4883,19 @@ void CL_LinkViewModel(void) pv->vm.prevframe = pv->stats[STAT_WEAPONFRAME]; pv->vm.oldlerptime = pv->vm.lerptime; - pv->vm.frameduration = (realtime - pv->vm.lerptime); + pv->vm.frameduration = (cl.time - pv->vm.lerptime); if (pv->vm.frameduration < 0.01)//no faster than 100 times a second... to avoid divide by zero pv->vm.frameduration = 0.01; if (pv->vm.frameduration > 0.2) //no slower than 5 times a second pv->vm.frameduration = 0.2; - pv->vm.lerptime = realtime; + pv->vm.lerptime = cl.time; } //work out the blend fraction ent.framestate.g[FS_REG].frame[0] = pv->vm.prevframe; ent.framestate.g[FS_REG].frame[1] = pv->vm.oldframe; - ent.framestate.g[FS_REG].frametime[0] = realtime - pv->vm.lerptime; - ent.framestate.g[FS_REG].frametime[1] = realtime - pv->vm.oldlerptime; - ent.framestate.g[FS_REG].lerpweight[0] = (realtime-pv->vm.lerptime)/pv->vm.frameduration; + ent.framestate.g[FS_REG].frametime[0] = cl.time - pv->vm.lerptime; + ent.framestate.g[FS_REG].frametime[1] = cl.time - pv->vm.oldlerptime; + ent.framestate.g[FS_REG].lerpweight[0] = (cl.time-pv->vm.lerptime)/pv->vm.frameduration; ent.framestate.g[FS_REG].lerpweight[0] = bound(0, ent.framestate.g[FS_REG].lerpweight[0], 1); ent.framestate.g[FS_REG].lerpweight[1] = 1-ent.framestate.g[FS_REG].lerpweight[0]; } diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 9a9f2433e..920e49355 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -33,7 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "fs.h" #ifdef _MSC_VER -#define _MSC_SEH +#define MSVC_SEH #endif //#define RESTARTTEST @@ -3903,7 +3903,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin #ifdef CATCHCRASH LoadLibraryU ("DBGHELP"); //heap corruption can prevent loadlibrary from working properly, so do this in advance. -#ifdef _MSC_SEH +#ifdef MSVC_SEH __try #else { @@ -4231,7 +4231,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin } } #ifdef CATCHCRASH -#ifdef _MSC_SEH +#ifdef MSVC_SEH __except (CrashExceptionHandler(false, GetExceptionCode(), GetExceptionInformation())) { return 1; diff --git a/engine/common/sys_win_threads.c b/engine/common/sys_win_threads.c index 838f1a5db..b9b6ab2ad 100644 --- a/engine/common/sys_win_threads.c +++ b/engine/common/sys_win_threads.c @@ -26,10 +26,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #if (defined(_DEBUG) || defined(DEBUG)) && !defined(NPFTE) #define CATCHCRASH +#ifdef _MSC_VER +#define MSVC_SEH +DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTION_POINTERS exceptionInfo); +#else LONG CALLBACK nonmsvc_CrashExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo); - -#ifdef _MSC_VER //nt5 -PVOID WINAPI AddVectoredExceptionHandler(ULONG FirstHandler, PVECTORED_EXCEPTION_HANDLER VectoredHandler); #endif #endif @@ -93,15 +94,28 @@ unsigned int WINAPI threadwrapper(void *args) #ifdef CATCHCRASH if (strcmp(((threadwrap_t *)args)->name, "watchdog")) //don't do this for the watchdog timer, as it just breaks the 'no' option. { - PVOID (WINAPI *pAddVectoredExceptionHandler)(ULONG FirstHandler, PVECTORED_EXCEPTION_HANDLER VectoredHandler); - dllfunction_t dbgfuncs[] = {{(void*)&pAddVectoredExceptionHandler, "AddVectoredExceptionHandler"}, {NULL,NULL}}; +#ifdef MSVC_SEH + __try + { + free(args); + tw.func(tw.args); + } + __except (CrashExceptionHandler(false, GetExceptionCode(), GetExceptionInformation())) + { + } +#else + PVOID (WINAPI *[SetUnhandledExceptionFilter)(ULONG FirstHandler, PVECTORED_EXCEPTION_HANDLER VectoredHandler); + dllfunction_t dbgfuncs[] = {{(void*)&pAddVectoredExceptionHandler, "SetUnhandledExceptionFilter"}, {NULL,NULL}}; if (Sys_LoadLibrary("kernel32.dll", dbgfuncs) && pAddVectoredExceptionHandler) pAddVectoredExceptionHandler(0, nonmsvc_CrashExceptionHandler); - } #endif - - free(args); - tw.func(tw.args); + } + else +#endif + { + free(args); + tw.func(tw.args); + } #ifndef WIN32CRTDLL _endthreadex(0); diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index 9fb4c24e9..73d41eca6 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -2684,27 +2684,29 @@ void SV_SendClientMessages (void) c->msecs = 1200; if (c->isindependant && !sv.paused) { + unsigned int stepmsec; usercmd_t cmd; memset(&cmd, 0, sizeof(cmd)); host_client = c; sv_player = c->edict; SV_PreRunCmd(); - cmd.msec = msecs;//25; - if (msecs > 1000) - msecs = 1000; //really? I blame the debugger. + stepmsec = 12; + cmd.msec = stepmsec; VectorCopy(c->lastcmd.angles, cmd.angles); cmd.buttons = c->lastcmd.buttons; SV_RunCmd (&cmd, true); SV_PostRunCmd(); - if (msecs > c->msecs) + if (stepmsec > c->msecs) c->msecs = 0; else - c->msecs -= msecs;//25; + c->msecs -= stepmsec; + if (c->msecs > 2000) + c->msecs = 2000; //assume debugger or system suspend/hibernate host_client = NULL; sv_player = NULL; } else - c->msecs = 500; + c->msecs = 500; //for switching between. } #endif diff --git a/engine/server/sv_sys_win.c b/engine/server/sv_sys_win.c index 743c2a6ad..616369eba 100644 --- a/engine/server/sv_sys_win.c +++ b/engine/server/sv_sys_win.c @@ -58,7 +58,7 @@ typedef BOOL (WINAPI *MINIDUMPWRITEDUMP) ( PMINIDUMP_CALLBACK_INFORMATION CallbackParam ); -DWORD CrashExceptionHandler (DWORD exceptionCode, LPEXCEPTION_POINTERS exceptionInfo) +DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTION_POINTERS exceptionInfo) { char dumpPath[1024]; HANDLE hProc = GetCurrentProcess(); @@ -305,7 +305,7 @@ DWORD CrashExceptionHandler (DWORD exceptionCode, LPEXCEPTION_POINTERS exception LONG CALLBACK nonmsvc_CrashExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) { DWORD foo = EXCEPTION_CONTINUE_SEARCH; - foo = CrashExceptionHandler(/*false, */ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo); + foo = CrashExceptionHandler(false, ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo); //we have no handler. thus we handle it by exiting. if (foo == EXCEPTION_EXECUTE_HANDLER) exit(1); @@ -1602,7 +1602,7 @@ int main (int argc, char **argv) } #ifdef CATCHCRASH #ifdef _MSC_VER - __except (CrashExceptionHandler(GetExceptionCode(), GetExceptionInformation())) + __except (CrashExceptionHandler(false, GetExceptionCode(), GetExceptionInformation())) { return 1; }