Mercurial > repos > blastem
comparison bindings.c @ 2053:3414a4423de1 segacd
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 15 Jan 2022 13:15:21 -0800 |
parents | 81df9aa2de9b |
children | 372625dd9590 |
comparison
equal
deleted
inserted
replaced
1692:5dacaef602a7 | 2053:3414a4423de1 |
---|---|
1 #include <string.h> | 1 #include <string.h> |
2 #include <stdlib.h> | |
2 #include "render.h" | 3 #include "render.h" |
3 #include "system.h" | 4 #include "system.h" |
4 #include "io.h" | 5 #include "io.h" |
5 #include "blastem.h" | 6 #include "blastem.h" |
6 #include "saves.h" | 7 #include "saves.h" |
33 UI_TOGGLE_FULLSCREEN, | 34 UI_TOGGLE_FULLSCREEN, |
34 UI_SOFT_RESET, | 35 UI_SOFT_RESET, |
35 UI_RELOAD, | 36 UI_RELOAD, |
36 UI_SMS_PAUSE, | 37 UI_SMS_PAUSE, |
37 UI_SCREENSHOT, | 38 UI_SCREENSHOT, |
39 UI_VGM_LOG, | |
38 UI_EXIT, | 40 UI_EXIT, |
39 UI_PLANE_DEBUG, | 41 UI_PLANE_DEBUG, |
40 UI_VRAM_DEBUG, | 42 UI_VRAM_DEBUG, |
41 UI_CRAM_DEBUG, | 43 UI_CRAM_DEBUG, |
42 UI_COMPOSITE_DEBUG | 44 UI_COMPOSITE_DEBUG |
255 | 257 |
256 #ifdef _WIN32 | 258 #ifdef _WIN32 |
257 #define localtime_r(a,b) localtime(a) | 259 #define localtime_r(a,b) localtime(a) |
258 #endif | 260 #endif |
259 | 261 |
262 char *get_content_config_path(char *config_path, char *config_template, char *default_name) | |
263 { | |
264 char *base = tern_find_path(config, config_path, TVAL_PTR).ptrval; | |
265 if (!base) { | |
266 base = "$HOME"; | |
267 } | |
268 const system_media *media = current_media(); | |
269 tern_node *vars = tern_insert_ptr(NULL, "HOME", get_home_dir()); | |
270 vars = tern_insert_ptr(vars, "EXEDIR", get_exe_dir()); | |
271 vars = tern_insert_ptr(vars, "USERDATA", (char *)get_userdata_dir()); | |
272 vars = tern_insert_ptr(vars, "ROMNAME", media->name); | |
273 vars = tern_insert_ptr(vars, "ROMDIR", media->dir); | |
274 base = replace_vars(base, vars, 1); | |
275 tern_free(vars); | |
276 ensure_dir_exists(base); | |
277 time_t now = time(NULL); | |
278 struct tm local_store; | |
279 char fname_part[256]; | |
280 char *template = tern_find_path(config, config_template, TVAL_PTR).ptrval; | |
281 if (template) { | |
282 vars = tern_insert_ptr(NULL, "ROMNAME", media->name); | |
283 template = replace_vars(template, vars, 0); | |
284 } else { | |
285 template = strdup(default_name); | |
286 } | |
287 strftime(fname_part, sizeof(fname_part), template, localtime_r(&now, &local_store)); | |
288 char const *parts[] = {base, PATH_SEP, fname_part}; | |
289 char *path = alloc_concat_m(3, parts); | |
290 free(base); | |
291 free(template); | |
292 return path; | |
293 } | |
294 | |
260 void handle_binding_up(keybinding * binding) | 295 void handle_binding_up(keybinding * binding) |
261 { | 296 { |
297 uint8_t allow_content_binds = content_binds_enabled && current_system; | |
262 switch(binding->bind_type) | 298 switch(binding->bind_type) |
263 { | 299 { |
264 case BIND_GAMEPAD: | 300 case BIND_GAMEPAD: |
265 if (content_binds_enabled && current_system->gamepad_up) { | 301 if (allow_content_binds && current_system->gamepad_up) { |
266 current_system->gamepad_up(current_system, binding->subtype_a, binding->subtype_b); | 302 current_system->gamepad_up(current_system, binding->subtype_a, binding->subtype_b); |
267 } | 303 } |
268 break; | 304 break; |
269 case BIND_MOUSE: | 305 case BIND_MOUSE: |
270 if (content_binds_enabled && current_system->mouse_up) { | 306 if (allow_content_binds && current_system->mouse_up) { |
271 current_system->mouse_up(current_system, binding->subtype_a, binding->subtype_b); | 307 current_system->mouse_up(current_system, binding->subtype_a, binding->subtype_b); |
272 } | 308 } |
273 break; | 309 break; |
274 case BIND_UI: | 310 case BIND_UI: |
275 switch (binding->subtype_a) | 311 switch (binding->subtype_a) |
276 { | 312 { |
277 case UI_DEBUG_MODE_INC: | 313 case UI_DEBUG_MODE_INC: |
278 if (content_binds_enabled) { | 314 if (allow_content_binds) { |
279 current_system->inc_debug_mode(current_system); | 315 current_system->inc_debug_mode(current_system); |
280 } | 316 } |
281 break; | 317 break; |
282 case UI_ENTER_DEBUGGER: | 318 case UI_ENTER_DEBUGGER: |
283 if (content_binds_enabled) { | 319 if (allow_content_binds) { |
284 current_system->enter_debugger = 1; | 320 current_system->enter_debugger = 1; |
285 } | 321 } |
286 break; | 322 break; |
287 case UI_SAVE_STATE: | 323 case UI_SAVE_STATE: |
288 if (content_binds_enabled) { | 324 if (allow_content_binds) { |
289 current_system->save_state = QUICK_SAVE_SLOT+1; | 325 current_system->save_state = QUICK_SAVE_SLOT+1; |
290 } | 326 } |
291 break; | 327 break; |
292 case UI_NEXT_SPEED: | 328 case UI_NEXT_SPEED: |
293 if (content_binds_enabled) { | 329 if (allow_content_binds) { |
294 current_speed++; | 330 current_speed++; |
295 if (current_speed >= num_speeds) { | 331 if (current_speed >= num_speeds) { |
296 current_speed = 0; | 332 current_speed = 0; |
297 } | 333 } |
298 printf("Setting speed to %d: %d\n", current_speed, speeds[current_speed]); | 334 printf("Setting speed to %d: %d\n", current_speed, speeds[current_speed]); |
299 current_system->set_speed_percent(current_system, speeds[current_speed]); | 335 current_system->set_speed_percent(current_system, speeds[current_speed]); |
300 } | 336 } |
301 break; | 337 break; |
302 case UI_PREV_SPEED: | 338 case UI_PREV_SPEED: |
303 if (content_binds_enabled) { | 339 if (allow_content_binds) { |
304 current_speed--; | 340 current_speed--; |
305 if (current_speed < 0) { | 341 if (current_speed < 0) { |
306 current_speed = num_speeds - 1; | 342 current_speed = num_speeds - 1; |
307 } | 343 } |
308 printf("Setting speed to %d: %d\n", current_speed, speeds[current_speed]); | 344 printf("Setting speed to %d: %d\n", current_speed, speeds[current_speed]); |
309 current_system->set_speed_percent(current_system, speeds[current_speed]); | 345 current_system->set_speed_percent(current_system, speeds[current_speed]); |
310 } | 346 } |
311 break; | 347 break; |
312 case UI_SET_SPEED: | 348 case UI_SET_SPEED: |
313 if (content_binds_enabled) { | 349 if (allow_content_binds) { |
314 if (binding->subtype_b < num_speeds) { | 350 if (binding->subtype_b < num_speeds) { |
315 current_speed = binding->subtype_b; | 351 current_speed = binding->subtype_b; |
316 printf("Setting speed to %d: %d\n", current_speed, speeds[current_speed]); | 352 printf("Setting speed to %d: %d\n", current_speed, speeds[current_speed]); |
317 current_system->set_speed_percent(current_system, speeds[current_speed]); | 353 current_system->set_speed_percent(current_system, speeds[current_speed]); |
318 } else { | 354 } else { |
326 mouse_captured = 0; | 362 mouse_captured = 0; |
327 render_relative_mouse(0); | 363 render_relative_mouse(0); |
328 } | 364 } |
329 break; | 365 break; |
330 case UI_TOGGLE_KEYBOARD_CAPTURE: | 366 case UI_TOGGLE_KEYBOARD_CAPTURE: |
331 if (content_binds_enabled && current_system->has_keyboard) { | 367 if (allow_content_binds && current_system->has_keyboard) { |
332 keyboard_captured = !keyboard_captured; | 368 keyboard_captured = !keyboard_captured; |
333 } | 369 } |
334 break; | 370 break; |
335 case UI_TOGGLE_FULLSCREEN: | 371 case UI_TOGGLE_FULLSCREEN: |
336 render_toggle_fullscreen(); | 372 render_toggle_fullscreen(); |
337 break; | 373 break; |
338 case UI_SOFT_RESET: | 374 case UI_SOFT_RESET: |
339 if (content_binds_enabled) { | 375 if (allow_content_binds) { |
340 current_system->soft_reset(current_system); | 376 current_system->soft_reset(current_system); |
341 } | 377 } |
342 break; | 378 break; |
343 case UI_RELOAD: | 379 case UI_RELOAD: |
344 if (content_binds_enabled) { | 380 if (allow_content_binds) { |
345 reload_media(); | 381 reload_media(); |
346 } | 382 } |
347 break; | 383 break; |
348 case UI_SMS_PAUSE: | 384 case UI_SMS_PAUSE: |
349 if (content_binds_enabled && current_system->gamepad_down) { | 385 if (allow_content_binds && current_system->gamepad_down) { |
350 current_system->gamepad_down(current_system, GAMEPAD_MAIN_UNIT, MAIN_UNIT_PAUSE); | 386 current_system->gamepad_down(current_system, GAMEPAD_MAIN_UNIT, MAIN_UNIT_PAUSE); |
351 } | 387 } |
352 break; | 388 break; |
353 case UI_SCREENSHOT: { | 389 case UI_SCREENSHOT: |
354 if (content_binds_enabled) { | 390 if (allow_content_binds) { |
355 char *screenshot_base = tern_find_path(config, "ui\0screenshot_path\0", TVAL_PTR).ptrval; | 391 char *path = get_content_config_path("ui\0screenshot_path\0", "ui\0screenshot_template\0", "blastem_%c.ppm"); |
356 if (!screenshot_base) { | 392 render_save_screenshot(path); |
357 screenshot_base = "$HOME"; | 393 } |
394 break; | |
395 case UI_VGM_LOG: | |
396 if (allow_content_binds && current_system->start_vgm_log) { | |
397 if (current_system->vgm_logging) { | |
398 current_system->stop_vgm_log(current_system); | |
399 } else { | |
400 char *path = get_content_config_path("ui\0vgm_path\0", "ui\0vgm_template\0", "blastem_%c.vgm"); | |
401 current_system->start_vgm_log(current_system, path); | |
402 free(path); | |
358 } | 403 } |
359 tern_node *vars = tern_insert_ptr(NULL, "HOME", get_home_dir()); | 404 } |
360 vars = tern_insert_ptr(vars, "EXEDIR", get_exe_dir()); | 405 break; |
361 screenshot_base = replace_vars(screenshot_base, vars, 1); | |
362 tern_free(vars); | |
363 time_t now = time(NULL); | |
364 struct tm local_store; | |
365 char fname_part[256]; | |
366 char *template = tern_find_path(config, "ui\0screenshot_template\0", TVAL_PTR).ptrval; | |
367 if (!template) { | |
368 template = "blastem_%c.ppm"; | |
369 } | |
370 strftime(fname_part, sizeof(fname_part), template, localtime_r(&now, &local_store)); | |
371 char const *parts[] = {screenshot_base, PATH_SEP, fname_part}; | |
372 char *path = alloc_concat_m(3, parts); | |
373 free(screenshot_base); | |
374 render_save_screenshot(path); | |
375 } | |
376 break; | |
377 } | |
378 case UI_EXIT: | 406 case UI_EXIT: |
379 #ifndef DISABLE_NUKLEAR | 407 #ifndef DISABLE_NUKLEAR |
380 if (is_nuklear_active()) { | 408 if (is_nuklear_active()) { |
381 show_pause_menu(); | 409 show_pause_menu(); |
382 } else { | 410 } else { |
383 #endif | 411 #endif |
384 current_system->request_exit(current_system); | 412 system_request_exit(current_system, 1); |
385 if (current_system->type == SYSTEM_GENESIS) { | 413 if (current_system->type == SYSTEM_GENESIS) { |
386 genesis_context *gen = (genesis_context *)current_system; | 414 genesis_context *gen = (genesis_context *)current_system; |
387 if (gen->extra) { | 415 if (gen->extra) { |
388 //TODO: More robust mechanism for detecting menu | 416 //TODO: More robust mechanism for detecting menu |
389 menu_context *menu = gen->extra; | 417 menu_context *menu = gen->extra; |
396 break; | 424 break; |
397 case UI_PLANE_DEBUG: | 425 case UI_PLANE_DEBUG: |
398 case UI_VRAM_DEBUG: | 426 case UI_VRAM_DEBUG: |
399 case UI_CRAM_DEBUG: | 427 case UI_CRAM_DEBUG: |
400 case UI_COMPOSITE_DEBUG: | 428 case UI_COMPOSITE_DEBUG: |
401 if (content_binds_enabled) { | 429 if (allow_content_binds) { |
402 vdp_context *vdp = NULL; | 430 vdp_context *vdp = NULL; |
403 if (current_system->type == SYSTEM_GENESIS) { | 431 if (current_system->type == SYSTEM_GENESIS) { |
404 genesis_context *gen = (genesis_context *)current_system; | 432 genesis_context *gen = (genesis_context *)current_system; |
405 vdp = gen->vdp; | 433 vdp = gen->vdp; |
406 } else if (current_system->type == SYSTEM_SMS) { | 434 } else if (current_system->type == SYSTEM_SMS) { |
554 | 582 |
555 int parse_binding_target(int device_num, char * target, tern_node * padbuttons, tern_node *mousebuttons, uint8_t * subtype_a, uint8_t * subtype_b) | 583 int parse_binding_target(int device_num, char * target, tern_node * padbuttons, tern_node *mousebuttons, uint8_t * subtype_a, uint8_t * subtype_b) |
556 { | 584 { |
557 const int gpadslen = strlen("gamepads."); | 585 const int gpadslen = strlen("gamepads."); |
558 const int mouselen = strlen("mouse."); | 586 const int mouselen = strlen("mouse."); |
559 if (!strncmp(target, "gamepads.", gpadslen)) { | 587 if (startswith(target, "gamepads.")) { |
560 int padnum = target[gpadslen] == 'n' ? device_num + 1 : target[gpadslen] - '0'; | 588 int padnum = target[gpadslen] == 'n' ? device_num + 1 : target[gpadslen] - '0'; |
561 if (padnum >= 1 && padnum <= 8) { | 589 if (padnum >= 1 && padnum <= 8) { |
562 int button = tern_find_int(padbuttons, target + gpadslen + 1, 0); | 590 int button = tern_find_int(padbuttons, target + gpadslen + 1, 0); |
563 if (button) { | 591 if (button) { |
564 *subtype_a = padnum; | 592 *subtype_a = padnum; |
572 } | 600 } |
573 } | 601 } |
574 } else { | 602 } else { |
575 warning("Gamepad mapping string '%s' refers to an invalid gamepad number %c\n", target, target[gpadslen]); | 603 warning("Gamepad mapping string '%s' refers to an invalid gamepad number %c\n", target, target[gpadslen]); |
576 } | 604 } |
577 } else if(!strncmp(target, "mouse.", mouselen)) { | 605 } else if(startswith(target, "mouse.")) { |
578 int mousenum = target[mouselen] == 'n' ? device_num + 1 : target[mouselen] - '0'; | 606 int mousenum = target[mouselen] == 'n' ? device_num + 1 : target[mouselen] - '0'; |
579 if (mousenum >= 1 && mousenum <= 8) { | 607 if (mousenum >= 1 && mousenum <= 8) { |
580 int button = tern_find_int(mousebuttons, target + mouselen + 1, 0); | 608 int button = tern_find_int(mousebuttons, target + mouselen + 1, 0); |
581 if (button) { | 609 if (button) { |
582 *subtype_a = mousenum; | 610 *subtype_a = mousenum; |
590 } | 618 } |
591 } | 619 } |
592 } else { | 620 } else { |
593 warning("Gamepad mapping string '%s' refers to an invalid mouse number %c\n", target, target[mouselen]); | 621 warning("Gamepad mapping string '%s' refers to an invalid mouse number %c\n", target, target[mouselen]); |
594 } | 622 } |
595 } else if(!strncmp(target, "ui.", strlen("ui."))) { | 623 } else if(startswith(target, "ui.")) { |
596 if (!strcmp(target + 3, "vdp_debug_mode")) { | 624 if (!strcmp(target + 3, "vdp_debug_mode")) { |
597 *subtype_a = UI_DEBUG_MODE_INC; | 625 *subtype_a = UI_DEBUG_MODE_INC; |
598 } else if(!strcmp(target + 3, "vdp_debug_pal")) { | 626 } else if(!strcmp(target + 3, "vdp_debug_pal")) { |
599 //legacy binding, ignore | 627 //legacy binding, ignore |
600 return 0; | 628 return 0; |
601 } else if(!strcmp(target + 3, "enter_debugger")) { | 629 } else if(!strcmp(target + 3, "enter_debugger")) { |
602 *subtype_a = UI_ENTER_DEBUGGER; | 630 *subtype_a = UI_ENTER_DEBUGGER; |
603 } else if(!strcmp(target + 3, "save_state")) { | 631 } else if(!strcmp(target + 3, "save_state")) { |
604 *subtype_a = UI_SAVE_STATE; | 632 *subtype_a = UI_SAVE_STATE; |
605 } else if(!strncmp(target + 3, "set_speed.", strlen("set_speed."))) { | 633 } else if(startswith(target + 3, "set_speed.")) { |
606 *subtype_a = UI_SET_SPEED; | 634 *subtype_a = UI_SET_SPEED; |
607 *subtype_b = atoi(target + 3 + strlen("set_speed.")); | 635 *subtype_b = atoi(target + 3 + strlen("set_speed.")); |
608 } else if(!strcmp(target + 3, "next_speed")) { | 636 } else if(!strcmp(target + 3, "next_speed")) { |
609 *subtype_a = UI_NEXT_SPEED; | 637 *subtype_a = UI_NEXT_SPEED; |
610 } else if(!strcmp(target + 3, "prev_speed")) { | 638 } else if(!strcmp(target + 3, "prev_speed")) { |
621 *subtype_a = UI_RELOAD; | 649 *subtype_a = UI_RELOAD; |
622 } else if (!strcmp(target + 3, "sms_pause")) { | 650 } else if (!strcmp(target + 3, "sms_pause")) { |
623 *subtype_a = UI_SMS_PAUSE; | 651 *subtype_a = UI_SMS_PAUSE; |
624 } else if (!strcmp(target + 3, "screenshot")) { | 652 } else if (!strcmp(target + 3, "screenshot")) { |
625 *subtype_a = UI_SCREENSHOT; | 653 *subtype_a = UI_SCREENSHOT; |
654 } else if (!strcmp(target + 3, "vgm_log")) { | |
655 *subtype_a = UI_VGM_LOG; | |
626 } else if(!strcmp(target + 3, "exit")) { | 656 } else if(!strcmp(target + 3, "exit")) { |
627 *subtype_a = UI_EXIT; | 657 *subtype_a = UI_EXIT; |
628 } else if (!strcmp(target + 3, "plane_debug")) { | 658 } else if (!strcmp(target + 3, "plane_debug")) { |
629 *subtype_a = UI_PLANE_DEBUG; | 659 *subtype_a = UI_PLANE_DEBUG; |
630 } else if (!strcmp(target + 3, "vram_debug")) { | 660 } else if (!strcmp(target + 3, "vram_debug")) { |
812 hostbutton = render_translate_input_name(hostpadnum, key, 0); | 842 hostbutton = render_translate_input_name(hostpadnum, key, 0); |
813 if (hostbutton < 0) { | 843 if (hostbutton < 0) { |
814 if (hostbutton == RENDER_INVALID_NAME) { | 844 if (hostbutton == RENDER_INVALID_NAME) { |
815 warning("%s is not a valid gamepad input name\n", key); | 845 warning("%s is not a valid gamepad input name\n", key); |
816 } else if (hostbutton == RENDER_NOT_MAPPED && hostpadnum != map_warning_pad) { | 846 } else if (hostbutton == RENDER_NOT_MAPPED && hostpadnum != map_warning_pad) { |
817 warning("No SDL 2 mapping exists for input %s on gamepad %d\n", key, hostpadnum); | 847 debug_message("No SDL 2 mapping exists for input %s on gamepad %d\n", key, hostpadnum); |
818 map_warning_pad = hostpadnum; | 848 map_warning_pad = hostpadnum; |
819 } | 849 } |
820 return; | 850 return; |
821 } | 851 } |
822 if (hostbutton & RENDER_DPAD_BIT) { | 852 if (hostbutton & RENDER_DPAD_BIT) { |
823 bind_dpad(hostpadnum, render_dpad_part(hostbutton), render_direction_part(hostbutton), bindtype, subtype_a, subtype_b); | 853 bind_dpad(hostpadnum, render_dpad_part(hostbutton), render_direction_part(hostbutton), bindtype, subtype_a, subtype_b); |
824 return; | 854 return; |
825 } else if (hostbutton & RENDER_AXIS_BIT) { | 855 } else if (hostbutton & RENDER_AXIS_BIT) { |
826 bind_axis(hostpadnum, render_axis_part(hostbutton), 1, bindtype, subtype_a, subtype_b); | 856 bind_axis(hostpadnum, render_axis_part(hostbutton), hostbutton & RENDER_AXIS_POS, bindtype, subtype_a, subtype_b); |
827 return; | 857 return; |
828 } | 858 } |
829 } | 859 } |
830 bind_button(hostpadnum, hostbutton, bindtype, subtype_a, subtype_b); | 860 bind_button(hostpadnum, hostbutton, bindtype, subtype_a, subtype_b); |
831 } | 861 } |
859 axis = render_translate_input_name(hostpadnum, key, 1); | 889 axis = render_translate_input_name(hostpadnum, key, 1); |
860 if (axis < 0) { | 890 if (axis < 0) { |
861 if (axis == RENDER_INVALID_NAME) { | 891 if (axis == RENDER_INVALID_NAME) { |
862 warning("%s is not a valid gamepad input name\n", key); | 892 warning("%s is not a valid gamepad input name\n", key); |
863 } else if (axis == RENDER_NOT_MAPPED && hostpadnum != map_warning_pad) { | 893 } else if (axis == RENDER_NOT_MAPPED && hostpadnum != map_warning_pad) { |
864 warning("No SDL 2 mapping exists for input %s on gamepad %d\n", key, hostpadnum); | 894 debug_message("No SDL 2 mapping exists for input %s on gamepad %d\n", key, hostpadnum); |
865 map_warning_pad = hostpadnum; | 895 map_warning_pad = hostpadnum; |
866 } | 896 } |
867 goto done; | 897 goto done; |
868 } | 898 } |
869 if (axis & RENDER_DPAD_BIT) { | 899 if (axis & RENDER_DPAD_BIT) { |
955 for (int dpad = 0; dpad < 10; dpad++) | 985 for (int dpad = 0; dpad < 10; dpad++) |
956 { | 986 { |
957 char numstr[2] = {dpad + '0', 0}; | 987 char numstr[2] = {dpad + '0', 0}; |
958 tern_node * pad_dpad = tern_find_node(dpad_node, numstr); | 988 tern_node * pad_dpad = tern_find_node(dpad_node, numstr); |
959 char * dirs[] = {"up", "down", "left", "right"}; | 989 char * dirs[] = {"up", "down", "left", "right"}; |
960 //TODO: Support controllers that have d-pads implemented as analog axes or buttons | 990 char *render_dirs[] = {"dpup", "dpdown", "dpleft", "dpright"}; |
961 int dirnums[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; | 991 int dirnums[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; |
962 for (int dir = 0; dir < sizeof(dirs)/sizeof(dirs[0]); dir++) { | 992 for (int dir = 0; dir < sizeof(dirs)/sizeof(dirs[0]); dir++) { |
963 char * target = tern_find_ptr(pad_dpad, dirs[dir]); | 993 char * target = tern_find_ptr(pad_dpad, dirs[dir]); |
964 if (target) { | 994 if (target) { |
965 uint8_t subtype_a = 0, subtype_b = 0; | 995 uint8_t subtype_a = 0, subtype_b = 0; |
966 int bindtype = parse_binding_target(joystick, target, get_pad_buttons(), get_mouse_buttons(), &subtype_a, &subtype_b); | 996 int bindtype = parse_binding_target(joystick, target, get_pad_buttons(), get_mouse_buttons(), &subtype_a, &subtype_b); |
967 bind_dpad(joystick, dpad, dirnums[dir], bindtype, subtype_a, subtype_b); | 997 int32_t hostbutton = dpad >0 ? -1 : render_translate_input_name(joystick, render_dirs[dir], 0); |
998 if (hostbutton < 0) { | |
999 //assume this is a raw dpad mapping | |
1000 bind_dpad(joystick, dpad, dirnums[dir], bindtype, subtype_a, subtype_b); | |
1001 } else if (hostbutton & RENDER_DPAD_BIT) { | |
1002 bind_dpad(joystick, render_dpad_part(hostbutton), render_direction_part(hostbutton), bindtype, subtype_a, subtype_b); | |
1003 } else if (hostbutton & RENDER_AXIS_BIT) { | |
1004 //SDL2 knows internally whether this should be a positive or negative binding, but doesn't expose that externally | |
1005 //for now I'll just assume that any controller with axes for a d-pad has these mapped the "sane" way | |
1006 bind_axis(joystick, render_axis_part(hostbutton), dir == 1 || dir == 3 ? 1 : 0, bindtype, subtype_a, subtype_b); | |
1007 } else { | |
1008 bind_button(joystick, hostbutton, bindtype, subtype_a, subtype_b); | |
1009 } | |
968 } | 1010 } |
969 } | 1011 } |
970 } | 1012 } |
971 } | 1013 } |
972 tern_node *button_node = tern_find_node(pad, "buttons"); | 1014 tern_node *button_node = tern_find_node(pad, "buttons"); |