From 6c1a1f7cd20a2674f33b5318e6e07a3a28d016f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Sun, 26 Apr 2020 13:25:03 +0300 Subject: Initial GLFW support --- src/skel/crossplatform.h | 67 +- src/skel/events.cpp | 9 +- src/skel/glfw/glfw.cpp | 1651 ++++++++++++++++++++++++++++++++++++++++++++++ src/skel/skeleton.cpp | 2 +- src/skel/win/win.cpp | 5 +- src/skel/win/win.h | 37 +- 6 files changed, 1723 insertions(+), 48 deletions(-) create mode 100644 src/skel/glfw/glfw.cpp (limited to 'src/skel') diff --git a/src/skel/crossplatform.h b/src/skel/crossplatform.h index 1b3ad7d6..342aab4e 100644 --- a/src/skel/crossplatform.h +++ b/src/skel/crossplatform.h @@ -1,5 +1,61 @@ #include +// This is the common include for platform/renderer specific skeletons(glfw, win etc.) and cross platform things (like Windows directories wrapper, platform specific global arrays etc.) + +// This only has as Win header. +#ifdef _WIN32 +#include "win.h" +#endif + +#ifdef RW_GL3 +typedef struct +{ + GLFWwindow* window; + RwBool fullScreen; + RwV2d lastMousePos; + double mouseWheel; // glfw doesn't cache it + int8 joy1id; + int8 joy2id; +} +psGlobalType; + +#define PSGLOBAL(var) (((psGlobalType *)(RsGlobal.ps))->var) + +void CapturePad(RwInt32 padID); +void joysChangeCB(int jid, int event); +#endif + +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, +#ifndef MASTER + GS_ANIMVIEWER, +#endif +}; +extern RwUInt32 gGameState; + +RwBool IsForegroundApp(); +void InitialiseLanguage(); +RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode); + +RwChar** _psGetVideoModeList(); +RwInt32 _psGetNumVideModes(); + +void _psSelectScreenVM(RwInt32 videoMode); +void HandleExit(); +void _InputTranslateShiftKeyUpDown(RsKeyCodes* rs); + +// Mostly wrappers around Windows functions + #ifndef MAX_PATH #if !defined _WIN32 || defined __MINGW32__ #define MAX_PATH PATH_MAX @@ -8,8 +64,6 @@ #endif #endif -// Mostly wrappers around Windows functions - // TODO: Remove USEALTERNATIVEWINFUNCS and don't use it anywhere when re3 becomes fully cross-platform, this is for testing // Codes compatible with Windows and Linux #if defined USEALTERNATIVEWINFUNCS || !defined _WIN32 || defined __MINGW32__ @@ -27,18 +81,13 @@ struct SYSTEMTIME { uint16 wMilliseconds; }; +void GetLocalTime_CP(SYSTEMTIME* out); #define GetLocalTime GetLocalTime_CP -#else -#include +#define OutputDebugString(s) re3_debug("[DBG-2]: " s "\n") #endif -void GetLocalTime_CP(SYSTEMTIME* out); - - // Only runs on GNU/POSIX/etc. #if !defined _WIN32 || defined __MINGW32__ -#define OutputDebugString(s) re3_debug("[DBG-2]: " s "\n") - #include #include #include diff --git a/src/skel/events.cpp b/src/skel/events.cpp index 7116833d..3e1e95b3 100644 --- a/src/skel/events.cpp +++ b/src/skel/events.cpp @@ -1,13 +1,14 @@ -#include "rwcore.h" -#include "skeleton.h" -#include "events.h" - #include "common.h" #include "Pad.h" #include "ControllerConfig.h" #include "Frontend.h" #include "Camera.h" +#include "rwcore.h" +#include "skeleton.h" +#include "events.h" + + /* ***************************************************************************** */ diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp new file mode 100644 index 00000000..0d7dc384 --- /dev/null +++ b/src/skel/glfw/glfw.cpp @@ -0,0 +1,1651 @@ +#if defined RW_GL3 && !defined LIBRW_SDL2 + +#define WITHWINDOWS +#include "common.h" + +#pragma warning( push ) +#pragma warning( disable : 4005) +#pragma warning( pop ) + +#pragma comment( lib, "Winmm.lib" ) // Needed for time + +#if (defined(_MSC_VER)) +#include +#endif /* (defined(_MSC_VER)) */ +#include +#include "rwcore.h" +#include "resource.h" +#include "skeleton.h" +#include "platform.h" +#include "crossplatform.h" + +#define MAX_SUBSYSTEMS (16) + + +using namespace rw; +EngineOpenParams openParams; + +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 useDefault; + +static RwBool defaultFullscreenRes = TRUE; + +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;} + +#include "patcher.h" +#include "main.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" +#include "AnimViewer.h" + +// TODO: This is used on selecting video mode, so either think something or remove it completely +DWORD _dwMemTotalVideo = 1024 * (1024 * 1024); // 1024 MB as placeholder +DWORD _dwMemAvailPhys; + +DWORD _dwOperatingSystemVersion; + +RwUInt32 gGameState; +/* + ***************************************************************************** + */ +void _psCreateFolder(const char *path) +{ +#ifdef _WIN32 + HANDLE hfle = CreateFile(path, GENERIC_READ, + FILE_SHARE_READ, + nil, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL, + nil); + + if ( hfle == INVALID_HANDLE_VALUE ) + CreateDirectory(path, nil); + else + CloseHandle(hfle); +#else + struct stat info; + char fullpath[PATH_MAX]; + realpath(path, fullpath); + + if (lstat(fullpath, &info) != 0) { + if (errno == ENOENT || (errno != EACCES && !S_ISDIR(info.st_mode))) { + mkdir(fullpath, 0755); + } + } +#endif +} + +/* + ***************************************************************************** + */ +const char *_psGetUserFilesFolder() +{ +#if defined USE_MY_DOCUMENTS && defined _WIN32 + 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; +#else + static CHAR szUserFiles[256]; + strcpy(szUserFiles, "userfiles"); + _psCreateFolder(szUserFiles); + return szUserFiles; +#endif +} + +/* + ***************************************************************************** + */ +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; + + glfwSetCursorPos(PSGLOBAL(window), point.x, point.y); + + PSGLOBAL(lastMousePos.x) = (RwInt32)pos->x; + + PSGLOBAL(lastMousePos.y) = (RwInt32)pos->y; + + return; +} + +/* + ***************************************************************************** + */ +RwMemoryFunctions* +psGetMemoryFunctions(void) +{ + return nil; +} + +/* + ***************************************************************************** + */ +RwBool +psInstallFileSystem(void) +{ + return (TRUE); +} + + +/* + ***************************************************************************** + */ +RwBool +psNativeTextureSupport(void) +{ + return true; +} + +/* + ***************************************************************************** + */ +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.0f; + + RsGlobal.ps = &PsGlobal; + + PsGlobal.fullScreen = FALSE; + + PsGlobal.joy1id = -1; + PsGlobal.joy2id = -1; + + 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 = OS_WIN95; + + 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; + } + } + + MEMORYSTATUS memstats; + GlobalMemoryStatus(&memstats); + + _dwMemAvailPhys = memstats.dwAvailPhys; + +#ifdef FIX_BUGS + debug("Physical memory size %u\n", memstats.dwTotalPhys); + debug("Available physical memory %u\n", memstats.dwAvailPhys); +#else + debug("Physical memory size %d\n", memstats.dwTotalPhys); + debug("Available physical memory %d\n", memstats.dwAvailPhys); +#endif + + 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 == nil ) + return TRUE; + + for ( i = 0; i < numModes; i++ ) + { + RwFree(_VMList[i]); + } + + RwFree(_VMList); + + _VMList = nil; + + return TRUE; +} + +/* + ***************************************************************************** + */ +RwChar **_psGetVideoModeList() +{ + RwInt32 numModes; + RwInt32 i; + + if ( _VMList != nil ) + { + 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] = nil; + } + else + _VMList[i] = nil; + } + + return _VMList; +} + +/* + ***************************************************************************** + */ +void _psSelectScreenVM(RwInt32 videoMode) +{ + RwTexDictionarySetCurrent( nil ); + + FrontEndMenuManager.UnloadTextures(); + + if ( !_psSetVideoMode(RwEngineGetCurrentSubSystem(), videoMode) ) + { + RsGlobal.quit = TRUE; + } + else + FrontEndMenuManager.LoadAllTextures(); +} + +/* + ***************************************************************************** + */ + +RwBool IsForegroundApp() +{ + return !!ForegroundApp; +} +/* +UINT GetBestRefreshRate(UINT width, UINT height, UINT depth) +{ + LPDIRECT3D8 d3d = Direct3DCreate8(D3D_SDK_VERSION); + + ASSERT(d3d != nil); + + UINT refreshRate = INT_MAX; + 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; + + if ( mode.RefreshRate < refreshRate && mode.RefreshRate >= 60 ) + refreshRate = mode.RefreshRate; + } + } + +#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 + { +#ifdef DEFAULT_NATIVE_RESOLUTION + // get the native video mode + HDC hDevice = GetDC(NULL); + int w = GetDeviceCaps(hDevice, HORZRES); + int h = GetDeviceCaps(hDevice, VERTRES); + int d = GetDeviceCaps(hDevice, BITSPIXEL); +#else + const int w = 640; + const int h = 480; + const int d = 16; +#endif + while ( !modeFound && GcurSelVM < RwEngineGetNumVideoModes() ) + { + RwEngineGetVideoModeInfo(&vm, GcurSelVM); + if ( defaultFullscreenRes && vm.width != w + || vm.height != h + || vm.depth != d + || !(vm.flags & rwVIDEOMODEEXCLUSIVE) ) + ++GcurSelVM; + else + modeFound = TRUE; + } + + if ( !modeFound ) + { +#ifdef DEFAULT_NATIVE_RESOLUTION + GcurSelVM = 1; +#else + MessageBox(nil, "Cannot find 640x480 video mode", "GTA3", MB_OK); + return FALSE; +#endif + } + } + } + + 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; + } + /* + TODO + 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, nil); + + 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() +{ + WORD primUserLCID = PRIMARYLANGID(GetSystemDefaultLCID()); + WORD primSystemLCID = PRIMARYLANGID(GetUserDefaultLCID()); + WORD primLayout = PRIMARYLANGID((DWORD)GetKeyboardLayout(0)); + + WORD subUserLCID = SUBLANGID(GetSystemDefaultLCID()); + WORD subSystemLCID = SUBLANGID(GetUserDefaultLCID()); + WORD subLayout = SUBLANGID((DWORD)GetKeyboardLayout(0)); + + 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; + +#ifdef NASTY_GAME + CGame::nastyGame = true; + CMenuManager::m_PrefsAllowNastyGame = true; + CGame::noProstitutes = false; +#endif + + 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 HandleExit() +{ + MSG message; + while ( PeekMessage(&message, nil, 0U, 0U, PM_REMOVE|PM_NOYIELD) ) + { + if( message.message == WM_QUIT ) + { + RsGlobal.quit = TRUE; + } + else + { + TranslateMessage(&message); + DispatchMessage(&message); + } + } +} + +void resizeCB(GLFWwindow* window, int width, int height) { + /* + * 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. + */ + /* redraw window */ + if (RwInitialised && (gGameState == GS_PLAYING_GAME || gGameState == GS_ANIMVIEWER)) + { + RsEventHandler((gGameState == GS_PLAYING_GAME ? rsIDLE : rsANIMVIEWER), (void*)TRUE); + } + + if (RwInitialised && height > 0 && width > 0) { + RwRect r; + + r.x = 0; + r.y = 0; + r.w = RsGlobal.maximumWidth; + r.h = RsGlobal.maximumHeight; + + RsEventHandler(rsCAMERASIZE, &r); + } + glfwSetWindowPos(window, 0, 0); +} + +void scrollCB(GLFWwindow* window, double xoffset, double yoffset) { + PSGLOBAL(mouseWheel) = yoffset; +} + +int keymap[GLFW_KEY_LAST + 1]; + +static void +initkeymap(void) +{ + int i; + for (i = 0; i < GLFW_KEY_LAST + 1; i++) + keymap[i] = rsNULL; + + keymap[GLFW_KEY_SPACE] = ' '; + keymap[GLFW_KEY_APOSTROPHE] = '\''; + keymap[GLFW_KEY_COMMA] = ','; + keymap[GLFW_KEY_MINUS] = '-'; + keymap[GLFW_KEY_PERIOD] = '.'; + keymap[GLFW_KEY_SLASH] = '/'; + keymap[GLFW_KEY_0] = '0'; + keymap[GLFW_KEY_1] = '1'; + keymap[GLFW_KEY_2] = '2'; + keymap[GLFW_KEY_3] = '3'; + keymap[GLFW_KEY_4] = '4'; + keymap[GLFW_KEY_5] = '5'; + keymap[GLFW_KEY_6] = '6'; + keymap[GLFW_KEY_7] = '7'; + keymap[GLFW_KEY_8] = '8'; + keymap[GLFW_KEY_9] = '9'; + keymap[GLFW_KEY_SEMICOLON] = ';'; + keymap[GLFW_KEY_EQUAL] = '='; + keymap[GLFW_KEY_A] = 'A'; + keymap[GLFW_KEY_B] = 'B'; + keymap[GLFW_KEY_C] = 'C'; + keymap[GLFW_KEY_D] = 'D'; + keymap[GLFW_KEY_E] = 'E'; + keymap[GLFW_KEY_F] = 'F'; + keymap[GLFW_KEY_G] = 'G'; + keymap[GLFW_KEY_H] = 'H'; + keymap[GLFW_KEY_I] = 'I'; + keymap[GLFW_KEY_J] = 'J'; + keymap[GLFW_KEY_K] = 'K'; + keymap[GLFW_KEY_L] = 'L'; + keymap[GLFW_KEY_M] = 'M'; + keymap[GLFW_KEY_N] = 'N'; + keymap[GLFW_KEY_O] = 'O'; + keymap[GLFW_KEY_P] = 'P'; + keymap[GLFW_KEY_Q] = 'Q'; + keymap[GLFW_KEY_R] = 'R'; + keymap[GLFW_KEY_S] = 'S'; + keymap[GLFW_KEY_T] = 'T'; + keymap[GLFW_KEY_U] = 'U'; + keymap[GLFW_KEY_V] = 'V'; + keymap[GLFW_KEY_W] = 'W'; + keymap[GLFW_KEY_X] = 'X'; + keymap[GLFW_KEY_Y] = 'Y'; + keymap[GLFW_KEY_Z] = 'Z'; + keymap[GLFW_KEY_LEFT_BRACKET] = '['; + keymap[GLFW_KEY_BACKSLASH] = '\\'; + keymap[GLFW_KEY_RIGHT_BRACKET] = ']'; + keymap[GLFW_KEY_GRAVE_ACCENT] = '`'; + keymap[GLFW_KEY_ESCAPE] = rsESC; + keymap[GLFW_KEY_ENTER] = rsENTER; + keymap[GLFW_KEY_TAB] = rsTAB; + keymap[GLFW_KEY_BACKSPACE] = rsBACKSP; + keymap[GLFW_KEY_INSERT] = rsINS; + keymap[GLFW_KEY_DELETE] = rsDEL; + keymap[GLFW_KEY_RIGHT] = rsRIGHT; + keymap[GLFW_KEY_LEFT] = rsLEFT; + keymap[GLFW_KEY_DOWN] = rsDOWN; + keymap[GLFW_KEY_UP] = rsUP; + keymap[GLFW_KEY_PAGE_UP] = rsPGUP; + keymap[GLFW_KEY_PAGE_DOWN] = rsPGDN; + keymap[GLFW_KEY_HOME] = rsHOME; + keymap[GLFW_KEY_END] = rsEND; + keymap[GLFW_KEY_CAPS_LOCK] = rsCAPSLK; + keymap[GLFW_KEY_SCROLL_LOCK] = rsSCROLL; + keymap[GLFW_KEY_NUM_LOCK] = rsNUMLOCK; + keymap[GLFW_KEY_PRINT_SCREEN] = rsNULL; + keymap[GLFW_KEY_PAUSE] = rsPAUSE; + + keymap[GLFW_KEY_F1] = rsF1; + keymap[GLFW_KEY_F2] = rsF2; + keymap[GLFW_KEY_F3] = rsF3; + keymap[GLFW_KEY_F4] = rsF4; + keymap[GLFW_KEY_F5] = rsF5; + keymap[GLFW_KEY_F6] = rsF6; + keymap[GLFW_KEY_F7] = rsF7; + keymap[GLFW_KEY_F8] = rsF8; + keymap[GLFW_KEY_F9] = rsF9; + keymap[GLFW_KEY_F10] = rsF10; + keymap[GLFW_KEY_F11] = rsF11; + keymap[GLFW_KEY_F12] = rsF12; + keymap[GLFW_KEY_F13] = rsNULL; + keymap[GLFW_KEY_F14] = rsNULL; + keymap[GLFW_KEY_F15] = rsNULL; + keymap[GLFW_KEY_F16] = rsNULL; + keymap[GLFW_KEY_F17] = rsNULL; + keymap[GLFW_KEY_F18] = rsNULL; + keymap[GLFW_KEY_F19] = rsNULL; + keymap[GLFW_KEY_F20] = rsNULL; + keymap[GLFW_KEY_F21] = rsNULL; + keymap[GLFW_KEY_F22] = rsNULL; + keymap[GLFW_KEY_F23] = rsNULL; + keymap[GLFW_KEY_F24] = rsNULL; + keymap[GLFW_KEY_F25] = rsNULL; + keymap[GLFW_KEY_KP_0] = rsPADINS; + keymap[GLFW_KEY_KP_1] = rsPADEND; + keymap[GLFW_KEY_KP_2] = rsPADDOWN; + keymap[GLFW_KEY_KP_3] = rsPADPGDN; + keymap[GLFW_KEY_KP_4] = rsPADLEFT; + keymap[GLFW_KEY_KP_5] = rsPAD5; + keymap[GLFW_KEY_KP_6] = rsPADRIGHT; + keymap[GLFW_KEY_KP_7] = rsPADHOME; + keymap[GLFW_KEY_KP_8] = rsPADUP; + keymap[GLFW_KEY_KP_9] = rsPADPGUP; + keymap[GLFW_KEY_KP_DECIMAL] = rsPADDEL; + keymap[GLFW_KEY_KP_DIVIDE] = rsDIVIDE; + keymap[GLFW_KEY_KP_MULTIPLY] = rsTIMES; + keymap[GLFW_KEY_KP_SUBTRACT] = rsMINUS; + keymap[GLFW_KEY_KP_ADD] = rsPLUS; + keymap[GLFW_KEY_KP_ENTER] = rsPADENTER; + keymap[GLFW_KEY_KP_EQUAL] = rsNULL; + keymap[GLFW_KEY_LEFT_SHIFT] = rsLSHIFT; + keymap[GLFW_KEY_LEFT_CONTROL] = rsLCTRL; + keymap[GLFW_KEY_LEFT_ALT] = rsLALT; + keymap[GLFW_KEY_LEFT_SUPER] = rsLWIN; + keymap[GLFW_KEY_RIGHT_SHIFT] = rsRSHIFT; + keymap[GLFW_KEY_RIGHT_CONTROL] = rsRCTRL; + keymap[GLFW_KEY_RIGHT_ALT] = rsRALT; + keymap[GLFW_KEY_RIGHT_SUPER] = rsRWIN; + keymap[GLFW_KEY_MENU] = rsNULL; +} + +bool lshiftStatus = false; +bool rshiftStatus = false; + +void +keypressCB(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key >= 0 && key <= GLFW_KEY_LAST) { + RsKeyCodes ks = (RsKeyCodes)keymap[key]; + + if (key == GLFW_KEY_LEFT_SHIFT) + lshiftStatus = action != GLFW_RELEASE; + + if (key == GLFW_KEY_RIGHT_SHIFT) + rshiftStatus = action != GLFW_RELEASE; + + if (action == GLFW_RELEASE) RsKeyboardEventHandler(rsKEYUP, &ks); + else if (action == GLFW_PRESS) RsKeyboardEventHandler(rsKEYDOWN, &ks); + else if (action == GLFW_REPEAT) RsKeyboardEventHandler(rsKEYDOWN, &ks); + } +} + +// R* calls that in ControllerConfig, idk why +void +_InputTranslateShiftKeyUpDown(RsKeyCodes *rs) { + RsKeyboardEventHandler(lshiftStatus ? rsKEYDOWN : rsKEYUP, &(*rs = rsLSHIFT)); + RsKeyboardEventHandler(rshiftStatus ? rsKEYDOWN : rsKEYUP, &(*rs = rsRSHIFT)); +} + +// TODO this only works in frontend(and luckily only frontend use this), maybe because of glfw knows that mouse pos is > 32000 in game?? +void +cursorCB(GLFWwindow* window, double xpos, double ypos) { + FrontEndMenuManager.m_nMouseTempPosX = xpos; + FrontEndMenuManager.m_nMouseTempPosY = ypos; +} + +void _InputInitialiseJoys() +{ + for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) { + if (glfwJoystickPresent(i)) { + if (PSGLOBAL(joy1id) == -1) + PSGLOBAL(joy1id) = i; + else if (PSGLOBAL(joy2id) == -1) + PSGLOBAL(joy2id) = i; + else + break; + } + } + + if (PSGLOBAL(joy1id) != -1) { + int count; + glfwGetJoystickButtons(PSGLOBAL(joy1id), &count); + ControlsManager.InitDefaultControlConfigJoyPad(count); + } +} + +void _InputInitialiseMouse() +{ + glfwSetInputMode(PSGLOBAL(window), GLFW_CURSOR, GLFW_CURSOR_HIDDEN); +} + +/* + ***************************************************************************** + */ +int PASCAL +WinMain(HINSTANCE instance, + HINSTANCE prevInstance __RWUNUSED__, + CMDSTR cmdLine, + int cmdShow) +{ + RwV2d pos; + RwInt32 argc, i; + RwChar** argv; + StaticPatcher::Apply(); + SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE); + + /* + * Initialize the platform independent data. + * This will in turn initialize the platform specific data... + */ + if( RsEventHandler(rsINITIALISE, nil) == rsEVENTERROR ) + { + 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 -0.8f; + ControlsManager.m_NewState.mappedButtons[16] = gamepadState.axes[5] > -0.8f; + } + // TODO I'm not sure how to find/what to do with L2-R2, if joystick isn't registered in SDL database. + + if (ControlsManager.m_bFirstCapture == true) { + memcpy(&ControlsManager.m_OldState, &ControlsManager.m_NewState, sizeof(ControlsManager.m_NewState)); + + ControlsManager.m_bFirstCapture = false; + } + + RsPadButtonStatus bs; + bs.padID = padID; + + RsPadEventHandler(rsPADBUTTONUP, (void *)&bs); + + // Gamepad axes are guaranteed to return 0.0f if that particular gamepad doesn't have that axis. + if ( glfwPad != -1 ) { + leftStickPos.x = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[0] : numAxes >= 0 ? axes[0] : 0.0f; + leftStickPos.y = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[1] : numAxes >= 1 ? axes[1] : 0.0f; + + rightStickPos.x = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[2] : numAxes >= 2 ? axes[2] : 0.0f; + rightStickPos.y = ControlsManager.m_NewState.isGamepad ? gamepadState.axes[3] : numAxes >= 3 ? axes[3] : 0.0f; + } + + { + if (CPad::m_bMapPadOneToPadTwo) + bs.padID = 1; + + RsPadEventHandler(rsPADBUTTONUP, (void *)&bs); + RsPadEventHandler(rsPADBUTTONDOWN, (void *)&bs); + } + + { + if (CPad::m_bMapPadOneToPadTwo) + bs.padID = 1; + + CPad *pad = CPad::GetPad(bs.padID); + + if ( Abs(leftStickPos.x) > 0.3f ) + pad->PCTempJoyState.LeftStickX = (int32)(leftStickPos.x * 128.0f); + + if ( Abs(leftStickPos.y) > 0.3f ) + pad->PCTempJoyState.LeftStickY = (int32)(leftStickPos.y * 128.0f); + + if ( Abs(rightStickPos.x) > 0.3f ) + pad->PCTempJoyState.RightStickX = (int32)(rightStickPos.x * 128.0f); + + if ( Abs(rightStickPos.y) > 0.3f ) + pad->PCTempJoyState.RightStickY = (int32)(rightStickPos.y * 128.0f); + } + + return; +} + +void joysChangeCB(int jid, int event) +{ + if (event == GLFW_CONNECTED) + { + if (PSGLOBAL(joy1id) == -1) + PSGLOBAL(joy1id) = jid; + else if (PSGLOBAL(joy2id) == -1) + PSGLOBAL(joy2id) = jid; + } + else if (event == GLFW_DISCONNECTED) + { + if (PSGLOBAL(joy1id) == jid) + PSGLOBAL(joy1id) = -1; + else if (PSGLOBAL(joy2id) == jid) + PSGLOBAL(joy2id) = -1; + } +} + +#if (defined(_MSC_VER)) +int strcasecmp(const char* str1, const char* str2) +{ + return _strcmpi(str1, str2); +} +#endif +#endif \ No newline at end of file diff --git a/src/skel/skeleton.cpp b/src/skel/skeleton.cpp index f48089cb..b5ce744a 100644 --- a/src/skel/skeleton.cpp +++ b/src/skel/skeleton.cpp @@ -293,7 +293,7 @@ RwBool RsRwInitialise(void *displayID) { RwEngineOpenParams openParams; - + /* * Start RenderWare... */ diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index cde9f9e5..e623defb 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -1,3 +1,5 @@ +#if defined RW_D3D9 || defined RWLIBS + #define _WIN32_WINDOWS 0x0500 #define WINVER 0x0500 #define DIRECTINPUT_VERSION 0x0800 @@ -40,7 +42,7 @@ #include "resource.h" #include "skeleton.h" #include "platform.h" -#include "win.h" +#include "crossplatform.h" #define MAX_SUBSYSTEMS (16) @@ -3033,3 +3035,4 @@ int strcasecmp(const char *str1, const char *str2) return _strcmpi(str1, str2); } #endif +#endif \ No newline at end of file diff --git a/src/skel/win/win.h b/src/skel/win/win.h index d6326294..0e63502e 100644 --- a/src/skel/win/win.h +++ b/src/skel/win/win.h @@ -1,3 +1,6 @@ + +// DON'T include directly. crossplatform.h includes this if you're on Windows. + #if (!defined(_PLATFORM_WIN_H)) #define _PLATFORM_WIN_H @@ -10,23 +13,6 @@ #include #endif -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, -#ifndef MASTER - GS_ANIMVIEWER, -#endif -}; - enum eWinVersion { OS_WIN95 = 0, @@ -38,8 +24,6 @@ enum eWinVersion extern DWORD _dwOperatingSystemVersion; -extern RwUInt32 gGameState; - #ifdef __DINPUT_INCLUDED__ /* platform specfic global data */ typedef struct @@ -101,12 +85,10 @@ extern "C" { #endif /* __cplusplus */ +#ifdef __DINPUT_INCLUDED__ extern LRESULT CALLBACK MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam); -RwBool IsForegroundApp(); - -#ifdef __DINPUT_INCLUDED__ HRESULT _InputInitialise(); HRESULT _InputInitialiseMouse(); HRESULT CapturePad(RwInt32 padID); @@ -117,26 +99,15 @@ HRESULT _InputGetMouseState(DIMOUSESTATE2 *state); void _InputShutdown(); BOOL CALLBACK _InputEnumDevicesCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext ); BOOL _InputTranslateKey(RsKeyCodes *rs, UINT flag, UINT key); -void _InputTranslateShiftKeyUpDown(RsKeyCodes *rs);; BOOL _InputTranslateShiftKey(RsKeyCodes *rs, UINT key, BOOLEAN bDown); BOOL _InputIsExtended(INT flag); #endif -void InitialiseLanguage(); -RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode); void CenterVideo(void); void CloseClip(void); -RwChar **_psGetVideoModeList(); -RwInt32 _psGetNumVideModes(); - -void _psSelectScreenVM(RwInt32 videoMode); -void HandleExit(); - #ifdef __cplusplus } #endif /* __cplusplus */ - -extern DWORD _dwOperatingSystemVersion; #endif /* (!defined(_PLATFORM_WIN_H)) */ -- cgit v1.2.3