shithub: m8c

Download patch

ref: e5df91377545372b1481a8d65777d665054140d9
parent: 9ed3e3ad7b229b22593a2bcbd50f15caaa58f3a5
parent: 5a16605b4cf23c91f0a070e7d52ed1dcb93ce552
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Fri Jul 1 04:19:36 EDT 2022

Merge pull request #77 from smootalicious/main

Added config and handling for special game controller buttons to quit and reset display.

--- a/command.c
+++ b/command.c
@@ -134,7 +134,7 @@
 
     SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Invalid packet\n");
     dump_packet(size, recv_buf);
-    return 1;
+    return 0;
     break;
   }
 }
--- a/config.c
+++ b/config.c
@@ -26,6 +26,7 @@
   c.init_use_gpu = 1;    // default to use hardware acceleration
   c.idle_ms = 10;        // default to high performance
   c.wait_for_device = 0; // default to exit if device disconnected
+  c.wait_packets = 128;   // default zero-byte attempts to disconnect (about 2 sec for default idle_ms)
 
   c.key_up = SDL_SCANCODE_UP;
   c.key_left = SDL_SCANCODE_LEFT;
@@ -50,6 +51,8 @@
   c.gamepad_start = SDL_CONTROLLER_BUTTON_START;
   c.gamepad_opt = SDL_CONTROLLER_BUTTON_B;
   c.gamepad_edit = SDL_CONTROLLER_BUTTON_A;
+  c.gamepad_quit = SDL_CONTROLLER_BUTTON_RIGHTSTICK;
+  c.gamepad_reset = SDL_CONTROLLER_BUTTON_LEFTSTICK;
 
   c.gamepad_analog_threshold = 32766;
   c.gamepad_analog_invert = 0;
@@ -74,7 +77,7 @@
 
   SDL_Log("Writing config file to %s", config_path);
 
-  const unsigned int INI_LINE_COUNT = 37;
+  const unsigned int INI_LINE_COUNT = 40;
   const unsigned int LINELEN = 50;
 
   // Entries for the config file
@@ -88,6 +91,7 @@
   snprintf(ini_values[initPointer++], LINELEN, "idle_ms=%d\n", conf->idle_ms);
   snprintf(ini_values[initPointer++], LINELEN, "wait_for_device=%s\n",
            conf->wait_for_device ? "true" : "false");
+  snprintf(ini_values[initPointer++], LINELEN, "wait_packets=%d\n", conf->wait_packets);
   snprintf(ini_values[initPointer++], LINELEN, "[keyboard]\n");
   snprintf(ini_values[initPointer++], LINELEN, "key_up=%d\n", conf->key_up);
   snprintf(ini_values[initPointer++], LINELEN, "key_left=%d\n", conf->key_left);
@@ -129,6 +133,10 @@
            conf->gamepad_opt);
   snprintf(ini_values[initPointer++], LINELEN, "gamepad_edit=%d\n",
            conf->gamepad_edit);
+  snprintf(ini_values[initPointer++], LINELEN, "gamepad_quit=%d\n",
+           conf->gamepad_quit);
+  snprintf(ini_values[initPointer++], LINELEN, "gamepad_reset=%d\n",
+           conf->gamepad_reset);
   snprintf(ini_values[initPointer++], LINELEN, "gamepad_analog_threshold=%d\n",
            conf->gamepad_analog_threshold);
   snprintf(ini_values[initPointer++], LINELEN, "gamepad_analog_invert=%s\n",
@@ -198,6 +206,7 @@
   const char *param_gpu = ini_get(ini, "graphics", "use_gpu");
   const char *idle_ms = ini_get(ini, "graphics", "idle_ms");
   const char *param_wait = ini_get(ini, "graphics", "wait_for_device");
+  const char *wait_packets = ini_get(ini, "graphics", "wait_packets");
 
   if (strcmpci(param_fs, "true") == 0) {
     conf->init_fullscreen = 1;
@@ -221,6 +230,8 @@
       conf->wait_for_device = 0;
     }
   }
+  if (wait_packets != NULL)
+    conf->wait_packets = SDL_atoi(wait_packets);
 }
 
 void read_key_config(ini_t *ini, config_params_s *conf) {
@@ -282,6 +293,8 @@
   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_quit = ini_get(ini, "gamepad", "gamepad_quit");
+  const char *gamepad_reset = ini_get(ini, "gamepad", "gamepad_reset");
   const char *gamepad_analog_threshold =
       ini_get(ini, "gamepad", "gamepad_analog_threshold");
   const char *gamepad_analog_invert =
@@ -315,6 +328,10 @@
     conf->gamepad_opt = SDL_atoi(gamepad_opt);
   if (gamepad_edit)
     conf->gamepad_edit = SDL_atoi(gamepad_edit);
+  if (gamepad_quit)
+    conf->gamepad_quit = SDL_atoi(gamepad_quit);
+  if (gamepad_reset)
+    conf->gamepad_reset = SDL_atoi(gamepad_reset);
   if (gamepad_analog_threshold)
     conf->gamepad_analog_threshold = SDL_atoi(gamepad_analog_threshold);
 
--- a/config.h
+++ b/config.h
@@ -12,6 +12,7 @@
   int init_use_gpu;
   int idle_ms;
   int wait_for_device;
+  int wait_packets;
 
   int key_up;
   int key_left;
@@ -36,6 +37,8 @@
   int gamepad_start;
   int gamepad_opt;
   int gamepad_edit;
+  int gamepad_quit;
+  int gamepad_reset;
 
   int gamepad_analog_threshold;
   int gamepad_analog_invert;
--- a/config.ini.sample
+++ b/config.ini.sample
@@ -12,6 +12,8 @@
 idle_ms = 10
 ; show a spinning cube if device is not inserted
 wait_for_device = true
+; number of zero-byte attempts to disconnect if wait_for_device = false (128 = about 2 sec for default idle_ms)
+wait_packets = 128
 
 [keyboard]
 ; these need to be the decimal value of the SDL scancodes.
@@ -42,6 +44,8 @@
 gamepad_start=6
 gamepad_opt=1
 gamepad_edit=0
+gamepad_quit=8
+gamepad_reset=7
 
 gamepad_analog_threshold=32766 ;the threshold for analog sticks to trigger cursor movement (working values: 1-32766)
 gamepad_analog_invert=false ;NOT IMPLEMENTED YET: invert up/down and left/right axis (true/false)
--- a/gamecontrollerdb.txt
+++ b/gamecontrollerdb.txt
@@ -887,6 +887,19 @@
 xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
 03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
 03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+# rk3326 devices
+#Odroid Go Advance 1.0 and RK2020
+190000004b4800000010000000010000,GO-Advance Gamepad,a:b1,b:b0,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,leftx:a0,lefty:a1,back:b10,lefttrigger:b12,righttrigger:b13,start:b15,platform:Linux,
+#Odroid Go Advance 1.1 and RGB10 
+190000004b4800000010000001010000,GO-Advance Gamepad (rev 1.1),a:b1,b:b0,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftx:a0,lefty:a1,righttrigger:b15,leftstick:b13,lefttrigger:b14,rightstick:b16,back:b12,start:b17,platform:Linux,
+#RG351M, RG351P, and RG351V
+03000000091200000031000011010000,OpenSimHardware OSH PB Controller,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0~,lefty:a1~,guide:b12,leftstick:b8,lefttrigger:b10,rightstick:b9,back:b7,start:b6,rightx:a2,righty:a3,righttrigger:b11,platform:Linux,
+#Odroid Go Super, RG351MP, RGB10Max, and RGB10Max2
+190000004b4800000011000000010000,GO-Super Gamepad,x:b2,a:b1,b:b0,y:b3,back:b12,guide:b16,start:b13,dpleft:b10,dpdown:b9,dpright:b11,dpup:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b14,rightstick:b15,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux,
+#Gameforce Chi
+19000000030000000300000002030000,gameforce_gamepad,leftstick:b14,rightx:a3,leftshoulder:b4,start:b9,lefty:a0,dpup:b10,righty:a2,a:b1,b:b0,back:b8,dpdown:b11,rightshoulder:b5,righttrigger:b7,rightstick:b15,dpright:b13,x:b2,guide:b16,leftx:a1,y:b3,dpleft:b12,lefttrigger:b6,platform:Linux,
+#RG552
+190000004b4800000111000000010000,retrogame_joypad,a:b1,b:b0,x:b2,y:b3,back:b8,start:b9,rightstick:b12,leftstick:b11,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux,
 
 # Android
 05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,platform:Android,
--- a/input.c
+++ b/input.c
@@ -49,24 +49,18 @@
   SDL_Delay(
       10); // Some controllers like XBone wired need a little while to get ready
 
-  // 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++;
-  }
-
   // 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");
+  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);
@@ -80,6 +74,18 @@
                  "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;
 }
 
@@ -355,6 +361,17 @@
   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)) {
+    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)) {
+    key = (input_msg_s){special, msg_reset_display};
+   }
   }
 
   SDL_PollEvent(&event);
--- a/input.h
+++ b/input.h
@@ -36,6 +36,7 @@
   uint32_t eventType;
 } input_msg_s;
 
+int initialize_game_controllers();
 void close_game_controllers();
 input_msg_s get_input_msg();
 
--- a/main.c
+++ b/main.c
@@ -82,6 +82,9 @@
   if (initialize_sdl(conf.init_fullscreen, conf.init_use_gpu) == -1)
     run = QUIT;
 
+  // initial scan for (existing) game controllers
+  initialize_game_controllers();
+
 #ifdef DEBUG_MSG
   SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
 #endif
@@ -96,6 +99,7 @@
       if (result == 1) {
         run = RUN;
       } else {
+        SDL_LogCritical(SDL_LOG_CATEGORY_ERROR,"Device not detected on begin loop.");
         run = QUIT;
       }
     }
@@ -112,6 +116,7 @@
         // get current inputs
         input_msg_s input = get_input_msg(&conf);
         if (input.type == special && input.value == msg_quit) {
+          SDL_LogCritical(SDL_LOG_CATEGORY_ERROR,"Input message QUIT.");
           run = QUIT;
         }
 
@@ -133,6 +138,7 @@
               run = RUN;
               screensaver_destroy();
             } else {
+              SDL_LogCritical(SDL_LOG_CATEGORY_ERROR,"Device not detected.");
               run = QUIT;
               screensaver_destroy();
             }
@@ -159,6 +165,7 @@
       // get current inputs
       input_msg_s input = get_input_msg(&conf);
 
+      if (input.value != 0) zerobyte_packets = 0; // don't try to detect disconnect until user stops pressing buttons 
       switch (input.type) {
       case normal:
         if (input.value != prev_input) {
@@ -182,6 +189,7 @@
           prev_input = input.value;
           switch (input.value) {
           case msg_quit:
+            SDL_Log("Received msg_quit from input device.");
             run = 0;
             break;
           case msg_reset_display:
@@ -223,14 +231,16 @@
         } else {
           // zero byte packet, increment counter
           zerobyte_packets++;
-          if (zerobyte_packets > 128) {
+          if (zerobyte_packets > conf.wait_packets) {
             // i guess it can be assumed that the device has been disconnected
             if (conf.wait_for_device) {
+              zerobyte_packets = 0; // reset so we dont constantly reset the device if waiting
               run = WAIT_FOR_DEVICE;
               close_serial_port(port);
               port = NULL;
               break;
             } else {
+              SDL_LogCritical(SDL_LOG_CATEGORY_ERROR,"Device disconnect detected.");
               run = QUIT;
             }
           }
--