-
-
Notifications
You must be signed in to change notification settings - Fork 502
Fix some small problems with Device Selection Dialog #3851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Dutchman101
merged 14 commits into
multitheftauto:master
from
forkerer:feature/DeviceSelectionFixes
Nov 21, 2024
Merged
Changes from 8 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
30f9675
Fix some small problems with Device Selection Dialog
forkerer 8bc4427
Fix file comment
forkerer 0d66ab4
Remove NOMINMAX directive
forkerer ca847bb
Early outs
forkerer 83b210d
RwGlobals and RwDevice stup in Renderware.h
forkerer 148aef6
Pointles static removal, clarification of some addresses
forkerer 406f74c
added missing std::
forkerer 40b4752
Fixed incorrect comment
forkerer c621fc8
Remove windows 7 safety checks
forkerer 486aa59
Instant return from function if possible
forkerer cc90226
use auto* for pointers
forkerer 1a7e9cd
Move every single magic number to the defines at the top of the file
forkerer 479f0f7
Replace std::map with std::unordered_map
forkerer 20a5659
Merge branch 'master' into feature/DeviceSelectionFixes
Dutchman101 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
157 changes: 157 additions & 0 deletions
157
Client/multiplayer_sa/CMultiplayerSA_DeviceSelection.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| /***************************************************************************** | ||
| * | ||
| * PROJECT: Multi Theft Auto v1.0 | ||
| * LICENSE: See LICENSE in the top level directory | ||
| * FILE: multiplayer_sa/CMultiplayerSA_DeviceSelection.cpp | ||
| * | ||
| * Multi Theft Auto is available from http://www.multitheftauto.com/ | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| #include "StdInc.h" | ||
|
|
||
| // This is copied from SilentPatch: | ||
| // https://github.com/CookiePLMonster/SilentPatch/blob/dev/SilentPatch/FriendlyMonitorNames.cpp | ||
| std::map<std::string, std::string, std::less<>> GetFriendlyMonitorNamesForDevicePaths() | ||
| { | ||
| std::map<std::string, std::string, std::less<>> monitorNames; | ||
|
|
||
| #if WINVER < _WIN32_WINNT_WIN7 | ||
| return monitorNames; | ||
| #else | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| HMODULE user32Lib = LoadLibrary(TEXT("user32")); | ||
| if (!user32Lib) | ||
| return monitorNames; | ||
|
|
||
| auto getDisplayConfigBufferSizes = (decltype(GetDisplayConfigBufferSizes)*)GetProcAddress(user32Lib, "GetDisplayConfigBufferSizes"); | ||
| auto queryDisplayConfig = (decltype(QueryDisplayConfig)*)GetProcAddress(user32Lib, "QueryDisplayConfig"); | ||
| auto displayConfigGetDeviceInfo = (decltype(DisplayConfigGetDeviceInfo)*)GetProcAddress(user32Lib, "DisplayConfigGetDeviceInfo"); | ||
| if (!getDisplayConfigBufferSizes || !queryDisplayConfig || !displayConfigGetDeviceInfo) | ||
| { | ||
| FreeLibrary(user32Lib); | ||
| return monitorNames; | ||
| } | ||
|
|
||
| UINT32 pathCount, modeCount; | ||
| std::unique_ptr<DISPLAYCONFIG_PATH_INFO[]> paths; | ||
| std::unique_ptr<DISPLAYCONFIG_MODE_INFO[]> modes; | ||
|
|
||
| LONG result = ERROR_SUCCESS; | ||
| do | ||
| { | ||
| result = getDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount); | ||
| if (result != ERROR_SUCCESS) | ||
| { | ||
| break; | ||
| } | ||
| paths = std::make_unique<DISPLAYCONFIG_PATH_INFO[]>(pathCount); | ||
| modes = std::make_unique<DISPLAYCONFIG_MODE_INFO[]>(modeCount); | ||
| result = queryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &pathCount, paths.get(), &modeCount, modes.get(), nullptr); | ||
| } while (result == ERROR_INSUFFICIENT_BUFFER); | ||
|
|
||
| if (result != ERROR_SUCCESS) | ||
| { | ||
| FreeLibrary(user32Lib); | ||
| return monitorNames; | ||
| } | ||
|
|
||
| for (size_t i = 0; i < pathCount; i++) | ||
| { | ||
| DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {}; | ||
| targetName.header.adapterId = paths[i].targetInfo.adapterId; | ||
| targetName.header.id = paths[i].targetInfo.id; | ||
| targetName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; | ||
| targetName.header.size = sizeof(targetName); | ||
| const LONG targetNameResult = DisplayConfigGetDeviceInfo(&targetName.header); | ||
|
|
||
| DISPLAYCONFIG_SOURCE_DEVICE_NAME sourceName = {}; | ||
| sourceName.header.adapterId = paths[i].sourceInfo.adapterId; | ||
| sourceName.header.id = paths[i].sourceInfo.id; | ||
| sourceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; | ||
| sourceName.header.size = sizeof(sourceName); | ||
| const LONG sourceNameResult = DisplayConfigGetDeviceInfo(&sourceName.header); | ||
| if (targetNameResult == ERROR_SUCCESS && sourceNameResult == ERROR_SUCCESS && targetName.monitorFriendlyDeviceName[0] != '\0') | ||
| { | ||
| char gdiDeviceName[std::size(sourceName.viewGdiDeviceName)]; | ||
| char monitorFriendlyDeviceName[std::size(targetName.monitorFriendlyDeviceName)]; | ||
| WideCharToMultiByte(CP_ACP, 0, sourceName.viewGdiDeviceName, -1, gdiDeviceName, static_cast<int>(std::size(gdiDeviceName)), nullptr, nullptr); | ||
| WideCharToMultiByte(CP_ACP, 0, targetName.monitorFriendlyDeviceName, -1, monitorFriendlyDeviceName, | ||
| static_cast<int>(std::size(monitorFriendlyDeviceName)), nullptr, nullptr); | ||
|
|
||
| monitorNames.try_emplace(gdiDeviceName, monitorFriendlyDeviceName); | ||
| } | ||
| } | ||
|
|
||
| FreeLibrary(user32Lib); | ||
| return monitorNames; | ||
| #endif | ||
| } | ||
|
|
||
| struct RwSubSystemInfo | ||
| { | ||
| char name[80]; | ||
| }; | ||
|
|
||
| #define FUNC_rwDeviceSystemRequest 0x7F2AB0 | ||
| using rwDeviceSystemRequest = RwSubSystemInfo*(__cdecl*)(RwDevice* device, std::int32_t requestId, RwSubSystemInfo* pOut, void* pInOut, std::int32_t numIn); | ||
| static RwSubSystemInfo* RwEngineGetSubSystemInfo_Hooked(RwSubSystemInfo* subSystemInfo, std::int32_t subSystemIndex) | ||
| { | ||
| auto rwGlobals = *(RwGlobals**)(0xC97B24); | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| auto rwDeviceSystemRequestFunc = (rwDeviceSystemRequest)(FUNC_rwDeviceSystemRequest); | ||
| auto result = rwDeviceSystemRequestFunc(&rwGlobals->dOpenDevice, 14, subSystemInfo, nullptr, subSystemIndex); | ||
| if (!result) | ||
| return nullptr; | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| auto pDxDevice = *(IDirect3D9**)0xC97C20; | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (!pDxDevice) | ||
| return subSystemInfo; | ||
|
|
||
| D3DADAPTER_IDENTIFIER9 identifier; | ||
| if (FAILED(pDxDevice->GetAdapterIdentifier(subSystemIndex, 0, &identifier))) | ||
| return subSystemInfo; | ||
|
|
||
| static const auto friendlyNames = GetFriendlyMonitorNamesForDevicePaths(); | ||
|
|
||
| // 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()) | ||
| { | ||
| strncpy_s(subSystemInfo->name, it->second.c_str(), _TRUNCATE); | ||
| } | ||
| else | ||
| { | ||
| strncpy_s(subSystemInfo->name, identifier.Description, _TRUNCATE); | ||
| } | ||
forkerer marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| return subSystemInfo; | ||
| } | ||
|
|
||
| #define FUNC_DialogFunc 0x745E50 | ||
| INT_PTR CALLBACK CustomDlgProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam) | ||
| { | ||
| auto orgDialogFunc = (DLGPROC)FUNC_DialogFunc; | ||
| if (msg != WM_INITDIALOG) | ||
| return orgDialogFunc(window, msg, wParam, lParam); | ||
|
|
||
| orgDialogFunc(window, msg, wParam, lParam); | ||
|
|
||
| // Set Icon | ||
| HMODULE hGameModule = GetModuleHandle(nullptr); | ||
| SendMessage(window, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(LoadIcon(hGameModule, MAKEINTRESOURCE(100)))); | ||
|
|
||
| // Make the dialog visible in the task bar | ||
| // https://stackoverflow.com/a/1462811 | ||
| SetWindowLongPtr(window, GWL_EXSTYLE, WS_EX_APPWINDOW); | ||
| ShowWindow(window, SW_HIDE); | ||
| ShowWindow(window, SW_SHOW); | ||
| return FALSE; | ||
| } | ||
|
|
||
| #define FUNC_RwEngineGetSubSystemInfo 0x7F2C30 | ||
| void CMultiplayerSA::InitHooks_DeviceSelection() | ||
| { | ||
| // 0x746239 -> Exact address where the original DialogFunc address is being pushed as an argument to DialogBoxParamA(), | ||
| // we're replacing it with out own proxy function | ||
| MemPut<DLGPROC>(0x746239, (DLGPROC)&CustomDlgProc); | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| HookInstall(FUNC_RwEngineGetSubSystemInfo, (DWORD)RwEngineGetSubSystemInfo_Hooked, 6); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.