ref: a6a0098d0d37998ace5b3df4b57cd842d4c3922f
parent: 7f4526eeeb658bdcf04d7c8428c91c3286810f82
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Tue Nov 30 18:25:44 EST 2021
rewrite gamepad input code
--- a/config.c
+++ b/config.c
@@ -25,15 +25,25 @@
c.key_delete = SDL_SCANCODE_DELETE;
c.key_reset = SDL_SCANCODE_R;
- c.gamepad_up = SDL_CONTROLLER_BUTTON_DPAD_UP;
- c.gamepad_left = SDL_CONTROLLER_BUTTON_DPAD_LEFT;
- c.gamepad_down = SDL_CONTROLLER_BUTTON_DPAD_DOWN;
- c.gamepad_right = SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
- c.gamepad_select = SDL_CONTROLLER_BUTTON_BACK;
- c.gamepad_start = SDL_CONTROLLER_BUTTON_START;
- c.gamepad_opt = SDL_CONTROLLER_BUTTON_B;
- c.gamepad_edit = SDL_CONTROLLER_BUTTON_A;
- c.gamepad_analog_threshold = 32767;
+ c.gamepad_up = SDL_CONTROLLER_BUTTON_DPAD_UP;
+ c.gamepad_left = SDL_CONTROLLER_BUTTON_DPAD_LEFT;
+ c.gamepad_down = SDL_CONTROLLER_BUTTON_DPAD_DOWN;
+ c.gamepad_right = SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
+ c.gamepad_select = SDL_CONTROLLER_BUTTON_BACK;
+ c.gamepad_start = SDL_CONTROLLER_BUTTON_START;
+ c.gamepad_opt = SDL_CONTROLLER_BUTTON_B;
+ c.gamepad_edit = SDL_CONTROLLER_BUTTON_A;
+
+ c.gamepad_analog_threshold = 32767;
+ c.gamepad_analog_invert = 0;
+ c.gamepad_analog_axis_updown = SDL_CONTROLLER_AXIS_LEFTY;
+ c.gamepad_analog_axis_leftright = SDL_CONTROLLER_AXIS_LEFTX;
+ c.gamepad_analog_axis_start = SDL_CONTROLLER_AXIS_TRIGGERRIGHT;
+ c.gamepad_analog_axis_select = SDL_CONTROLLER_AXIS_TRIGGERLEFT;
+ c.gamepad_analog_axis_opt = SDL_CONTROLLER_AXIS_INVALID;
+ c.gamepad_analog_axis_edit = SDL_CONTROLLER_AXIS_INVALID;
+
+
return c;
}
@@ -99,23 +109,43 @@
void read_gamepad_config(ini_t *ini, config_params_s *conf) {// TODO: Some form of validation
- const char *gamepad_up = ini_get(ini, "gamepad", "gamepad_up");
- const char *gamepad_left = ini_get(ini, "gamepad", "gamepad_left");
- const char *gamepad_down = ini_get(ini, "gamepad", "gamepad_down");
- const char *gamepad_right = ini_get(ini, "gamepad", "gamepad_right");
- const char *gamepad_select = ini_get(ini, "gamepad", "gamepad_select");
- const char *gamepad_start = ini_get(ini, "gamepad", "gamepad_start");
- const char *gamepad_opt = ini_get(ini, "gamepad", "gamepad_opt");
- const char *gamepad_edit = ini_get(ini, "gamepad", "gamepad_edit");
- const char *gamepad_analog_threshold = ini_get(ini, "gamepad", "gamepad_analog_threshold");
+ const char *gamepad_up = ini_get(ini, "gamepad", "gamepad_up");
+ const char *gamepad_left = ini_get(ini, "gamepad", "gamepad_left");
+ const char *gamepad_down = ini_get(ini, "gamepad", "gamepad_down");
+ const char *gamepad_right = ini_get(ini, "gamepad", "gamepad_right");
+ const char *gamepad_select = ini_get(ini, "gamepad", "gamepad_select");
+ const char *gamepad_start = ini_get(ini, "gamepad", "gamepad_start");
+ const char *gamepad_opt = ini_get(ini, "gamepad", "gamepad_opt");
+ const char *gamepad_edit = ini_get(ini, "gamepad", "gamepad_edit");
+ const char *gamepad_analog_threshold = ini_get(ini, "gamepad", "gamepad_analog_threshold");
+ const char *gamepad_analog_invert = ini_get(ini, "gamepad", "gamepad_analog_invert");
+ const char *gamepad_analog_axis_updown = ini_get(ini, "gamepad", "gamepad_analog_axis_updown");
+ const char *gamepad_analog_axis_leftright = ini_get(ini, "gamepad", "gamepad_analog_axis_leftright");
+ const char *gamepad_analog_axis_select = ini_get(ini, "gamepad", "gamepad_analog_axis_select");
+ const char *gamepad_analog_axis_start = ini_get(ini, "gamepad", "gamepad_analog_axis_start");
+ const char *gamepad_analog_axis_opt = ini_get(ini, "gamepad", "gamepad_analog_axis_opt");
+ const char *gamepad_analog_axis_edit = ini_get(ini, "gamepad", "gamepad_analog_axis_edit");
- conf->gamepad_up = atoi(gamepad_up);
- conf->gamepad_left = atoi(gamepad_left);
- conf->gamepad_down = atoi(gamepad_down);
- conf->gamepad_right = atoi(gamepad_right);
- conf->gamepad_select = atoi(gamepad_select);
- conf->gamepad_start = atoi(gamepad_start);
- conf->gamepad_opt = atoi(gamepad_opt);
- conf->gamepad_edit = atoi(gamepad_edit);
- conf->gamepad_analog_threshold = atoi(gamepad_analog_threshold);
+ conf->gamepad_up = atoi(gamepad_up);
+ conf->gamepad_left = atoi(gamepad_left);
+ conf->gamepad_down = atoi(gamepad_down);
+ conf->gamepad_right = atoi(gamepad_right);
+ conf->gamepad_select = atoi(gamepad_select);
+ conf->gamepad_start = atoi(gamepad_start);
+ conf->gamepad_opt = atoi(gamepad_opt);
+ conf->gamepad_edit = atoi(gamepad_edit);
+ conf->gamepad_analog_threshold = atoi(gamepad_analog_threshold);
+
+ // This obviously requires the parameter to be a lowercase true to enable fullscreen
+ if ( strcmp(gamepad_analog_invert, "true") == 0 ) {+ conf->gamepad_analog_invert = 1;
+ }
+ else conf->gamepad_analog_invert = 0;
+
+ conf->gamepad_analog_axis_updown = atoi(gamepad_analog_axis_updown);
+ conf->gamepad_analog_axis_leftright = atoi(gamepad_analog_axis_leftright);
+ conf->gamepad_analog_axis_select = atoi(gamepad_analog_axis_select);
+ conf->gamepad_analog_axis_start = atoi(gamepad_analog_axis_start);
+ conf->gamepad_analog_axis_opt = atoi(gamepad_analog_axis_opt);
+ conf->gamepad_analog_axis_edit = atoi(gamepad_analog_axis_edit);
}
\ No newline at end of file
--- a/config.h
+++ b/config.h
@@ -35,6 +35,14 @@
int gamepad_edit;
int gamepad_analog_threshold;
+ int gamepad_analog_invert;
+ int gamepad_analog_axis_updown;
+ int gamepad_analog_axis_leftright;
+ int gamepad_analog_axis_start;
+ int gamepad_analog_axis_select;
+ int gamepad_analog_axis_opt;
+ int gamepad_analog_axis_edit;
+
} config_params_s;
--- a/config.ini
+++ b/config.ini
@@ -31,4 +31,15 @@
gamepad_start=6
gamepad_opt=1
gamepad_edit=0
-gamepad_analog_threshold=32767 ;the threshold for analog sticks to trigger cursor movement (range: 1-32767)
\ No newline at end of file
+
+gamepad_analog_threshold=32766 ;the threshold for analog sticks to trigger cursor movement (range: 1-32767)
+gamepad_analog_invert=false ;invert up/down and left/right axis (true/false)
+
+; these need to be the decimal value of the controller axis
+; you can use -1 if you do not wish to map the function to an analog axis
+gamepad_analog_axis_updown=1
+gamepad_analog_axis_leftright=0
+gamepad_analog_axis_start=5
+gamepad_analog_axis_select=4
+gamepad_analog_axis_opt=-1
+gamepad_analog_axis_edit=-1
--- a/input.c
+++ b/input.c
@@ -2,6 +2,10 @@
// Released under the MIT licence, https://opensource.org/licenses/MIT
#include <SDL2/SDL.h>
+#include <SDL2/SDL_events.h>
+#include <SDL2/SDL_gamecontroller.h>
+#include <SDL2/SDL_joystick.h>
+#include <SDL2/SDL_stdinc.h>
#include <stdio.h>
#include "config.h"
@@ -28,8 +32,8 @@
uint8_t keyjazz_enabled = 0;
uint8_t keyjazz_base_octave = 2;
-uint8_t keycode = 0; // value of the pressed key
-static int controller_axis_released = 1; // is analog axis released
+static uint8_t keycode = 0; // value of the pressed key
+
input_msg_s key = {normal, 0}; uint8_t toggle_input_keyjazz() {@@ -219,107 +223,114 @@
return key;
}
-static input_msg_s handle_game_controller_buttons(SDL_Event *event,
+/*static input_msg_s handle_game_controller_buttons(SDL_Event *event,
config_params_s *conf,
uint8_t keyvalue) { input_msg_s key = {normal, keyvalue}; if (event->cbutton.button == conf->gamepad_up) {- key.value = key_up;
+ key.value |= key_up;
} else if (event->cbutton.button == conf->gamepad_left) {- key.value = key_left;
+ key.value |= key_left;
} else if (event->cbutton.button == conf->gamepad_down) {- key.value = key_down;
+ key.value |= key_down;
} else if (event->cbutton.button == conf->gamepad_right) {- key.value = key_right;
+ key.value |= key_right;
} else if (event->cbutton.button == conf->gamepad_select) {- key.value = key_select;
+ key.value |= key_select;
} else if (event->cbutton.button == conf->gamepad_start) {- key.value = key_start;
+ key.value |= key_start;
} else if (event->cbutton.button == conf->gamepad_opt) {- key.value = key_opt;
+ key.value |= key_opt;
} else if (event->cbutton.button == conf->gamepad_edit) {- key.value = key_edit;
+ key.value |= key_edit;
} else {key.value = 0;
}
return key;
+} */
+
+int axis_in_threshold(int axis_value, int threshold) {+ if (axis_value <= 0 - threshold || axis_value >= threshold) {+ return 1;
+ } else {+ return 0;
+ }
}
-// Handle analog sticks and digital pads that emulate analog behavior.
-static input_msg_s handle_game_controller_axis(SDL_Event *event,
- config_params_s *conf,
- uint8_t keyvalue) {+static int get_game_controller_button(config_params_s *conf,
+ SDL_GameController *controller,
+ int button) {- input_msg_s key = {normal, keyvalue};- static int active_keys;
+ const int button_mappings[8] = {conf->gamepad_up, conf->gamepad_down,+ conf->gamepad_left, conf->gamepad_right,
+ conf->gamepad_opt, conf->gamepad_edit,
+ conf->gamepad_select, conf->gamepad_start};
- // If the controller returns to zero position, clear all active directions
- if (controller_axis_released == 0 &&
- event->caxis.value > 0 - conf->gamepad_analog_threshold &&
- event->caxis.value < conf->gamepad_analog_threshold) {-
- SDL_LogDebug(
- SDL_LOG_CATEGORY_INPUT,
- "Analog controller axis at zero, axis: %d, value: %d, active keys: %d",
- event->caxis.axis, event->caxis.value, active_keys);
-
- key.value = active_keys;
- controller_axis_released = 1;
- active_keys = 0;
+ if (SDL_GameControllerGetButton(controller, button_mappings[button])) {+ return 1;
+ } else {+ switch (button) {+ case INPUT_UP:
+ return SDL_GameControllerGetAxis(controller,
+ conf->gamepad_analog_axis_updown) <
+ -conf->gamepad_analog_threshold;
+ case INPUT_DOWN:
+ return SDL_GameControllerGetAxis(controller,
+ conf->gamepad_analog_axis_updown) >
+ conf->gamepad_analog_threshold;
+ case INPUT_LEFT:
+ return SDL_GameControllerGetAxis(controller,
+ conf->gamepad_analog_axis_leftright) <
+ -conf->gamepad_analog_threshold;
+ case INPUT_RIGHT:
+ return SDL_GameControllerGetAxis(controller,
+ conf->gamepad_analog_axis_leftright) >
+ conf->gamepad_analog_threshold;
+ case INPUT_OPT:
+ return SDL_GameControllerGetAxis(controller,
+ conf->gamepad_analog_axis_opt) >
+ conf->gamepad_analog_threshold;
+ case INPUT_EDIT:
+ return SDL_GameControllerGetAxis(controller,
+ conf->gamepad_analog_axis_edit) >
+ conf->gamepad_analog_threshold;
+ case INPUT_SELECT:
+ return SDL_GameControllerGetAxis(controller,
+ conf->gamepad_analog_axis_select) >
+ conf->gamepad_analog_threshold;
+ case INPUT_START:
+ return SDL_GameControllerGetAxis(controller,
+ conf->gamepad_analog_axis_start) >
+ conf->gamepad_analog_threshold;
+ default:
+ return 0;
+ }
}
+ return 0;
+}
- // Handle up-down movement
- if (event->caxis.axis == SDL_CONTROLLER_AXIS_LEFTY ||
- event->caxis.axis == SDL_CONTROLLER_AXIS_RIGHTY) {+// Handle game controllers, simply check all buttons and analog axis on every
+// cycle
+static int handle_game_controller_buttons(config_params_s *conf) {- if (event->caxis.value >= conf->gamepad_analog_threshold) {+ const int keycodes[8] = {key_up, key_down, key_left, key_right,+ key_opt, key_edit, key_select, key_start};
- active_keys |= key_down;
- key.value = active_keys;
- controller_axis_released = 0;
+ int key = 0;
- SDL_LogDebug(
- SDL_LOG_CATEGORY_INPUT,
- "Analog controller axis down, axis: %d, value: %d, active keys: %d",
- event->caxis.axis, event->caxis.value, active_keys);
-
- } else if (event->caxis.value <= 0 - conf->gamepad_analog_threshold) {-
- active_keys |= key_up;
- key.value = active_keys;
- controller_axis_released = 0;
-
- SDL_LogDebug(
- SDL_LOG_CATEGORY_INPUT,
- "Analog controller axis up, axis: %d, value: %d, active keys: %d",
- event->caxis.axis, event->caxis.value, active_keys);
+ // Cycle through every active game controller
+ for (int gc = 0; gc < SDL_NumJoysticks(); gc++) {+ // Cycle through all M8 buttons
+ for (int button = 0; button < (input_buttons_t)INPUT_MAX; button++) {+ // If the button is active, add the keycode to the variable containing
+ // active keys
+ if (get_game_controller_button(conf, game_controllers[gc], button)) {+ key |= keycodes[button];
+ }
}
}
- // Handle left-right movement
- else if (event->caxis.axis == SDL_CONTROLLER_AXIS_LEFTX ||
- event->caxis.axis == SDL_CONTROLLER_AXIS_RIGHTX) {- if (event->caxis.value >= conf->gamepad_analog_threshold) {-
- active_keys |= key_right;
- key.value = active_keys;
- controller_axis_released = 0;
- SDL_LogDebug(
- SDL_LOG_CATEGORY_INPUT,
- "Analog controller axis right, axis: %d, value: %d, active keys: %d",
- event->caxis.axis, event->caxis.value, active_keys);
- } else if (event->caxis.value <= 0 - conf->gamepad_analog_threshold) {- active_keys |= key_left;
- key.value = active_keys;
- controller_axis_released = 0;
- SDL_LogDebug(
- SDL_LOG_CATEGORY_INPUT,
- "Analog controller axis left, axis: %d, value: %d, active keys: %d",
- event->caxis.axis, event->caxis.value, active_keys);
- }
- }
-
return key;
}
@@ -326,8 +337,17 @@
// Handles SDL input events
void handle_sdl_events(config_params_s *conf) {+ static int prev_key_analog = 0;
+
SDL_Event event;
+ // Read joysticks
+ int key_analog = handle_game_controller_buttons(conf);
+ if (prev_key_analog != key_analog) {+ keycode = key_analog;
+ prev_key_analog = key_analog;
+ }
+
SDL_PollEvent(&event);
switch (event.type) {@@ -372,35 +392,29 @@
key = handle_keyjazz(&event, key.value);
break;
- // Game controller events
- case SDL_CONTROLLERBUTTONDOWN:
- case SDL_CONTROLLERBUTTONUP:
- key = handle_game_controller_buttons(&event, conf, 0);
- break;
-
- case SDL_CONTROLLERAXISMOTION:
- key = handle_game_controller_axis(&event, conf, 0);
- break;
-
default:
break;
}
- // Do not allow pressing multiple keys with keyjazz
- if (key.type == normal) {-
- if (event.type == SDL_KEYDOWN || event.type == SDL_CONTROLLERBUTTONDOWN ||
- controller_axis_released == 0) {+ switch (key.type) {+ case normal:
+ if (event.type == SDL_KEYDOWN) {keycode |= key.value;
} else {keycode &= ~key.value;
}
-
- } else {- if (event.type == SDL_KEYDOWN)
+ break;
+ case keyjazz:
+ // Do not allow pressing multiple keys with keyjazz
+ case special:
+ if (event.type == SDL_KEYDOWN) {keycode = key.value;
- else
+ } else {keycode = 0;
+ }
+ break;
+ default:
+ break;
}
}
--- a/input.h
+++ b/input.h
@@ -6,6 +6,18 @@
#include <stdint.h>
+typedef enum input_buttons_t {+ INPUT_UP,
+ INPUT_DOWN,
+ INPUT_LEFT,
+ INPUT_RIGHT,
+ INPUT_OPT,
+ INPUT_EDIT,
+ INPUT_SELECT,
+ INPUT_START,
+ INPUT_MAX
+} input_buttons_t;
+
typedef enum input_type_t {normal,
keyjazz,
--- a/render.c
+++ b/render.c
@@ -4,9 +4,6 @@
#include "render.h"
#include <SDL2/SDL.h>
-#include <SDL2/SDL_log.h>
-#include <SDL2/SDL_pixels.h>
-#include <SDL2/SDL_render.h>
#include <stdio.h>
#include "SDL2_inprint.h"
@@ -59,7 +56,7 @@
prepare_inline_font();
// Uncomment this for debug level logging
- // SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
+ //SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
return 1;
}
--
⑨