102 Patches: Detours to the Rescue
C reference for DttR maintainers and modders.
Loading...
Searching...
No Matches
inputs.c
Go to the documentation of this file.
1#include <SDL3/SDL.h>
2#include <dttr_pcdogs.h>
3
4#include "hooks_private.h"
5#include "inputs_private.h"
6#include "sidecar_private.h"
7
8#include <dttr_config.h>
9#include <dttr_log.h>
10
12
14
15static bool set_joystick_available(int32_t available) {
17 available
18 );
19 if (!DTTR_ResultOK(result)) {
21 "Failed to update joystick availability: %s",
23 );
24 return false;
25 }
26
27 return true;
28}
29
31 int count = 0;
32 SDL_JoystickID *const joysticks = SDL_GetGamepads(&count);
33 const int index = dttr_config.gamepad_index;
34
35 if (!joysticks || index < 0 || index >= count) {
36 if (count > 0) {
37 DTTR_LOG_WARN("Gamepad index %d out of range (%d connected)", index, count);
38 }
39
40 SDL_free(joysticks);
41 return false;
42 }
43
44 dttr_inputs_gamepad = SDL_OpenGamepad(joysticks[index]);
45
47 DTTR_LOG_INFO("Gamepad connected: %s", SDL_GetGamepadName(dttr_inputs_gamepad));
48 } else {
49 DTTR_LOG_ERROR("Failed to open gamepad: %s", SDL_GetError());
50 }
51
52 SDL_free(joysticks);
53 return dttr_inputs_gamepad != NULL;
54}
55
56static void close_gamepad() {
59 return;
60 }
61
62 SDL_CloseGamepad(dttr_inputs_gamepad);
64}
65
67 if (!SDL_InitSubSystem(SDL_INIT_GAMEPAD)) {
68 DTTR_LOG_ERROR("SDL_InitSubSystem(GAMEPAD) failed: %s", SDL_GetError());
69 }
70
71 if (dttr_config.gamepad_enabled) {
73 }
74}
75
77 DTTR_Result alloc_status = DTTR_PCDOGS_F_Mem_MallocCRT->Status(&ctx->runtime);
78 if (!DTTR_ResultOK(alloc_status)) {
80 "Required DInput allocator unavailable: %s",
81 dttr_sidecar_result_detail(alloc_status)
82 );
83 return false;
84 }
85
86 const DTTR_PCDOGS_T_Patch_Spec inputs_patches[] = {
88 true,
89 "56 8B 74 24 ?? 56 8B 06",
90 0,
92 ),
95 };
96
98 ctx,
99 "sidecar/inputs",
100 inputs_patches,
101 DTTR_ARRAY_COUNT(inputs_patches),
103 );
104}
105
106// Tracks SDL gamepad hotplug events and updates the game joystick-available flag.
108 switch (event->type) {
109 case SDL_EVENT_GAMEPAD_ADDED:
111 return;
112 }
113
114 if (!dttr_config.gamepad_enabled) {
115 return;
116 }
117
119 return;
120 }
121
122 int32_t game_initialized = 0;
124 &game_initialized
125 );
126 if (!DTTR_ResultOK(result)) {
128 "Failed to read game input init state: %s",
130 );
132 return;
133 }
134
135 if (game_initialized == 1 && !set_joystick_available(1)) {
137 }
138
139 return;
140 case SDL_EVENT_GAMEPAD_REMOVED:
142 || SDL_GetGamepadID(dttr_inputs_gamepad) != event->gdevice.which) {
143 return;
144 }
145
146 DTTR_LOG_INFO("Gamepad disconnected: %s", SDL_GetGamepadName(dttr_inputs_gamepad));
148 return;
149 default:
150 return;
151 }
152}
153
154// Publishes joystick availability after the game has initialized its input globals.
156 if (!dttr_config.gamepad_enabled || !dttr_inputs_gamepad) {
157 return set_joystick_available(0);
158 }
159
160 if (!set_joystick_available(1)) {
161 return false;
162 }
163
164 DTTR_LOG_DEBUG("Joystick is available");
165 return true;
166}
167
171
DTTR_Graphics_COM_Direct3DDevice7 void DWORD flags DWORD count
void void * ctx
void void DWORD HANDLE event
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void NULL
DTTR_Config dttr_config
Definition defaults.c:53
DTTR_Result DTTR_Core_PatchGroupRelease(DTTR_Core_PatchGroup **group)
Definition core.c:657
#define DTTR_ARRAY_COUNT(array_)
Definition dttr_core.h:18
struct DTTR_Core_PatchGroup DTTR_Core_PatchGroup
Definition dttr_core.h:25
#define DTTR_LOG_DEBUG(...)
Definition dttr_log.h:28
#define DTTR_LOG_WARN(...)
Definition dttr_log.h:30
#define DTTR_LOG_INFO(...)
Definition dttr_log.h:29
#define DTTR_LOG_ERROR(...)
Definition dttr_log.h:31
union SDL_Event SDL_Event
Definition dttr_mods.h:20
DTTR_PCDOGS_API const struct dttr_pcdogs_function_accessor_Mem_MallocCRT *const DTTR_PCDOGS_F_Mem_MallocCRT
Accessor object for Mem_MallocCRT.
DTTR_PCDOGS_API const struct DTTR_PCDOGS_D_Window_ProcessGameProc_Initialized_type *const DTTR_PCDOGS_D_Window_ProcessGameProc_Initialized
DTTR_PCDOGS_API const struct DTTR_PCDOGS_D_Video_PlayMovieLoop_GetAsyncKeyStateThunk_type *const DTTR_PCDOGS_D_Video_PlayMovieLoop_GetAsyncKeyStateThunk
#define DTTR_PCDOGS_PATCH_SPEC_AOB_REL32_JMP(required_, aob_, offset_, detour_)
DTTR_PCDOGS_API const struct DTTR_PCDOGS_D_Input_GetPressedButton_JoystickAvailable_type *const DTTR_PCDOGS_D_Input_GetPressedButton_JoystickAvailable
bool DTTR_ResultOK(DTTR_Result result)
Definition core.c:78
void * dttr_inputs_hook_dinput_poll_callback(void *device)
SHORT dttr_inputs_hook_get_async_key_state_callback(int vkey)
static bool set_joystick_available(int32_t available)
Definition inputs.c:15
void dttr_inputs_hooks_cleanup(const DTTR_Mods_Context *ctx)
Definition inputs.c:168
bool dttr_inputs_hooks_init(const DTTR_Mods_Context *ctx)
Definition inputs.c:76
bool dttr_inputs_late_init()
Definition inputs.c:155
static bool try_open_configured_gamepad()
Definition inputs.c:30
void dttr_inputs_handle_device_event(const SDL_Event *event)
Definition inputs.c:107
static void close_gamepad()
Definition inputs.c:56
void dttr_inputs_init()
Definition inputs.c:66
static DTTR_Core_PatchGroup * inputs_targets
Definition inputs.c:13
SDL_Gamepad * dttr_inputs_gamepad
Definition inputs.c:11
void dttr_inputs_cleanup()
Definition inputs.c:172
static const char * dttr_sidecar_result_detail(DTTR_Result result)
static bool dttr_sidecar_install_pcdogs_patch_group(const DTTR_Mods_Context *ctx, const char *label, const DTTR_PCDOGS_T_Patch_Spec *patches, size_t patch_count, DTTR_Core_PatchGroup **group)