102 Patches: Detours to the Rescue
C reference for DttR maintainers and modders.
Loading...
Searching...
No Matches
parse.c
Go to the documentation of this file.
1#include "config_internal.h"
2#include <dttr_log.h>
3
4#include <errno.h>
5#include <limits.h>
6#include <math.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11#define CONFIG_SCALING_FIT_TOKENS(X) \
12 X("letterbox", DTTR_SCALING_MODE_LETTERBOX) \
13 X("stretch", DTTR_SCALING_MODE_STRETCH) \
14 X("integer", DTTR_SCALING_MODE_INTEGER)
15
16#define CONFIG_SCALING_METHOD_TOKENS(X) \
17 X("present", DTTR_SCALING_METHOD_PRESENT) \
18 X("logical", DTTR_SCALING_METHOD_LOGICAL)
19
20#define CONFIG_GRAPHICS_API_FORMAT_TOKENS(X) \
21 X(DTTR_DRIVER_AUTO, DTTR_GRAPHICS_API_AUTO) \
22 X(DTTR_DRIVER_VULKAN, DTTR_GRAPHICS_API_VULKAN) \
23 X(DTTR_DRIVER_DIRECT3D12, DTTR_GRAPHICS_API_DIRECT3D12) \
24 X(DTTR_DRIVER_OPENGL, DTTR_GRAPHICS_API_OPENGL)
25
26#define CONFIG_PRESENT_FILTER_TOKENS(X) \
27 X("nearest", SDL_GPU_FILTER_NEAREST) \
28 X("linear", SDL_GPU_FILTER_LINEAR)
29
30#define CONFIG_GAMEPAD_MISC_SOURCE_TOKENS(X) \
31 X("misc1", SDL_GAMEPAD_BUTTON_MISC1) \
32 X("misc2", SDL_GAMEPAD_BUTTON_MISC2) \
33 X("misc3", SDL_GAMEPAD_BUTTON_MISC3) \
34 X("misc4", SDL_GAMEPAD_BUTTON_MISC4) \
35 X("misc5", SDL_GAMEPAD_BUTTON_MISC5) \
36 X("misc6", SDL_GAMEPAD_BUTTON_MISC6)
37
38#define CONFIG_GAMEPAD_PADDLE_SOURCE_TOKENS(X) \
39 X("right_paddle1", SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1) \
40 X("left_paddle1", SDL_GAMEPAD_BUTTON_LEFT_PADDLE1) \
41 X("right_paddle2", SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2) \
42 X("left_paddle2", SDL_GAMEPAD_BUTTON_LEFT_PADDLE2)
43
44#define CONFIG_GAMEPAD_SOURCE_TOKENS(X) \
45 X("south", SDL_GAMEPAD_BUTTON_SOUTH) \
46 X("east", SDL_GAMEPAD_BUTTON_EAST) \
47 X("west", SDL_GAMEPAD_BUTTON_WEST) \
48 X("north", SDL_GAMEPAD_BUTTON_NORTH) \
49 X("back", SDL_GAMEPAD_BUTTON_BACK) \
50 X("guide", SDL_GAMEPAD_BUTTON_GUIDE) \
51 X("start", SDL_GAMEPAD_BUTTON_START) \
52 X("left_stick_click", SDL_GAMEPAD_BUTTON_LEFT_STICK) \
53 X("right_stick_click", SDL_GAMEPAD_BUTTON_RIGHT_STICK) \
54 X("left_shoulder", SDL_GAMEPAD_BUTTON_LEFT_SHOULDER) \
55 X("right_shoulder", SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER) \
56 X("dpad_up", SDL_GAMEPAD_BUTTON_DPAD_UP) \
57 X("dpad_down", SDL_GAMEPAD_BUTTON_DPAD_DOWN) \
58 X("dpad_left", SDL_GAMEPAD_BUTTON_DPAD_LEFT) \
59 X("dpad_right", SDL_GAMEPAD_BUTTON_DPAD_RIGHT) \
60 CONFIG_GAMEPAD_MISC_SOURCE_TOKENS(X) \
61 CONFIG_GAMEPAD_PADDLE_SOURCE_TOKENS(X) \
62 X("touchpad", SDL_GAMEPAD_BUTTON_TOUCHPAD) \
63 X("left_trigger", DTTR_GAMEPAD_SOURCE_TRIGGER_LEFT) \
64 X("right_trigger", DTTR_GAMEPAD_SOURCE_TRIGGER_RIGHT)
65
66#define CONFIG_GAME_ACTION_TOKENS(X) \
67 X("none", DTTR_GAMEPAD_MAPPING_NONE) \
68 X("up", PCDOGS_GAMEPAD_IDX_UP) \
69 X("down", PCDOGS_GAMEPAD_IDX_DOWN) \
70 X("left", PCDOGS_GAMEPAD_IDX_LEFT) \
71 X("right", PCDOGS_GAMEPAD_IDX_RIGHT) \
72 X("pov_up", PCDOGS_GAMEPAD_IDX_POV_UP) \
73 X("pov_down", PCDOGS_GAMEPAD_IDX_POV_DOWN) \
74 X("joy_1", PCDOGS_GAMEPAD_IDX_BTN_0) \
75 X("joy_2", PCDOGS_GAMEPAD_IDX_BTN_1) \
76 X("joy_3", PCDOGS_GAMEPAD_IDX_BTN_2) \
77 X("joy_4", PCDOGS_GAMEPAD_IDX_BTN_3) \
78 X("joy_5", PCDOGS_GAMEPAD_IDX_BTN_4) \
79 X("joy_6", PCDOGS_GAMEPAD_IDX_BTN_5) \
80 X("joy_7", PCDOGS_GAMEPAD_IDX_BTN_6) \
81 X("joy_8", PCDOGS_GAMEPAD_IDX_BTN_7) \
82 X("joy_9", PCDOGS_GAMEPAD_IDX_BTN_8) \
83 X("joy_10", PCDOGS_GAMEPAD_IDX_BTN_9) \
84 X("joy_11", PCDOGS_GAMEPAD_IDX_BTN_10) \
85 X("joy_12", PCDOGS_GAMEPAD_IDX_BTN_11) \
86 X("joy_13", PCDOGS_GAMEPAD_IDX_BTN_12)
87
88#define CONFIG_GAMEPAD_AXIS_TOKENS(X) \
89 X("none", DTTR_GAMEPAD_MAPPING_NONE) \
90 X("axis_left_x", SDL_GAMEPAD_AXIS_LEFTX) \
91 X("axis_left_y", SDL_GAMEPAD_AXIS_LEFTY) \
92 X("axis_right_x", SDL_GAMEPAD_AXIS_RIGHTX) \
93 X("axis_right_y", SDL_GAMEPAD_AXIS_RIGHTY) \
94 X("axis_left_trigger", SDL_GAMEPAD_AXIS_LEFT_TRIGGER) \
95 X("axis_right_trigger", SDL_GAMEPAD_AXIS_RIGHT_TRIGGER)
96
97#define CONFIG_LOG_LEVEL_TOKENS(X) \
98 X("trace", LOG_TRACE) \
99 X("debug", LOG_DEBUG) \
100 X("info", LOG_INFO) \
101 X("warn", LOG_WARN) \
102 X("error", LOG_ERROR) \
103 X("fatal", LOG_FATAL)
104
105#define CONFIG_MINIDUMP_TYPE_TOKENS(X) \
106 X("normal", DTTR_MINIDUMP_NORMAL) \
107 X("detailed", DTTR_MINIDUMP_DETAILED)
108
109#define CONFIG_VERTEX_PRECISION_TOKENS(X) \
110 X("native", DTTR_VERTEX_PRECISION_NATIVE) \
111 X("subpixel", DTTR_VERTEX_PRECISION_SUBPIXEL)
112
113#define CONFIG_CHOICE(token, enum_value) {(token), (int)(enum_value)},
114
118
122
126
130
134
138
142
146
150
151#undef CONFIG_CHOICE
152
157
158#define CONFIG_CHOICE_LIST_DATA(array) {(array), (int)SDL_arraysize(array)}
159
187
188#undef CONFIG_CHOICE_LIST_DATA
189
191 if (list < 0 || list >= (DTTR_ConfigChoiceList)SDL_arraysize(CONFIG_CHOICE_LISTS)) {
192 return NULL;
193 }
194
195 return &CONFIG_CHOICE_LISTS[list];
196}
197
200 return data ? data->count : 0;
201}
202
205 if (!data || index < 0 || index >= data->count) {
206 return NULL;
207 }
208
209 return &data->choices[index];
210}
211
214 if (count) {
215 *count = data ? data->count : 0;
216 }
217
218 return data ? data->choices : NULL;
219}
220
223 const char *value,
224 int *out_value
225) {
226 int count = 0;
227 const DTTR_ConfigChoice *choices = DTTR_Config_Choices(list, &count);
228 if (!value || !out_value || !choices) {
229 return false;
230 }
231
232 for (int i = 0; i < count; i++) {
233 if (strcmp(value, choices[i].label) == 0) {
234 *out_value = choices[i].value;
235 return true;
236 }
237 }
238
239 return false;
240}
241
242bool config_parse_bool(const char *value, bool *out_value) {
243 if (!value || !out_value) {
244 return false;
245 }
246
247 if (strcmp(value, "true") == 0) {
248 *out_value = true;
249 return true;
250 }
251
252 if (strcmp(value, "false") == 0) {
253 *out_value = false;
254 return true;
255 }
256
257 return false;
258}
259
260#define CONFIG_PARSE_CHOICE_FN(fn_name, type, choice_list) \
261 bool fn_name(const char *value, type *out_value) { \
262 int parsed = 0; \
263 if (!out_value || !config_parse_choice(choice_list, value, &parsed)) { \
264 return false; \
265 } \
266 *out_value = (type)parsed; \
267 return true; \
268 }
269
274)
279)
282 SDL_GPUFilter,
284)
285
286bool config_parse_graphics_api(const char *value, DTTR_GraphicsApi *out_value) {
287 if (!out_value) {
288 return false;
289 }
290
291 if (value && strcmp(value, DTTR_DRIVER_DIRECT3D12_SHORT) == 0) {
292 *out_value = DTTR_GRAPHICS_API_DIRECT3D12;
293 return true;
294 }
295
296 int parsed = 0;
298 return false;
299 }
300
301 *out_value = (DTTR_GraphicsApi)parsed;
302 return true;
303}
304
305#define CONFIG_PARSE_TOKEN(token, enum_value) \
306 if (strcmp(value, token) == 0) { \
307 *out_value = enum_value; \
308 return true; \
309 }
310
311bool config_parse_gamepad_source(const char *value, int *out_value) {
312 if (!value || !out_value) {
313 return false;
314 }
315
317 return false;
318}
319
320#undef CONFIG_PARSE_TOKEN
321
322bool config_parse_game_action(const char *value, int *out_value) {
324}
325
326bool config_parse_gamepad_axis(const char *value, int *out_value) {
328}
329
330bool config_parse_log_level(const char *value, int *out_value) {
331 return config_parse_choice(DTTR_CONFIG_CHOICES_LOG_LEVEL, value, out_value);
332}
333
338)
343)
344
345#undef CONFIG_PARSE_CHOICE_FN
346
347bool config_parse_int(const char *value, int *out_value) {
348 if (!value || !out_value) {
349 return false;
350 }
351
352 char *end = NULL;
353 errno = 0;
354
355 const long parsed = strtol(value, &end, 10);
356
357 if (errno != 0 || !end || *end != '\0') {
358 return false;
359 }
360
361 if (parsed < INT_MIN || parsed > INT_MAX) {
362 return false;
363 }
364
365 *out_value = (int)parsed;
366 return true;
367}
368
369bool config_parse_float(const char *value, float *out_value) {
370 if (!value || !out_value) {
371 return false;
372 }
373
374 char *end = NULL;
375 errno = 0;
376
377 const float parsed = strtof(value, &end);
378 if (errno != 0 || !end || *end != '\0' || !isfinite(parsed)) {
379 return false;
380 }
381
382 *out_value = parsed;
383 return true;
384}
385
386bool config_parse_string(const char *value, char *out_value, size_t out_size) {
387 if (!value || !out_value || out_size == 0) {
388 return false;
389 }
390
391 const size_t value_len = strlen(value);
392 if (value_len >= out_size) {
393 return false;
394 }
395
396 memcpy(out_value, value, value_len + 1);
397 return true;
398}
399
400#define CONFIG_FORMAT_TOKEN(token, enum_value) \
401 case (enum_value): \
402 return (token);
403
404void config_format_int(int value, char *buf, size_t buf_size) {
405 snprintf(buf, buf_size, "%d", value);
406}
407
408void config_format_float(float value, char *buf, size_t buf_size) {
409 snprintf(buf, buf_size, "%.9g", value);
410}
411
412#define CONFIG_FORMAT_FN(fn_name, type, arg_name, token_list, default_token) \
413 const char *fn_name(type arg_name) { \
414 switch (arg_name) { \
415 token_list(CONFIG_FORMAT_TOKEN) default : return (default_token); \
416 } \
417 }
418
422 mode,
424 "letterbox"
425)
429 method,
431 "present"
432)
436 api,
439)
442 SDL_GPUFilter,
443 filter,
445 "linear"
446)
451 type,
453 "normal"
454)
457 int,
458 source,
460 NULL
461)
467 precision,
469 "subpixel"
470)
471
472#undef CONFIG_FORMAT_FN
473#undef CONFIG_FORMAT_TOKEN
DTTR_Graphics_COM_Direct3DDevice7 void DWORD flags DWORD count
const DTTR_PrimitiveType type
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void DTTR_Graphics_COM_DirectDrawSurface7 *self DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags DTTR_Graphics_COM_DirectDrawSurface7 void void * data
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void NULL
bool config_parse_scaling_fit(const char *value, DTTR_ScalingMode *out_value)
const char * config_format_graphics_api(DTTR_GraphicsApi api)
const char * config_format_vertex_precision(DTTR_VertexPrecision precision)
bool config_parse_scaling_method(const char *value, DTTR_ScalingMethod *out_value)
bool config_parse_present_filter(const char *value, SDL_GPUFilter *out_value)
const char * config_format_scaling_fit(DTTR_ScalingMode mode)
bool config_parse_minidump_type(const char *value, DTTR_MinidumpType *out_value)
bool config_parse_graphics_api(const char *value, DTTR_GraphicsApi *out_value)
bool config_parse_int(const char *value, int *out_value)
const char * config_format_minidump_type(DTTR_MinidumpType type)
const char * config_format_present_filter(SDL_GPUFilter filter)
const char * config_format_gamepad_axis(int axis)
const char * config_format_game_action(int action)
const char * config_format_gamepad_source(int source)
bool config_parse_vertex_precision(const char *value, DTTR_VertexPrecision *out_value)
const char * config_format_scaling_method(DTTR_ScalingMethod method)
const char * config_format_log_level(int level)
DTTR_VertexPrecision
Definition dttr_config.h:43
DTTR_GraphicsApi
Definition dttr_config.h:36
@ DTTR_GRAPHICS_API_DIRECT3D12
Definition dttr_config.h:39
#define DTTR_DRIVER_DIRECT3D12_SHORT
Definition dttr_config.h:33
#define DTTR_DRIVER_AUTO
Definition dttr_config.h:30
DTTR_ScalingMethod
Definition dttr_config.h:20
DTTR_MinidumpType
Definition dttr_config.h:25
DTTR_ScalingMode
Definition dttr_config.h:14
DTTR_ConfigChoiceList
@ DTTR_CONFIG_CHOICES_MINIDUMP_TYPE
@ DTTR_CONFIG_CHOICES_GAMEPAD_AXIS
@ DTTR_CONFIG_CHOICES_GRAPHICS_API
@ DTTR_CONFIG_CHOICES_LOG_LEVEL
@ DTTR_CONFIG_CHOICES_SCALING_FIT
@ DTTR_CONFIG_CHOICES_SCALING_METHOD
@ DTTR_CONFIG_CHOICES_PRESENT_FILTER
@ DTTR_CONFIG_CHOICES_GAME_ACTION
@ DTTR_CONFIG_CHOICES_VERTEX_PRECISION
static game_data_source source
Definition game_data.c:21
bool config_parse_float(const char *value, float *out_value)
Definition parse.c:369
static const config_choice_list_data * config_choice_list(DTTR_ConfigChoiceList list)
Definition parse.c:190
bool config_parse_game_action(const char *value, int *out_value)
Definition parse.c:322
bool config_parse_string(const char *value, char *out_value, size_t out_size)
Definition parse.c:386
#define CONFIG_GAME_ACTION_TOKENS(X)
Definition parse.c:66
static const DTTR_ConfigChoice CONFIG_LOG_LEVEL_CHOICES[]
Definition parse.c:139
#define CONFIG_CHOICE(token, enum_value)
Definition parse.c:113
#define CONFIG_FORMAT_FN(fn_name, type, arg_name, token_list, default_token)
Definition parse.c:412
static const DTTR_ConfigChoice CONFIG_GAMEPAD_AXIS_CHOICES[]
Definition parse.c:135
#define CONFIG_CHOICE_LIST_DATA(array)
Definition parse.c:158
static bool config_parse_choice(DTTR_ConfigChoiceList list, const char *value, int *out_value)
Definition parse.c:221
static const DTTR_ConfigChoice CONFIG_VERTEX_PRECISION_CHOICES[]
Definition parse.c:147
#define CONFIG_MINIDUMP_TYPE_TOKENS(X)
Definition parse.c:105
void config_format_int(int value, char *buf, size_t buf_size)
Definition parse.c:404
static const DTTR_ConfigChoice CONFIG_MINIDUMP_TYPE_CHOICES[]
Definition parse.c:143
#define CONFIG_PARSE_TOKEN(token, enum_value)
Definition parse.c:305
#define CONFIG_LOG_LEVEL_TOKENS(X)
Definition parse.c:97
static const DTTR_ConfigChoice CONFIG_SCALING_FIT_CHOICES[]
Definition parse.c:115
#define CONFIG_SCALING_FIT_TOKENS(X)
Definition parse.c:11
bool config_parse_bool(const char *value, bool *out_value)
Definition parse.c:242
static const DTTR_ConfigChoice CONFIG_GRAPHICS_API_CHOICES[]
Definition parse.c:123
const DTTR_ConfigChoice * DTTR_Config_Choices(DTTR_ConfigChoiceList list, int *count)
Definition parse.c:212
#define CONFIG_GAMEPAD_SOURCE_TOKENS(X)
Definition parse.c:44
static const DTTR_ConfigChoice CONFIG_SCALING_METHOD_CHOICES[]
Definition parse.c:119
const DTTR_ConfigChoice * DTTR_Config_ChoiceGet(DTTR_ConfigChoiceList list, int index)
Definition parse.c:203
#define CONFIG_GAMEPAD_AXIS_TOKENS(X)
Definition parse.c:88
static const DTTR_ConfigChoice CONFIG_GAME_ACTION_CHOICES[]
Definition parse.c:131
bool config_parse_log_level(const char *value, int *out_value)
Definition parse.c:330
#define CONFIG_PARSE_CHOICE_FN(fn_name, type, choice_list)
Definition parse.c:260
#define CONFIG_SCALING_METHOD_TOKENS(X)
Definition parse.c:16
static const config_choice_list_data CONFIG_CHOICE_LISTS[]
Definition parse.c:160
static const DTTR_ConfigChoice CONFIG_PRESENT_FILTER_CHOICES[]
Definition parse.c:127
#define CONFIG_GRAPHICS_API_FORMAT_TOKENS(X)
Definition parse.c:20
#define CONFIG_PRESENT_FILTER_TOKENS(X)
Definition parse.c:26
bool config_parse_gamepad_axis(const char *value, int *out_value)
Definition parse.c:326
void config_format_float(float value, char *buf, size_t buf_size)
Definition parse.c:408
int DTTR_Config_ChoiceCount(DTTR_ConfigChoiceList list)
Definition parse.c:198
bool config_parse_gamepad_source(const char *value, int *out_value)
Definition parse.c:311
#define CONFIG_VERTEX_PRECISION_TOKENS(X)
Definition parse.c:109
const DTTR_ConfigChoice * choices
Definition parse.c:154