shithub: m8c

Download patch

ref: 96574b7204a58cf4f50bb2774b89ab9fcb7bf6cd
parent: 7bf257a35ab14872f1bb1fe0f504b5dc0d5765a1
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Mon Aug 19 10:18:13 EDT 2024

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