Mercurial > repos > blastem
comparison render_sdl.c @ 1207:9d6f155732ed
Basic support for mapping an analog axis to functionality
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 26 Jan 2017 23:49:13 -0800 |
parents | 3d3bad51183d |
children | 1148567ab355 |
comparison
equal
deleted
inserted
replaced
1206:32265f6b79e9 | 1207:9d6f155732ed |
---|---|
654 } | 654 } |
655 } | 655 } |
656 return -1; | 656 return -1; |
657 } | 657 } |
658 | 658 |
659 int32_t render_translate_input_name(int32_t controller, char *name) | 659 int32_t render_translate_input_name(int32_t controller, char *name, uint8_t is_axis) |
660 { | 660 { |
661 static tern_node *button_lookup; | 661 static tern_node *button_lookup, *axis_lookup; |
662 if (controller > MAX_JOYSTICKS || !joysticks[controller]) { | 662 if (controller > MAX_JOYSTICKS || !joysticks[controller]) { |
663 return RENDER_NOT_PLUGGED_IN; | 663 return RENDER_NOT_PLUGGED_IN; |
664 } | 664 } |
665 | 665 |
666 if (!SDL_IsGameController(joystick_sdl_index[controller])) { | 666 if (!SDL_IsGameController(joystick_sdl_index[controller])) { |
667 return RENDER_NOT_MAPPED; | 667 return RENDER_NOT_MAPPED; |
668 } | |
669 | |
670 if (!button_lookup) { | |
671 for (int i = SDL_CONTROLLER_BUTTON_A; i < SDL_CONTROLLER_BUTTON_MAX; i++) | |
672 { | |
673 button_lookup = tern_insert_int(button_lookup, SDL_GameControllerGetStringForButton(i), i); | |
674 } | |
675 //alternative Playstation-style names | |
676 button_lookup = tern_insert_int(button_lookup, "cross", SDL_CONTROLLER_BUTTON_A); | |
677 button_lookup = tern_insert_int(button_lookup, "circle", SDL_CONTROLLER_BUTTON_B); | |
678 button_lookup = tern_insert_int(button_lookup, "square", SDL_CONTROLLER_BUTTON_X); | |
679 button_lookup = tern_insert_int(button_lookup, "triangle", SDL_CONTROLLER_BUTTON_Y); | |
680 button_lookup = tern_insert_int(button_lookup, "share", SDL_CONTROLLER_BUTTON_BACK); | |
681 button_lookup = tern_insert_int(button_lookup, "select", SDL_CONTROLLER_BUTTON_BACK); | |
682 button_lookup = tern_insert_int(button_lookup, "options", SDL_CONTROLLER_BUTTON_START); | |
683 button_lookup = tern_insert_int(button_lookup, "l1", SDL_CONTROLLER_BUTTON_LEFTSHOULDER); | |
684 button_lookup = tern_insert_int(button_lookup, "r1", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); | |
685 button_lookup = tern_insert_int(button_lookup, "l3", SDL_CONTROLLER_BUTTON_LEFTSTICK); | |
686 button_lookup = tern_insert_int(button_lookup, "r3", SDL_CONTROLLER_BUTTON_RIGHTSTICK); | |
687 } | |
688 intptr_t sdl_button = tern_find_int(button_lookup, name, SDL_CONTROLLER_BUTTON_INVALID); | |
689 if (sdl_button == SDL_CONTROLLER_BUTTON_INVALID) { | |
690 return RENDER_INVALID_NAME; | |
691 } | 668 } |
692 SDL_GameController *control = SDL_GameControllerOpen(joystick_sdl_index[controller]); | 669 SDL_GameController *control = SDL_GameControllerOpen(joystick_sdl_index[controller]); |
693 if (!control) { | 670 if (!control) { |
694 warning("Failed to open game controller %d: %s\n", controller, SDL_GetError()); | 671 warning("Failed to open game controller %d: %s\n", controller, SDL_GetError()); |
695 return RENDER_NOT_PLUGGED_IN; | 672 return RENDER_NOT_PLUGGED_IN; |
696 } | 673 } |
697 SDL_GameControllerButtonBind cbind = SDL_GameControllerGetBindForButton(control, sdl_button); | 674 |
675 SDL_GameControllerButtonBind cbind; | |
676 if (is_axis) { | |
677 if (!axis_lookup) { | |
678 for (int i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++) | |
679 { | |
680 axis_lookup = tern_insert_int(axis_lookup, SDL_GameControllerGetStringForAxis(i), i); | |
681 } | |
682 //alternative Playstation-style names | |
683 axis_lookup = tern_insert_int(axis_lookup, "l2", SDL_CONTROLLER_AXIS_TRIGGERLEFT); | |
684 axis_lookup = tern_insert_int(axis_lookup, "r2", SDL_CONTROLLER_AXIS_TRIGGERRIGHT); | |
685 } | |
686 intptr_t sdl_axis = tern_find_int(axis_lookup, name, SDL_CONTROLLER_AXIS_INVALID); | |
687 if (sdl_axis == SDL_CONTROLLER_AXIS_INVALID) { | |
688 SDL_GameControllerClose(control); | |
689 return RENDER_INVALID_NAME; | |
690 } | |
691 cbind = SDL_GameControllerGetBindForAxis(control, sdl_axis); | |
692 } else { | |
693 if (!button_lookup) { | |
694 for (int i = SDL_CONTROLLER_BUTTON_A; i < SDL_CONTROLLER_BUTTON_MAX; i++) | |
695 { | |
696 button_lookup = tern_insert_int(button_lookup, SDL_GameControllerGetStringForButton(i), i); | |
697 } | |
698 //alternative Playstation-style names | |
699 button_lookup = tern_insert_int(button_lookup, "cross", SDL_CONTROLLER_BUTTON_A); | |
700 button_lookup = tern_insert_int(button_lookup, "circle", SDL_CONTROLLER_BUTTON_B); | |
701 button_lookup = tern_insert_int(button_lookup, "square", SDL_CONTROLLER_BUTTON_X); | |
702 button_lookup = tern_insert_int(button_lookup, "triangle", SDL_CONTROLLER_BUTTON_Y); | |
703 button_lookup = tern_insert_int(button_lookup, "share", SDL_CONTROLLER_BUTTON_BACK); | |
704 button_lookup = tern_insert_int(button_lookup, "select", SDL_CONTROLLER_BUTTON_BACK); | |
705 button_lookup = tern_insert_int(button_lookup, "options", SDL_CONTROLLER_BUTTON_START); | |
706 button_lookup = tern_insert_int(button_lookup, "l1", SDL_CONTROLLER_BUTTON_LEFTSHOULDER); | |
707 button_lookup = tern_insert_int(button_lookup, "r1", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); | |
708 button_lookup = tern_insert_int(button_lookup, "l3", SDL_CONTROLLER_BUTTON_LEFTSTICK); | |
709 button_lookup = tern_insert_int(button_lookup, "r3", SDL_CONTROLLER_BUTTON_RIGHTSTICK); | |
710 } | |
711 intptr_t sdl_button = tern_find_int(button_lookup, name, SDL_CONTROLLER_BUTTON_INVALID); | |
712 if (sdl_button == SDL_CONTROLLER_BUTTON_INVALID) { | |
713 SDL_GameControllerClose(control); | |
714 return RENDER_INVALID_NAME; | |
715 } | |
716 cbind = SDL_GameControllerGetBindForButton(control, sdl_button); | |
717 } | |
698 SDL_GameControllerClose(control); | 718 SDL_GameControllerClose(control); |
699 switch (cbind.bindType) | 719 switch (cbind.bindType) |
700 { | 720 { |
701 case SDL_CONTROLLER_BINDTYPE_BUTTON: | 721 case SDL_CONTROLLER_BINDTYPE_BUTTON: |
702 return cbind.value.button; | 722 return cbind.value.button; |
708 return RENDER_NOT_MAPPED; | 728 return RENDER_NOT_MAPPED; |
709 } | 729 } |
710 | 730 |
711 int32_t render_dpad_part(int32_t input) | 731 int32_t render_dpad_part(int32_t input) |
712 { | 732 { |
713 return input >> 4 & 0x7FFFFF; | 733 return input >> 4 & 0xFFFFFF; |
714 } | 734 } |
715 | 735 |
716 uint8_t render_direction_part(int32_t input) | 736 uint8_t render_direction_part(int32_t input) |
717 { | 737 { |
718 return input & 0xF; | 738 return input & 0xF; |
739 } | |
740 | |
741 int32_t render_axis_part(int32_t input) | |
742 { | |
743 return input & 0xFFFFFFF; | |
719 } | 744 } |
720 | 745 |
721 static uint8_t scancode_map[SDL_NUM_SCANCODES] = { | 746 static uint8_t scancode_map[SDL_NUM_SCANCODES] = { |
722 [SDL_SCANCODE_A] = 0x1C, | 747 [SDL_SCANCODE_A] = 0x1C, |
723 [SDL_SCANCODE_B] = 0x32, | 748 [SDL_SCANCODE_B] = 0x32, |
838 handle_joyup(find_joystick_index(event->jbutton.which), event->jbutton.button); | 863 handle_joyup(find_joystick_index(event->jbutton.which), event->jbutton.button); |
839 break; | 864 break; |
840 case SDL_JOYHATMOTION: | 865 case SDL_JOYHATMOTION: |
841 handle_joy_dpad(find_joystick_index(event->jbutton.which), event->jhat.hat, event->jhat.value); | 866 handle_joy_dpad(find_joystick_index(event->jbutton.which), event->jhat.hat, event->jhat.value); |
842 break; | 867 break; |
868 case SDL_JOYAXISMOTION: | |
869 handle_joy_axis(find_joystick_index(event->jaxis.which), event->jaxis.axis, event->jaxis.value); | |
870 break; | |
843 case SDL_JOYDEVICEADDED: | 871 case SDL_JOYDEVICEADDED: |
844 if (event->jdevice.which < MAX_JOYSTICKS) { | 872 if (event->jdevice.which < MAX_JOYSTICKS) { |
845 int index = lowest_unused_joystick_index(); | 873 int index = lowest_unused_joystick_index(); |
846 if (index >= 0) { | 874 if (index >= 0) { |
847 SDL_Joystick * joy = joysticks[index] = SDL_JoystickOpen(event->jdevice.which); | 875 SDL_Joystick * joy = joysticks[index] = SDL_JoystickOpen(event->jdevice.which); |