00001 /// \file CATTimeWarp.h 00002 /// \brief Time function interception, made for slowing down video games. 00003 /// \ingroup CAT 00004 /// 00005 /// Copyright (c) 2007-2008 by Michael Ellison. 00006 /// See COPYING.txt for the \ref gaslicense License (MIT License). 00007 /// 00008 // $Author: mikeellison $ 00009 // $Date: 2008-01-27 12:56:42 -0600 (Sun, 27 Jan 2008) $ 00010 // $Revision: $ 00011 // $NoKeywords: $ 00012 00013 #ifndef _CATTimeWarp_H_ 00014 #define _CATTimeWarp_H_ 00015 00016 #include "CATIntercept.h" 00017 #ifdef CAT_CONFIG_WIN32 00018 #include "CATCritSec.h" 00019 00020 /// \class CATTimeWarp 00021 /// \brief Time function interception, made for slowing down video games. 00022 /// \ingroup CAT 00023 /// 00024 /// CATTimeWarp works by intercepting the timing functions that games typically use 00025 /// and scaling them to the desired speed. 00026 /// 00027 /// To avoid the horrible results of negative diff values, it stores the last value 00028 /// each of the hooked functions returned natively and its internal calculated value. 00029 /// The next time that function is called, the result is the scaled time difference 00030 /// between the last call and the current call. 00031 /// 00032 /// Currently hooking timeGetTime(), GetTickCount(), and QueryPerformanceCounter(). 00033 /// 00034 /// Usage: 00035 /// -# First call HookFunctions() to start it. It will hook all of the functions 00036 /// and set the speed to 1.0 (normal). 00037 /// -# Call SetSpeed() with the percentage of normal speed that you wish to 00038 /// run the process at (recommended 0.1f - 1.0f). 00039 /// 00040 /// 00041 class CATTimeWarp : public CATIntercept 00042 { 00043 public: 00044 CATTimeWarp(); 00045 virtual ~CATTimeWarp(); 00046 00047 /// Hooks all functions and sets the speed to 1.0f. 00048 /// 00049 /// \return CAT_SUCCESS on success. 00050 CATResult HookFunctions(); 00051 00052 /// Sets the speed to run the timers at. 00053 /// 00054 /// \param speed Percentage of normal speed to run (0 - 1) 00055 /// Recommend using 0.1f-1.0f to as range. 00056 /// 00057 /// \return CAT_SUCCESS on success. 00058 CATResult SetSpeed(CATFloat32 speed); 00059 CATFloat32 GetSpeed(); 00060 00061 protected: 00062 /// Adjusts the passed in value(s) according to speed, and saves off the real timer 00063 /// result and calculated result for the next query. 00064 /// 00065 /// \param lastPerf On entry, should point to system's result 00066 /// from QueryPerformanceCounter. 00067 /// On return, set to scaled counter value. 00068 /// 00069 /// \param lastTick On entry, should point to the system's result 00070 /// from GetTickCount(). 00071 /// On return, set to scaled tick count. 00072 /// 00073 /// \param lastTime On entry, should point to the system's result 00074 /// from timeGetTime(). 00075 /// On return, set to scaled time value. 00076 /// 00077 /// \note 00078 /// Null parameters will be ignored. 00079 void AdjustSaveTime( LARGE_INTEGER* lastPerf, 00080 DWORD* lastTick, 00081 DWORD* lastTime); 00082 00083 /// Hook function - receives control when timeGetTime is called. 00084 static void OnTimeGetTime( CATHOOK* hookInst); 00085 00086 /// Hook function - receives control when QueryPerformanceCounter is called. 00087 static void OnQueryPerformanceCounter( CATHOOK* hookInst, 00088 LARGE_INTEGER* lpCount); 00089 00090 /// Hook function - receives control when GetTickCount is called. 00091 static void OnGetTickCount( CATHOOK* hookInst); 00092 00093 /// Adjust timer for QueryPerformanceCounter 00094 static void FixupQPC (CATHOOK* hookInst, LARGE_INTEGER* lpCount); 00095 00096 /// Adjust timer for timeGetTime() 00097 static void FixupTime(CATHOOK* hookInst, DWORD* time); 00098 00099 /// Adjust timer for GetTickCount() 00100 static void FixupTick(CATHOOK* hookInst, DWORD* tick); 00101 00102 protected: 00103 static CATINTERCEPT_DLL_TABLE_ENTRY kKernel32Funcs[]; ///< Kernel32 functions to hook 00104 00105 static CATINTERCEPT_DLL_TABLE_ENTRY kWinMMFuncs[]; ///< WinMM functions to hook 00106 00107 00108 CATCritSec fLock; ///< Critical section for timer data 00109 CATFloat32 fSpeed; ///< Speed (0.1 - 1.0) to run at 00110 HMODULE fWinmmDLL; ///< winmm.dll module handle 00111 HMODULE fKernelDLL; ///< kernel32.dll module handle 00112 00113 LARGE_INTEGER fLastPerfCounter; ///< Last calculated result for QueryPerformanceCounter() 00114 DWORD fLastTimeGetTime; ///< Last calculated result for timeGetTime() 00115 DWORD fLastTickCount; ///< Last calculated result for GetTickCount() 00116 00117 LARGE_INTEGER fLastRealPerfCounter; ///< Last real system result for QueryPerformanceCounter() 00118 DWORD fLastRealTimeGetTime; ///< Last real system result for timeGetTime() 00119 DWORD fLastRealTickCount; ///< Last real system result for GetTickCount() 00120 }; 00121 00122 #endif // CAT_CONFIG_WIN32 00123 #endif // _CATTimeWarp_H_