Skip to content

Commit 0f99d18

Browse files
authored
Merge branch 'master' into fix/sort-resolution-dialog
2 parents e0c44ef + 5e8fb14 commit 0f99d18

16 files changed

+387
-115
lines changed

Client/core/CGUI.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -700,9 +700,21 @@ bool CLocalGUI::InputGoesToGUI()
700700
if (!pGUI)
701701
return false;
702702

703-
// Here we're supposed to check if things like menues are up, console is up or the chatbox is expecting input
704-
// If the console is visible OR the chat is expecting input OR the mainmenu is visible
705-
return (IsConsoleVisible() || IsMainMenuVisible() || IsChatBoxInputEnabled() || m_bForceCursorVisible || pGUI->GetGUIInputEnabled() ||
703+
bool shouldShowCursorForGUI = false;
704+
if (pGUI->GetGUIInputEnabled())
705+
{
706+
eInputMode inputMode = pGUI->GetGUIInputMode();
707+
if (inputMode == INPUTMODE_NO_BINDS_ON_EDIT)
708+
{
709+
shouldShowCursorForGUI = true;
710+
}
711+
else if (inputMode == INPUTMODE_NO_BINDS)
712+
{
713+
shouldShowCursorForGUI = false;
714+
}
715+
}
716+
717+
return (IsConsoleVisible() || IsMainMenuVisible() || IsChatBoxInputEnabled() || m_bForceCursorVisible || shouldShowCursorForGUI ||
706718
!CCore::GetSingleton().IsFocused() || IsWebRequestGUIVisible());
707719
}
708720

Client/core/DXHook/CProxyDirect3D9.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,30 @@ HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND
246246
hResult =
247247
HandleCreateDeviceResult(hResult, m_pDevice, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
248248

249+
// After successful device creation
250+
if (SUCCEEDED(hResult) && *ppReturnedDeviceInterface)
251+
{
252+
// Check if we're in borderless mode
253+
bool bIsBorderlessMode = pPresentationParameters->Windowed == TRUE;
254+
255+
if (bIsBorderlessMode)
256+
{
257+
// Enable sRGB correction for borderless mode to compensate for DWM composition
258+
CProxyDirect3DDevice9* pProxyDevice = static_cast<CProxyDirect3DDevice9*>(*ppReturnedDeviceInterface);
259+
260+
// Set initial render states for proper color handling
261+
pProxyDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, TRUE);
262+
263+
// Configure samplers for sRGB texture reading
264+
for (DWORD i = 0; i < 8; i++)
265+
{
266+
pProxyDevice->SetSamplerState(i, D3DSAMP_SRGBTEXTURE, TRUE);
267+
}
268+
269+
WriteDebugEvent("Applied sRGB color correction for borderless mode");
270+
}
271+
}
272+
249273
return hResult;
250274
}
251275

Client/core/DXHook/CProxyDirect3DDevice9.cpp

Lines changed: 113 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
bool g_bInGTAScene = false;
1616
CProxyDirect3DDevice9* g_pProxyDevice = NULL;
1717
CProxyDirect3DDevice9::SD3DDeviceState* g_pDeviceState = NULL;
18+
SGammaState g_GammaState;
1819

1920
// Proxy constructor and destructor.
2021
CProxyDirect3DDevice9::CProxyDirect3DDevice9(IDirect3DDevice9* pDevice)
@@ -123,6 +124,22 @@ CProxyDirect3DDevice9::~CProxyDirect3DDevice9()
123124
{
124125
WriteDebugEvent(SString("CProxyDirect3DDevice9::~CProxyDirect3DDevice9 %08x", this));
125126

127+
// Reset gamma state when device is destroyed
128+
if (g_pProxyDevice == this)
129+
{
130+
// Restore original gamma if we had stored it
131+
if (g_GammaState.bOriginalGammaStored && m_pDevice)
132+
{
133+
m_pDevice->SetGammaRamp(g_GammaState.lastSwapChain, 0, &g_GammaState.originalGammaRamp);
134+
WriteDebugEvent("Restored original gamma ramp on device destruction");
135+
}
136+
137+
// Reset gamma state
138+
g_GammaState.bOriginalGammaStored = false;
139+
g_GammaState.bLastWasBorderless = false;
140+
ZeroMemory(&g_GammaState.originalGammaRamp, sizeof(g_GammaState.originalGammaRamp));
141+
}
142+
126143
// Release our reference to the wrapped device
127144
// Note: We don't check m_ulRefCount here because destructor is only called
128145
// when Release() determined the count reached 0
@@ -374,6 +391,12 @@ HRESULT CProxyDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS* pPresentationParamet
374391
return D3DERR_INVALIDCALL;
375392
}
376393

394+
// Reset gamma state since display mode might change
395+
g_GammaState.bOriginalGammaStored = false;
396+
g_GammaState.bLastWasBorderless = false;
397+
ZeroMemory(&g_GammaState.originalGammaRamp, sizeof(g_GammaState.originalGammaRamp));
398+
WriteDebugEvent("Reset gamma state due to device reset");
399+
377400
// Check cooperative level before attempting reset
378401
HRESULT hCoopLevel = m_pDevice->TestCooperativeLevel();
379402
if (hCoopLevel == D3DERR_DEVICELOST)
@@ -473,6 +496,7 @@ HRESULT CProxyDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS* pPresentationParamet
473496
return hResult;
474497
}
475498

499+
476500
HRESULT CProxyDirect3DDevice9::Present(CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion)
477501
{
478502
CDirect3DEvents9::OnPresent(m_pDevice);
@@ -508,12 +532,99 @@ HRESULT CProxyDirect3DDevice9::SetDialogBoxMode(BOOL bEnableDialogs)
508532

509533
VOID CProxyDirect3DDevice9::SetGammaRamp(UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp)
510534
{
511-
m_pDevice->SetGammaRamp(iSwapChain, Flags, pRamp);
535+
// Validate inputs first
536+
if (!pRamp)
537+
{
538+
WriteDebugEvent("CProxyDirect3DDevice9::SetGammaRamp - Invalid gamma ramp pointer");
539+
return;
540+
}
541+
542+
// Validate swap chain index
543+
if (iSwapChain >= GetNumberOfSwapChains())
544+
{
545+
WriteDebugEvent(SString("CProxyDirect3DDevice9::SetGammaRamp - Invalid swap chain index: %d", iSwapChain));
546+
return;
547+
}
548+
549+
// Get current display mode state - use a timeout to avoid race conditions during mode transitions
550+
CVideoModeManagerInterface* pVideoModeManager = GetVideoModeManager();
551+
if (!pVideoModeManager)
552+
{
553+
// Fallback to original behavior if video mode manager is unavailable
554+
m_pDevice->SetGammaRamp(iSwapChain, Flags, pRamp);
555+
return;
556+
}
557+
558+
bool bIsBorderlessMode = pVideoModeManager->IsDisplayModeWindowed() || pVideoModeManager->IsDisplayModeFullScreenWindow();
559+
560+
// Store original gamma ramp on first call or mode change
561+
if (!g_GammaState.bOriginalGammaStored || g_GammaState.lastSwapChain != iSwapChain || g_GammaState.bLastWasBorderless != bIsBorderlessMode)
562+
{
563+
if (!bIsBorderlessMode || !g_GammaState.bOriginalGammaStored)
564+
{
565+
// In fullscreen mode or first time - this is likely the original gamma
566+
g_GammaState.originalGammaRamp = *pRamp;
567+
g_GammaState.bOriginalGammaStored = true;
568+
g_GammaState.lastSwapChain = iSwapChain;
569+
}
570+
g_GammaState.bLastWasBorderless = bIsBorderlessMode;
571+
}
572+
573+
if (bIsBorderlessMode)
574+
{
575+
// Apply brightness and contrast adjustment to match fullscreen mode
576+
D3DGAMMARAMP adjustedRamp = *pRamp;
577+
578+
// Use lighter gamma correction to prevent darkening effect
579+
// and optimize brightness boost for better visibility
580+
const float fGammaCorrection = 1.0f / 1.3f;
581+
const float fBrightnessBoost = 1.4f;
582+
583+
for (int i = 0; i < 256; i++)
584+
{
585+
// Convert to normalized float (0.0 - 1.0)
586+
float fRed = static_cast<float>(pRamp->red[i]) / 65535.0f;
587+
float fGreen = static_cast<float>(pRamp->green[i]) / 65535.0f;
588+
float fBlue = static_cast<float>(pRamp->blue[i]) / 65535.0f;
589+
590+
// Clamp input values to valid range
591+
fRed = std::max(0.0f, std::min(1.0f, fRed));
592+
fGreen = std::max(0.0f, std::min(1.0f, fGreen));
593+
fBlue = std::max(0.0f, std::min(1.0f, fBlue));
594+
595+
// Apply gentler gamma correction first
596+
fRed = powf(fRed, fGammaCorrection);
597+
fGreen = powf(fGreen, fGammaCorrection);
598+
fBlue = powf(fBlue, fGammaCorrection);
599+
600+
// Then apply balanced brightness boost
601+
fRed = std::min(1.0f, fRed * fBrightnessBoost);
602+
fGreen = std::min(1.0f, fGreen * fBrightnessBoost);
603+
fBlue = std::min(1.0f, fBlue * fBrightnessBoost);
604+
605+
// Convert back to WORD values with proper rounding
606+
adjustedRamp.red[i] = static_cast<WORD>(fRed * 65535.0f + 0.5f);
607+
adjustedRamp.green[i] = static_cast<WORD>(fGreen * 65535.0f + 0.5f);
608+
adjustedRamp.blue[i] = static_cast<WORD>(fBlue * 65535.0f + 0.5f);
609+
}
610+
611+
// Set the adjusted gamma ramp
612+
m_pDevice->SetGammaRamp(iSwapChain, Flags, &adjustedRamp);
613+
614+
WriteDebugEvent("Applied gamma adjustment for borderless windowed mode");
615+
}
616+
else
617+
{
618+
// In exclusive fullscreen mode, use the original gamma ramp
619+
m_pDevice->SetGammaRamp(iSwapChain, Flags, pRamp);
620+
621+
WriteDebugEvent("Applied original gamma ramp for fullscreen mode");
622+
}
512623
}
513624

514625
VOID CProxyDirect3DDevice9::GetGammaRamp(UINT iSwapChain, D3DGAMMARAMP* pRamp)
515626
{
516-
m_pDevice->GetGammaRamp(iSwapChain, pRamp);
627+
return m_pDevice->GetGammaRamp(iSwapChain, pRamp);
517628
}
518629

519630
HRESULT CProxyDirect3DDevice9::CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture,

Client/core/DXHook/CProxyDirect3DDevice9.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,3 +557,19 @@ interface CProxyDirect3DDevice9 : public IDirect3DDevice9
557557

558558
extern CProxyDirect3DDevice9* g_pProxyDevice;
559559
extern CProxyDirect3DDevice9::SD3DDeviceState* g_pDeviceState;
560+
561+
// Add gamma state management
562+
struct SGammaState
563+
{
564+
volatile bool bOriginalGammaStored;
565+
volatile bool bLastWasBorderless;
566+
D3DGAMMARAMP originalGammaRamp;
567+
volatile UINT lastSwapChain;
568+
569+
SGammaState() : bOriginalGammaStored(false), bLastWasBorderless(false), lastSwapChain(0)
570+
{
571+
ZeroMemory(&originalGammaRamp, sizeof(originalGammaRamp));
572+
}
573+
};
574+
575+
extern SGammaState g_GammaState;

Client/core/DXHook/CProxyDirect3DVertexBuffer.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
*
33
* PROJECT: Multi Theft Auto v1.0
44
* LICENSE: See LICENSE in the top level directory
5-
* FILE:
6-
* PURPOSE:
5+
* FILE: core/CProxyDirect3DVertexBuffer.cpp
6+
* PURPOSE: Direct3D 9 vertex buffer function hooking proxy
77
*
88
* Multi Theft Auto is available from https://www.multitheftauto.com/
99
*
@@ -86,15 +86,10 @@ HRESULT CProxyDirect3DVertexBuffer::QueryInterface(REFIID riid, void** ppvObj)
8686
ULONG CProxyDirect3DVertexBuffer::Release()
8787
{
8888
// Call original function
89-
ULONG count = m_pOriginal->Release();
90-
91-
if (count == 0)
92-
{
93-
// now, the Original Object has deleted itself, so do we here
94-
delete this; // destructor will be called automatically
95-
}
96-
97-
return count;
89+
ULONG ulRefCount = m_pOriginal->Release();
90+
if (ulRefCount == 0)
91+
delete this;
92+
return ulRefCount;
9893
}
9994

10095
/////////////////////////////////////////////////////////////

Client/core/DXHook/CProxyDirect3DVertexBuffer.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@
22
*
33
* PROJECT: Multi Theft Auto v1.0
44
* LICENSE: See LICENSE in the top level directory
5-
* FILE:
6-
* PURPOSE:
5+
* FILE: core/CProxyDirect3DVertexBuffer.h
6+
* PURPOSE: Direct3D 9 vertex buffer function hooking proxy
77
*
88
* Multi Theft Auto is available from https://www.multitheftauto.com/
99
*
1010
*****************************************************************************/
1111

12+
#pragma once
13+
14+
#include <d3d9.h>
15+
#include "CProxyDirect3DDevice9.h" // Include full definition for SResourceMemory
16+
1217
DEFINE_GUID(CProxyDirect3DVertexBuffer_GUID, 0x128A025E, 0x0100, 0x04F1, 0x40, 0x60, 0x53, 0x19, 0x44, 0x56, 0x59, 0x42);
1318

1419
class CProxyDirect3DVertexBuffer : public IDirect3DVertexBuffer9
@@ -29,7 +34,7 @@ class CProxyDirect3DVertexBuffer : public IDirect3DVertexBuffer9
2934
HRESULT __stdcall FreePrivateData(REFGUID refguid) { return m_pOriginal->FreePrivateData(refguid); }
3035
DWORD __stdcall SetPriority(DWORD PriorityNew) { return m_pOriginal->SetPriority(PriorityNew); }
3136
DWORD __stdcall GetPriority() { return m_pOriginal->GetPriority(); }
32-
void __stdcall PreLoad() { return m_pOriginal->PreLoad(); }
37+
void __stdcall PreLoad() { m_pOriginal->PreLoad(); }
3338
D3DRESOURCETYPE __stdcall GetType() { return m_pOriginal->GetType(); }
3439

3540
/*** IDirect3DVertexBuffer9 methods ***/

Client/core/Graphics/CVideoModeManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ class CVideoModeManager : public CVideoModeManagerInterface
4242
virtual bool GetRequiredDisplayResolution(int& iOutWidth, int& iOutHeight, int& iOutColorBits, int& iOutAdapterIndex) override;
4343
virtual int GetFullScreenStyle() override { return m_iCurrentFullscreenStyle; }
4444
virtual bool IsDisplayModeWindowed() override;
45+
virtual bool IsDisplayModeFullScreenWindow() override;
4546

4647
bool IsDisplayModeFullScreen();
47-
bool IsDisplayModeFullScreenWindow();
4848
bool GetCurrentAdapterRect(LPRECT pOutRect);
4949
SString GetCurrentAdapterDeviceName();
5050

Client/core/Graphics/CVideoModeManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class CVideoModeManagerInterface
3737
virtual bool GetRequiredDisplayResolution(int& iOutWidth, int& iOutHeight, int& iOutColorBits, int& iOutAdapterIndex) = 0;
3838
virtual int GetFullScreenStyle() = 0;
3939
virtual bool IsDisplayModeWindowed() = 0;
40+
virtual bool IsDisplayModeFullScreenWindow() = 0;
4041
};
4142

4243
CVideoModeManagerInterface* GetVideoModeManager();

Client/game_sa/CAudioEngineSA.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,14 +425,14 @@ static void __declspec(naked) HOOK_CAEAmbienceTrackManager_CheckForPause()
425425

426426
__asm
427427
{
428-
push esi
428+
pushad
429429
call IsAmbientSoundGeneralEnabled
430430
test al, al
431+
popad
431432
jnz continueWithOriginalCode
432433
mov dword ptr [esp+8], 0 // Pause by setting 0.0f for the last argument to CAEAudioHardware::SetChannelFrequencyScalingFactor
433434

434435
continueWithOriginalCode:
435-
pop esi
436436
mov edi, [esp+8]
437437
xor ecx, ecx
438438
jmp RETURN_CAEAmbienceTrackManager_CheckForPause

Client/mods/deathmatch/logic/CClientPed.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2014,6 +2014,13 @@ void CClientPed::SetFrozen(bool bFrozen)
20142014
if (m_pPlayerPed)
20152015
{
20162016
m_pPlayerPed->GetMatrix(&m_matFrozen);
2017+
2018+
CVector vecFrozenRotation = m_matFrozen.GetRotation();
2019+
2020+
if (vecFrozenRotation.fX == 0.0f && vecFrozenRotation.fY == 0.0f && vecFrozenRotation.fZ == 0.0f)
2021+
{
2022+
m_matFrozen.SetRotation(m_Matrix.GetRotation());
2023+
}
20172024
}
20182025
else
20192026
{
@@ -3326,6 +3333,12 @@ void CClientPed::ApplyControllerStateFixes(CControllerState& Current)
33263333

33273334
float CClientPed::GetCurrentRotation()
33283335
{
3336+
if (IsFrozen())
3337+
{
3338+
CVector vecRotation = m_matFrozen.GetRotation();
3339+
return vecRotation.fZ;
3340+
}
3341+
33293342
if (m_pPlayerPed)
33303343
{
33313344
return m_pPlayerPed->GetCurrentRotation();

0 commit comments

Comments
 (0)