Added lightgun support to xapi
This commit is contained in:
parent
4645d42130
commit
2c1f5bd430
|
@ -157,6 +157,15 @@ struct XidSBCOutput {
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
struct LightGunOffsets {
|
||||||
|
xbox::short_xt x;
|
||||||
|
xbox::short_xt y;
|
||||||
|
};
|
||||||
|
|
||||||
|
union ExtraData {
|
||||||
|
LightGunOffsets offsets;
|
||||||
|
};
|
||||||
|
|
||||||
union InputBuff {
|
union InputBuff {
|
||||||
XidGamepadInput ctrl;
|
XidGamepadInput ctrl;
|
||||||
XidSBCInput sbc;
|
XidSBCInput sbc;
|
||||||
|
@ -170,8 +179,9 @@ struct DeviceInfo {
|
||||||
uint8_t ucSubType; // xapi subtype
|
uint8_t ucSubType; // xapi subtype
|
||||||
uint8_t ucInputStateSize; // input state size in bytes, does not include dwPacketNumber
|
uint8_t ucInputStateSize; // input state size in bytes, does not include dwPacketNumber
|
||||||
uint8_t ucFeedbackSize; // feedback size in bytes, does not include FeedbackHeader
|
uint8_t ucFeedbackSize; // feedback size in bytes, does not include FeedbackHeader
|
||||||
uint32_t dwPacketNumber;
|
uint32_t dwPacketNumber; // increases by one when the input state changes
|
||||||
InputBuff buff;
|
InputBuff buff; // input buffer
|
||||||
|
ExtraData data; // device-specific additional data
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DeviceState {
|
struct DeviceState {
|
||||||
|
|
|
@ -346,6 +346,7 @@ std::map<const std::string, const xbox_patch_t> g_PatchTable = {
|
||||||
PATCH_ENTRY("XInputGetState", xbox::EMUPATCH(XInputGetState), PATCH_HLE_OHCI),
|
PATCH_ENTRY("XInputGetState", xbox::EMUPATCH(XInputGetState), PATCH_HLE_OHCI),
|
||||||
PATCH_ENTRY("XInputOpen", xbox::EMUPATCH(XInputOpen), PATCH_HLE_OHCI),
|
PATCH_ENTRY("XInputOpen", xbox::EMUPATCH(XInputOpen), PATCH_HLE_OHCI),
|
||||||
PATCH_ENTRY("XInputPoll", xbox::EMUPATCH(XInputPoll), PATCH_HLE_OHCI),
|
PATCH_ENTRY("XInputPoll", xbox::EMUPATCH(XInputPoll), PATCH_HLE_OHCI),
|
||||||
|
PATCH_ENTRY("XInputSetLightgunCalibration", xbox::EMUPATCH(XInputSetLightgunCalibration), PATCH_HLE_OHCI),
|
||||||
PATCH_ENTRY("XInputSetState", xbox::EMUPATCH(XInputSetState), PATCH_HLE_OHCI),
|
PATCH_ENTRY("XInputSetState", xbox::EMUPATCH(XInputSetState), PATCH_HLE_OHCI),
|
||||||
|
|
||||||
// XAPI
|
// XAPI
|
||||||
|
|
|
@ -114,6 +114,7 @@ bool operator==(xbox::PXPP_DEVICE_TYPE XppType, XBOX_INPUT_DEVICE XidType)
|
||||||
{
|
{
|
||||||
case XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE:
|
case XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE:
|
||||||
case XBOX_INPUT_DEVICE::MS_CONTROLLER_S:
|
case XBOX_INPUT_DEVICE::MS_CONTROLLER_S:
|
||||||
|
case XBOX_INPUT_DEVICE::LIGHTGUN:
|
||||||
case XBOX_INPUT_DEVICE::ARCADE_STICK:
|
case XBOX_INPUT_DEVICE::ARCADE_STICK:
|
||||||
case XBOX_INPUT_DEVICE::HW_XBOX_CONTROLLER: {
|
case XBOX_INPUT_DEVICE::HW_XBOX_CONTROLLER: {
|
||||||
if (XppType == g_DeviceType_Gamepad) {
|
if (XppType == g_DeviceType_Gamepad) {
|
||||||
|
@ -137,7 +138,6 @@ bool operator==(xbox::PXPP_DEVICE_TYPE XppType, XBOX_INPUT_DEVICE XidType)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XBOX_INPUT_DEVICE::LIGHTGUN:
|
|
||||||
case XBOX_INPUT_DEVICE::STEERING_WHEEL:
|
case XBOX_INPUT_DEVICE::STEERING_WHEEL:
|
||||||
case XBOX_INPUT_DEVICE::IR_DONGLE:
|
case XBOX_INPUT_DEVICE::IR_DONGLE:
|
||||||
default:
|
default:
|
||||||
|
@ -154,6 +154,7 @@ void UpdateXppState(DeviceState *dev, XBOX_INPUT_DEVICE type, std::string_view p
|
||||||
{
|
{
|
||||||
case XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE:
|
case XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE:
|
||||||
case XBOX_INPUT_DEVICE::MS_CONTROLLER_S:
|
case XBOX_INPUT_DEVICE::MS_CONTROLLER_S:
|
||||||
|
case XBOX_INPUT_DEVICE::LIGHTGUN:
|
||||||
case XBOX_INPUT_DEVICE::ARCADE_STICK:
|
case XBOX_INPUT_DEVICE::ARCADE_STICK:
|
||||||
case XBOX_INPUT_DEVICE::HW_XBOX_CONTROLLER:
|
case XBOX_INPUT_DEVICE::HW_XBOX_CONTROLLER:
|
||||||
xpp = g_DeviceType_Gamepad;
|
xpp = g_DeviceType_Gamepad;
|
||||||
|
@ -256,6 +257,15 @@ void ConstructHleInputDevice(DeviceState *dev, DeviceState *upstream, int type,
|
||||||
dev->info.ucFeedbackSize = sizeof(XpadOutput);
|
dev->info.ucFeedbackSize = sizeof(XpadOutput);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case to_underlying(XBOX_INPUT_DEVICE::LIGHTGUN):
|
||||||
|
dev->type = XBOX_INPUT_DEVICE::LIGHTGUN;
|
||||||
|
dev->info.bAutoPollDefault = true;
|
||||||
|
dev->info.ucType = XINPUT_DEVTYPE_GAMEPAD;
|
||||||
|
dev->info.ucSubType = XINPUT_DEVSUBTYPE_GC_LIGHTGUN;
|
||||||
|
dev->info.ucInputStateSize = sizeof(XpadInput);
|
||||||
|
dev->info.ucFeedbackSize = sizeof(XpadOutput);
|
||||||
|
break;
|
||||||
|
|
||||||
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER):
|
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER):
|
||||||
case to_underlying(XBOX_INPUT_DEVICE::HW_STEEL_BATTALION_CONTROLLER):
|
case to_underlying(XBOX_INPUT_DEVICE::HW_STEEL_BATTALION_CONTROLLER):
|
||||||
dev->type = XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER;
|
dev->type = XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER;
|
||||||
|
@ -325,6 +335,7 @@ void DestructHleInputDevice(DeviceState *dev)
|
||||||
{
|
{
|
||||||
case XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE:
|
case XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE:
|
||||||
case XBOX_INPUT_DEVICE::MS_CONTROLLER_S:
|
case XBOX_INPUT_DEVICE::MS_CONTROLLER_S:
|
||||||
|
case XBOX_INPUT_DEVICE::LIGHTGUN:
|
||||||
dev->info.bAutoPollDefault = false;
|
dev->info.bAutoPollDefault = false;
|
||||||
dev->info.ucType = 0;
|
dev->info.ucType = 0;
|
||||||
dev->info.ucSubType = 0;
|
dev->info.ucSubType = 0;
|
||||||
|
@ -480,7 +491,7 @@ xbox::dword_xt CxbxImpl_XInputHandler(xbox::HANDLE hDevice, xbox::PXINPUT_STATE
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (!IsXInputPoll) {
|
if constexpr (!IsXInputPoll) {
|
||||||
std::memcpy((void *)&pState->Gamepad, reinterpret_cast<uint8_t *>(&g_devs[port].info.buff) + 2, g_devs[port].info.ucInputStateSize);
|
std::memcpy((void *)&pState->Gamepad, reinterpret_cast<uint8_t *>(&g_devs[port].info.buff) + XID_PACKET_HEADER, g_devs[port].info.ucInputStateSize);
|
||||||
pState->dwPacketNumber = g_devs[port].info.dwPacketNumber;
|
pState->dwPacketNumber = g_devs[port].info.dwPacketNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -787,6 +798,86 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(XInputSetState)
|
||||||
RETURN(pFeedback->Header.dwStatus);
|
RETURN(pFeedback->Header.dwStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// * patch: XGetDeviceEnumerationStatus
|
||||||
|
// ******************************************************************
|
||||||
|
xbox::dword_xt WINAPI xbox::EMUPATCH(XGetDeviceEnumerationStatus)()
|
||||||
|
{
|
||||||
|
LOG_FUNC();
|
||||||
|
|
||||||
|
dword_xt ret = (g_bIsDevicesInitializing || g_bIsDevicesEmulating) ? XDEVICE_ENUMERATION_BUSY : XDEVICE_ENUMERATION_IDLE;
|
||||||
|
|
||||||
|
RETURN(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// * patch: XInputGetDeviceDescription
|
||||||
|
// ******************************************************************
|
||||||
|
xbox::dword_xt WINAPI xbox::EMUPATCH(XInputGetDeviceDescription)
|
||||||
|
(
|
||||||
|
HANDLE hDevice,
|
||||||
|
PXINPUT_DEVICE_DESCRIPTION pDescription
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LOG_FUNC_BEGIN
|
||||||
|
LOG_FUNC_ARG(hDevice)
|
||||||
|
LOG_FUNC_ARG(pDescription)
|
||||||
|
LOG_FUNC_END;
|
||||||
|
|
||||||
|
dword_xt ret;
|
||||||
|
int port = static_cast<DeviceState *>(hDevice)->port_idx;
|
||||||
|
if (g_devs[port].info.hHandle == hDevice && !g_devs[port].bPendingRemoval) {
|
||||||
|
if (g_devs[port].type == XBOX_INPUT_DEVICE::LIGHTGUN) {
|
||||||
|
// These values are those reported in the device descriptor for the EMS TopGun II documented in the xboxdevwiki
|
||||||
|
pDescription->wVendorID = 0x0b9a;
|
||||||
|
pDescription->wProductID = 0x016b;
|
||||||
|
pDescription->wVersion = 0x457;
|
||||||
|
ret = ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// NOTE: Phantasy star online also calls this on the keyboard device
|
||||||
|
ret = ERROR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = ERROR_DEVICE_NOT_CONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// * patch: XInputSetLightgunCalibration
|
||||||
|
// ******************************************************************
|
||||||
|
xbox::dword_xt WINAPI xbox::EMUPATCH(XInputSetLightgunCalibration)
|
||||||
|
(
|
||||||
|
HANDLE hDevice,
|
||||||
|
PXINPUT_LIGHTGUN_CALIBRATION_OFFSETS pCalibrationOffsets
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LOG_FUNC_BEGIN
|
||||||
|
LOG_FUNC_ARG(hDevice)
|
||||||
|
LOG_FUNC_ARG(pCalibrationOffsets)
|
||||||
|
LOG_FUNC_END;
|
||||||
|
|
||||||
|
dword_xt ret;
|
||||||
|
int port = static_cast<DeviceState *>(hDevice)->port_idx;
|
||||||
|
if (g_devs[port].info.hHandle == hDevice && !g_devs[port].bPendingRemoval) {
|
||||||
|
if (g_devs[port].type == XBOX_INPUT_DEVICE::LIGHTGUN) {
|
||||||
|
g_devs[port].info.data.offsets.x = pCalibrationOffsets->wCenterX;
|
||||||
|
g_devs[port].info.data.offsets.y = pCalibrationOffsets->wCenterY;
|
||||||
|
ret = ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = ERROR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = ERROR_DEVICE_NOT_CONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN(ret);
|
||||||
|
}
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * patch: SetThreadPriorityBoost
|
// * patch: SetThreadPriorityBoost
|
||||||
|
@ -1394,42 +1485,6 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(XMountMUA)
|
||||||
RETURN(ERROR_SUCCESS);
|
RETURN(ERROR_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ******************************************************************
|
|
||||||
// * patch: XGetDeviceEnumerationStatus
|
|
||||||
// ******************************************************************
|
|
||||||
xbox::dword_xt WINAPI xbox::EMUPATCH(XGetDeviceEnumerationStatus)()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
LOG_FUNC();
|
|
||||||
|
|
||||||
dword_xt ret = (g_bIsDevicesInitializing || g_bIsDevicesEmulating) ? XDEVICE_ENUMERATION_BUSY : XDEVICE_ENUMERATION_IDLE;
|
|
||||||
|
|
||||||
RETURN(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ******************************************************************
|
|
||||||
// * patch: XInputGetDeviceDescription
|
|
||||||
// ******************************************************************
|
|
||||||
xbox::dword_xt WINAPI xbox::EMUPATCH(XInputGetDeviceDescription)
|
|
||||||
(
|
|
||||||
HANDLE hDevice,
|
|
||||||
PVOID pDescription
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
LOG_FUNC_BEGIN
|
|
||||||
LOG_FUNC_ARG(hDevice)
|
|
||||||
LOG_FUNC_ARG(pDescription)
|
|
||||||
LOG_FUNC_END;
|
|
||||||
|
|
||||||
// TODO: Lightgun support?
|
|
||||||
LOG_UNIMPLEMENTED();
|
|
||||||
|
|
||||||
RETURN(ERROR_NOT_SUPPORTED); // ERROR_DEVICE_NOT_CONNECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * patch: XMountMURootA
|
// * patch: XMountMURootA
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
|
|
@ -270,6 +270,30 @@ typedef struct _XINPUT_FEEDBACK
|
||||||
}
|
}
|
||||||
XINPUT_FEEDBACK, *PXINPUT_FEEDBACK;
|
XINPUT_FEEDBACK, *PXINPUT_FEEDBACK;
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// * XINPUT_DEVICE_DESCRIPTION
|
||||||
|
// ******************************************************************
|
||||||
|
typedef struct _XINPUT_DEVICE_DESCRIPTION
|
||||||
|
{
|
||||||
|
WORD wVendorID;
|
||||||
|
WORD wProductID;
|
||||||
|
WORD wVersion;
|
||||||
|
}
|
||||||
|
XINPUT_DEVICE_DESCRIPTION, *PXINPUT_DEVICE_DESCRIPTION;
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// * XINPUT_LIGHTGUN_CALIBRATION_OFFSETS
|
||||||
|
// ******************************************************************
|
||||||
|
typedef struct _XINPUT_LIGHTGUN_CALIBRATION_OFFSETS
|
||||||
|
{
|
||||||
|
WORD wCenterX;
|
||||||
|
WORD wCenterY;
|
||||||
|
WORD wUpperLeftX;
|
||||||
|
WORD wUpperLeftY;
|
||||||
|
}
|
||||||
|
XINPUT_LIGHTGUN_CALIBRATION_OFFSETS, *PXINPUT_LIGHTGUN_CALIBRATION_OFFSETS;
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * RTL_HEAP_PARAMETERS
|
// * RTL_HEAP_PARAMETERS
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
@ -439,6 +463,28 @@ xbox::dword_xt WINAPI EMUPATCH(XInputSetState)
|
||||||
IN OUT PXINPUT_FEEDBACK pFeedback
|
IN OUT PXINPUT_FEEDBACK pFeedback
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// * patch: XGetDeviceEnumerationStatus
|
||||||
|
// ******************************************************************
|
||||||
|
xbox::dword_xt WINAPI EMUPATCH(XGetDeviceEnumerationStatus)();
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// * patch: XInputGetDeviceDescription
|
||||||
|
// ******************************************************************
|
||||||
|
xbox::dword_xt WINAPI EMUPATCH(XInputGetDeviceDescription)
|
||||||
|
(
|
||||||
|
HANDLE hDevice,
|
||||||
|
PXINPUT_DEVICE_DESCRIPTION pDescription
|
||||||
|
);
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// * patch: XInputSetLightgunCalibration
|
||||||
|
// ******************************************************************
|
||||||
|
xbox::dword_xt WINAPI EMUPATCH(XInputSetLightgunCalibration)
|
||||||
|
(
|
||||||
|
HANDLE hDevice,
|
||||||
|
PXINPUT_LIGHTGUN_CALIBRATION_OFFSETS pCalibrationOffsets
|
||||||
|
);
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * patch: CreateMutex
|
// * patch: CreateMutex
|
||||||
|
@ -732,25 +778,11 @@ xbox::bool_xt WINAPI EMUPATCH(MoveFileA)
|
||||||
LPCSTR lpNewFileName
|
LPCSTR lpNewFileName
|
||||||
);
|
);
|
||||||
|
|
||||||
// ******************************************************************
|
|
||||||
// * patch: XGetDeviceEnumerationStatus
|
|
||||||
// ******************************************************************
|
|
||||||
xbox::dword_xt WINAPI EMUPATCH(XGetDeviceEnumerationStatus)();
|
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * patch: SwitchToThread
|
// * patch: SwitchToThread
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
xbox::bool_xt WINAPI EMUPATCH(SwitchToThread)();
|
xbox::bool_xt WINAPI EMUPATCH(SwitchToThread)();
|
||||||
|
|
||||||
// ******************************************************************
|
|
||||||
// * patch: XInputGetDeviceDescription
|
|
||||||
// ******************************************************************
|
|
||||||
xbox::dword_xt WINAPI EMUPATCH(XInputGetDeviceDescription)
|
|
||||||
(
|
|
||||||
HANDLE hDevice,
|
|
||||||
PVOID pDescription
|
|
||||||
);
|
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * patch: ReadFileEx
|
// * patch: ReadFileEx
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
|
Loading…
Reference in New Issue