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);