#define _WIN32_WINDOWS 0x0410 #define WINVER 0x0500 #define DIRECTINPUT_VERSION 0x0800 #define WM_GRAPHNOTIFY WM_USER+13 #include #include #include #include #include #include #include #include #include #pragma warning( push ) #pragma warning( disable : 4005) #include #include #include #include #pragma warning( pop ) #pragma comment( lib, "d3d8.lib" ) #pragma comment( lib, "ddraw.lib" ) #pragma comment( lib, "Winmm.lib" ) #pragma comment( lib, "dxguid.lib" ) #pragma comment( lib, "strmiids.lib" ) #if (defined(_MSC_VER)) #include #endif /* (defined(_MSC_VER)) */ #include #include "rwcore.h" #include "resource.h" #include "skeleton.h" #include "platform.h" #include "win.h" #define MAX_SUBSYSTEMS (16) //static RwBool ForegroundApp = TRUE; static RwBool &ForegroundApp = *(RwBool*)0x060F000; //static RwBool RwInitialised = FALSE; static RwBool &RwInitialised = *(RwBool*)0x885B88; static RwSubSystemInfo GsubSysInfo[MAX_SUBSYSTEMS]; static RwInt32 GnumSubSystems = 0; static RwInt32 GcurSel = 0, GcurSelVM = 0; //static RwBool startupDeactivate; static RwBool &startupDeactivate = *(RwBool*)0x8E2878; //static RwBool useDefault; static RwBool &useDefault = *(RwBool*)0x6510D4; //static RwBool defaultFullscreenRes = TRUE; static RwBool &defaultFullscreenRes = *(RwBool*)0x60EFFC; /* Class name for the MS Window's window class. */ static const RwChar *AppClassName = RWSTRING("Grand theft auto 3"); /* platform specfic global data */ typedef struct { HWND window; HINSTANCE instance; RwBool fullScreen; RwV2d lastMousePos; DWORD field_14; LPDIRECTINPUT8 diInterface; LPDIRECTINPUTDEVICE8 diMouse; LPDIRECTINPUTDEVICE8 diDevice1; LPDIRECTINPUTDEVICE8 diDevice2; } psGlobalType; //static psGlobalType PsGlobal; static psGlobalType &PsGlobal = *(psGlobalType*)0x72CF60; #define PSGLOBAL(var) (((psGlobalType *)(RsGlobal.ps))->var) #undef MAKEPOINTS #define MAKEPOINTS(l) (*((POINTS /*FAR*/ *)&(l))) #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; } #define JIF(x) if (FAILED(hr=(x))) \ {debug(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) TEXT("\n"), hr); return;} #include "common.h" #include "patcher.h" #include "FileMgr.h" #include "Text.h" #include "Pad.h" #include "Timer.h" #include "DMAudio.h" #include "ControllerConfig.h" #include "Frontend.h" #include "Game.h" #include "PCSave.h" #include "Sprite2D.h" VALIDATE_SIZE(psGlobalType, 0x28); // DirectShow interfaces IGraphBuilder *pGB = NULL; IMediaControl *pMC = NULL; IMediaEventEx *pME = NULL; IVideoWindow *pVW = NULL; IMediaSeeking *pMS = NULL; /**/ DWORD dwDXVersion; DWORD _dwMemTotalPhys; DWORD &_dwMemAvailPhys = *(DWORD*)0x70F29C; DWORD _dwMemTotalVirtual; DWORD _dwMemAvailVirtual; DWORD &_dwMemTotalVideo = *(DWORD*)0x70F2A8; DWORD _dwMemAvailVideo; DWORD &_dwOperatingSystemVersion = *(DWORD*)0x70F290; RwUInt32 &gGameState = *(RwUInt32*)0x8F5838; WRAPPER BOOL _InputTranslateKey(RsKeyCodes *rs, DWORD flag, UINT key) { EAXJMP(0x583A20); } WRAPPER void _InputTranslateShiftKeyUpDown(RsKeyCodes *rs) { EAXJMP(0x583DC0); } WRAPPER HRESULT _InputInitialise() { EAXJMP(0x5830D0); } WRAPPER void _InputShutdown() { EAXJMP(0x583910); } WRAPPER HRESULT _InputInitialiseMouse() { EAXJMP(0x583110); } WRAPPER void _InputInitialiseJoys() { EAXJMP(0x583580); } WRAPPER Bool InitialiseGame(void) { EAXJMP(0x48E7E0); } WRAPPER const Char *GetLevelSplashScreen(Int32 number) { EAXJMP(0x48D750); } // void LoadingScreen(char const *msg1, char const *msg2, char const *screen); CSprite2d *LoadSplash(const char *name); void InitialiseLanguage(); RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode); void CenterVideo(void); void CloseClip(void); /**/ _TODO("") //CJoySticks::CJoySticks((void)) 00580B30 //CJoySticks::ClearJoyInfo((int)) 00580B50 /* ***************************************************************************** */ void _psCreateFolder(LPCSTR path) { HANDLE hfle = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL, NULL); if ( hfle == INVALID_HANDLE_VALUE ) CreateDirectory(path, NULL); else CloseHandle(hfle); } /* ***************************************************************************** */ const char *_psGetUserFilesFolder() { HKEY hKey = NULL; static CHAR szUserFiles[256]; if ( RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_SPECIAL_FOLDERS, REG_OPTION_RESERVED, KEY_READ, &hKey) == ERROR_SUCCESS ) { DWORD KeyType; DWORD KeycbData = sizeof(szUserFiles); if ( RegQueryValueEx(hKey, "Personal", NULL, &KeyType, (LPBYTE)szUserFiles, &KeycbData) == ERROR_SUCCESS ) { RegCloseKey(hKey); strcat(szUserFiles, "\\GTA3 User Files"); _psCreateFolder(szUserFiles); return szUserFiles; } RegCloseKey(hKey); } strcpy(szUserFiles, "data"); return szUserFiles; } /* ***************************************************************************** */ RwBool psCameraBeginUpdate(RwCamera *camera) { if ( !RwCameraBeginUpdate(Scene.camera) ) { ForegroundApp = FALSE; RsEventHandler(rsACTIVATE, (void *)FALSE); return FALSE; } return TRUE; } /* ***************************************************************************** */ void psCameraShowRaster(RwCamera *camera) { if (CMenuManager::m_PrefsVsync) RwCameraShowRaster(camera, PSGLOBAL(window), rwRASTERFLIPWAITVSYNC); else RwCameraShowRaster(camera, PSGLOBAL(window), rwRASTERFLIPDONTWAIT); return; } /* ***************************************************************************** */ RwUInt32 psTimer(void) { RwUInt32 time; TIMECAPS TimeCaps; timeGetDevCaps(&TimeCaps, sizeof(TIMECAPS)); timeBeginPeriod(TimeCaps.wPeriodMin); time = (RwUInt32) timeGetTime(); timeEndPeriod(TimeCaps.wPeriodMin); return time; } /* ***************************************************************************** */ void psMouseSetPos(RwV2d *pos) { POINT point; point.x = (RwInt32) pos->x; point.y = (RwInt32) pos->y; ClientToScreen(PSGLOBAL(window), &point); SetCursorPos(point.x, point.y); PSGLOBAL(lastMousePos.x) = (RwInt32)pos->x; PSGLOBAL(lastMousePos.y) = (RwInt32)pos->y; return; } /* ***************************************************************************** */ RwMemoryFunctions* psGetMemoryFunctions(void) { return 0; } /* ***************************************************************************** */ RwBool psInstallFileSystem(void) { return (TRUE); } /* ***************************************************************************** */ RwBool psNativeTextureSupport(void) { return RwD3D8DeviceSupportsDXTTexture(); } /* ***************************************************************************** */ static BOOL InitApplication(HANDLE instance) { /* * Perform any necessary MS Windows application initialization. Basically, * this means registering the window class for this application. */ WNDCLASS windowClass; windowClass.style = CS_BYTEALIGNWINDOW; windowClass.lpfnWndProc = (WNDPROC) MainWndProc; windowClass.cbClsExtra = 0; windowClass.cbWndExtra = 0; windowClass.hInstance = (HINSTANCE)instance; windowClass.hIcon = NULL; windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); windowClass.hbrBackground = NULL; windowClass.lpszMenuName = NULL; windowClass.lpszClassName = AppClassName; return RegisterClass(&windowClass); } /* ***************************************************************************** */ static HWND InitInstance(HANDLE instance) { /* * Perform any necessary initialization for this instance of the * application. * * Create the MS Window's window instance for this application. The * initial window size is given by the defined camera size. The window * is not given a title as we set it during Init3D() with information * about the version of RenderWare being used. */ RECT rect; rect.left = rect.top = 0; rect.right = RsGlobal.maximumWidth; rect.bottom = RsGlobal.maximumHeight; AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); return CreateWindow(AppClassName, RsGlobal.appName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, (HWND)NULL, (HMENU)NULL, (HINSTANCE)instance, NULL); } void _GetVideoMemInfo(LPDWORD total, LPDWORD avaible) { HRESULT hr; LPDIRECTDRAW7 pDD7; hr = DirectDrawCreateEx(NULL, (VOID**)&pDD7, IID_IDirectDraw7, NULL); if ( FAILED(hr) ) return; DDSCAPS2 caps; ZeroMemory(&caps, sizeof(DDSCAPS2)); caps.dwCaps = DDSCAPS_VIDEOMEMORY; pDD7->GetAvailableVidMem(&caps, total, avaible); pDD7->Release(); } /* ***************************************************************************** */ typedef HRESULT(WINAPI * DIRECTDRAWCREATEEX)( GUID*, VOID**, REFIID, IUnknown* ); //----------------------------------------------------------------------------- // Name: GetDXVersion() // Desc: This function returns the DirectX version number as follows: // 0x0000 = No DirectX installed // 0x0700 = At least DirectX 7 installed. // 0x0800 = At least DirectX 8 installed. // // Please note that this code is intended as a general guideline. Your // app will probably be able to simply query for functionality (via // QueryInterface) for one or two components. // // Please also note: // "if( dwDXVersion != 0x500 ) return FALSE;" is VERY BAD. // "if( dwDXVersion < 0x500 ) return FALSE;" is MUCH BETTER. // to ensure your app will run on future releases of DirectX. //----------------------------------------------------------------------------- DWORD GetDXVersion() { DIRECTDRAWCREATEEX DirectDrawCreateEx = NULL; HINSTANCE hDDrawDLL = NULL; HINSTANCE hD3D8DLL = NULL; HINSTANCE hDPNHPASTDLL = NULL; DWORD dwDXVersion = 0; //HRESULT hr; // First see if DDRAW.DLL even exists. hDDrawDLL = LoadLibrary( "DDRAW.DLL" ); if( hDDrawDLL == NULL ) { dwDXVersion = 0; OutputDebugString( "Couldn't LoadLibrary DDraw\r\n" ); return dwDXVersion; } //------------------------------------------------------------------------- // DirectX 7.0 Checks //------------------------------------------------------------------------- // Check for DirectX 7 by creating a DDraw7 object LPDIRECTDRAW7 pDD7; DirectDrawCreateEx = (DIRECTDRAWCREATEEX)GetProcAddress( hDDrawDLL, "DirectDrawCreateEx" ); if( NULL == DirectDrawCreateEx ) { FreeLibrary( hDDrawDLL ); OutputDebugString( "Couldn't GetProcAddress DirectDrawCreateEx\r\n" ); return dwDXVersion; } if( FAILED( DirectDrawCreateEx( NULL, (VOID**)&pDD7, IID_IDirectDraw7, NULL ) ) ) { FreeLibrary( hDDrawDLL ); OutputDebugString( "Couldn't DirectDrawCreateEx\r\n" ); return dwDXVersion; } // DDraw7 was created successfully. We must be at least DX7.0 dwDXVersion = 0x700; pDD7->Release(); //------------------------------------------------------------------------- // DirectX 8.0 Checks //------------------------------------------------------------------------- // Simply see if D3D8.dll exists. hD3D8DLL = LoadLibrary( "D3D8.DLL" ); if( hD3D8DLL == NULL ) { FreeLibrary( hDDrawDLL ); OutputDebugString( "Couldn't LoadLibrary D3D8.DLL\r\n" ); return dwDXVersion; } // D3D8.dll exists. We must be at least DX8.0 dwDXVersion = 0x800; //------------------------------------------------------------------------- // DirectX 8.1 Checks //------------------------------------------------------------------------- // Simply see if dpnhpast.dll exists. hDPNHPASTDLL = LoadLibrary( "dpnhpast.dll" ); if( hDPNHPASTDLL == NULL ) { FreeLibrary( hDPNHPASTDLL ); OutputDebugString( "Couldn't LoadLibrary dpnhpast.dll\r\n" ); return dwDXVersion; } // dpnhpast.dll exists. We must be at least DX8.1 dwDXVersion = 0x801; //------------------------------------------------------------------------- // End of checking for versions of DirectX //------------------------------------------------------------------------- // Close open libraries and return FreeLibrary( hDDrawDLL ); FreeLibrary( hD3D8DLL ); return dwDXVersion; } /* ***************************************************************************** */ static char cpuvendor[16] = "UnknownVendr"; __declspec(naked) const char * _psGetCpuVendr() { __asm { push ebx xor eax, eax cpuid mov dword ptr [cpuvendor+0], ebx mov dword ptr [cpuvendor+4], edx mov dword ptr [cpuvendor+8], ecx mov eax, offset cpuvendor pop ebx retn } } /* ***************************************************************************** */ __declspec(naked) RwUInt32 _psGetCpuFeatures() { __asm { mov eax, 1 cpuid mov eax, edx retn } } /* ***************************************************************************** */ __declspec(naked) RwUInt32 _psGetCpuFeaturesEx() { __asm { mov eax, 80000000h cpuid cmp eax, 80000000h jbe short _NOEX mov eax, 80000001h cpuid mov eax, edx jmp short _RETEX _NOEX: xor eax, eax mov eax, eax _RETEX: retn } } void _psPrintCpuInfo() { RwUInt32 features = _psGetCpuFeatures(); RwUInt32 FeaturesEx = _psGetCpuFeaturesEx(); debug("Running on a %s", _psGetCpuVendr()); if ( features & 0x800000 ) debug("with MMX"); if ( features & 0x2000000 ) debug("with SSE"); if ( FeaturesEx & 0x80000000 ) debug("with 3DNow"); } /* ***************************************************************************** */ #ifdef UNDER_CE #define CMDSTR LPWSTR #else #define CMDSTR LPSTR #endif /* ***************************************************************************** */ RwBool psInitialise(void) { PsGlobal.lastMousePos.x = PsGlobal.lastMousePos.y = 0.0; RsGlobal.ps = &PsGlobal; PsGlobal.fullScreen = FALSE; PsGlobal.diInterface = NULL; PsGlobal.diMouse = NULL; PsGlobal.diDevice1 = NULL; PsGlobal.diDevice2 = NULL; CFileMgr::Initialise(); C_PcSave::SetSaveDirectory(_psGetUserFilesFolder()); InitialiseLanguage(); FrontEndMenuManager.LoadSettings(); gGameState = GS_START_UP; TRACE("gGameState = GS_START_UP"); _psPrintCpuInfo(); OSVERSIONINFO verInfo; verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&verInfo); _dwOperatingSystemVersion = 0; if ( verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) { if ( verInfo.dwMajorVersion == 4 ) { debug("Operating System is WinNT\n"); _dwOperatingSystemVersion = oS_WINNT; } else if ( verInfo.dwMajorVersion == 5 ) { debug("Operating System is Win2000\n"); _dwOperatingSystemVersion = OS_WIN2000; } else if ( verInfo.dwMajorVersion > 5 ) { debug("Operating System is WinXP or greater\n"); _dwOperatingSystemVersion = OS_WINXP; } } else if ( verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) { if ( verInfo.dwMajorVersion > 4 || verInfo.dwMajorVersion == 4 && verInfo.dwMinorVersion == 1 ) { debug("Operating System is Win98\n"); _dwOperatingSystemVersion = OS_WIN98; } else { debug("Operating System is Win95\n"); _dwOperatingSystemVersion = OS_WIN95; } } dwDXVersion = GetDXVersion(); debug("DirectX version 0x%x\n", dwDXVersion); if ( _dwOperatingSystemVersion == OS_WIN95 ) { MessageBoxW(NULL, (LPCWSTR)TheText.Get("WIN_95"), // Grand Theft Auto III cannot run on Windows 95 (LPCWSTR)TheText.Get("WIN_TTL"), // Grand Theft Auto III MB_OK); return FALSE; } if ( dwDXVersion < 0x801 ) { MessageBoxW(NULL, (LPCWSTR)TheText.Get("WIN_DX"), // Grand Theft Auto III requires at least DirectX version 8.1 (LPCWSTR)TheText.Get("WIN_TTL"), // Grand Theft Auto III MB_OK); return FALSE; } MEMORYSTATUS memstats; GlobalMemoryStatus(&memstats); _dwMemTotalPhys = memstats.dwTotalPhys; _dwMemAvailPhys = memstats.dwAvailPhys; _dwMemTotalVirtual = memstats.dwTotalVirtual; _dwMemAvailVirtual = memstats.dwAvailVirtual; _GetVideoMemInfo(&_dwMemTotalVideo, &_dwMemAvailVideo); debug("Physical memory size %d\n", _dwMemTotalPhys); debug("Available physical memory %d\n", _dwMemAvailPhys); debug("Video memory size %d\n", _dwMemTotalVideo); debug("Available video memory %d\n", _dwMemAvailVideo); if ( _dwMemAvailVideo < (12 * 1024 * 1024) /*12 MB*/ ) { MessageBoxW(NULL, (LPCWSTR)TheText.Get("WIN_VDM"), // Grand Theft Auto III requires at least 12MB of available video memory (LPCWSTR)TheText.Get("WIN_TTL"), // Grand Theft Auto III MB_OK); return FALSE; } TheText.Unload(); return TRUE; } /* ***************************************************************************** */ void psTerminate(void) { return; } /* ***************************************************************************** */ static RwChar **_VMList; RwInt32 _psGetNumVideModes() { return RwEngineGetNumVideoModes(); } /* ***************************************************************************** */ RwBool _psFreeVideoModeList() { RwInt32 numModes; RwInt32 i; numModes = _psGetNumVideModes(); if ( _VMList == NULL ) return TRUE; for ( i = 0; i < numModes; i++ ) { RwFree(_VMList[i]); } RwFree(_VMList); _VMList = NULL; return TRUE; } /* ***************************************************************************** */ RwChar **_psGetVideoModeList() { RwInt32 numModes; RwInt32 i; if ( _VMList != NULL ) { return _VMList; } numModes = RwEngineGetNumVideoModes(); _VMList = (RwChar **)RwCalloc(numModes, sizeof(RwChar*)); for ( i = 0; i < numModes; i++ ) { RwVideoMode vm; RwEngineGetVideoModeInfo(&vm, i); if ( vm.flags & rwVIDEOMODEEXCLUSIVE ) { if ( vm.width >= 640 && vm.height >= 480 && (vm.width == 640 && vm.height == 480) || !(vm.flags & rwVIDEOMODEEXCLUSIVE) || (_dwMemTotalVideo - vm.depth * vm.height * vm.width / 8) > (12 * 1024 * 1024)/*12 MB*/ ) { _VMList[i] = (RwChar*)RwCalloc(100, sizeof(RwChar)); rwsprintf(_VMList[i],"%lu X %lu X %lu", vm.width, vm.height, vm.depth); } else _VMList[i] = NULL; } else _VMList[i] = NULL; } return _VMList; } /* ***************************************************************************** */ void _psSelectScreenVM(RwInt32 videoMode) { RwTexDictionarySetCurrent( NULL ); FrontEndMenuManager.UnloadTextures(); if ( !_psSetVideoMode(RwEngineGetCurrentSubSystem(), videoMode) ) { RsGlobal.quit = TRUE; ShowWindow(PSGLOBAL(window), SW_HIDE); MessageBoxW(NULL, (LPCWSTR)TheText.Get("WIN_RSZ"), // Failed to select new screen resolution (LPCWSTR)TheText.Get("WIN_TTL"), // Grand Theft Auto III MB_OK); } else FrontEndMenuManager.LoadAllTextures(); } /* ***************************************************************************** */ void WaitForState(FILTER_STATE State) { HRESULT hr; ASSERT(pMC != NULL); // Make sure we have switched to the required state LONG lfs; do { hr = pMC->GetState(10, &lfs); } while (State != lfs); } /* ***************************************************************************** */ void HandleGraphEvent(void) { LONG evCode, evParam1, evParam2; HRESULT hr=S_OK; ASSERT(pME != NULL); // Process all queued events while (SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR *)&evParam1, (LONG_PTR *)&evParam2, 0))) { // Free memory associated with callback, since we're not using it hr = pME->FreeEventParams(evCode, evParam1, evParam2); // If this is the end of the clip, reset to beginning if (EC_COMPLETE == evCode) { switch (gGameState) { case GS_LOGO_MPEG: { gGameState = GS_INIT_INTRO_MPEG; TRACE("gGameState = GS_INIT_INTRO_MPEG"); break; } case GS_INTRO_MPEG: { gGameState = GS_INIT_ONCE; TRACE("gGameState = GS_INIT_ONCE"); break; } default: { break; } } pME->SetNotifyWindow((OAHWND)NULL, 0, 0); } } } /* ***************************************************************************** */ LRESULT CALLBACK MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) { POINTS points; static BOOL noMemory = FALSE; switch( message ) { case WM_SETCURSOR: { ShowCursor(FALSE); SetCursor(NULL); break; // is this correct ? } case WM_SIZE: { RwRect r; r.x = 0; r.y = 0; r.w = LOWORD(lParam); r.h = HIWORD(lParam); if (RwInitialised && r.h > 0 && r.w > 0) { RsEventHandler(rsCAMERASIZE, &r); if (r.w != LOWORD(lParam) && r.h != HIWORD(lParam)) { WINDOWPLACEMENT wp; /* failed to create window of required size */ noMemory = TRUE; /* stop re-sizing */ ReleaseCapture(); /* handle maximised window */ GetWindowPlacement(window, &wp); if (wp.showCmd == SW_SHOWMAXIMIZED) { SendMessage(window, WM_WINDOWPOSCHANGED, 0, 0); } } else { noMemory = FALSE; } } return 0L; } case WM_SIZING: { /* * Handle event to ensure window contents are displayed during re-size * as this can be disabled by the user, then if there is not enough * memory things don't work. */ RECT *newPos = (LPRECT) lParam; RECT rect; /* redraw window */ if (RwInitialised && gGameState == GS_PLAYING_GAME) { RsEventHandler(rsIDLE, (void *)TRUE); } /* Manually resize window */ rect.left = rect.top = 0; rect.bottom = newPos->bottom - newPos->top; rect.right = newPos->right - newPos->left; SetWindowPos(window, HWND_TOP, rect.left, rect.top, (rect.right - rect.left), (rect.bottom - rect.top), SWP_NOMOVE); return 0L; } case WM_LBUTTONDOWN: { SetCapture(window); return 0L; } case WM_RBUTTONDOWN: { SetCapture(window); return 0L; } case WM_MBUTTONDOWN: { SetCapture(window); return 0L; } case WM_MOUSEWHEEL: { return 0L; } case WM_MOUSEMOVE: { points = MAKEPOINTS(lParam); FrontEndMenuManager.m_nMouseTempPosX = points.x; FrontEndMenuManager.m_nMouseTempPosY = points.y; return 0L; } case WM_LBUTTONUP: { ReleaseCapture(); return 0L; } case WM_RBUTTONUP: { ReleaseCapture(); return 0L; } case WM_MBUTTONUP: { ReleaseCapture(); return 0L; } case WM_KEYDOWN: { RsKeyCodes ks; if ( _InputTranslateKey(&ks, lParam, wParam) ) RsKeyboardEventHandler(rsKEYDOWN, &ks); if ( wParam == VK_SHIFT ) _InputTranslateShiftKeyUpDown(&ks); return 0L; } case WM_KEYUP: { RsKeyCodes ks; if ( _InputTranslateKey(&ks, lParam, wParam) ) RsKeyboardEventHandler(rsKEYUP, &ks); if ( wParam == VK_SHIFT ) _InputTranslateShiftKeyUpDown(&ks); return 0L; } case WM_SYSKEYDOWN: { RsKeyCodes ks; if ( _InputTranslateKey(&ks, lParam, wParam) ) RsKeyboardEventHandler(rsKEYDOWN, &ks); if ( wParam == VK_SHIFT ) _InputTranslateShiftKeyUpDown(&ks); return 0L; } case WM_SYSKEYUP: { RsKeyCodes ks; if ( _InputTranslateKey(&ks, lParam, wParam) ) RsKeyboardEventHandler(rsKEYUP, &ks); if ( wParam == VK_SHIFT ) _InputTranslateShiftKeyUpDown(&ks); return 0L; } case WM_ACTIVATEAPP: { switch ( gGameState ) { case GS_LOGO_MPEG: case GS_INTRO_MPEG: { ASSERT(pMC != NULL); LONG state; pMC->GetState(10, &state); if ( !(BOOL)wParam ) // losing activation { if ( state == State_Running && pMC != NULL ) { HRESULT hr = pMC->Pause(); if (hr == S_FALSE) OutputDebugString("Failed to pause the MPEG"); else WaitForState(State_Paused); } } else { CenterVideo(); if ( state != State_Running && pMC != NULL ) { HRESULT hr = pMC->Run(); if ( hr == S_FALSE ) OutputDebugString("Failed to run the MPEG"); else { WaitForState(State_Running); SetFocus(PSGLOBAL(window)); } } } break; } case GS_START_UP: { if ( !(BOOL)wParam && PSGLOBAL(fullScreen) ) // losing activation startupDeactivate = TRUE; break; } } CPad::GetPad(0)->Clear(false); CPad::GetPad(1)->Clear(false); return 0L; } case WM_TIMER: { return 0L; } case WM_GRAPHNOTIFY: { if (gGameState == GS_INTRO_MPEG || gGameState == GS_LOGO_MPEG) HandleGraphEvent(); break; } case WM_CLOSE: case WM_DESTROY: { /* * Quit message handling. */ ClipCursor(NULL); _InputShutdown(); PostQuitMessage(0); return 0L; } case WM_DEVICECHANGE: { if( wParam == DBT_DEVICEREMOVECOMPLETE ) { PDEV_BROADCAST_HDR pDev = (PDEV_BROADCAST_HDR)lParam; if (pDev->dbch_devicetype != DBT_DEVTYP_VOLUME) break; if ( DMAudio.IsAudioInitialised() ) { PDEV_BROADCAST_VOLUME pVol = (PDEV_BROADCAST_VOLUME)pDev; if ( pVol->dbcv_flags & DBTF_MEDIA ) { Char c = DMAudio.GetCDAudioDriveLetter(); if ( c >= 'A' && pVol->dbcv_unitmask & (1 << (c - 'A')) ) { OutputDebugString("About to check CD drive..."); while ( true ) { FrontEndMenuManager.WaitForUserCD(); if ( !FrontEndMenuManager.m_bQuitGameNoCD ) { if ( DMAudio.CheckForAnAudioFileOnCD() ) { OutputDebugString("GTA3 Audio CD has been inserted"); break; } } else { OutputDebugString("Exiting game as Audio CD was not inserted"); break; } } } } } } break; } } /* * Let Windows handle all other messages. */ return DefWindowProc(window, message, wParam, lParam); } /* ***************************************************************************** */ RwBool IsForegroundApp() { return !!ForegroundApp; } UINT GetBestRefreshRate(UINT width, UINT height, UINT depth) { LPDIRECT3D8 d3d = Direct3DCreate8(D3D_SDK_VERSION); ASSERT(d3d != NULL); INT refreshRate = -1; D3DFORMAT format; if ( depth == 32 ) format = D3DFMT_X8R8G8B8; else if ( depth == 24 ) format = D3DFMT_R8G8B8; else format = D3DFMT_R5G6B5; UINT modeCount = d3d->GetAdapterModeCount(GcurSel); for ( UINT i = 0; i < modeCount; i++ ) { D3DDISPLAYMODE mode; d3d->EnumAdapterModes(GcurSel, i, &mode); if ( mode.Width == width && mode.Height == height && mode.Format == format ) { if ( mode.RefreshRate == 0 ) return 0; #pragma warning( push ) #pragma warning( disable : 4018) if ( mode.RefreshRate < refreshRate && mode.RefreshRate >= 60 ) refreshRate = mode.RefreshRate; #pragma warning( pop ) } } #ifdef FIX_BUGS d3d->Release(); #endif if ( refreshRate == -1 ) return -1; return refreshRate; } /* ***************************************************************************** */ RwBool psSelectDevice() { RwVideoMode vm; RwInt32 subSysNum; RwInt32 AutoRenderer = 0; RwBool modeFound = FALSE; if ( !useDefault ) { GnumSubSystems = RwEngineGetNumSubSystems(); if ( !GnumSubSystems ) { return FALSE; } /* Just to be sure ... */ GnumSubSystems = (GnumSubSystems > MAX_SUBSYSTEMS) ? MAX_SUBSYSTEMS : GnumSubSystems; /* Get the names of all the sub systems */ for (subSysNum = 0; subSysNum < GnumSubSystems; subSysNum++) { RwEngineGetSubSystemInfo(&GsubSysInfo[subSysNum], subSysNum); } /* Get the default selection */ GcurSel = RwEngineGetCurrentSubSystem(); } /* Set the driver to use the correct sub system */ if (!RwEngineSetSubSystem(GcurSel)) { return FALSE; } if ( !useDefault ) { if ( _psGetVideoModeList()[FrontEndMenuManager.m_nDisplayVideoMode] && FrontEndMenuManager.m_nDisplayVideoMode ) { FrontEndMenuManager.m_nPrefsVideoMode = FrontEndMenuManager.m_nDisplayVideoMode; GcurSelVM = FrontEndMenuManager.m_nDisplayVideoMode; } else { while ( !modeFound && GcurSelVM < RwEngineGetNumVideoModes() ) { RwEngineGetVideoModeInfo(&vm, GcurSelVM); if ( defaultFullscreenRes && vm.width != 640 || vm.height != 480 || vm.depth != 16 || !(vm.flags & rwVIDEOMODEEXCLUSIVE) ) ++GcurSelVM; else modeFound = TRUE; } if ( !modeFound ) { MessageBox(NULL, "Cannot find 640x480 video mode", "GTA3", MB_OK); return FALSE; } } } RwEngineGetVideoModeInfo(&vm, GcurSelVM); FrontEndMenuManager.m_nCurrOption = 0; /* Set up the video mode and set the apps window * dimensions to match */ if (!RwEngineSetVideoMode(GcurSelVM)) { return FALSE; } if (vm.flags & rwVIDEOMODEEXCLUSIVE) { debug("%dx%dx%d", vm.width, vm.height, vm.depth); UINT refresh = GetBestRefreshRate(vm.width, vm.height, vm.depth); if ( refresh != (UINT)-1 ) { debug("refresh %d", refresh); RwD3D8EngineSetRefreshRate((RwUInt32)refresh); } } if (vm.flags & rwVIDEOMODEEXCLUSIVE) { RsGlobal.maximumWidth = vm.width; RsGlobal.maximumHeight = vm.height; RsGlobal.width = vm.width; RsGlobal.height = vm.height; PSGLOBAL(fullScreen) = TRUE; } return TRUE; } /* ***************************************************************************** */ RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode) { RwInitialised = FALSE; RsEventHandler(rsRWTERMINATE, NULL); GcurSel = subSystem; GcurSelVM = videoMode; useDefault = TRUE; if ( RsEventHandler(rsRWINITIALISE, PSGLOBAL(window)) == rsEVENTERROR ) return FALSE; RwInitialised = TRUE; useDefault = FALSE; RwRect r; r.x = 0; r.y = 0; r.w = RsGlobal.maximumWidth; r.h = RsGlobal.maximumHeight; RsEventHandler(rsCAMERASIZE, &r); return TRUE; } /* ***************************************************************************** */ static RwChar ** CommandLineToArgv(RwChar *cmdLine, RwInt32 *argCount) { RwInt32 numArgs = 0; RwBool inArg, inString; RwInt32 i, len; RwChar *res, *str, **aptr; len = strlen(cmdLine); /* * Count the number of arguments... */ inString = FALSE; inArg = FALSE; for(i=0; i<=len; i++) { if( cmdLine[i] == '"' ) { inString = !inString; } if( (cmdLine[i] <= ' ' && !inString) || i == len ) { if( inArg ) { inArg = FALSE; numArgs++; } } else if( !inArg ) { inArg = TRUE; } } /* * Allocate memory for result... */ res = (RwChar *)malloc(sizeof(RwChar *) * numArgs + len + 1); str = res + sizeof(RwChar *) * numArgs; aptr = (RwChar **)res; strcpy(str, cmdLine); /* * Walk through cmdLine again this time setting pointer to each arg... */ inArg = FALSE; inString = FALSE; for(i=0; i<=len; i++) { if( cmdLine[i] == '"' ) { inString = !inString; } if( (cmdLine[i] <= ' ' && !inString) || i == len ) { if( inArg ) { if( str[i-1] == '"' ) { str[i-1] = '\0'; } else { str[i] = '\0'; } inArg = FALSE; } } else if( !inArg && cmdLine[i] != '"' ) { inArg = TRUE; *aptr++ = &str[i]; } } *argCount = numArgs; return (RwChar **)res; } /* ***************************************************************************** */ void InitialiseLanguage() { #pragma warning( push ) #pragma warning( disable : 4302) WORD primUserLCID = PRIMARYLANGID(GetSystemDefaultLCID()); WORD primSystemLCID = PRIMARYLANGID(GetUserDefaultLCID()); WORD primLayout = PRIMARYLANGID(GetKeyboardLayout(0)); WORD subUserLCID = SUBLANGID(GetSystemDefaultLCID()); WORD subSystemLCID = SUBLANGID(GetUserDefaultLCID()); WORD subLayout = SUBLANGID(GetKeyboardLayout(0)); #pragma warning( pop ) if ( primUserLCID == LANG_GERMAN || primSystemLCID == LANG_GERMAN || primLayout == LANG_GERMAN ) { CGame::nastyGame = false; CMenuManager::m_PrefsAllowNastyGame = false; CGame::germanGame = true; } if ( primUserLCID == LANG_FRENCH || primSystemLCID == LANG_FRENCH || primLayout == LANG_FRENCH ) { CGame::nastyGame = false; CMenuManager::m_PrefsAllowNastyGame = false; CGame::frenchGame = true; } if ( subUserLCID == SUBLANG_ENGLISH_AUS || subSystemLCID == SUBLANG_ENGLISH_AUS || subLayout == SUBLANG_ENGLISH_AUS ) CGame::noProstitutes = true; Int32 lang; switch ( primSystemLCID ) { case LANG_GERMAN: { lang = LANG_GERMAN; break; } case LANG_FRENCH: { lang = LANG_FRENCH; break; } case LANG_SPANISH: { lang = LANG_SPANISH; break; } case LANG_ITALIAN: { lang = LANG_ITALIAN; break; } default: { lang = ( subSystemLCID == SUBLANG_ENGLISH_AUS ) ? -99 : LANG_ENGLISH; break; } } CMenuManager::OS_Language = primUserLCID; switch ( lang ) { case LANG_GERMAN: { CMenuManager::m_PrefsLanguage = LANGUAGE_GERMAN; break; } case LANG_SPANISH: { CMenuManager::m_PrefsLanguage = LANGUAGE_SPANISH; break; } case LANG_FRENCH: { CMenuManager::m_PrefsLanguage = LANGUAGE_FRENCH; break; } case LANG_ITALIAN: { CMenuManager::m_PrefsLanguage = LANGUAGE_ITALIAN; break; } default: { CMenuManager::m_PrefsLanguage = LANGUAGE_AMERICAN; break; } } TheText.Unload(); TheText.Load(); } /* ***************************************************************************** */ void CenterVideo(void) { HRESULT hr = S_OK; RECT rect; ASSERT(pVW != NULL); GetClientRect(PSGLOBAL(window), &rect); JIF(pVW->SetWindowPosition(rect.left, rect.top, rect.right, rect.bottom)); JIF(pVW->put_MessageDrain((OAHWND) PSGLOBAL(window))); SetFocus(PSGLOBAL(window)); } /* ***************************************************************************** */ void PlayMovieInWindow(int cmdShow, LPTSTR szFile) { WCHAR wFileName[256]; HRESULT hr; // Clear open dialog remnants before calling RenderFile() UpdateWindow(PSGLOBAL(window)); // Convert filename to wide character string MultiByteToWideChar(CP_ACP, 0, szFile, -1, wFileName, sizeof(wFileName) - 1); // Initialize COM JIF(CoInitialize(NULL)); // Get the interface for DirectShow's GraphBuilder JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGB)); if(SUCCEEDED(hr)) { // Have the graph builder construct its the appropriate graph automatically JIF(pGB->RenderFile(&wFileName[0], NULL)); // QueryInterface for DirectShow interfaces JIF(pGB->QueryInterface(IID_IMediaControl, (void **)&pMC)); JIF(pGB->QueryInterface(IID_IMediaEventEx, (void **)&pME)); JIF(pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS)); // Query for video interfaces, which may not be relevant for audio files JIF(pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW)); JIF(pVW->put_Owner((OAHWND) PSGLOBAL(window))); JIF(pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)); // Have the graph signal event via window callbacks for performance JIF(pME->SetNotifyWindow((OAHWND)PSGLOBAL(window), WM_GRAPHNOTIFY, 0)); CenterVideo(); // Run the graph to play the media file JIF(pMC->Run()); SetFocus(PSGLOBAL(window)); } ASSERT(pGB != NULL); ASSERT(pVW != NULL); ASSERT(pME != NULL); ASSERT(pMC != NULL); if(FAILED(hr)) CloseClip(); } /* ***************************************************************************** */ void CloseInterfaces(void) { // Release and zero DirectShow interfaces SAFE_RELEASE(pME); SAFE_RELEASE(pMS); SAFE_RELEASE(pMC); SAFE_RELEASE(pVW); SAFE_RELEASE(pGB); } /* ***************************************************************************** */ void CloseClip(void) { HRESULT hr; // Stop playback if(pMC) hr = pMC->Stop(); // Free DirectShow interfaces CloseInterfaces(); } /* ***************************************************************************** */ void HandleExit() { MSG message; while ( PeekMessage(&message, NULL, 0U, 0U, PM_REMOVE|PM_NOYIELD) ) { if( message.message == WM_QUIT ) { RsGlobal.quit = TRUE; } else { TranslateMessage(&message); DispatchMessage(&message); } } } /* ***************************************************************************** */ int PASCAL _WinMain(HINSTANCE instance, HINSTANCE prevInstance __RWUNUSED__, CMDSTR cmdLine, int cmdShow) { MSG message; RwV2d pos; RwInt32 argc, i; RwChar **argv; SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, NULL, SPIF_SENDCHANGE); /* * Initialize the platform independent data. * This will in turn initialize the platform specific data... */ if( RsEventHandler(rsINITIALISE, NULL) == rsEVENTERROR ) { return FALSE; } /* * Register the window class... */ if( !InitApplication(instance) ) { return FALSE; } /* * Get proper command line params, cmdLine passed to us does not * work properly under all circumstances... */ cmdLine = GetCommandLine(); /* * Parse command line into standard (argv, argc) parameters... */ argv = CommandLineToArgv(cmdLine, &argc); /* * Parse command line parameters (except program name) one at * a time BEFORE RenderWare initialization... */ for(i=1; iGetLeftMouseJustDown() ) ++gGameState; else if ( CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetExtEnterJustDown() ) ++gGameState; else if ( CPad::GetPad(0)->GetCharJustDown(' ') ) ++gGameState; else if ( CPad::GetPad(0)->GetLeftAltJustDown() || CPad::GetPad(0)->GetRightAltJustDown() ) ++gGameState; else if ( CPad::GetPad(0)->GetTabJustDown() ) ++gGameState; break; } case GS_INIT_INTRO_MPEG: { CloseClip(); CoUninitialize(); if ( CMenuManager::OS_Language == LANG_FRENCH || CMenuManager::OS_Language == LANG_GERMAN ) PlayMovieInWindow(cmdShow, "movies\\GTAtitlesGER.mpg"); else PlayMovieInWindow(cmdShow, "movies\\GTAtitles.mpg"); gGameState = GS_INTRO_MPEG; TRACE("gGameState = GS_INTRO_MPEG;"); break; } case GS_INTRO_MPEG: { CPad::UpdatePads(); if ( startupDeactivate || ControlsManager.GetJoyButtonJustDown() != 0 ) ++gGameState; else if ( CPad::GetPad(0)->GetLeftMouseJustDown() ) ++gGameState; else if ( CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetExtEnterJustDown() ) ++gGameState; else if ( CPad::GetPad(0)->GetCharJustDown(' ') ) ++gGameState; else if ( CPad::GetPad(0)->GetLeftAltJustDown() || CPad::GetPad(0)->GetRightAltJustDown() ) ++gGameState; else if ( CPad::GetPad(0)->GetTabJustDown() ) ++gGameState; break; } case GS_INIT_ONCE: { CloseClip(); CoUninitialize(); LoadingScreen(NULL, NULL, "loadsc0"); if ( !CGame::InitialiseOnceAfterRW() ) RsGlobal.quit = TRUE; gGameState = GS_INIT_FRONTEND; TRACE("gGameState = GS_INIT_FRONTEND;"); break; } case GS_INIT_FRONTEND: { LoadingScreen(NULL, NULL, "loadsc0"); FrontEndMenuManager.m_bGameNotLoaded = true; CMenuManager::m_bStartUpFrontEndRequested = true; if ( defaultFullscreenRes ) { defaultFullscreenRes = FALSE; FrontEndMenuManager.m_nPrefsVideoMode = GcurSelVM; FrontEndMenuManager.m_nDisplayVideoMode = GcurSelVM; } gGameState = GS_FRONTEND; TRACE("gGameState = GS_FRONTEND;"); break; } case GS_FRONTEND: { GetWindowPlacement(PSGLOBAL(window), &wp); if ( wp.showCmd != SW_SHOWMINIMIZED ) RsEventHandler(rsFRONTENDIDLE, NULL); if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bLoadingSavedGame ) { gGameState = GS_INIT_PLAYING_GAME; TRACE("gGameState = GS_INIT_PLAYING_GAME;"); } if ( FrontEndMenuManager.m_bLoadingSavedGame ) { InitialiseGame(); FrontEndMenuManager.m_bGameNotLoaded = false; gGameState = GS_PLAYING_GAME; TRACE("gGameState = GS_PLAYING_GAME;"); } break; } case GS_INIT_PLAYING_GAME: { InitialiseGame(); FrontEndMenuManager.m_bGameNotLoaded = false; gGameState = GS_PLAYING_GAME; TRACE("gGameState = GS_PLAYING_GAME;"); break; } case GS_PLAYING_GAME: { Float ms = (Float)CTimer::GetCurrentTimeInCycles() / (Float)CTimer::GetCyclesPerMillisecond(); if ( RwInitialised ) { if (!CMenuManager::m_PrefsFrameLimiter || (1000.0f / (Float)RsGlobal.maxFPS) < ms) RsEventHandler(rsIDLE, (void *)TRUE); } break; } } } else { if ( RwCameraBeginUpdate(Scene.camera) ) { RwCameraEndUpdate(Scene.camera); ForegroundApp = TRUE; RsEventHandler(rsACTIVATE, (void *)TRUE); } WaitMessage(); } } /* * About to shut down - block resize events again... */ RwInitialised = FALSE; FrontEndMenuManager.UnloadTextures(); if ( !FrontEndMenuManager.m_bStartGameLoading ) break; CPad::ResetCheats(); CPad::StopPadsShaking(); DMAudio.ChangeMusicMode(_TODOCONST(3)); CTimer::Stop(); if ( FrontEndMenuManager.m_bLoadingSavedGame ) { CGame::ShutDownForRestart(); CGame::InitialiseWhenRestarting(); DMAudio.ChangeMusicMode(_TODOCONST(1)); LoadSplash(GetLevelSplashScreen(CGame::currLevel)); FrontEndMenuManager.m_bLoadingSavedGame = false; } else { if ( gGameState == GS_PLAYING_GAME ) CGame::ShutDown(); CTimer::Stop(); if ( FrontEndMenuManager.m_bFirstTime == true ) { gGameState = GS_INIT_FRONTEND; TRACE("gGameState = GS_INIT_FRONTEND;"); } else { gGameState = GS_INIT_PLAYING_GAME; TRACE("gGameState = GS_INIT_PLAYING_GAME;"); } } FrontEndMenuManager.m_bFirstTime = false; FrontEndMenuManager.m_bStartGameLoading = false; } if ( gGameState == GS_PLAYING_GAME ) CGame::ShutDown(); DMAudio.Terminate(); _psFreeVideoModeList(); /* * Tidy up the 3D (RenderWare) components of the application... */ RsEventHandler(rsRWTERMINATE, NULL); /* * Kill the window... */ DestroyWindow(PSGLOBAL(window)); /* * Free the platform dependent data... */ RsEventHandler(rsTERMINATE, NULL); /* * Free the argv strings... */ free(argv); ShowCursor(TRUE); SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &SavedStickyKeys, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETPOWEROFFACTIVE, TRUE, NULL, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETLOWPOWERACTIVE, TRUE, NULL, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, NULL, SPIF_SENDCHANGE); SetErrorMode(0); return message.wParam; } /* ***************************************************************************** */ _TODO(""); // _InputInitialise .text 005830D0 00000033 00000000 00000000 R . . . . . . //_InputInitialiseMouse .text 00583110 00000073 00000004 00000000 R . . . . . . //CapturePad(int) .text 00583190 000003E7 00000128 00000004 R . . . . . . //_InputInitialiseJoys .text 00583580 000000EA 00000044 00000000 R . . . . . . //_InputAddJoyStick .text 00583670 00000197 00000164 00000008 R . . . . . . //_InputAddJoys .text 00583810 0000005B 00000004 00000000 R . . . . . . //_InputGetMouseState .text 00583870 00000095 00000008 00000004 R . . . . T . //_InputShutdown .text 00583910 00000021 00000004 00000000 R . . . . . . //_InputEnumDevicesCallback .text 00583940 000000DB 00000008 00000004 R . . . . . . //_InputTranslateKey .text 00583A20 0000039C 00000008 0000000C R . . . . T . //_InputTranslateShiftKeyUpDown .text 00583DC0 00000088 00000004 00000004 R . . . . T . //_InputTranslateShiftKey .text 00583E50 00000085 00000008 00000009 R . . . . T . //_InputIsExtended .text 00583EE0 00000013 00000000 00000004 R . . . . . . STARTPATCHES InjectHook(0x580B70, _psCreateFolder, PATCH_JUMP); InjectHook(0x580BB0, _psGetUserFilesFolder, PATCH_JUMP); InjectHook(0x580C70, psCameraBeginUpdate, PATCH_JUMP); InjectHook(0x580CA0, psCameraShowRaster, PATCH_JUMP); InjectHook(0x580CE0, psTimer, PATCH_JUMP); InjectHook(0x580D20, psMouseSetPos, PATCH_JUMP); InjectHook(0x580E10, psGetMemoryFunctions, PATCH_JUMP); InjectHook(0x580E20, psInstallFileSystem, PATCH_JUMP); InjectHook(0x580E30, psNativeTextureSupport, PATCH_JUMP); InjectHook(0x580E40, InitApplication, PATCH_JUMP); InjectHook(0x580EB0, InitInstance, PATCH_JUMP); InjectHook(0x580F30, _GetVideoMemInfo, PATCH_JUMP); InjectHook(0x580FA0, GetDXVersion, PATCH_JUMP); InjectHook(0x5810C0, _psGetCpuVendr, PATCH_JUMP); InjectHook(0x5810E0, _psGetCpuFeatures, PATCH_JUMP); InjectHook(0x5810F0, _psGetCpuFeaturesEx, PATCH_JUMP); InjectHook(0x581120, _psPrintCpuInfo, PATCH_JUMP); InjectHook(0x581180, psInitialise, PATCH_JUMP); InjectHook(0x581460, psTerminate, PATCH_JUMP); InjectHook(0x581470, _psGetNumVideModes, PATCH_JUMP); InjectHook(0x581480, _psFreeVideoModeList, PATCH_JUMP); InjectHook(0x5814F0, _psGetVideoModeList, PATCH_JUMP); InjectHook(0x581630, _psSelectScreenVM, PATCH_JUMP); InjectHook(0x5816B0, WaitForState, PATCH_JUMP); InjectHook(0x5816E0, HandleGraphEvent, PATCH_JUMP); InjectHook(0x581790, MainWndProc, PATCH_JUMP); InjectHook(0x581C90, IsForegroundApp, PATCH_JUMP); InjectHook(0x581CB0, GetBestRefreshRate, PATCH_JUMP); InjectHook(0x581D80, psSelectDevice, PATCH_JUMP); InjectHook(0x581F90, _psSetVideoMode, PATCH_JUMP); InjectHook(0x582030, CommandLineToArgv, PATCH_JUMP); InjectHook(0x582160, InitialiseLanguage, PATCH_JUMP); InjectHook(0x5822F0, CenterVideo, PATCH_JUMP); InjectHook(0x582380, PlayMovieInWindow, PATCH_JUMP); InjectHook(0x5825E0, CloseInterfaces, PATCH_JUMP); InjectHook(0x582680, CloseClip, PATCH_JUMP); InjectHook(0x5826A0, HandleExit, PATCH_JUMP); InjectHook(0x582710, _WinMain, PATCH_JUMP); ENDPATCHES