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;
}
}
--
⑨