From 8e96f42543dc36fabeead3f1293b6c97cb78ec5b Mon Sep 17 00:00:00 2001
From: Kirill Yurkin <47507219+ugozapad@users.noreply.github.com>
Date: Thu, 25 Jan 2024 15:31:17 +0300
Subject: [PATCH] Ported renderer to SDL

---
 SourceCode/CryInput/CMakeLists.txt            |  2 +-
 SourceCode/CryInput/CryInput.cpp              | 11 ++-
 .../RenderDll/XRenderD3D9/CMakeLists.txt      |  4 ++
 .../RenderDll/XRenderD3D9/D3DSystem.cpp       | 68 +++++++++++++++----
 .../RenderDll/XRenderD3D9/DriverD3D9.cpp      | 15 ++--
 5 files changed, 78 insertions(+), 22 deletions(-)

diff --git a/SourceCode/CryInput/CMakeLists.txt b/SourceCode/CryInput/CMakeLists.txt
index 31092ab2..b340fdd5 100644
--- a/SourceCode/CryInput/CMakeLists.txt
+++ b/SourceCode/CryInput/CMakeLists.txt
@@ -19,4 +19,4 @@ target_include_directories(${PROJECT_NAME} PRIVATE
     ${CMAKE_SOURCE_DIR}/SourceCode/CryCommon
 )
 
-target_link_libraries(${PROJECT_NAME})
+target_link_libraries(${PROJECT_NAME} SDL2)
diff --git a/SourceCode/CryInput/CryInput.cpp b/SourceCode/CryInput/CryInput.cpp
index febd983f..ed7565f6 100644
--- a/SourceCode/CryInput/CryInput.cpp
+++ b/SourceCode/CryInput/CryInput.cpp
@@ -38,11 +38,20 @@ BOOL APIENTRY DllMain( HANDLE hModule,
 }
 #endif //_XBOX
 
+#include <SDL_syswm.h>
+
 IInput *CreateInput( ISystem *pSystem,void* hinst, void* hwnd, bool usedinput)
 {
 	gISystem = pSystem;
 	CInput *pInput=new CInput;
-	if (!pInput->Init(pSystem,(HINSTANCE)hinst,(HWND)hwnd,usedinput))
+
+	// #TODO: properly HWND gettings, and remove 
+	SDL_SysWMinfo wmInfo;
+	SDL_VERSION(&wmInfo.version);
+	SDL_GetWindowWMInfo((SDL_Window*)hwnd, &wmInfo);
+	HWND realhwnd = wmInfo.info.win.window;
+
+	if (!pInput->Init(pSystem,(HINSTANCE)hinst, realhwnd,usedinput))
 	{
 		delete pInput;
 		return NULL;
diff --git a/SourceCode/RenderDll/XRenderD3D9/CMakeLists.txt b/SourceCode/RenderDll/XRenderD3D9/CMakeLists.txt
index 6d702bfd..adb8cf77 100644
--- a/SourceCode/RenderDll/XRenderD3D9/CMakeLists.txt
+++ b/SourceCode/RenderDll/XRenderD3D9/CMakeLists.txt
@@ -5,6 +5,10 @@ if (${ARCH_TYPE} STREQUAL "x86")
     add_definitions(-DDO_ASM)
 endif()
 
+if (MSVC)
+	add_compile_options(/SAFESEH:NO)
+endif()
+
 set(SRC_FILES
     "../Common/3DUtils.cpp"
     "../Common/CRT.cpp"
diff --git a/SourceCode/RenderDll/XRenderD3D9/D3DSystem.cpp b/SourceCode/RenderDll/XRenderD3D9/D3DSystem.cpp
index 080725aa..43f070cf 100644
--- a/SourceCode/RenderDll/XRenderD3D9/D3DSystem.cpp
+++ b/SourceCode/RenderDll/XRenderD3D9/D3DSystem.cpp
@@ -13,9 +13,19 @@
 #include "D3DCGVProgram.h"
 #include "D3DCGPShader.h"
 
+#include <SDL_syswm.h>
+
 #undef THIS_FILE
 static char THIS_FILE[] = __FILE__;
 
+HWND Cry_GetHWND(SDL_Window* window)
+{
+    SDL_SysWMinfo wmInfo;
+    SDL_VERSION(&wmInfo.version);
+    SDL_GetWindowWMInfo(window, &wmInfo);
+    HWND hwnd = wmInfo.info.win.window;
+    return hwnd;
+}
 
 void CD3D9Renderer::DisplaySplash()
 {
@@ -722,6 +732,8 @@ bool CD3D9Renderer::SetWindow(int width, int height, bool fullscreen, WIN_HWND h
     {
         m_hWnd = (SDL_Window*)hWnd;
     }
+
+    return true;
 }
 
 #ifdef USE_3DC
@@ -1054,6 +1066,10 @@ bool CD3D9Renderer::Error(char *Msg, HRESULT h)
   const char *str = D3DError(h);
   iLog->Log("Error: %s (%s)", Msg, str);
 
+#ifdef WIN32
+  __debugbreak();
+#endif // WIN32
+
   //UnSetRes();
 
   //if (Msg)
@@ -1416,12 +1432,14 @@ HRESULT CD3D9Renderer::Initialize3DEnvironment()
       behaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
   }
 
+  HWND hWnd = Cry_GetHWND(m_hWnd);
+
   // Create the device
   iLog->Log("Creating D3D device (Adapter format: %s, BackBuffer format: %s, Depth format: %s)", sD3DFMT(m_D3DSettings.AdapterFormat()), sD3DFMT(m_d3dpp.BackBufferFormat), sD3DFMT(m_d3dpp.AutoDepthStencilFormat));
   if (!CV_d3d9_nvperfhud)
-    hr = m_pD3D->CreateDevice(m_D3DSettings.AdapterOrdinal(), pDeviceInfo->DevType, (HWND)m_CurrContext->m_hWnd, behaviorFlags, &m_d3dpp, &m_pd3dDevice);
+    hr = m_pD3D->CreateDevice(m_D3DSettings.AdapterOrdinal(), pDeviceInfo->DevType, hWnd, behaviorFlags, &m_d3dpp, &m_pd3dDevice);
   else
-    hr = m_pD3D->CreateDevice(m_pD3D->GetAdapterCount()-1, D3DDEVTYPE_REF, (HWND)m_CurrContext->m_hWnd, behaviorFlags & ~(D3DCREATE_PUREDEVICE), &m_d3dpp, &m_pd3dDevice);
+    hr = m_pD3D->CreateDevice(m_pD3D->GetAdapterCount()-1, D3DDEVTYPE_REF, hWnd, behaviorFlags & ~(D3DCREATE_PUREDEVICE), &m_d3dpp, &m_pd3dDevice);
 
   if( SUCCEEDED(hr) )
   {
@@ -1438,13 +1456,13 @@ HRESULT CD3D9Renderer::Initialize3DEnvironment()
         m_d3dpp.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
 
         // Create the device
-        hr = m_pD3D->CreateDevice(m_D3DSettings.AdapterOrdinal(), pDeviceInfo->DevType, (HWND)m_CurrContext->m_hWnd, behaviorFlags, &m_d3dpp, &m_pd3dDevice);
+        hr = m_pD3D->CreateDevice(m_D3DSettings.AdapterOrdinal(), pDeviceInfo->DevType, hWnd, behaviorFlags, &m_d3dpp, &m_pd3dDevice);
         if (FAILED(hr))
         {
           SAFE_RELEASE(m_pd3dDevice);
           Sleep(1000);
           m_d3dpp.Flags &= ~D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
-          hr = m_pD3D->CreateDevice(m_D3DSettings.AdapterOrdinal(), pDeviceInfo->DevType, (HWND)m_CurrContext->m_hWnd, behaviorFlags, &m_d3dpp, &m_pd3dDevice);
+          hr = m_pD3D->CreateDevice(m_D3DSettings.AdapterOrdinal(), pDeviceInfo->DevType, hWnd, behaviorFlags, &m_d3dpp, &m_pd3dDevice);
         }
       }
     }
@@ -1458,15 +1476,15 @@ HRESULT CD3D9Renderer::Initialize3DEnvironment()
       // the window size to 1000x600 until after the display mode has
       // changed to 1024x768, because windows cannot be larger than the
       // desktop.
-			ShowWindow(m_hWnd, SW_SHOW);
-			UpdateWindow(m_hWnd);
-
-			SetForegroundWindow(m_hWnd);
-			SetFocus(m_hWnd);
+			//ShowWindow(m_hWnd, SW_SHOW);
+			//UpdateWindow(m_hWnd);
+            //
+			//SetForegroundWindow(m_hWnd);
+			//SetFocus(m_hWnd);
 
       if(!m_bFullScreen )
       {
-        SetWindowPos(m_hWnd, HWND_NOTOPMOST, m_rcWindowBounds.left, m_rcWindowBounds.top, (m_rcWindowBounds.right-m_rcWindowBounds.left), (m_rcWindowBounds.bottom - m_rcWindowBounds.top), SWP_SHOWWINDOW);
+        //SetWindowPos(m_hWnd, HWND_NOTOPMOST, m_rcWindowBounds.left, m_rcWindowBounds.top, (m_rcWindowBounds.right-m_rcWindowBounds.left), (m_rcWindowBounds.bottom - m_rcWindowBounds.top), SWP_SHOWWINDOW);
       }
       ChangeLog();
 			DisplaySplash();
@@ -1560,6 +1578,14 @@ HRESULT CD3D9Renderer::Initialize3DEnvironment()
       // Cleanup before we try again
       Cleanup3DEnvironment();
     }
+    else
+    {
+        iLog->LogError("Failed to create DirectX 9 device. Error: %s", DXGetErrorStringA(hr));
+    }
+  }
+  else
+  {
+          iLog->LogError("Failed to create DirectX 9 device. Error: %s", DXGetErrorStringA(hr));
   }
 
   return hr;
@@ -1717,7 +1743,7 @@ void CD3D9Renderer::BuildPresentParamsFromSettings()
   m_d3dpp.MultiSampleQuality     = m_D3DSettings.MultisampleQuality();
   m_d3dpp.SwapEffect             = D3DSWAPEFFECT_DISCARD;
   m_d3dpp.EnableAutoDepthStencil = m_D3DEnum.AppUsesDepthBuffer;
-  m_d3dpp.hDeviceWindow          = m_hWnd;
+  m_d3dpp.hDeviceWindow          = Cry_GetHWND(m_hWnd);
   if( m_D3DEnum.AppUsesDepthBuffer )
   {
     if (CV_d3d9_forcesoftware)
@@ -1883,13 +1909,23 @@ HRESULT CD3D9Renderer::Reset3DEnvironment()
   return S_OK;
 }
 
+void Cry_GetWindowRect(SDL_Window* window, RECT* rect)
+{
+    SDL_GetWindowSize(window, (int*) & rect->right, (int*)&rect->bottom);
+}
+
+void Cry_GetClientRect(SDL_Window* window, RECT* rect)
+{
+    SDL_GetWindowSize(window, (int*)&rect->right, (int*)&rect->bottom);
+}
+
 bool CD3D9Renderer::ChooseDevice(void)
 {
   HRESULT hr;
 
   // Save window properties
-  GetWindowRect( m_hWnd, &m_rcWindowBounds );
-  GetClientRect( m_hWnd, &m_rcWindowClient );
+  Cry_GetWindowRect( m_hWnd, &m_rcWindowBounds );
+  Cry_GetClientRect( m_hWnd, &m_rcWindowClient );
 
   if(FAILED(hr = ChooseInitialD3DSettings()))
     return Error("Couldn't find any suitable device", hr);
@@ -2022,12 +2058,14 @@ HRESULT CD3D9Renderer::AdjustWindowForChange()
   if( !m_bFullScreen )
   {
     // Set windowed-mode style
-    SetWindowLong( m_hWnd, GWL_STYLE, m_dwWindowStyle );
+    //SetWindowLong( m_hWnd, GWL_STYLE, m_dwWindowStyle );
+      SDL_SetWindowFullscreen(m_hWnd, 0);
   }
   else
   {
     // Set fullscreen-mode style
-    SetWindowLong( m_hWnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE );
+    //SetWindowLong( m_hWnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE );
+      SDL_SetWindowFullscreen(m_hWnd, SDL_WINDOW_FULLSCREEN_DESKTOP);
   }
 
   return S_OK;
diff --git a/SourceCode/RenderDll/XRenderD3D9/DriverD3D9.cpp b/SourceCode/RenderDll/XRenderD3D9/DriverD3D9.cpp
index 900ba132..a6362953 100644
--- a/SourceCode/RenderDll/XRenderD3D9/DriverD3D9.cpp
+++ b/SourceCode/RenderDll/XRenderD3D9/DriverD3D9.cpp
@@ -285,6 +285,9 @@ void CD3D9Renderer::Reset (void)
   hReturn = m_pd3dDevice->BeginScene();
 }
 
+extern void Cry_GetWindowRect(SDL_Window* window, RECT* rect);
+extern void Cry_GetClientRect(SDL_Window* window, RECT* rect);
+
 bool CD3D9Renderer::ChangeResolution(int nNewWidth, int nNewHeight, int nNewColDepth, int nNewRefreshHZ, bool bFullScreen)
 {
   HRESULT hReturn;
@@ -358,11 +361,13 @@ bool CD3D9Renderer::ChangeResolution(int nNewWidth, int nNewHeight, int nNewColD
     int y = (m_deskheight-CRenderer::m_height)/2;
     int wdt = GetSystemMetrics(SM_CXDLGFRAME)*2 + CRenderer::m_width;
     int hgt = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXDLGFRAME)*2 + CRenderer::m_height;
-    SetWindowPos(m_hWnd, HWND_NOTOPMOST, x, y, wdt, hgt, SWP_SHOWWINDOW);
+    //SetWindowPos(m_hWnd, HWND_NOTOPMOST, x, y, wdt, hgt, SWP_SHOWWINDOW);
+    SDL_SetWindowPosition(m_hWnd, x, y);
+    SDL_SetWindowSize(m_hWnd, wdt, hgt);
   }
   // Save window properties
-  GetWindowRect( m_hWnd, &m_rcWindowBounds );
-  GetClientRect( m_hWnd, &m_rcWindowClient );
+  Cry_GetWindowRect( m_hWnd, &m_rcWindowBounds );
+  Cry_GetClientRect( m_hWnd, &m_rcWindowClient );
 
   hReturn = m_pd3dDevice->BeginScene();
   ICryFont *pCryFont = iSystem->GetICryFont();
@@ -1783,7 +1788,7 @@ void CD3D9Renderer::ScreenShot(const char *filename)
   POINT WndP;
   WndP.x = 0;
   WndP.y = 0;
-  ClientToScreen(m_hWnd, &WndP);  
+ // ClientToScreen(m_hWnd, &WndP);  
   h = pSysDeskSurf->LockRect(&d3dlrSys, NULL, D3DLOCK_READONLY);
   if (FAILED(h))
     return;
@@ -2030,7 +2035,7 @@ void CD3D9Renderer::ReadFrameBuffer(unsigned char * pRGB, int nSizeX, int nSizeY
     POINT WndP;
     WndP.x = 0;
     WndP.y = 0;
-    ClientToScreen(m_hWnd, &WndP);  
+   // ClientToScreen(m_hWnd, &WndP);  
     hr = pSysSurf->LockRect(&d3dlrSys, NULL, 0);
     byte *src = (byte *)d3dlrSys.pBits;
     byte *dst = pRGB;