Compare commits

...

5 commits

Author SHA1 Message Date
Silent
17baa64613
SA: Use DWLP_USER in the resolution dialog
GWLP_USERDATA was unlikely to cause issues, but it's technically
reserved since we didn't create the window class ourselves.
DWLP_USER is guaranteed to be free for us to use.
2024-10-28 22:36:50 +01:00
Silent
f1d85b825b
SA: Clean CVehicleModelInfo fields from ::Init so they are cleaned up after modloader loads the ASI
Fixes #44
2024-10-28 20:47:34 +01:00
Silent
4cb6edad7c
SA: Also scale the default size of the gamepad crosshair
Fixes #29
2024-10-28 19:51:57 +01:00
Silent
6e5b41c958
SA: Fix focus issues with the resolution selection dialog
Now requests focus the proper way from WM_INITDIALOG,
instead of a manual SetFocus call.

Fixes #49
2024-10-28 19:27:26 +01:00
Silent
a07d7936da
SA: Improve mod compatibility of the new resolution dialog
Should resolve compatibility issues with Renderhook
2024-10-28 18:56:52 +01:00

View file

@ -1167,10 +1167,10 @@ void DrawScriptSpritesAndRectangles( uint8_t arg )
bool ReadDoubleRearWheels(const wchar_t* pPath);
bool __stdcall CheckDoubleRWheelsList( void* modelInfo, uint8_t* handlingData );
CVehicleModelInfo* (__thiscall *orgVehicleModelInfoCtor)(CVehicleModelInfo*);
CVehicleModelInfo* __fastcall VehicleModelInfoCtor(CVehicleModelInfo* me)
CVehicleModelInfo* (__thiscall *orgVehicleModelInfoInit)(CVehicleModelInfo*);
CVehicleModelInfo* __fastcall VehicleModelInfoInit(CVehicleModelInfo* me)
{
orgVehicleModelInfoCtor(me);
orgVehicleModelInfoInit(me);
// Hack to satisfy some null checks
static uintptr_t DUMMY;
@ -2629,16 +2629,23 @@ namespace NewResolutionSelectionDialog
}
}
static RwSubSystemInfo* (*orgRwEngineGetSubSystemInfo)(RwSubSystemInfo *subSystemInfo, RwInt32 subSystemIndex);
static RwSubSystemInfo *RwEngineGetSubSystemInfo_GetFriendlyNames(RwSubSystemInfo *subSystemInfo, RwInt32 subSystemIndex)
{
static const auto friendlyNames = FriendlyMonitorNames::GetNamesForDevicePaths();
// If we can't do any our work, fall back to the original game functions that may already by customized by other mods
if (*ppRWD3D9 == nullptr)
{
return orgRwEngineGetSubSystemInfo(subSystemInfo, subSystemIndex);
}
D3DADAPTER_IDENTIFIER9 identifier;
if (FAILED((*ppRWD3D9)->GetAdapterIdentifier(subSystemIndex, 0, &identifier)))
{
return nullptr;
return orgRwEngineGetSubSystemInfo(subSystemInfo, subSystemIndex);
}
static const auto friendlyNames = FriendlyMonitorNames::GetNamesForDevicePaths();
// If we can't find the friendly name, either because it doesn't exist or we're on an ancient Windows, fall back to the device name
auto it = friendlyNames.find(identifier.DeviceName);
if (it != friendlyNames.end())
@ -2654,8 +2661,15 @@ namespace NewResolutionSelectionDialog
}
static size_t MenuManagerAdapterOffset = 0xDC;
static RwInt32 (*orgRwEngineGetCurrentSubSystem)();
static RwInt32 RwEngineGetCurrentSubSystem_FromSettings()
{
// If we can't do any our work, fall back to the original game functions that may already by customized by other mods
if (*ppRWD3D9 == nullptr)
{
return orgRwEngineGetCurrentSubSystem();
}
RwInt32 subSystem = *reinterpret_cast<RwInt32*>(static_cast<char*>(FrontEndMenuManager) + MenuManagerAdapterOffset);
if (subSystem > 0)
{
@ -2705,7 +2719,7 @@ namespace NewResolutionSelectionDialog
if (msg == WM_INITDIALOG)
{
const WrappedDialocFunc* data = reinterpret_cast<WrappedDialocFunc*>(lParam);
SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(data->lpDialogFunc));
SetWindowLongPtr(window, DWLP_USER, reinterpret_cast<LONG_PTR>(data->lpDialogFunc));
data->lpDialogFunc(window, msg, wParam, data->dwInitParam);
@ -2716,14 +2730,15 @@ namespace NewResolutionSelectionDialog
// The game inits the selected resolution weirdly, and corrects it in the IDOK handler
// so let's invoke it manually (bleh)
data->lpDialogFunc(window, WM_COMMAND, IDOK, 0);
return TRUE;
return FALSE;
}
HMODULE hGameModule = GetModuleHandle(nullptr);
SendMessage(window, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(LoadIcon(hGameModule, MAKEINTRESOURCE(100))));
CreateNewButtonTooltip(hGameModule, window);
// Return TRUE instead of FALSE on init, we want keyboard focus
// Return TRUE instead of FALSE on init, as we removed a manual SetFocus from the init function
// and we want to rely on Windows to give us focus.
return TRUE;
}
@ -2743,7 +2758,7 @@ namespace NewResolutionSelectionDialog
}
}
DLGPROC origProc = reinterpret_cast<DLGPROC>(GetWindowLongPtr(window, GWLP_USERDATA));
DLGPROC origProc = reinterpret_cast<DLGPROC>(GetWindowLongPtr(window, DWLP_USER));
if (origProc != nullptr)
{
return origProc(window, msg, wParam, lParam);
@ -2806,6 +2821,12 @@ namespace NewResolutionSelectionDialog
return result;
}
static auto* const pDialogBoxParamA_New = &DialogBoxParamA_New;
static HWND WINAPI SetFocus_NOP(HWND)
{
return nullptr;
}
static auto* const pSetFocus_NOP = &SetFocus_NOP;
}
@ -5583,9 +5604,7 @@ void Patch_SA_10(HINSTANCE hInstance)
// Properly initialize all CVehicleModelInfo fields
ReadCall( 0x4C75E4, orgVehicleModelInfoCtor );
InjectHook( 0x4C75E4, VehicleModelInfoCtor );
InterceptCall(0x4C7633, orgVehicleModelInfoInit, VehicleModelInfoInit);
// Animated Phoenix hood scoop
{
@ -6150,9 +6169,10 @@ void Patch_SA_10(HINSTANCE hInstance)
orgGetDocumentsPath = AddressByRegion_10<char*(*)()>(0x744FB0);
Patch(AddressByRegion_10(0x746241 + 2), &pDialogBoxParamA_New);
Patch(AddressByRegion_10(0x745DB3 + 2), &pSetFocus_NOP);
InjectHook(AddressByRegion_10(0x7461D8), RwEngineGetSubSystemInfo_GetFriendlyNames);
InjectHook(AddressByRegion_10(0x7461ED), RwEngineGetCurrentSubSystem_FromSettings);
InterceptCall(AddressByRegion_10(0x7461D8), orgRwEngineGetSubSystemInfo, RwEngineGetSubSystemInfo_GetFriendlyNames);
InterceptCall(AddressByRegion_10(0x7461ED), orgRwEngineGetCurrentSubSystem, RwEngineGetCurrentSubSystem_FromSettings);
}
@ -6233,14 +6253,14 @@ void Patch_SA_10(HINSTANCE hInstance)
};
// Triangular gamepad crosshairs - their size needs to scale to screen *height*
std::array<float**, 11> triangleSizes = {
std::array<float**, 13> triangleSizes = {
// Co-op offscreen crosshair
(float**)(0x7436F1 + 2), (float**)(0x7436FF + 2), (float**)(0x74370D + 2), (float**)(0x74374B + 2),
(float**)(0x743797 + 2), (float**)(0x7437D0 + 2), (float**)(0x7437FB + 2), (float**)(0x743819 + 2),
(float**)(0x74386F + 2),
// Regular crosshair
(float**)(0x743259 + 2), (float**)(0x743266 + 2),
(float**)(0x743212 + 2), (float**)(0x74321E + 2), (float**)(0x743259 + 2), (float**)(0x743266 + 2),
};
HookEach_RenderOneXLUSprite_Rotate_Aspect(renderRotateAspect, InterceptCall);
@ -8312,6 +8332,7 @@ void Patch_SA_NewBinaries_Common(HINSTANCE hInstance)
return get_pattern("53 FF 15 ? ? ? ? 85 C0", 1 + 2);
}
}();
auto setFocus = get_pattern("53 FF 15 ? ? ? ? 5F", 1 + 2);
auto rRwEngineGetSubSystemInfo = get_pattern("E8 ? ? ? ? 46 83 C4 08 83 C7 50");
auto rwEngineGetCurrentSubSystem = get_pattern("7C EA E8 ? ? ? ? A3", 2);
@ -8323,9 +8344,10 @@ void Patch_SA_NewBinaries_Common(HINSTANCE hInstance)
orgGetDocumentsPath = static_cast<char*(*)()>(get_pattern( "8D 45 FC 50 68 19 00 02 00", -6 ));
Patch(dialogBoxParam, &pDialogBoxParamA_New);
Patch(setFocus, &pSetFocus_NOP);
InjectHook(rRwEngineGetSubSystemInfo, RwEngineGetSubSystemInfo_GetFriendlyNames);
InjectHook(rwEngineGetCurrentSubSystem, RwEngineGetCurrentSubSystem_FromSettings);
InterceptCall(rRwEngineGetSubSystemInfo, orgRwEngineGetSubSystemInfo, RwEngineGetSubSystemInfo_GetFriendlyNames);
InterceptCall(rwEngineGetCurrentSubSystem, orgRwEngineGetCurrentSubSystem, RwEngineGetCurrentSubSystem_FromSettings);
}
TXN_CATCH();
@ -8436,6 +8458,7 @@ void Patch_SA_NewBinaries_Common(HINSTANCE hInstance)
// Triangular gamepad crosshairs - their size needs to scale to screen *height*
auto regularCrosshair = pattern("D8 0D ? ? ? ? D9 5D F4 D9 46 08 DC 0D ? ? ? ? D8 45 F4").get_one();
auto defaultCrosshairSize = pattern("DD 05 ? ? ? ? D8 C9 D9 5D F4 DC 0D ? ? ? ? D9 5D E8").get_one();
std::array<float**, 3> triangleSizes = {
// Co-op offscreen crosshair
get_pattern<float*>("D9 5D CC D9 05 ? ? ? ? D9 C0 D9 45 FC", 3 + 2),
@ -8444,8 +8467,10 @@ void Patch_SA_NewBinaries_Common(HINSTANCE hInstance)
// Regular crosshair (float)
regularCrosshair.get<float*>(2),
};
std::array<double**, 1> triangleSizesDouble = {
std::array<double**, 3> triangleSizesDouble = {
regularCrosshair.get<double*>(0xC + 2),
defaultCrosshairSize.get<double*>(2),
defaultCrosshairSize.get<double*>(0xB + 2),
};
HookEach_RenderOneXLUSprite_Rotate_Aspect(renderRotateAspect, InterceptCall);