Derive Gamepad Structure from XAPI functions

This commit is contained in:
Luke Usher 2017-10-04 10:19:55 +01:00 committed by PatrickvL
parent 3db0931518
commit 2b06bb5a59
3 changed files with 58 additions and 0 deletions

View File

@ -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<XINPUT_SETSTATE_SLOTS;v++)
{
g_pXInputSetStateStatus[v].hDevice = 0;

View File

@ -148,6 +148,17 @@ typedef struct _XPP_DEVICE_TYPE
}
XPP_DEVICE_TYPE, *PXPP_DEVICE_TYPE;
// ******************************************************************
// * XID_TYPE_INFORMATION
// ******************************************************************
typedef struct _XID_TYPE_INFORMATION
{
UCHAR ucType;
UCHAR ucUnknown[3];
PXPP_DEVICE_TYPE XppType;
DWORD dwUnknown[5];
} XID_TYPE_INFORMATION, *PXID_TYPE_INFORMATION;
// ******************************************************************
// * XDEVICE_PREALLOC_TYPE
// ******************************************************************

View File

@ -34,10 +34,14 @@
#ifndef HLEINTERCEPT_H
#define HLEINTERCEPT_H
#include <map>
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<std::string, xbaddr> g_SymbolAddresses;
void EmuHLEIntercept(Xbe::Header *XbeHeader);
std::string GetDetectedSymbolName(xbaddr address, int *symbolOffset);