Added lightgun support to xapi

This commit is contained in:
ergo720 2021-11-12 17:37:49 +01:00
parent 4645d42130
commit 2c1f5bd430
4 changed files with 152 additions and 54 deletions

View File

@ -157,6 +157,15 @@ struct XidSBCOutput {
#pragma pack()
struct LightGunOffsets {
xbox::short_xt x;
xbox::short_xt y;
};
union ExtraData {
LightGunOffsets offsets;
};
union InputBuff {
XidGamepadInput ctrl;
XidSBCInput sbc;
@ -170,8 +179,9 @@ struct DeviceInfo {
uint8_t ucSubType; // xapi subtype
uint8_t ucInputStateSize; // input state size in bytes, does not include dwPacketNumber
uint8_t ucFeedbackSize; // feedback size in bytes, does not include FeedbackHeader
uint32_t dwPacketNumber;
InputBuff buff;
uint32_t dwPacketNumber; // increases by one when the input state changes
InputBuff buff; // input buffer
ExtraData data; // device-specific additional data
};
struct DeviceState {

View File

@ -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("XInputOpen", xbox::EMUPATCH(XInputOpen), 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),
// XAPI

View File

@ -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_S:
case XBOX_INPUT_DEVICE::LIGHTGUN:
case XBOX_INPUT_DEVICE::ARCADE_STICK:
case XBOX_INPUT_DEVICE::HW_XBOX_CONTROLLER: {
if (XppType == g_DeviceType_Gamepad) {
@ -137,7 +138,6 @@ bool operator==(xbox::PXPP_DEVICE_TYPE XppType, XBOX_INPUT_DEVICE XidType)
}
break;
case XBOX_INPUT_DEVICE::LIGHTGUN:
case XBOX_INPUT_DEVICE::STEERING_WHEEL:
case XBOX_INPUT_DEVICE::IR_DONGLE:
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_S:
case XBOX_INPUT_DEVICE::LIGHTGUN:
case XBOX_INPUT_DEVICE::ARCADE_STICK:
case XBOX_INPUT_DEVICE::HW_XBOX_CONTROLLER:
xpp = g_DeviceType_Gamepad;
@ -256,6 +257,15 @@ void ConstructHleInputDevice(DeviceState *dev, DeviceState *upstream, int type,
dev->info.ucFeedbackSize = sizeof(XpadOutput);
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::HW_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_S:
case XBOX_INPUT_DEVICE::LIGHTGUN:
dev->info.bAutoPollDefault = false;
dev->info.ucType = 0;
dev->info.ucSubType = 0;
@ -480,7 +491,7 @@ xbox::dword_xt CxbxImpl_XInputHandler(xbox::HANDLE hDevice, xbox::PXINPUT_STATE
}
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;
}
@ -787,6 +798,86 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(XInputSetState)
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
@ -1394,42 +1485,6 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(XMountMUA)
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
// ******************************************************************

View File

@ -270,6 +270,30 @@ typedef struct _XINPUT_FEEDBACK
}
XINPUT_FEEDBACK, *PXINPUT_FEEDBACK;
#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
// ******************************************************************
@ -439,6 +463,28 @@ xbox::dword_xt WINAPI EMUPATCH(XInputSetState)
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
@ -732,25 +778,11 @@ xbox::bool_xt WINAPI EMUPATCH(MoveFileA)
LPCSTR lpNewFileName
);
// ******************************************************************
// * patch: XGetDeviceEnumerationStatus
// ******************************************************************
xbox::dword_xt WINAPI EMUPATCH(XGetDeviceEnumerationStatus)();
// ******************************************************************
// * patch: SwitchToThread
// ******************************************************************
xbox::bool_xt WINAPI EMUPATCH(SwitchToThread)();
// ******************************************************************
// * patch: XInputGetDeviceDescription
// ******************************************************************
xbox::dword_xt WINAPI EMUPATCH(XInputGetDeviceDescription)
(
HANDLE hDevice,
PVOID pDescription
);
// ******************************************************************
// * patch: ReadFileEx
// ******************************************************************