shithub: m8c

Download patch

ref: d6ac873907cc4f8e3b3b0754d88044c239a1fe29
parent: 5faa340a8137b82aaa7039bc57642df300daf3df
author: Jeff Alyanak <jeff@alyanak.ca>
date: Sun Oct 3 11:56:18 EDT 2021

Config file now allows for custom key/pad map

Keyboard and gamepad keys can now be mapped in the config file and are loaded on startup.

These currently have to be done as SDL keycodes, but I've included in the comments of the config the requisite links to the lookup tables.

--- a/config.c
+++ b/config.c
@@ -10,11 +10,34 @@
   c.filename        = "config.ini"; // default config file to load
   c.init_fullscreen = 0;            // default fullscreen state at load
 
+  c.key_up          = SDL_SCANCODE_UP;
+  c.key_left        = SDL_SCANCODE_LEFT;
+  c.key_down        = SDL_SCANCODE_DOWN;
+  c.key_right       = SDL_SCANCODE_RIGHT;
+  c.key_select      = SDL_SCANCODE_LSHIFT;
+  c.key_select_alt  = SDL_SCANCODE_A;
+  c.key_start       = SDL_SCANCODE_SPACE;
+  c.key_start_alt   = SDL_SCANCODE_S;
+  c.key_opt         = SDL_SCANCODE_LALT;
+  c.key_opt_alt     = SDL_SCANCODE_Z;
+  c.key_edit        = SDL_SCANCODE_LCTRL;
+  c.key_edit_alt    = SDL_SCANCODE_X;
+  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;
   return c;
 }
 
 // Read config 
-void read_config(struct config_params_s *conf) {
+void read_config(config_params_s *conf) {
   // Load the config and read the fullscreen setting from the graphics section
   ini_t *ini = ini_load(conf->filename);
   if (ini == NULL) {
@@ -21,17 +44,75 @@
     return;
   }
 
-  conf->init_fullscreen = read_fullscreen(ini);
+  read_graphics_config(ini, conf);
+  read_key_config(ini, conf);
+  read_gamepad_config(ini, conf);
 
   // Frees the mem used for the config
   ini_free(ini);
 }
 
-int read_fullscreen(ini_t *config) {
-  const char *param = ini_get(config, "graphics", "fullscreen");
+void read_graphics_config(ini_t *ini, config_params_s *conf) {
+  const char *param = ini_get(ini, "graphics", "fullscreen");
   // This obviously requires the parameter to be a lowercase true to enable fullscreen
   if ( strcmp(param, "true") == 0 ) {
-    return 1;
+    conf->init_fullscreen = 1;
   }
-  else return 0;
+  else conf->init_fullscreen = 0;
+}
+
+void read_key_config(ini_t *ini, config_params_s *conf) {
+  // TODO: Some form of validation
+
+  const char *key_up          = ini_get(ini, "keyboard", "key_up");
+  const char *key_left        = ini_get(ini, "keyboard", "key_left");
+  const char *key_down        = ini_get(ini, "keyboard", "key_down");
+  const char *key_right       = ini_get(ini, "keyboard", "key_right");
+  const char *key_select      = ini_get(ini, "keyboard", "key_select");
+  const char *key_select_alt  = ini_get(ini, "keyboard", "key_select_alt");
+  const char *key_start       = ini_get(ini, "keyboard", "key_start");
+  const char *key_start_alt   = ini_get(ini, "keyboard", "key_start_alt");
+  const char *key_opt         = ini_get(ini, "keyboard", "key_opt");
+  const char *key_opt_alt     = ini_get(ini, "keyboard", "key_opt_alt");
+  const char *key_edit        = ini_get(ini, "keyboard", "key_edit");
+  const char *key_edit_alt    = ini_get(ini, "keyboard", "key_edit_alt");
+  const char *key_delete      = ini_get(ini, "keyboard", "key_delete");
+  const char *key_reset       = ini_get(ini, "keyboard", "key_reset");
+
+  conf->key_up          = atoi(key_up);
+  conf->key_left        = atoi(key_left);
+  conf->key_down        = atoi(key_down);
+  conf->key_right       = atoi(key_right);
+  conf->key_select      = atoi(key_select);
+  conf->key_select_alt  = atoi(key_select_alt);
+  conf->key_start       = atoi(key_start);
+  conf->key_start_alt   = atoi(key_start_alt);
+  conf->key_opt         = atoi(key_opt);
+  conf->key_opt_alt     = atoi(key_opt_alt);
+  conf->key_edit        = atoi(key_edit);
+  conf->key_edit_alt    = atoi(key_edit_alt);
+  conf->key_delete      = atoi(key_delete);
+  conf->key_reset       = atoi(key_reset);
+}
+
+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");
+
+  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);
 }
\ No newline at end of file
--- a/config.h
+++ b/config.h
@@ -9,11 +9,37 @@
 typedef struct config_params_s {
   char *filename;
   int init_fullscreen;
+
+  int key_up;
+  int key_left;
+  int key_down;
+  int key_right;
+  int key_select;
+  int key_select_alt;
+  int key_start;
+  int key_start_alt;
+  int key_opt;
+  int key_opt_alt;
+  int key_edit;
+  int key_edit_alt;
+  int key_delete;
+  int key_reset;
+
+  int gamepad_up;
+  int gamepad_left;
+  int gamepad_down;
+  int gamepad_right;
+  int gamepad_select;
+  int gamepad_start;
+  int gamepad_opt;
+  int gamepad_edit;
 } config_params_s;
 
 
 config_params_s init_config();
 void read_config();
-int read_fullscreen(ini_t *config);
+void read_graphics_config(ini_t *config, config_params_s *conf);
+void read_key_config(ini_t *config, config_params_s *conf);
+void read_gamepad_config(ini_t *config, config_params_s *conf);
 
 #endif
\ No newline at end of file
--- a/config.ini
+++ b/config.ini
@@ -1,3 +1,33 @@
 [graphics]
 ; set this to true to have m8c start fullscreen
-fullscreen=true
+fullscreen=false
+
+[keyboard]
+; these need to be the decimal value of the SDL scancodes.
+; a table exists here: https://github.com/libsdl-org/sdlwiki/blob/main/SDLScancodeLookup.mediawiki
+key_up=82
+key_left=80
+key_down=81
+key_right=79
+key_select=225
+key_select_alt=4
+key_start=44
+key_start_alt=22
+key_opt=226
+key_opt_alt=29
+key_edit=224
+key_edit_alt=27
+key_delete=76
+key_reset=21
+
+[gamepad]
+; these need to be the decimal value of the SDL Controller buttons.
+; a table exists here: https://wiki.libsdl.org/SDL_GameControllerButton
+gamepad_up=11
+gamepad_left=13
+gamepad_down=12
+gamepad_right=14
+gamepad_select=4
+gamepad_start=6
+gamepad_opt=1
+gamepad_edit=0
\ No newline at end of file
--- a/input.c
+++ b/input.c
@@ -4,6 +4,7 @@
 #include <SDL2/SDL.h>
 #include <stdio.h>
 
+#include "config.h"
 #include "input.h"
 #include "render.h"
 #include "write.h"
@@ -183,108 +184,62 @@
   return key;
 }
 
-static input_msg_s handle_normal_keys(SDL_Event *event, uint8_t keyvalue) {
+static input_msg_s handle_normal_keys(SDL_Event *event, config_params_s *conf, uint8_t keyvalue) {
   input_msg_s key = {normal, keyvalue};
-  switch (event->key.keysym.scancode) {
 
-  case SDL_SCANCODE_UP:
+  if (event->key.keysym.scancode == conf->key_up) {
     key.value = key_up;
-    break;
-
-  case SDL_SCANCODE_LEFT:
+  } else if (event->key.keysym.scancode == conf->key_left) {
     key.value = key_left;
-    break;
-
-  case SDL_SCANCODE_DOWN:
+  } else if (event->key.keysym.scancode == conf->key_down) {
     key.value = key_down;
-    break;
-
-  case SDL_SCANCODE_RIGHT:
+  } else if (event->key.keysym.scancode == conf->key_right) {
     key.value = key_right;
-    break;
-
-  case SDL_SCANCODE_LSHIFT:
-  case SDL_SCANCODE_A:
+  } else if (event->key.keysym.scancode == conf->key_select || event->key.keysym.scancode == conf->key_select_alt ) {
     key.value = key_select;
-    break;
-
-  case SDL_SCANCODE_SPACE:
-  case SDL_SCANCODE_S:
+  } else if (event->key.keysym.scancode == conf->key_start || event->key.keysym.scancode == conf->key_start_alt) {
     key.value = key_start;
-    break;
-
-  case SDL_SCANCODE_LALT:
-  case SDL_SCANCODE_Z:
+  } else if (event->key.keysym.scancode == conf->key_opt || event->key.keysym.scancode == conf->key_opt_alt) {
     key.value = key_opt;
-    break;
-
-  case SDL_SCANCODE_LCTRL:
-  case SDL_SCANCODE_X:
+  } else if (event->key.keysym.scancode == conf->key_edit || event->key.keysym.scancode == conf->key_edit_alt) {
     key.value = key_edit;
-    break;
-
-  case SDL_SCANCODE_DELETE:
+  } else if (event->key.keysym.scancode == conf->key_delete) {
     key.value = key_opt | key_edit;
-    break;
-
-  case SDL_SCANCODE_R:
+  } else if (event->key.keysym.scancode == conf->key_reset) {
     key = (input_msg_s){special, msg_reset_display};
-    break;
-
-  default:
+  } else {
     key.value = 0;
-    break;
   }
   return key;
 }
 
-static input_msg_s handle_game_controller_buttons(SDL_Event *event,
-                                                  uint8_t keyvalue) {
+static input_msg_s handle_game_controller_buttons(SDL_Event *event, config_params_s *conf, uint8_t keyvalue) {
   input_msg_s key = {normal, keyvalue};
-  switch (event->cbutton.button) {
 
-  case SDL_CONTROLLER_BUTTON_DPAD_UP:
+  if (event->cbutton.button == conf->gamepad_up) {
     key.value = key_up;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
-    key.value = key_down;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
+  } else if (event->cbutton.button == conf->gamepad_left) {
     key.value = key_left;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
+  } else if (event->cbutton.button == conf->gamepad_down) {
+    key.value = key_down;
+  } else if (event->cbutton.button == conf->gamepad_right) {
     key.value = key_right;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_BACK:
+  } else if (event->cbutton.button == conf->gamepad_select) {
     key.value = key_select;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_START:
+  } else if (event->cbutton.button == conf->gamepad_start) {
     key.value = key_start;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_B:
-    key.value = key_edit;
-    break;
-
-  case SDL_CONTROLLER_BUTTON_A:
+  } else if (event->cbutton.button == conf->gamepad_opt) {
     key.value = key_opt;
-    break;
-
-  default:
+  } else if (event->cbutton.button == conf->gamepad_edit) {
+    key.value = key_edit;
+  } else {
     key.value = 0;
-    break;
   }
-
   return key;
 }
 
 // Handles SDL input events
-void handle_sdl_events() {
+void handle_sdl_events(config_params_s *conf) {
 
   SDL_Event event;
 
@@ -326,7 +281,7 @@
 
   // Normal keyboard inputs
   case SDL_KEYUP:
-    key = handle_normal_keys(&event, 0);
+    key = handle_normal_keys(&event, conf, 0);
 
     if (keyjazz_enabled)
       key = handle_keyjazz(&event, key.value);
@@ -335,7 +290,7 @@
   // Game controller events
   case SDL_CONTROLLERBUTTONDOWN:
   case SDL_CONTROLLERBUTTONUP:
-    key = handle_game_controller_buttons(&event, 0);
+    key = handle_game_controller_buttons(&event, conf, 0);
     break;
 
   default:
@@ -357,12 +312,12 @@
 }
 
 // Returns the currently pressed keys to main
-input_msg_s get_input_msg() {
+input_msg_s get_input_msg(config_params_s *conf) {
 
   key = (input_msg_s){normal, 0};
 
   // Query for SDL events
-  handle_sdl_events();
+  handle_sdl_events(conf);
 
   if (keycode == (key_start|key_select|key_opt|key_edit)){
     key = (input_msg_s){special,msg_reset_display};
--- a/main.c
+++ b/main.c
@@ -70,7 +70,7 @@
   while (run) {
 
     // get current inputs
-    input_msg_s input = get_input_msg();
+    input_msg_s input = get_input_msg(&conf);
 
     switch (input.type) {
     case normal:
--