Skip to content

Commit

Permalink
For all Unreal Engine games that use GameInput, enable Xbox Emulation…
Browse files Browse the repository at this point in the history
… by default on first launch
  • Loading branch information
Kaldaien committed Nov 29, 2024
1 parent 1625640 commit f83ecbb
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 12 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
24.11.29.5
24.11.30
========
+ For all Unreal Engine games that use GameInput, enable Xbox Emulation by
default on first launch.

24.11.29.5
==========
+ Enable XInput emulation by default in STALKER 2

Expand Down
6 changes: 3 additions & 3 deletions include/SpecialK/DLL_VERSION.H
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

#define SK_YEAR 24
#define SK_MONTH 11
#define SK_DATE 29
#define SK_REV_N 5
#define SK_REV 5
#define SK_DATE 30
#define SK_REV_N 0
#define SK_REV 0

#ifndef _A2
#define _A2(a) #a
Expand Down
1 change: 0 additions & 1 deletion src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3706,7 +3706,6 @@ auto DeclKeybind =
case SK_GAME_ID::Stalker2:
// Stupid game requires Fullscreen Exclusive (in D3D12) for HDR
config.render.dxgi.fake_fullscreen_mode = true;
config.input.gamepad.xinput.emulate = true; // Fix GameInput
break;

case SK_GAME_ID::Metaphor:
Expand Down
60 changes: 53 additions & 7 deletions src/input/game_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -788,13 +788,23 @@ GameInputCreate_Detour (IGameInput** gameInput)
{
if (gameInput != nullptr)
{
*gameInput = (IGameInput *)new SK_IWrapGameInput (pReal);
// Turn on XInput emulation by default on first-run for Unreal Engine.
//
// -> Their GameInput integration is extremely simple and SK is fully compatible.
//
if (SK_GetCurrentRenderBackend ().windows.unreal && config.system.first_run && (! SK_XInput_PollController (0)))
{
SK_HID_SetupPlayStationControllers ();

if (SK_ImGui_HasPlayStationController ())
{
SK_LOGi0 (L"Enabling Xbox Mode because Unreal Engine is using GameInput...");

config.input.gamepad.xinput.emulate = true;
}
}

pReal->EnableOemDeviceSupport (SK_HID_VID_SONY, SK_HID_PID_DUALSHOCK4, 0, 0);
pReal->EnableOemDeviceSupport (SK_HID_VID_SONY, SK_HID_PID_DUALSHOCK4_REV2, 0, 0);
pReal->EnableOemDeviceSupport (SK_HID_VID_SONY, SK_HID_PID_DUALSHOCK4_DONGLE, 0, 0);
pReal->EnableOemDeviceSupport (SK_HID_VID_SONY, SK_HID_PID_DUALSENSE, 0, 0);
pReal->EnableOemDeviceSupport (SK_HID_VID_SONY, SK_HID_PID_DUALSENSE_EDGE, 0, 0);
*gameInput = (IGameInput *)new SK_IWrapGameInput (pReal);
}

else
Expand Down Expand Up @@ -1581,8 +1591,44 @@ SK_IPlayStationGameInputReading::GetTimestamp (void) noexcept
{
SK_LOG_FIRST_CALL

//
// Obviously this is implemented wrong, it should be accessing a history buffer
// of previous readings, not iterating through all PlayStation controllers and
// finding the one with the newest input.
//
// * This entire class should be encapsulating a single reading, not merely
// providing the data from the newest sampled input available (!!)
//
static volatile UINT64 last_timestamp = 0;

if (config.input.gamepad.xinput.emulate && (! config.input.gamepad.xinput.blackout_api))
{
UINT64 timestamp = ReadULong64Acquire (&last_timestamp);
const UINT64 orig_timestamp { timestamp };

if (! SK_HID_PlayStationControllers.empty ())
{
for (const auto& controller : SK_HID_PlayStationControllers)
{
if (controller.bConnected)
{
timestamp =
std::max (timestamp, controller.xinput.last_active);
}
}
}

if (timestamp > orig_timestamp)
{
InterlockedCompareExchange (
&last_timestamp, timestamp,
orig_timestamp
);
}
}

return
SK_QueryPerf ().QuadPart;//pReal->GetTimestamp ();
ReadULong64Acquire (&last_timestamp);
}

void
Expand Down

0 comments on commit f83ecbb

Please sign in to comment.