From 2b06bb5a5980acaf69090fde58c7e4bb563b5a50 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Wed, 4 Oct 2017 10:19:55 +0100 Subject: [PATCH] Derive Gamepad Structure from XAPI functions --- src/CxbxKrnl/EmuXapi.cpp | 43 +++++++++++++++++++++++++++++++++++++ src/CxbxKrnl/EmuXapi.h | 11 ++++++++++ src/CxbxKrnl/HLEIntercept.h | 4 ++++ 3 files changed, 58 insertions(+) diff --git a/src/CxbxKrnl/EmuXapi.cpp b/src/CxbxKrnl/EmuXapi.cpp index f44b71c6e..41202eacf 100644 --- a/src/CxbxKrnl/EmuXapi.cpp +++ b/src/CxbxKrnl/EmuXapi.cpp @@ -61,6 +61,8 @@ extern HANDLE g_hInputHandle[XINPUT_HANDLE_SLOTS] = {0}; bool g_bXInputOpenCalled = false; +XTL::PXPP_DEVICE_TYPE gDeviceType_Gamepad = nullptr; + bool CxbxMountUtilityDrive(bool formatClean); // ****************************************************************** @@ -136,6 +138,47 @@ VOID WINAPI XTL::EMUPATCH(XInitDevices) LOG_FUNC_ARG(PreallocTypes) LOG_FUNC_END; + + // If we don't yet have the offset to gDeviceType_Gamepad, work it out! + if (gDeviceType_Gamepad == nullptr) { + // First, attempt to find GetTypeInformation + auto typeInformation = g_SymbolAddresses.find("GetTypeInformation"); + if (typeInformation != g_SymbolAddresses.end() && typeInformation->second != (xbaddr)nullptr) { + DbgPrintf("Deriving XDEVICE_TYPE_GAMEPAD from GetTypeInformation"); + // Read the offset values of the device table structure from GetTypeInformation + uint32_t deviceTableStartOffset = *(uint32_t*)((uint32_t)typeInformation->second + 0x01); + uint32_t deviceTableEndOffset = *(uint32_t*)((uint32_t)typeInformation->second + 0x09); + + // Calculate the number of device entires in the table + size_t deviceTableEntryCount = (deviceTableEndOffset - deviceTableStartOffset) / sizeof(uint32_t); + + // Iterate through the table until we find gamepad + PXID_TYPE_INFORMATION* deviceTable = (PXID_TYPE_INFORMATION*)(deviceTableStartOffset); + for (int i = 0; i < deviceTableEntryCount; i++) { + // If we found the gamepad structure (type 1), use it and exit the loop + if (deviceTable[i]->ucType == 1) { + gDeviceType_Gamepad = deviceTable[i]->XppType; + break; + } + } + } else { + // XDKs without GetTypeInformation have the GamePad address hardcoded in XInputOpen + // Only the earliest XDKs use this code path, and the offset never changed between them + // so this works well for us. + DbgPrintf("XAPI: Deriving XDEVICE_TYPE_GAMEPAD from XInputOpen"); + void* XInputOpenAddr = (VOID*)g_SymbolAddresses["XInputOpen"]; + gDeviceType_Gamepad = *(PXPP_DEVICE_TYPE*)((uint32_t)XInputOpenAddr + 0x0B); + } + + if (gDeviceType_Gamepad == nullptr) { + CxbxKrnlCleanup("XAPI: XDEVICE_TYPE_GAMEPAD was not found"); + } + + DbgPrintf("XAPI: XDEVICE_TYPE_GAMEPAD Found at 0x%08X", gDeviceType_Gamepad); + // Set the device as connected + gDeviceType_Gamepad->CurrentConnected = 1; + } + for(int v=0;v + extern bool bLLE_APU; // Set this to true for experimental APU (sound) LLE extern bool bLLE_GPU; // Set this to true for experimental GPU (graphics) LLE extern bool bLLE_JIT; // Set this to true for experimental JIT +extern std::map g_SymbolAddresses; + void EmuHLEIntercept(Xbe::Header *XbeHeader); std::string GetDetectedSymbolName(xbaddr address, int *symbolOffset);