diff options
Diffstat (limited to '')
-rw-r--r-- | src/skel/win/resource.h | 20 | ||||
-rw-r--r-- | src/skel/win/win.cpp | 2152 | ||||
-rw-r--r-- | src/skel/win/win.h | 46 | ||||
-rw-r--r-- | src/skel/win/win.rc | 37 |
4 files changed, 2255 insertions, 0 deletions
diff --git a/src/skel/win/resource.h b/src/skel/win/resource.h new file mode 100644 index 00000000..2fb3dc50 --- /dev/null +++ b/src/skel/win/resource.h @@ -0,0 +1,20 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by dungeon.rc +// +#define IDD_DIALOG1 104 +#define IDC_DEVICESEL 1000 +#define IDC_VIDMODE 1001 +#define IDEXIT 1002 +#define IDC_SELECTDEVICE 1005 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 104 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp new file mode 100644 index 00000000..35575892 --- /dev/null +++ b/src/skel/win/win.cpp @@ -0,0 +1,2152 @@ +#define _WIN32_WINDOWS 0x0410 +#define WINVER 0x0500 +#define DIRECTINPUT_VERSION 0x0800 +#define WM_GRAPHNOTIFY WM_USER+13 + +#include <windows.h> +#include <mmsystem.h> +#include <shellapi.h> + +#include <windowsx.h> +#include <basetsd.h> + +#include <regstr.h> +#include <shlobj.h> + +#include <dbt.h> + +#pragma warning( push ) +#pragma warning( disable : 4005) +#include <ddraw.h> +#include <dinput.h> +#include <DShow.h> +//#include <dmusici.h> +#pragma warning( pop ) + +#pragma comment( lib, "Winmm.lib" ) +#pragma comment( lib, "dxguid.lib" ) +#pragma comment( lib, "strmiids.lib" ) + +#if (defined(_MSC_VER)) +#include <tchar.h> +#endif /* (defined(_MSC_VER)) */ +#include <stdio.h> +#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 RwInitialised = FALSE; +static RwSubSystemInfo GsubSysInfo[MAX_SUBSYSTEMS]; +static RwInt32 GnumSubSystems = 0; +static RwInt32 GcurSel = 0, GcurSelVM = 0; + +static RwBool startupDeactivate; +static RwBool useDefault; +static RwBool defaultFullscreenRes = TRUE; + +/* 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; + +#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 hr;} + + + +#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" + +// 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 RwUInt32 GetBestRefreshRate(RwUInt32 width, RwUInt32 height, RwUInt32 depth) { EAXJMP(0x581CB0); } +WRAPPER HRESULT _GetVideoMemInfo(DWORD *total, DWORD *avaible) { EAXJMP(0x580F30); } + +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 void LoadingScreen(char const *msg1, char const *msg2, char const *screen) { EAXJMP(0x48D770); } +WRAPPER Bool InitialiseGame(void) { EAXJMP(0x48E7E0); } +WRAPPER const Char *GetLevelSplashScreen(Int32 number) { EAXJMP(0x48D750); } +WRAPPER CSprite2d *LoadSplash(const char *name) { EAXJMP(0x48D550); } +// + +void InitialiseLanguage(); +RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode); +HRESULT 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); +} + +_TODO("") +//_GetVideoMemInfo 0x580F30 + +/* + ***************************************************************************** + */ +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; + + PsGlobal.fullScreen = FALSE; + + 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; + + _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(); +} + +/* + ***************************************************************************** + */ +HRESULT WaitForState(FILTER_STATE State) +{ + HRESULT hr; + + // Make sure we have switched to the required state + LONG lfs; + do + { + hr = pMC->GetState(10, &lfs); + } while (State != lfs); + + return hr; +} + +/* + ***************************************************************************** + */ +HRESULT HandleGraphEvent(void) +{ + LONG evCode, evParam1, evParam2; + HRESULT hr=S_OK; + + // 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; + break; + case GS_INTRO_MPEG: + gGameState = GS_INIT_ONCE; + break; + default: + break; + } + + pME->SetNotifyWindow((OAHWND)NULL, 0, 0); + } + } + + return hr; +} + +/* + ***************************************************************************** + */ + +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: + { + 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; +} + +_TODO("") +//GetBestRefreshRate(uint,uint,uint) 00581CB0 + + +/* + ***************************************************************************** + */ +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); + + RwUInt32 refresh = GetBestRefreshRate(vm.width, vm.height, vm.depth); + + if ( refresh != (RwUInt32)-1 ) + { + debug("refresh %d", refresh); + RwD3D8EngineSetRefreshRate(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(); +} + +/* + ***************************************************************************** + */ +HRESULT CenterVideo(void) +{ + HRESULT hr = S_OK; + RECT rect; + + 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)); + + return hr; +} + +/* + ***************************************************************************** + */ +HRESULT 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)); + } + + if(FAILED(hr)) + CloseClip(); + + return hr; +} + +/* + ***************************************************************************** + */ +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; i<argc; i++) + { + RsEventHandler(rsPREINITCOMMANDLINE, argv[i]); + } + + /* + * Create the window... + */ + PSGLOBAL(window) = InitInstance(instance); + if( PSGLOBAL(window) == NULL ) + { + return FALSE; + } + + PSGLOBAL(instance) = instance; + + ControlsManager.MakeControllerActionsBlank(); + ControlsManager.InitDefaultControlConfiguration(); + + if ( _InputInitialise() == S_OK ) + { + _InputInitialiseMouse(); + _InputInitialiseJoys(); + } + + ControlsManager.InitDefaultControlConfigMouse(MousePointerStateHelper.GetMouseSetUp()); + + SetWindowLong(PSGLOBAL(window), GWL_STYLE, WS_POPUP); + SetWindowPos(PSGLOBAL(window), 0, 0, 0, 0, 0, + SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER| + SWP_FRAMECHANGED); + + /* + * Initialize the 3D (RenderWare) components of the app... + */ + if( rsEVENTERROR == RsEventHandler(rsRWINITIALISE, PSGLOBAL(window)) ) + { + DestroyWindow(PSGLOBAL(window)); + + RsEventHandler(rsTERMINATE, NULL); + + return FALSE; + } + + /* + * Parse command line parameters (except program name) one at + * a time AFTER RenderWare initialization... + */ + for(i=1; i<argc; i++) + { + RsEventHandler(rsCOMMANDLINE, argv[i]); + } + + /* + * Force a camera resize event... + */ + { + RwRect r; + + r.x = 0; + r.y = 0; + r.w = RsGlobal.maximumWidth; + r.h = RsGlobal.maximumHeight; + + RsEventHandler(rsCAMERASIZE, &r); + } + + SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, SPIF_SENDCHANGE); + SystemParametersInfo(SPI_SETPOWEROFFACTIVE, FALSE, NULL, SPIF_SENDCHANGE); + SystemParametersInfo(SPI_SETLOWPOWERACTIVE, FALSE, NULL, SPIF_SENDCHANGE); + + + STICKYKEYS SavedStickyKeys; + SavedStickyKeys.cbSize = sizeof(STICKYKEYS); + + SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &SavedStickyKeys, SPIF_SENDCHANGE); + + STICKYKEYS NewStickyKeys; + NewStickyKeys.cbSize = sizeof(STICKYKEYS); + NewStickyKeys.dwFlags = SKF_TWOKEYSOFF; + + SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &NewStickyKeys, SPIF_SENDCHANGE); + + + /* + * Show the window, and refresh it... + */ + ShowWindow(PSGLOBAL(window), cmdShow); + UpdateWindow(PSGLOBAL(window)); + + { + CFileMgr::SetDirMyDocuments(); + + Int32 gta3set = CFileMgr::OpenFile("gta3.set", "r"); + + if ( gta3set ) + { + ControlsManager.LoadSettings(gta3set); + CFileMgr::CloseFile(gta3set); + } + + CFileMgr::SetDir(""); + } + + SetErrorMode(SEM_FAILCRITICALERRORS); + + while ( TRUE ) + { + RwInitialised = TRUE; + + /* + * Set the initial mouse position... + */ + pos.x = RsGlobal.maximumWidth * 0.5f; + pos.y = RsGlobal.maximumHeight * 0.5f; + + RsMouseSetPos(&pos); + + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + + /* + * Enter the message processing loop... + */ + + while( !RsGlobal.quit && !FrontEndMenuManager.m_bStartGameLoading ) + { + if( PeekMessage(&message, NULL, 0U, 0U, PM_REMOVE|PM_NOYIELD) ) + { + if( message.message == WM_QUIT ) + { + break; + } + else + { + TranslateMessage(&message); + DispatchMessage(&message); + } + } + else if( ForegroundApp ) + { + switch ( gGameState ) + { + case GS_START_UP: + { + gGameState = GS_INIT_LOGO_MPEG; + break; + } + + case GS_INIT_LOGO_MPEG: + { + if ( !startupDeactivate ) + PlayMovieInWindow(cmdShow, "movies\\Logo.mpg"); + gGameState = GS_LOGO_MPEG; + break; + } + + case GS_LOGO_MPEG: + { + CPad::UpdatePads(); + if ( startupDeactivate || ControlsManager.GetJoyButtonJustDown() ) + ++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; + } + + 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; + break; + } + + case GS_INTRO_MPEG: + { + CPad::UpdatePads(); + if ( startupDeactivate || ControlsManager.GetJoyButtonJustDown() ) + ++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; + } + + case GS_INIT_ONCE: + { + CloseClip(); + CoUninitialize(); + + LoadingScreen(NULL, NULL, "loadsc0"); + + if ( !CGame::InitialiseOnceAfterRW() ) + RsGlobal.quit = TRUE; + + gGameState = GS_INIT_FRONTEND; + break; + } + + case GS_INIT_FRONTEND: + { + LoadingScreen(NULL, NULL, "loadsc0"); + + FrontEndMenuManager.m_bGameNotLoaded = true; + + CMenuManager::m_bStartUpFrontEndRequested = true; + + if ( defaultFullscreenRes ) + { + defaultFullscreenRes = 0; + FrontEndMenuManager.m_nPrefsVideoMode = GcurSelVM; + FrontEndMenuManager.m_nDisplayVideoMode = GcurSelVM; + } + + 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; + + if ( FrontEndMenuManager.m_bLoadingSavedGame ) + { + InitialiseGame(); + FrontEndMenuManager.m_bGameNotLoaded = false; + gGameState = GS_PLAYING_GAME; + } + break; + } + + case GS_INIT_PLAYING_GAME: + { + InitialiseGame(); + FrontEndMenuManager.m_bGameNotLoaded = false; + 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; + else + 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(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(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
\ No newline at end of file diff --git a/src/skel/win/win.h b/src/skel/win/win.h new file mode 100644 index 00000000..2fd6ab30 --- /dev/null +++ b/src/skel/win/win.h @@ -0,0 +1,46 @@ +#if (!defined(_PLATFORM_WIN_H)) +#define _PLATFORM_WIN_H + +#if (!defined(RSREGSETBREAKALLOC)) +#define RSREGSETBREAKALLOC(_name) /* No op */ +#endif /* (!defined(RSREGSETBREAKALLOC)) */ + +enum eGameState +{ + GS_START_UP = 0, + GS_INIT_LOGO_MPEG, + GS_LOGO_MPEG, + GS_INIT_INTRO_MPEG, + GS_INTRO_MPEG, + GS_INIT_ONCE, + GS_INIT_FRONTEND, + GS_FRONTEND, + GS_INIT_PLAYING_GAME, + GS_PLAYING_GAME, +}; + +enum eWinVersion +{ + OS_WIN95 = 0, + OS_WIN98, + oS_WINNT, + OS_WIN2000, + OS_WINXP, +}; + +extern RwUInt32 &gGameState; + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +extern LRESULT CALLBACK +MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* (!defined(_PLATFORM_WIN_H)) */ diff --git a/src/skel/win/win.rc b/src/skel/win/win.rc new file mode 100644 index 00000000..051f31ed --- /dev/null +++ b/src/skel/win/win.rc @@ -0,0 +1,37 @@ +#include "resource.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#if !defined(__GNU_C__) +#include "afxres.h" +#else +#include "winresrc.h" +#endif /* !defined(__GNU_C__) */ + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 90 +STYLE DS_MODALFRAME | DS_CENTER | DS_CENTERMOUSE | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Device Selection" +FONT 8, "MS Sans Serif" +BEGIN + COMBOBOX IDC_DEVICESEL,7,25,172,33,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + COMBOBOX IDC_VIDMODE,7,46,172,74,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + DEFPUSHBUTTON "EXIT",IDEXIT,103,69,52,14 + DEFPUSHBUTTON "OK",IDOK,28,69,50,14 + LTEXT "Please select the device to use:",IDC_SELECTDEVICE,7,7, + 137,8 +END + + |