ref: 621a093f2391ca8c8c2fc63eadee31dd2efa584c
parent: 7bf257a35ab14872f1bb1fe0f504b5dc0d5765a1
parent: 96574b7204a58cf4f50bb2774b89ab9fcb7bf6cd
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Mon Aug 19 18:02:45 EDT 2024
Merge pull request #164 from laamaa/refactor/split_input_c #157 split game controller related functions to a separate file
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
#Set all your object files (the object files of all the .c files in your project, e.g. main.o my_sub_functions.o )
-OBJ = src/main.o src/serial.o src/slip.o src/command.o src/render.o src/ini.o src/config.o src/input.o src/fx_cube.o src/usb.o src/audio.o src/usb_audio.o src/ringbuffer.o src/inprint2.o
+OBJ = src/main.o src/serial.o src/slip.o src/command.o src/render.o src/ini.o src/config.o src/input.o src/gamecontrollers.o src/fx_cube.o src/usb.o src/audio.o src/usb_audio.o src/ringbuffer.o src/inprint2.o
#Set any dependant header files so that if they are edited they cause a complete re-compile (e.g. main.h some_subfunctions.h some_definitions_file.h ), or leave blank
-DEPS = src/serial.h src/slip.h src/command.h src/render.h src/ini.h src/config.h src/input.h src/fx_cube.h src/audio.h src/ringbuffer.h src/inline_font.h
+DEPS = src/serial.h src/slip.h src/command.h src/render.h src/ini.h src/config.h src/input.h src/gamecontrollers.h src/fx_cube.h src/audio.h src/ringbuffer.h src/inline_font.h
#Any special libraries you are using in your project (e.g. -lbcm2835 -lrt `pkg-config --libs gtk+-3.0` ), or leave blank
INCLUDES = $(shell pkg-config --libs sdl2 libserialport | sed 's/-mwindows//')
--- /dev/null
+++ b/src/gamecontrollers.c
@@ -1,0 +1,150 @@
+//
+// Created by jonne on 8/19/24.
+//
+
+#include "gamecontrollers.h"
+#include "config.h"
+#include "input.h"
+
+#include <SDL.h>
+
+static int num_joysticks = 0;
+SDL_GameController *game_controllers[MAX_CONTROLLERS];
+
+// Opens available game controllers and returns the amount of opened controllers
+int gamecontrollers_initialize() {+
+ num_joysticks = SDL_NumJoysticks();
+ int controller_index = 0;
+
+ SDL_Log("Looking for game controllers");+ SDL_Delay(10); // Some controllers like XBone wired need a little while to get ready
+
+ // Try to load the game controller database file
+ char db_filename[1024] = {0};+ snprintf(db_filename, sizeof(db_filename), "%sgamecontrollerdb.txt", SDL_GetPrefPath("", "m8c"));+ SDL_Log("Trying to open game controller database from %s", db_filename);+ SDL_RWops *db_rw = SDL_RWFromFile(db_filename, "rb");
+ if (db_rw == NULL) {+ snprintf(db_filename, sizeof(db_filename), "%sgamecontrollerdb.txt", SDL_GetBasePath());
+ SDL_Log("Trying to open game controller database from %s", db_filename);+ db_rw = SDL_RWFromFile(db_filename, "rb");
+ }
+
+ if (db_rw != NULL) {+ int mappings = SDL_GameControllerAddMappingsFromRW(db_rw, 1);
+ if (mappings != -1)
+ SDL_Log("Found %d game controller mappings", mappings);+ else
+ SDL_LogError(SDL_LOG_CATEGORY_INPUT, "Error loading game controller mappings.");
+ } else {+ SDL_LogError(SDL_LOG_CATEGORY_INPUT, "Unable to open game controller database file.");
+ }
+
+ // Open all available game controllers
+ for (int i = 0; i < num_joysticks; i++) {+ if (!SDL_IsGameController(i))
+ continue;
+ if (controller_index >= MAX_CONTROLLERS)
+ break;
+ game_controllers[controller_index] = SDL_GameControllerOpen(i);
+ SDL_Log("Controller %d: %s", controller_index + 1,+ SDL_GameControllerName(game_controllers[controller_index]));
+ controller_index++;
+ }
+
+ return controller_index;
+}
+
+// Closes all open game controllers
+void gamecontrollers_close() {+
+ for (int i = 0; i < MAX_CONTROLLERS; i++) {+ if (game_controllers[i])
+ SDL_GameControllerClose(game_controllers[i]);
+ }
+}
+
+// Check whether a button is pressed on a gamepad and return 1 if pressed.
+static int get_game_controller_button(config_params_s *conf, SDL_GameController *controller,
+ int button) {+
+ 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};
+
+ // Check digital buttons
+ if (SDL_GameControllerGetButton(controller, button_mappings[button])) {+ return 1;
+ }
+
+ // If digital button isn't pressed, check the corresponding analog control
+ 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;
+ }
+}
+
+// Handle game controllers, simply check all buttons and analog axis on every
+// cycle
+int gamecontrollers_handle_buttons(config_params_s *conf) {+
+ const int keycodes[8] = {key_up, key_down, key_left, key_right,+ key_opt, key_edit, key_select, key_start};
+
+ int key = 0;
+
+ // Cycle through every active game controller
+ for (int gc = 0; gc < num_joysticks; gc++) {+ // Cycle through all M8 buttons
+ for (int button = 0; button < 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];
+ }
+ }
+ }
+
+ return key;
+}
+
+input_msg_s gamecontrollers_handle_special_messages(config_params_s *conf) {+ input_msg_s msg = {0};+ // Read special case game controller buttons quit and reset
+ for (int gc = 0; gc < num_joysticks; gc++) {+ if (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_quit) &&
+ (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_select) ||
+ SDL_GameControllerGetAxis(game_controllers[gc], conf->gamepad_analog_axis_select)))
+ msg = (input_msg_s){special, msg_quit};+ else if (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_reset) &&
+ (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_select) ||
+ SDL_GameControllerGetAxis(game_controllers[gc], conf->gamepad_analog_axis_select)))
+ msg = (input_msg_s){special, msg_reset_display};+ }
+ return msg;
+}
\ No newline at end of file
--- /dev/null
+++ b/src/gamecontrollers.h
@@ -1,0 +1,19 @@
+//
+// Created by jonne on 8/19/24.
+//
+
+#ifndef GAMECONTROLLERS_H_
+#define GAMECONTROLLERS_H_
+
+#include "config.h"
+#include "input.h"
+#include <SDL_gamecontroller.h>
+
+#define MAX_CONTROLLERS 4
+
+int gamecontrollers_initialize();
+void gamecontrollers_close();
+int gamecontrollers_handle_buttons(config_params_s *conf);
+input_msg_s gamecontrollers_handle_special_messages(config_params_s *conf);
+
+#endif //GAMECONTROLLERS_H_
--- a/src/input.c
+++ b/src/input.c
@@ -7,29 +7,13 @@
#include "config.h"
#include "input.h"
#include "render.h"
+#include "gamecontrollers.h"
-#define MAX_CONTROLLERS 4
-
-SDL_GameController *game_controllers[MAX_CONTROLLERS];
-
-// Bits for M8 input messages
-enum keycodes {- key_left = 1 << 7,
- key_up = 1 << 6,
- key_down = 1 << 5,
- key_select = 1 << 4,
- key_start = 1 << 3,
- key_right = 1 << 2,
- key_opt = 1 << 1,
- key_edit = 1
-};
-
uint8_t keyjazz_enabled = 0;
uint8_t keyjazz_base_octave = 2;
uint8_t keyjazz_velocity = 0x64;
static uint8_t keycode = 0; // value of the pressed key
-static int num_joysticks = 0;
static input_msg_s key = {normal, 0};@@ -39,60 +23,6 @@
return keyjazz_enabled;
}
-// Opens available game controllers and returns the amount of opened controllers
-int initialize_game_controllers() {-
- num_joysticks = SDL_NumJoysticks();
- int controller_index = 0;
-
- SDL_Log("Looking for game controllers\n");- SDL_Delay(10); // Some controllers like XBone wired need a little while to get ready
-
- // Try to load the game controller database file
- char db_filename[1024] = {0};- snprintf(db_filename, sizeof(db_filename), "%sgamecontrollerdb.txt", SDL_GetPrefPath("", "m8c"));- SDL_Log("Trying to open game controller database from %s", db_filename);- SDL_RWops *db_rw = SDL_RWFromFile(db_filename, "rb");
- if (db_rw == NULL) {- snprintf(db_filename, sizeof(db_filename), "%sgamecontrollerdb.txt", SDL_GetBasePath());
- SDL_Log("Trying to open game controller database from %s", db_filename);- db_rw = SDL_RWFromFile(db_filename, "rb");
- }
-
- if (db_rw != NULL) {- int mappings = SDL_GameControllerAddMappingsFromRW(db_rw, 1);
- if (mappings != -1)
- SDL_Log("Found %d game controller mappings", mappings);- else
- SDL_LogError(SDL_LOG_CATEGORY_INPUT, "Error loading game controller mappings.");
- } else {- SDL_LogError(SDL_LOG_CATEGORY_INPUT, "Unable to open game controller database file.");
- }
-
- // Open all available game controllers
- for (int i = 0; i < num_joysticks; i++) {- if (!SDL_IsGameController(i))
- continue;
- if (controller_index >= MAX_CONTROLLERS)
- break;
- game_controllers[controller_index] = SDL_GameControllerOpen(i);
- SDL_Log("Controller %d: %s", controller_index + 1,- SDL_GameControllerName(game_controllers[controller_index]));
- controller_index++;
- }
-
- return controller_index;
-}
-
-// Closes all open game controllers
-void close_game_controllers() {-
- for (int i = 0; i < MAX_CONTROLLERS; i++) {- if (game_controllers[i])
- SDL_GameControllerClose(game_controllers[i]);
- }
-}
-
static input_msg_s handle_keyjazz(SDL_Event *event, uint8_t keyvalue, config_params_s *conf) { input_msg_s key = {keyjazz, keyvalue, keyjazz_velocity, event->type}; switch (event->key.keysym.scancode) {@@ -259,75 +189,6 @@
return key;
}
-// Check whether a button is pressed on a gamepad and return 1 if pressed.
-static int get_game_controller_button(config_params_s *conf, SDL_GameController *controller,
- int button) {-
- 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};
-
- // Check digital buttons
- if (SDL_GameControllerGetButton(controller, button_mappings[button])) {- return 1;
- }
-
- // If digital button isn't pressed, check the corresponding analog control
- 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 game controllers, simply check all buttons and analog axis on every
-// cycle
-static int handle_game_controller_buttons(config_params_s *conf) {-
- const int keycodes[8] = {key_up, key_down, key_left, key_right,- key_opt, key_edit, key_select, key_start};
-
- int key = 0;
-
- // Cycle through every active game controller
- for (int gc = 0; gc < num_joysticks; gc++) {- // Cycle through all M8 buttons
- for (int button = 0; button < 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];
- }
- }
- }
-
- return key;
-}
-
// Handles SDL input events
void handle_sdl_events(config_params_s *conf) {@@ -336,23 +197,14 @@
SDL_Event event;
// Read joysticks
- int key_analog = handle_game_controller_buttons(conf);
+ int key_analog = gamecontrollers_handle_buttons(conf);
if (prev_key_analog != key_analog) {keycode = key_analog;
prev_key_analog = key_analog;
}
- // Read special case game controller buttons quit and reset
- for (int gc = 0; gc < num_joysticks; gc++) {- if (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_quit) &&
- (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_select) ||
- SDL_GameControllerGetAxis(game_controllers[gc], conf->gamepad_analog_axis_select)))
- key = (input_msg_s){special, msg_quit};- else if (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_reset) &&
- (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_select) ||
- SDL_GameControllerGetAxis(game_controllers[gc], conf->gamepad_analog_axis_select)))
- key = (input_msg_s){special, msg_reset_display};- }
+ input_msg_s gcmsg = gamecontrollers_handle_special_messages(conf);
+ if (gcmsg.type == special) { key = gcmsg; } while (SDL_PollEvent(&event)) {@@ -361,7 +213,7 @@
// Reinitialize game controllers on controller add/remove/remap
case SDL_CONTROLLERDEVICEADDED:
case SDL_CONTROLLERDEVICEREMOVED:
- initialize_game_controllers();
+ gamecontrollers_initialize();
break;
// Handle SDL quit events (for example, window close)
--- a/src/input.h
+++ b/src/input.h
@@ -19,6 +19,18 @@
INPUT_MAX
} input_buttons_t;
+// Bits for M8 input messages
+typedef enum keycodes_t {+ key_left = 1 << 7,
+ key_up = 1 << 6,
+ key_down = 1 << 5,
+ key_select = 1 << 4,
+ key_start = 1 << 3,
+ key_right = 1 << 2,
+ key_opt = 1 << 1,
+ key_edit = 1
+} keycodes_t;
+
typedef enum input_type_t { normal, keyjazz, special } input_type_t; typedef enum special_messages_t {@@ -34,8 +46,6 @@
uint32_t eventType;
} input_msg_s;
-int initialize_game_controllers();
-void close_game_controllers();
input_msg_s get_input_msg(config_params_s *conf);
#endif
--- a/src/main.c
+++ b/src/main.c
@@ -13,6 +13,7 @@
#include "command.h"
#include "config.h"
#include "input.h"
+#include "gamecontrollers.h"
#include "render.h"
#include "serial.h"
#include "slip.h"
@@ -88,7 +89,7 @@
run = QUIT;
// initial scan for (existing) game controllers
- initialize_game_controllers();
+ gamecontrollers_initialize();
#ifdef DEBUG_MSG
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
@@ -172,7 +173,7 @@
if (conf.audio_enabled == 1) {audio_destroy();
}
- close_game_controllers();
+ gamecontrollers_close();
close_renderer();
kill_inline_font();
SDL_free(serial_buf);
@@ -286,7 +287,7 @@
if (conf.audio_enabled == 1) {audio_destroy();
}
- close_game_controllers();
+ gamecontrollers_close();
close_renderer();
close_serial_port();
SDL_free(serial_buf);
--
⑨