summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraap <aap@papnet.eu>2020-04-26 12:49:31 +0200
committerGitHub <noreply@github.com>2020-04-26 12:49:31 +0200
commit7052b0b64c2fbab2d4ef94e50e902eea4904dbe0 (patch)
tree7a01b47b48a106ca6ff9154cc5c14d3baf54c22f
parentupdate librw (diff)
parentInitial GLFW support (diff)
downloadre3-7052b0b64c2fbab2d4ef94e50e902eea4904dbe0.tar
re3-7052b0b64c2fbab2d4ef94e50e902eea4904dbe0.tar.gz
re3-7052b0b64c2fbab2d4ef94e50e902eea4904dbe0.tar.bz2
re3-7052b0b64c2fbab2d4ef94e50e902eea4904dbe0.tar.lz
re3-7052b0b64c2fbab2d4ef94e50e902eea4904dbe0.tar.xz
re3-7052b0b64c2fbab2d4ef94e50e902eea4904dbe0.tar.zst
re3-7052b0b64c2fbab2d4ef94e50e902eea4904dbe0.zip
-rw-r--r--premake5.lua27
-rw-r--r--src/core/ControllerConfig.cpp98
-rw-r--r--src/core/ControllerConfig.h17
-rw-r--r--src/core/Frontend.cpp24
-rw-r--r--src/core/Game.cpp2
-rw-r--r--src/core/Pad.cpp58
-rw-r--r--src/core/common.h4
-rw-r--r--src/core/config.h2
-rw-r--r--src/core/patcher.cpp3
-rw-r--r--src/fakerw/fake.cpp8
-rw-r--r--src/rw/RwHelper.cpp2
-rw-r--r--src/rw/TexRead.cpp2
-rw-r--r--src/rw/TxdStore.cpp35
-rw-r--r--src/skel/crossplatform.h67
-rw-r--r--src/skel/events.cpp9
-rw-r--r--src/skel/glfw/glfw.cpp1651
-rw-r--r--src/skel/skeleton.cpp2
-rw-r--r--src/skel/win/win.cpp5
-rw-r--r--src/skel/win/win.h37
-rw-r--r--src/text/Messages.cpp3
-rw-r--r--src/vehicles/Boat.cpp8
21 files changed, 1982 insertions, 82 deletions
diff --git a/premake5.lua b/premake5.lua
index baf26a42..f2a58880 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -1,7 +1,7 @@
Librw = os.getenv("LIBRW") or "librw"
workspace "re3"
- configurations { "Debug", "Release", "ReleaseFH", "DebugRW", "ReleaseRW" }
+ configurations { "Debug", "Release", "ReleaseFH", "DebugRW", "ReleaseRW", "ReleaseGLFW" }
location "build"
files { "src/*.*" }
@@ -19,6 +19,7 @@ workspace "re3"
files { "src/save/*.*" }
files { "src/skel/*.*" }
files { "src/skel/win/*.*" }
+ files { "src/skel/glfw/*.*" }
files { "src/text/*.*" }
files { "src/vehicles/*.*" }
files { "src/weapons/*.*" }
@@ -40,6 +41,7 @@ workspace "re3"
includedirs { "src/save/" }
includedirs { "src/skel/" }
includedirs { "src/skel/win" }
+ includedirs { "src/skel/glfw" }
includedirs { "src/text" }
includedirs { "src/vehicles" }
includedirs { "src/weapons" }
@@ -67,6 +69,21 @@ workspace "re3"
links { "rwcore", "rpworld", "rpmatfx", "rpskin", "rphanim", "rtbmp", "rtquat", "rtcharse" }
filter {}
+ filter "configurations:ReleaseGLFW"
+ defines { "GLEW_STATIC", "GLFW_DLL" }
+ files { "src/fakerw/*.*" }
+ includedirs { "src/fakerw" }
+ includedirs { Librw }
+ includedirs { "glfw-3.3.2.bin.WIN32/include" }
+ includedirs { "glew-2.1.0/include" }
+ libdirs { path.join(Librw, "lib/win-x86-gl3/Release") }
+ libdirs { "glew-2.1.0/lib/Release/Win32" }
+ libdirs { "glfw-3.3.2.bin.WIN32/lib-vc2015" }
+ links { "opengl32" }
+ links { "glew32s" }
+ links { "glfw3dll" }
+ links { "rw" }
+ filter {}
pbcommands = {
"setlocal EnableDelayedExpansion",
@@ -107,14 +124,18 @@ project "re3"
symbols "Full"
staticruntime "off"
- filter "configurations:not *RW"
- -- prebuildcommands { "cd \"../librw\" && premake5 " .. _ACTION .. " && msbuild \"build/librw.sln\" /property:Configuration=%{cfg.longname} /property:Platform=\"win-x86-d3d9\"" }
+ filter "configurations:Debug or Release or ReleaseFH"
+ prebuildcommands { "cd \"../librw\" && premake5 " .. _ACTION .. " && msbuild \"build/librw.sln\" /property:Configuration=%{cfg.longname} /property:Platform=\"win-x86-d3d9\"" }
defines { "LIBRW", "RW_D3D9" }
filter "configurations:*RW"
defines { "RWLIBS" }
staticruntime "on"
linkoptions "/SECTION:_rwcseg,ER!W /MERGE:_rwcseg=.text"
+
+ filter "configurations:*GLFW"
+ prebuildcommands { "cd \"../librw\" && premake5 " .. _ACTION .. " && msbuild \"build/librw.sln\" /property:Configuration=Release /property:Platform=\"win-x86-gl3\"" }
+ defines { "LIBRW", "RW_GL3" }
filter "configurations:Debug*"
defines { "DEBUG" }
diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp
index a2382c12..f55568be 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -1,7 +1,10 @@
+#if defined RW_D3D9 || defined RWLIBS
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
-#include "common.h"
+#endif
+#include "common.h"
+#include "crossplatform.h"
#include "ControllerConfig.h"
#include "Pad.h"
#include "FileMgr.h"
@@ -15,7 +18,6 @@
#include "World.h"
#include "ModelIndices.h"
#include "Camera.h"
-#include "win.h"
#include "GenericGameStorage.h"
CControllerConfigManager ControlsManager;
@@ -41,14 +43,72 @@ void CControllerConfigManager::MakeControllerActionsBlank()
}
}
+#ifdef RW_GL3
+int MapIdToButtonId(int mapId) {
+ switch (mapId) {
+ case GLFW_GAMEPAD_BUTTON_A: // Cross
+ return 2;
+ case GLFW_GAMEPAD_BUTTON_B: // Circle
+ return 1;
+ case GLFW_GAMEPAD_BUTTON_X: // Square
+ return 3;
+ case GLFW_GAMEPAD_BUTTON_Y: // Triangle
+ return 4;
+ case GLFW_GAMEPAD_BUTTON_LEFT_BUMPER:
+ return 7;
+ case GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER:
+ return 8;
+ case GLFW_GAMEPAD_BUTTON_BACK:
+ return 9;
+ case GLFW_GAMEPAD_BUTTON_START:
+ return 12;
+ case GLFW_GAMEPAD_BUTTON_LEFT_THUMB:
+ return 10;
+ case GLFW_GAMEPAD_BUTTON_RIGHT_THUMB:
+ return 11;
+ case GLFW_GAMEPAD_BUTTON_DPAD_UP:
+ return 13;
+ case GLFW_GAMEPAD_BUTTON_DPAD_RIGHT:
+ return 14;
+ case GLFW_GAMEPAD_BUTTON_DPAD_DOWN:
+ return 15;
+ case GLFW_GAMEPAD_BUTTON_DPAD_LEFT:
+ return 16;
+ // GLFW sends those as axes, so I added them here manually.
+ case 15: // Left trigger
+ return 5;
+ case 16: // Right trigger
+ return 6;
+ default:
+ return 0;
+ }
+}
+#endif
+
int32 CControllerConfigManager::GetJoyButtonJustDown()
{
#ifdef __DINPUT_INCLUDED__
+#ifdef FIX_BUGS
+ for (int32 i = 0; i < MAX_BUTTONS; i++)
+#else
for (int32 i = 0; i < JOY_BUTTONS; i++)
+#endif
{
if (m_NewState.rgbButtons[i] & 0x80 && !(m_OldState.rgbButtons[i] & 0x80))
return i + 1;
}
+#elif defined RW_GL3
+ if (m_NewState.isGamepad) {
+ for (int32 i = 0; i < MAX_BUTTONS; i++) {
+ if (m_NewState.mappedButtons[i] && !(m_OldState.mappedButtons[i]))
+ return MapIdToButtonId(i);
+ }
+ } else {
+ for (int32 i = 0; i < Min(m_NewState.numButtons, MAX_BUTTONS); i++) {
+ if (m_NewState.buttons[i] && !(m_OldState.buttons[i]))
+ return i + 1;
+ }
+ }
#endif
return 0;
}
@@ -249,8 +309,13 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons)
if (buttons > 16)
btn = 16;
+ // Now we use SDL Game Controller DB
+#if defined RW_D3D9 || defined RWLIBS
if ( AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
&& AllValidWinJoys.m_aJoys[JOYSTICK1].m_nProductID == 0x1190)
+#else
+ if (0)
+#endif
{
//GIC USB Joystick, PS2 Gamepad ?
@@ -445,8 +510,13 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonDown(int32 button, i
break;
}
- if ( AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
+ // Now we use SDL Game Controller DB
+#if defined RW_D3D9 || defined RWLIBS
+ if (AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
&& AllValidWinJoys.m_aJoys[JOYSTICK1].m_nProductID == 0x1190)
+#else
+ if (0)
+#endif
{
//GIC USB Joystick, PS2 Gamepad ?
@@ -872,8 +942,13 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonUp(int32 button, int
break;
}
- if ( AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
+ // Now we use SDL Game Controller DB
+#if defined RW_D3D9 || defined RWLIBS
+ if (AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427
&& AllValidWinJoys.m_aJoys[JOYSTICK1].m_nProductID == 0x1190)
+#else
+ if (0)
+#endif
{
//GIC USB Joystick, PS2 Gamepad ?
@@ -1809,7 +1884,7 @@ wchar *CControllerConfigManager::GetControllerSettingTextKeyBoard(e_ControllerAc
static wchar ActionText[50];
static wchar NewStringWithNumber[30];
- for (int32 i = 0; i < ARRAYSIZE(ActionText); i++)
+ for (int32 i = 0; i < ARRAY_SIZE(ActionText); i++)
ActionText[i] = '\0';
if (GetControllerKeyAssociatedWithAction(action, type) != rsNULL)
@@ -2266,6 +2341,19 @@ void CControllerConfigManager::UpdateJoyButtonState(int32 padnumber)
else
m_aButtonStates[i] = false;
}
+#elif defined RW_GL3
+ if (m_NewState.isGamepad) {
+ for (int32 i = 0; i < MAX_BUTTONS; i++) {
+ if (i == GLFW_GAMEPAD_BUTTON_GUIDE)
+ continue;
+
+ m_aButtonStates[MapIdToButtonId(i)-1] = m_NewState.mappedButtons[i];
+ }
+ } else {
+ for (int32 i = 0; i < Min(m_NewState.numButtons, MAX_BUTTONS); i++) {
+ m_aButtonStates[i] = m_NewState.buttons[i];
+ }
+ }
#endif
}
diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h
index 82174343..76f9882b 100644
--- a/src/core/ControllerConfig.h
+++ b/src/core/ControllerConfig.h
@@ -96,6 +96,16 @@ class CControllerState;
#define ACTIONNAME_LENGTH 40
+#ifdef RW_GL3
+struct GlfwJoyState {
+ int8 id;
+ bool isGamepad;
+ uint8 numButtons;
+ uint8* buttons;
+ bool mappedButtons[17];
+};
+#endif
+
class CControllerConfigManager
{
public:
@@ -115,8 +125,9 @@ public:
#ifdef __DINPUT_INCLUDED__
DIJOYSTATE2 m_OldState;
DIJOYSTATE2 m_NewState;
-#else
- uint32 ___padd[0x110 / 4 * 2];
+#elif defined RW_GL3
+ GlfwJoyState m_OldState;
+ GlfwJoyState m_NewState;
#endif
wchar m_aActionNames[MAX_CONTROLLERACTIONS][ACTIONNAME_LENGTH];
bool m_aButtonStates[MAX_BUTTONS];
@@ -193,6 +204,6 @@ public:
void ResetSettingOrder (e_ControllerAction action);
};
-VALIDATE_SIZE(CControllerConfigManager, 0x143C);
+//VALIDATE_SIZE(CControllerConfigManager, 0x143C);
extern CControllerConfigManager ControlsManager; \ No newline at end of file
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index c7e7d26e..cc076057 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -1,8 +1,11 @@
+#if defined RW_D3D9 || defined RWLIBS
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
-#include "common.h"
+#endif
-#include "win.h"
+#define WITHWINDOWS
+#include "common.h"
+#include "crossplatform.h"
#include "Frontend.h"
#include "Font.h"
#include "Pad.h"
@@ -430,13 +433,16 @@ CMenuManager::BuildStatLine(char *text, void *stat, bool itsFloat, void *stat2)
void
CMenuManager::CentreMousePointer()
{
- tagPOINT Point;
-
if (SCREEN_WIDTH * 0.5f != 0.0f && 0.0f != SCREEN_HEIGHT * 0.5f) {
+#if defined RW_D3D9 || defined RWLIBS
+ tagPOINT Point;
Point.x = SCREEN_WIDTH / 2;
Point.y = SCREEN_HEIGHT / 2;
ClientToScreen(PSGLOBAL(window), &Point);
SetCursorPos(Point.x, Point.y);
+#elif defined RW_GL3
+ glfwSetCursorPos(PSGLOBAL(window), SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
+#endif
PSGLOBAL(lastMousePos.x) = SCREEN_WIDTH / 2;
PSGLOBAL(lastMousePos.y) = SCREEN_HEIGHT / 2;
@@ -4474,12 +4480,20 @@ CMenuManager::ProcessButtonPresses(void)
ControlsManager.MakeControllerActionsBlank();
ControlsManager.InitDefaultControlConfiguration();
ControlsManager.InitDefaultControlConfigMouse(MousePointerStateHelper.GetMouseSetUp());
- if (AllValidWinJoys.m_aJoys[0].m_bInitialised) {
+#if !defined RW_GL3
+ if (AllValidWinJoys.m_aJoys[JOYSTICK1].m_bInitialised) {
DIDEVCAPS devCaps;
devCaps.dwSize = sizeof(DIDEVCAPS);
PSGLOBAL(joy1)->GetCapabilities(&devCaps);
ControlsManager.InitDefaultControlConfigJoyPad(devCaps.dwButtons);
}
+#else
+ if (PSGLOBAL(joy1id) != -1 && glfwJoystickPresent(PSGLOBAL(joy1id))) {
+ int count;
+ glfwGetJoystickButtons(PSGLOBAL(joy1id), &count);
+ ControlsManager.InitDefaultControlConfigJoyPad(count);
+ }
+#endif
m_ControlMethod = CONTROL_STANDARD;
MousePointerStateHelper.bInvertVertically = false;
TheCamera.m_fMouseAccelHorzntl = 0.0025f;
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index f72d342f..8633d222 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -2,7 +2,7 @@
#pragma warning( disable : 4005)
#pragma warning( pop )
#include "common.h"
-#include "win.h"
+#include "crossplatform.h"
#include "Game.h"
#include "main.h"
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index 8a3fc7cb..84bb1526 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -1,10 +1,13 @@
#pragma warning( push )
#pragma warning( disable : 4005)
+#if defined RW_D3D9 || defined RWLIBS
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
+#endif
#pragma warning( pop )
#include "common.h"
+#include "crossplatform.h"
#ifdef XINPUT
#include <xinput.h>
#pragma comment( lib, "Xinput9_1_0.lib" )
@@ -29,7 +32,6 @@
#include "Record.h"
#include "Replay.h"
#include "Weather.h"
-#include "win.h"
#include "Streaming.h"
#include "PathFind.h"
#include "Wanted.h"
@@ -423,6 +425,7 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
{
CMouseControllerState state;
+#if defined RW_D3D9 || defined RWLIBS
if ( PSGLOBAL(mouse) == nil )
_InputInitialiseMouse();
@@ -432,7 +435,6 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
devCaps.dwSize = sizeof(DIDEVCAPS);
PSGLOBAL(mouse)->GetCapabilities(&devCaps);
-
switch ( devCaps.dwButtons )
{
case 3:
@@ -456,6 +458,19 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
state.WHEELUP = true;
}
}
+#else
+ // It seems there is no way to get number of buttons on mouse, so assign all buttons if we have mouse.
+ double xpos = 1.0f, ypos;
+ glfwGetCursorPos(PSGLOBAL(window), &xpos, &ypos);
+
+ if (xpos != NULL) {
+ state.MMB = true;
+ state.RMB = true;
+ state.LMB = true;
+ state.WHEELDN = true;
+ state.WHEELUP = true;
+ }
+#endif
return state;
}
@@ -464,6 +479,7 @@ void CPad::UpdateMouse()
{
if ( IsForegroundApp() )
{
+#if defined RW_D3D9 || defined RWLIBS
if ( PSGLOBAL(mouse) == nil )
_InputInitialiseMouse();
@@ -500,6 +516,44 @@ void CPad::UpdateMouse()
OldMouseControllerState = NewMouseControllerState;
NewMouseControllerState = PCTempMouseControllerState;
}
+#else
+ double xpos = 1.0f, ypos;
+ glfwGetCursorPos(PSGLOBAL(window), &xpos, &ypos);
+ if (xpos == NULL)
+ return;
+
+ int32 signX = 1;
+ int32 signy = 1;
+
+ if (!FrontEndMenuManager.m_bMenuActive)
+ {
+ if (MousePointerStateHelper.bInvertVertically)
+ signy = -1;
+ if (MousePointerStateHelper.bInvertHorizontally)
+ signX = -1;
+ }
+
+ PCTempMouseControllerState.Clear();
+
+ PCTempMouseControllerState.x = (float)(signX * (xpos - PSGLOBAL(lastMousePos.x)));
+ PCTempMouseControllerState.y = (float)(signy * (ypos - PSGLOBAL(lastMousePos.y)));
+ PCTempMouseControllerState.LMB = glfwGetMouseButton(PSGLOBAL(window), GLFW_MOUSE_BUTTON_LEFT);
+ PCTempMouseControllerState.RMB = glfwGetMouseButton(PSGLOBAL(window), GLFW_MOUSE_BUTTON_RIGHT);
+ PCTempMouseControllerState.MMB = glfwGetMouseButton(PSGLOBAL(window), GLFW_MOUSE_BUTTON_MIDDLE);
+ PCTempMouseControllerState.MXB1 = glfwGetMouseButton(PSGLOBAL(window), GLFW_MOUSE_BUTTON_4);
+ PCTempMouseControllerState.MXB2 = glfwGetMouseButton(PSGLOBAL(window), GLFW_MOUSE_BUTTON_5);
+
+ PSGLOBAL(lastMousePos.x) = xpos;
+ PSGLOBAL(lastMousePos.y) = ypos;
+
+ if (PSGLOBAL(mouseWheel) > 0)
+ PCTempMouseControllerState.WHEELUP = 1;
+ else if (PSGLOBAL(mouseWheel) < 0)
+ PCTempMouseControllerState.WHEELDN = 1;
+
+ OldMouseControllerState = NewMouseControllerState;
+ NewMouseControllerState = PCTempMouseControllerState;
+#endif
}
}
diff --git a/src/core/common.h b/src/core/common.h
index 8b057efa..2cc3d98c 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -11,11 +11,11 @@
#include <string.h>
#include <math.h>
-#ifdef WITHWINDOWS
+#if defined _WIN32 && defined WITHWINDOWS
#include <windows.h>
#endif
-#ifdef WITHD3D
+#if defined _WIN32 && defined WITHD3D
#include <windows.h>
#include <d3d8types.h>
#endif
diff --git a/src/core/config.h b/src/core/config.h
index 84712af3..80e2ff19 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -200,7 +200,7 @@ enum Config {
//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2
// Pad
-#define XINPUT
+// #define XINPUT
#define KANGAROO_CHEAT
#define REGISTER_START_BUTTON
diff --git a/src/core/patcher.cpp b/src/core/patcher.cpp
index 58f19767..e5242e9d 100644
--- a/src/core/patcher.cpp
+++ b/src/core/patcher.cpp
@@ -1,11 +1,10 @@
+#define WITHWINDOWS
#include "common.h"
#include "patcher.h"
#include <algorithm>
#include <vector>
-#include <windows.h>
-
StaticPatcher *StaticPatcher::ms_head;
StaticPatcher::StaticPatcher(Patcher func)
diff --git a/src/fakerw/fake.cpp b/src/fakerw/fake.cpp
index c4ff2dd2..3d4ddf5d 100644
--- a/src/fakerw/fake.cpp
+++ b/src/fakerw/fake.cpp
@@ -460,13 +460,17 @@ RwBool RwRenderStateSet(RwRenderState state, void *value)
}
}
-
-static EngineOpenParams openParams;
// WARNING: unused parameters
RwBool RwEngineInit(RwMemoryFunctions *memFuncs, RwUInt32 initFlags, RwUInt32 resArenaSize) { Engine::init(); return true; }
// TODO: this is platform dependent
RwBool RwEngineOpen(RwEngineOpenParams *initParams) {
+#if defined RW_D3D9 || defined RWLIBS
+ static EngineOpenParams openParams;
openParams.window = (HWND)initParams->displayID;
+#else
+ extern EngineOpenParams openParams;
+ openParams.window = (GLFWwindow**)initParams->displayID;
+#endif
return Engine::open(&openParams);
}
RwBool RwEngineStart(void) {
diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp
index 707f1b44..ed618dd8 100644
--- a/src/rw/RwHelper.cpp
+++ b/src/rw/RwHelper.cpp
@@ -1,4 +1,6 @@
+#if defined RW_D3D9 || defined RWLIBS
#define WITHD3D
+#endif
#include "common.h"
#include "Timecycle.h"
diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp
index 9f0cae3c..60945665 100644
--- a/src/rw/TexRead.cpp
+++ b/src/rw/TexRead.cpp
@@ -2,7 +2,7 @@
#pragma warning( disable : 4005)
#pragma warning( pop )
#include "common.h"
-#include "win.h"
+#include "crossplatform.h"
#include "Timer.h"
#ifdef GTA_PC
diff --git a/src/rw/TxdStore.cpp b/src/rw/TxdStore.cpp
index 51d018f6..bb7386d5 100644
--- a/src/rw/TxdStore.cpp
+++ b/src/rw/TxdStore.cpp
@@ -127,6 +127,38 @@ CTxdStore::RemoveRefWithoutDelete(int slot)
GetSlot(slot)->refCount--;
}
+#ifdef RW_GL3
+rw::Raster*
+convertTexRaster(rw::Raster* ras)
+{
+ rw::Image* img = ras->toImage();
+// ras->destroy();
+ img->unindex();
+ ras = rw::Raster::createFromImage(img);
+ img->destroy();
+ return ras;
+}
+
+void
+convertTxd(rw::TexDictionary* txd)
+{
+ rw::Texture* tex;
+ FORLIST(lnk, txd->textures) {
+ tex = rw::Texture::fromDict(lnk);
+ rw::Raster* ras = tex->raster;
+ if (ras && ras->platform != rw::platform) {
+ if (!(ras->platform == rw::PLATFORM_D3D8 && rw::platform == rw::PLATFORM_D3D9 ||
+ ras->platform == rw::PLATFORM_D3D9 && rw::platform == rw::PLATFORM_D3D8)) {
+ tex->raster = convertTexRaster(ras);
+ ras->destroy();
+ }
+ }
+ tex->setFilter(rw::Texture::LINEAR);
+ }
+
+}
+#endif
+
bool
CTxdStore::LoadTxd(int slot, RwStream *stream)
{
@@ -134,6 +166,9 @@ CTxdStore::LoadTxd(int slot, RwStream *stream)
if(RwStreamFindChunk(stream, rwID_TEXDICTIONARY, nil, nil)){
def->texDict = RwTexDictionaryGtaStreamRead(stream);
+#ifdef RW_GL3
+ convertTxd(def->texDict);
+#endif
return def->texDict != nil;
}
printf("Failed to load TXD\n");
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 <time.h>
+// 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 <windef.h> 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 <Windows.h>
+#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 <iostream>
#include <dirent.h>
#include <sys/types.h>
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 <tchar.h>
+#endif /* (defined(_MSC_VER)) */
+#include <stdio.h>
+#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<argc; i++)
+ {
+ RsEventHandler(rsPREINITCOMMANDLINE, argv[i]);
+ }
+
+ /*
+ * Parameters to be used in RwEngineOpen / rsRWINITIALISE event
+ */
+
+ openParams.width = RsGlobal.maximumWidth;
+ openParams.height = RsGlobal.maximumHeight;
+ openParams.windowtitle = RsGlobal.appName;
+
+ ControlsManager.MakeControllerActionsBlank();
+ ControlsManager.InitDefaultControlConfiguration();
+
+ /*
+ * Initialize the 3D (RenderWare) components of the app...
+ */
+ if( rsEVENTERROR == RsEventHandler(rsRWINITIALISE, &PSGLOBAL(window)) )
+ {
+ RsEventHandler(rsTERMINATE, nil);
+
+ return 0;
+ }
+
+ _InputInitialiseJoys();
+ _InputInitialiseMouse();
+ ControlsManager.InitDefaultControlConfigMouse(MousePointerStateHelper.GetMouseSetUp());
+
+ glfwSetWindowPos(PSGLOBAL(window), 0, 0);
+
+ /*
+ * 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, nil, SPIF_SENDCHANGE);
+ SystemParametersInfo(SPI_SETPOWEROFFACTIVE, FALSE, nil, SPIF_SENDCHANGE);
+ SystemParametersInfo(SPI_SETLOWPOWERACTIVE, FALSE, nil, 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);
+
+
+ {
+ CFileMgr::SetDirMyDocuments();
+
+ int32 gta3set = CFileMgr::OpenFile("gta3.set", "r");
+
+ if ( gta3set )
+ {
+ ControlsManager.LoadSettings(gta3set);
+ CFileMgr::CloseFile(gta3set);
+ }
+
+ CFileMgr::SetDir("");
+ }
+
+ SetErrorMode(SEM_FAILCRITICALERRORS);
+
+#ifndef MASTER
+ if (TurnOnAnimViewer) {
+ CAnimViewer::Initialise();
+ FrontEndMenuManager.m_bGameNotLoaded = false;
+ gGameState = GS_ANIMVIEWER;
+ TurnOnAnimViewer = false;
+ }
+#endif
+
+ initkeymap();
+ glfwSetKeyCallback(PSGLOBAL(window), keypressCB);
+ glfwSetWindowSizeCallback(PSGLOBAL(window), resizeCB);
+ glfwSetScrollCallback(PSGLOBAL(window), scrollCB);
+ glfwSetCursorPosCallback(PSGLOBAL(window), cursorCB);
+ glfwSetJoystickCallback(joysChangeCB);
+
+ while ( TRUE )
+ {
+ RwInitialised = TRUE;
+
+ /*
+ * Set the initial mouse position...
+ */
+ pos.x = RsGlobal.maximumWidth * 0.5f;
+ pos.y = RsGlobal.maximumHeight * 0.5f;
+
+ RsMouseSetPos(&pos);
+
+ /*
+ * Enter the message processing loop...
+ */
+
+ while( !RsGlobal.quit && !FrontEndMenuManager.m_bWantToRestart && !glfwWindowShouldClose(PSGLOBAL(window)))
+ {
+ glfwPollEvents();
+ if( ForegroundApp )
+ {
+ switch ( gGameState )
+ {
+ case GS_START_UP:
+ {
+ gGameState = GS_INIT_ONCE;
+ TRACE("gGameState = GS_INIT_ONCE");
+ break;
+ }
+
+ case GS_INIT_ONCE:
+ {
+ CoUninitialize();
+
+ LoadingScreen(nil, nil, "loadsc0");
+
+ if ( !CGame::InitialiseOnceAfterRW() )
+ RsGlobal.quit = TRUE;
+
+ gGameState = GS_INIT_FRONTEND;
+ TRACE("gGameState = GS_INIT_FRONTEND;");
+ break;
+ }
+
+ case GS_INIT_FRONTEND:
+ {
+ LoadingScreen(nil, nil, "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:
+ {
+ if(!glfwGetWindowAttrib(PSGLOBAL(window), GLFW_ICONIFIED))
+ RsEventHandler(rsFRONTENDIDLE, nil);
+
+ if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bWantToLoad )
+ {
+ gGameState = GS_INIT_PLAYING_GAME;
+ TRACE("gGameState = GS_INIT_PLAYING_GAME;");
+ }
+
+ if ( FrontEndMenuManager.m_bWantToLoad )
+ {
+ 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;
+ }
+#ifndef MASTER
+ case GS_ANIMVIEWER:
+ {
+ float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
+ if (RwInitialised)
+ {
+ if (!CMenuManager::m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms)
+ RsEventHandler(rsANIMVIEWER, (void*)TRUE);
+ }
+ break;
+ }
+#endif
+ }
+ }
+ else
+ {
+ if ( RwCameraBeginUpdate(Scene.camera) )
+ {
+ RwCameraEndUpdate(Scene.camera);
+ ForegroundApp = TRUE;
+ RsEventHandler(rsACTIVATE, (void *)TRUE);
+ }
+
+ }
+ }
+
+
+ /*
+ * About to shut down - block resize events again...
+ */
+ RwInitialised = FALSE;
+
+ FrontEndMenuManager.UnloadTextures();
+ if ( !FrontEndMenuManager.m_bWantToRestart )
+ break;
+
+ CPad::ResetCheats();
+ CPad::StopPadsShaking();
+
+ DMAudio.ChangeMusicMode(MUSICMODE_DISABLE);
+
+ CTimer::Stop();
+
+ if ( FrontEndMenuManager.m_bWantToLoad )
+ {
+ CGame::ShutDownForRestart();
+ CGame::InitialiseWhenRestarting();
+ DMAudio.ChangeMusicMode(MUSICMODE_GAME);
+ LoadSplash(GetLevelSplashScreen(CGame::currLevel));
+ FrontEndMenuManager.m_bWantToLoad = false;
+ }
+ else
+ {
+ if ( gGameState == GS_PLAYING_GAME )
+ CGame::ShutDown();
+ else if ( gGameState == GS_ANIMVIEWER )
+ CAnimViewer::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_bWantToRestart = false;
+ }
+
+
+ if ( gGameState == GS_PLAYING_GAME )
+ CGame::ShutDown();
+ else if ( gGameState == GS_ANIMVIEWER )
+ CAnimViewer::Shutdown();
+
+ DMAudio.Terminate();
+
+ _psFreeVideoModeList();
+
+
+ /*
+ * Tidy up the 3D (RenderWare) components of the application...
+ */
+ RsEventHandler(rsRWTERMINATE, nil);
+
+ /*
+ * Free the platform dependent data...
+ */
+ RsEventHandler(rsTERMINATE, nil);
+
+ /*
+ * Free the argv strings...
+ */
+ free(argv);
+
+ SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &SavedStickyKeys, SPIF_SENDCHANGE);
+ SystemParametersInfo(SPI_SETPOWEROFFACTIVE, TRUE, nil, SPIF_SENDCHANGE);
+ SystemParametersInfo(SPI_SETLOWPOWERACTIVE, TRUE, nil, SPIF_SENDCHANGE);
+ SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, nil, SPIF_SENDCHANGE);
+
+ SetErrorMode(0);
+
+ return 0;
+}
+
+/*
+ *****************************************************************************
+ */
+
+RwV2d leftStickPos;
+RwV2d rightStickPos;
+
+void CapturePad(RwInt32 padID)
+{
+ int8 glfwPad = -1;
+
+ if( padID == 0 )
+ glfwPad = PSGLOBAL(joy1id);
+ else if( padID == 1)
+ glfwPad = PSGLOBAL(joy2id);
+ else
+ assert("invalid padID");
+
+ if ( glfwPad == -1 )
+ return;
+
+ int numButtons, numAxes;
+ const uint8 *buttons = glfwGetJoystickButtons(glfwPad, &numButtons);
+ const float *axes = glfwGetJoystickAxes(glfwPad, &numAxes);
+ GLFWgamepadstate gamepadState;
+
+ if (ControlsManager.m_bFirstCapture == false)
+ {
+ memcpy(&ControlsManager.m_OldState, &ControlsManager.m_NewState, sizeof(ControlsManager.m_NewState));
+ }
+
+ ControlsManager.m_NewState.buttons = (uint8*)buttons;
+ ControlsManager.m_NewState.numButtons = numButtons;
+ ControlsManager.m_NewState.id = glfwPad;
+ ControlsManager.m_NewState.isGamepad = glfwJoystickIsGamepad(glfwPad);
+ if (ControlsManager.m_NewState.isGamepad) {
+ glfwGetGamepadState(glfwPad, &gamepadState);
+ memcpy(&ControlsManager.m_NewState.mappedButtons, gamepadState.buttons, sizeof(gamepadState.buttons));
+ ControlsManager.m_NewState.mappedButtons[15] = gamepadState.axes[4] > -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 <windef.h>
#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)) */
diff --git a/src/text/Messages.cpp b/src/text/Messages.cpp
index 3233ebc4..5abaa7ae 100644
--- a/src/text/Messages.cpp
+++ b/src/text/Messages.cpp
@@ -1,6 +1,3 @@
-#define DIRECTINPUT_VERSION 0x0800
-#include "dinput.h"
-
#include "common.h"
#include "Messages.h"
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index d31182cd..b93ab35e 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -707,13 +707,13 @@ CBoat::Render()
((CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()))->SetVehicleColour(m_currentColour1, m_currentColour2);
if (!CVehicle::bWheelsOnlyCheat)
CEntity::Render();
- KeepWaterOutVertices[0].color = -1;
+ KeepWaterOutVertices[0].setColor(255, 255, 255, 255);
KeepWaterOutIndices[0] = 0;
- KeepWaterOutVertices[1].color = -1;
+ KeepWaterOutVertices[1].setColor(255, 255, 255, 255);
KeepWaterOutIndices[1] = 2;
- KeepWaterOutVertices[2].color = -1;
+ KeepWaterOutVertices[2].setColor(255, 255, 255, 255);
KeepWaterOutIndices[2] = 1;
- KeepWaterOutVertices[3].color = -1;
+ KeepWaterOutVertices[3].setColor(255, 255, 255, 255);
KeepWaterOutIndices[3] = 1;
KeepWaterOutIndices[4] = 2;
KeepWaterOutIndices[5] = 3;