mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 20:58:07 +03:00
input: add Xbox one controller support
This commit is contained in:
parent
72c3693af8
commit
a7f1e56c21
5 changed files with 268 additions and 0 deletions
14
README.md
14
README.md
|
@ -76,6 +76,20 @@ Not all options are turned on by default. Refer to `Tomb1Main.json5` for details
|
|||
- added save game crystals game mode (enabled via gameflow)
|
||||
- added pause screen
|
||||
- added movable camera on W,A,S,D
|
||||
- added Xbox One Controller support
|
||||
- Per Axis Dead Zone
|
||||
- Left Stick = movement
|
||||
- A = Jump/Select
|
||||
- B = Roll/Deselect
|
||||
- X = Action/Select
|
||||
- Y = Look/Select
|
||||
- LB = Walk
|
||||
- RB = Draw Weapons
|
||||
- Dpad Up = Draw Weapons
|
||||
- Back = Option
|
||||
- Start = Pause
|
||||
- Right Stick = Camera Movement
|
||||
- R3 = Reset Camera
|
||||
- changed internal game memory limit from 3.5 MB to 16 MB
|
||||
- changed moveable limit from 256 to 10240
|
||||
- changed input method to DirectInput
|
||||
|
|
|
@ -157,6 +157,10 @@
|
|||
"resolution_width": -1,
|
||||
"resolution_height": -1,
|
||||
|
||||
// Enable XBox One Controller with PS1 layout and Per Axis Dead Zone
|
||||
"enable_xbox_one_controller": true,
|
||||
|
||||
// Overrides ingame brightness.
|
||||
"brightness": 1.0,
|
||||
|
||||
}
|
||||
|
|
|
@ -152,6 +152,7 @@ int8_t T1MReadConfigFromJson(const char *cfg_data)
|
|||
READ_BOOL(disable_fmv, 0);
|
||||
READ_BOOL(disable_cine, 0);
|
||||
READ_BOOL(disable_music_in_menu, 0);
|
||||
READ_BOOL(enable_xbox_one_controller, 0);
|
||||
READ_FLOAT(brightness, 1.0);
|
||||
|
||||
READ_BAR_SHOWING_MODE(healthbar_showing_mode, T1M_BSM_FLASHING_OR_DEFAULT);
|
||||
|
|
|
@ -67,6 +67,7 @@ typedef struct {
|
|||
int8_t disable_music_in_menu;
|
||||
int32_t resolution_width;
|
||||
int32_t resolution_height;
|
||||
int8_t enable_xbox_one_controller;
|
||||
float brightness;
|
||||
} T1MConfigStruct;
|
||||
|
||||
|
|
|
@ -74,6 +74,8 @@ static LPDIRECTINPUT8 DInput;
|
|||
static LPDIRECTINPUTDEVICE8 IDID_SysKeyboard;
|
||||
static uint8_t DIKeys[256];
|
||||
|
||||
static LPDIRECTINPUTDEVICE8 IDID_Joystick;
|
||||
|
||||
static int32_t MedipackCoolDown = 0;
|
||||
|
||||
static void DInputCreate();
|
||||
|
@ -83,15 +85,30 @@ static void DInputKeyboardRelease();
|
|||
static void DInputKeyboardRead();
|
||||
static int8_t Key_(KEY_NUMBER number);
|
||||
|
||||
static HRESULT DInputJoystickCreate();
|
||||
static void DInputJoystickRelease();
|
||||
static BOOL CALLBACK
|
||||
EnumAxesCallback(const LPDIDEVICEOBJECTINSTANCE instance, LPVOID context);
|
||||
static BOOL CALLBACK
|
||||
EnumCallback(const LPDIDEVICEINSTANCE instance, LPVOID context);
|
||||
|
||||
void InputInit()
|
||||
{
|
||||
DInputCreate();
|
||||
DInputKeyboardCreate();
|
||||
if (T1MConfig.enable_xbox_one_controller) {
|
||||
DInputJoystickCreate();
|
||||
} else {
|
||||
IDID_Joystick = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void InputShutdown()
|
||||
{
|
||||
DInputKeyboardRelease();
|
||||
if (T1MConfig.enable_xbox_one_controller) {
|
||||
DInputJoystickRelease();
|
||||
}
|
||||
DInputShutdown();
|
||||
}
|
||||
|
||||
|
@ -212,6 +229,168 @@ int16_t KeyGet()
|
|||
return -1;
|
||||
}
|
||||
|
||||
static HRESULT DInputJoystickCreate()
|
||||
{
|
||||
HRESULT result;
|
||||
|
||||
// Look for the first simple joystick we can find.
|
||||
if (FAILED(
|
||||
result = IDirectInput8_EnumDevices(
|
||||
DInput, DI8DEVCLASS_GAMECTRL, EnumCallback, NULL,
|
||||
DIEDFL_ATTACHEDONLY))) {
|
||||
LOG_ERROR(
|
||||
"Error while calling IDirectInput8_EnumDevices: 0x%lx", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Make sure we got a joystick
|
||||
if (IDID_Joystick == NULL) {
|
||||
LOG_ERROR("Joystick not found.\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
LOG_INFO("Joystick found.\n");
|
||||
|
||||
DIDEVCAPS capabilities;
|
||||
// request simple joystick format 2
|
||||
if (FAILED(
|
||||
result = IDirectInputDevice_SetDataFormat(
|
||||
IDID_Joystick, &c_dfDIJoystick2))) {
|
||||
LOG_ERROR(
|
||||
"Error while calling IDirectInputDevice_SetDataFormat: 0x%lx",
|
||||
result);
|
||||
DInputJoystickRelease();
|
||||
return result;
|
||||
}
|
||||
|
||||
// don't request exclusive access
|
||||
if (FAILED(
|
||||
result = IDirectInputDevice_SetCooperativeLevel(
|
||||
IDID_Joystick, NULL, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND))) {
|
||||
LOG_ERROR(
|
||||
"Error while calling IDirectInputDevice_SetCooperativeLevel: 0x%lx",
|
||||
result);
|
||||
DInputJoystickRelease();
|
||||
return result;
|
||||
}
|
||||
|
||||
// get axis count, we should know what it is but best to ask
|
||||
capabilities.dwSize = sizeof(DIDEVCAPS);
|
||||
if (FAILED(
|
||||
result = IDirectInputDevice_GetCapabilities(
|
||||
IDID_Joystick, &capabilities))) {
|
||||
LOG_ERROR(
|
||||
"Error while calling IDirectInputDevice_GetCapabilities: 0x%lx",
|
||||
result);
|
||||
DInputJoystickRelease();
|
||||
return result;
|
||||
}
|
||||
|
||||
// set the range we expect each axis to report back in
|
||||
if (FAILED(
|
||||
result = IDirectInputDevice_EnumObjects(
|
||||
IDID_Joystick, EnumAxesCallback, NULL, DIDFT_AXIS))) {
|
||||
LOG_ERROR(
|
||||
"Error while calling IDirectInputDevice_EnumObjects: 0x%lx",
|
||||
result);
|
||||
DInputJoystickRelease();
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void DInputJoystickRelease()
|
||||
{
|
||||
if (IDID_Joystick) {
|
||||
IDirectInputDevice_Unacquire(IDID_Joystick);
|
||||
IDirectInputDevice_Release(IDID_Joystick);
|
||||
IDID_Joystick = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL CALLBACK
|
||||
EnumAxesCallback(const LPDIDEVICEOBJECTINSTANCE instance, LPVOID context)
|
||||
{
|
||||
DIPROPRANGE propRange;
|
||||
propRange.diph.dwSize = sizeof(DIPROPRANGE);
|
||||
propRange.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
propRange.diph.dwHow = DIPH_BYID;
|
||||
propRange.diph.dwObj = instance->dwType;
|
||||
propRange.lMin = -1024;
|
||||
propRange.lMax = 1024;
|
||||
|
||||
// Set the range for the axis
|
||||
if (FAILED(IDirectInputDevice8_SetProperty(
|
||||
IDID_Joystick, DIPROP_RANGE, &propRange.diph))) {
|
||||
LOG_ERROR(
|
||||
"Error while calling IDirectInputDevice8_SetProperty: 0x%lx",
|
||||
result);
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK
|
||||
EnumCallback(const LPDIDEVICEINSTANCE instance, LPVOID context)
|
||||
{
|
||||
HRESULT result;
|
||||
|
||||
// Obtain an interface to the enumerated joystick.
|
||||
result = IDirectInput8_CreateDevice(
|
||||
DInput, &instance->guidInstance, &IDID_Joystick, NULL);
|
||||
|
||||
if (FAILED(result)) {
|
||||
LOG_ERROR(
|
||||
"Error while calling IDirectInput8_CreateDevice: 0x%lx", result);
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
// we got one, it will do.
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
|
||||
static HRESULT DInputJoystickPoll(DIJOYSTATE2 *joystate)
|
||||
{
|
||||
HRESULT result;
|
||||
|
||||
if (!IDID_Joystick) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Poll the device to read the current state
|
||||
result = IDirectInputDevice8_Poll(IDID_Joystick);
|
||||
if (FAILED(result)) {
|
||||
// focus was lost, try to reaquire the device
|
||||
result = IDirectInputDevice8_Acquire(IDID_Joystick);
|
||||
while (result == DIERR_INPUTLOST) {
|
||||
result = IDirectInputDevice8_Acquire(IDID_Joystick);
|
||||
}
|
||||
|
||||
// A fatal error? Return failure.
|
||||
if ((result == DIERR_INVALIDPARAM)
|
||||
|| (result == DIERR_NOTINITIALIZED)) {
|
||||
LOG_ERROR(
|
||||
"Error while calling IDirectInputDevice8_Acquire: 0x%lx",
|
||||
result);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// If another application has control of this device, return
|
||||
// successfully.
|
||||
if (result == DIERR_OTHERAPPHASPRIO) {
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the input's device state
|
||||
if (FAILED(
|
||||
result = IDirectInputDevice8_GetDeviceState(
|
||||
IDID_Joystick, sizeof(DIJOYSTATE2), joystate))) {
|
||||
return result; // The device should have been acquired during the Poll()
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void S_UpdateInput()
|
||||
{
|
||||
int32_t linput = 0;
|
||||
|
@ -373,6 +552,75 @@ void S_UpdateInput()
|
|||
}
|
||||
}
|
||||
|
||||
if (IDID_Joystick) {
|
||||
DIJOYSTATE2 state;
|
||||
DInputJoystickPoll(&state);
|
||||
// check Y
|
||||
if (state.lY > 512) {
|
||||
linput |= IN_BACK;
|
||||
} else if (state.lY < -512) {
|
||||
linput |= IN_FORWARD;
|
||||
}
|
||||
// check X
|
||||
if (state.lX > 512) {
|
||||
linput |= IN_RIGHT;
|
||||
} else if (state.lX < -512) {
|
||||
linput |= IN_LEFT;
|
||||
}
|
||||
// check Z
|
||||
if (state.lZ > 512) {
|
||||
linput |= IN_STEPL;
|
||||
} else if (state.lZ < -512) {
|
||||
linput |= IN_STEPR;
|
||||
}
|
||||
|
||||
// check 2nd stick X
|
||||
if (state.lRx > 512) {
|
||||
linput |= IN_CAMERA_RIGHT;
|
||||
} else if (state.lRx < -512) {
|
||||
linput |= IN_CAMERA_LEFT;
|
||||
}
|
||||
// check 2nd stick Y
|
||||
if (state.lRy > 512) {
|
||||
linput |= IN_CAMERA_DOWN;
|
||||
} else if (state.lRy < -512) {
|
||||
linput |= IN_CAMERA_UP;
|
||||
}
|
||||
|
||||
// check buttons
|
||||
if (state.rgbButtons[0]) { // A
|
||||
linput |= IN_JUMP | IN_SELECT;
|
||||
}
|
||||
if (state.rgbButtons[1]) { // B
|
||||
linput |= IN_ROLL | IN_DESELECT;
|
||||
}
|
||||
if (state.rgbButtons[2]) { // X
|
||||
linput |= IN_ACTION | IN_SELECT;
|
||||
}
|
||||
if (state.rgbButtons[3]) { // Y
|
||||
linput |= IN_LOOK | IN_DESELECT;
|
||||
}
|
||||
if (state.rgbButtons[4]) { // LB
|
||||
linput |= IN_SLOW;
|
||||
}
|
||||
if (state.rgbButtons[5]) { // RB
|
||||
linput |= IN_DRAW;
|
||||
}
|
||||
if (state.rgbButtons[6]) { // back
|
||||
linput |= IN_OPTION;
|
||||
}
|
||||
if (state.rgbButtons[7]) { // start
|
||||
linput |= IN_PAUSE;
|
||||
}
|
||||
if (state.rgbButtons[9]) { // 2nd axis click
|
||||
linput |= IN_CAMERA_RESET;
|
||||
}
|
||||
// check dpad
|
||||
if (state.rgdwPOV[0] == 0) { // up
|
||||
linput |= IN_DRAW;
|
||||
}
|
||||
}
|
||||
|
||||
Input = linput;
|
||||
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue