-
-
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 2 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" | ||
|
|
||
| #ifdef _WIN32 | ||
| #ifndef NOMINMAX | ||
| #define NOMINMAX | ||
| #endif | ||
| #endif | ||
|
|
||
| // 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; | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| #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 != nullptr) | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| auto getDisplayConfigBufferSizes = (decltype(GetDisplayConfigBufferSizes)*)GetProcAddress(user32Lib, "GetDisplayConfigBufferSizes"); | ||
| auto queryDisplayConfig = (decltype(QueryDisplayConfig)*)GetProcAddress(user32Lib, "QueryDisplayConfig"); | ||
| auto displayConfigGetDeviceInfo = (decltype(DisplayConfigGetDeviceInfo)*)GetProcAddress(user32Lib, "DisplayConfigGetDeviceInfo"); | ||
| if (getDisplayConfigBufferSizes != nullptr && queryDisplayConfig != nullptr && displayConfigGetDeviceInfo != nullptr) | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| 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) | ||
| { | ||
| 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; | ||
forkerer marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #endif | ||
| } | ||
|
|
||
| struct RwSubSystemInfo | ||
| { | ||
| char name[80]; | ||
| }; | ||
|
|
||
| #define FUNC_rwDeviceSystemRequest 0x7F2AB0 | ||
| using rwDeviceSystemRequest = RwSubSystemInfo*(__cdecl*)(void* device, uint32_t requestId, RwSubSystemInfo* pOut, void* pInOut, uint32_t numIn); | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| static RwSubSystemInfo* RwEngineGetSubSystemInfo_Hooked(RwSubSystemInfo* subSystemInfo, int32_t subSystemIndex) | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| static auto rwDeviceSystemRequestFunc = (rwDeviceSystemRequest)(FUNC_rwDeviceSystemRequest); | ||
| auto devicePointer = *(uint32_t*)(0xC97B24); | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| auto result = rwDeviceSystemRequestFunc((void*)(devicePointer + 0x10), 14, subSystemInfo, nullptr, subSystemIndex); | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (result == nullptr) | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return nullptr; | ||
|
|
||
| auto pDxDevice = *(IDirect3D9**)0xC97C20; | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (pDxDevice == nullptr) | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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 | ||
| static INT_PTR CALLBACK CustomDlgProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam) | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| auto orgDialogFunc = (DLGPROC)FUNC_DialogFunc; | ||
| if (msg == WM_INITDIALOG) | ||
| { | ||
| 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; | ||
| } | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| return orgDialogFunc(window, msg, wParam, lParam); | ||
| } | ||
|
|
||
| void CMultiplayerSA::InitHooks_DeviceSelection() | ||
| { | ||
| MemPut<DLGPROC>(0x746239, (DLGPROC)&CustomDlgProc); | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| HookInstall(0x7F2C30, (DWORD)RwEngineGetSubSystemInfo_Hooked, 6); | ||
forkerer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
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.