Skip to content

Commit 96574b7

Browse files
committed
#157 split game controller related functions to a separate file
1 parent 7bf257a commit 96574b7

File tree

6 files changed

+192
-160
lines changed

6 files changed

+192
-160
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#Set all your object files (the object files of all the .c files in your project, e.g. main.o my_sub_functions.o )
2-
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
2+
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
33

44
#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
5-
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
5+
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
66

77
#Any special libraries you are using in your project (e.g. -lbcm2835 -lrt `pkg-config --libs gtk+-3.0` ), or leave blank
88
INCLUDES = $(shell pkg-config --libs sdl2 libserialport | sed 's/-mwindows//')

src/gamecontrollers.c

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
//
2+
// Created by jonne on 8/19/24.
3+
//
4+
5+
#include "gamecontrollers.h"
6+
#include "config.h"
7+
#include "input.h"
8+
9+
#include <SDL.h>
10+
11+
static int num_joysticks = 0;
12+
SDL_GameController *game_controllers[MAX_CONTROLLERS];
13+
14+
// Opens available game controllers and returns the amount of opened controllers
15+
int gamecontrollers_initialize() {
16+
17+
num_joysticks = SDL_NumJoysticks();
18+
int controller_index = 0;
19+
20+
SDL_Log("Looking for game controllers");
21+
SDL_Delay(10); // Some controllers like XBone wired need a little while to get ready
22+
23+
// Try to load the game controller database file
24+
char db_filename[1024] = {0};
25+
snprintf(db_filename, sizeof(db_filename), "%sgamecontrollerdb.txt", SDL_GetPrefPath("", "m8c"));
26+
SDL_Log("Trying to open game controller database from %s", db_filename);
27+
SDL_RWops *db_rw = SDL_RWFromFile(db_filename, "rb");
28+
if (db_rw == NULL) {
29+
snprintf(db_filename, sizeof(db_filename), "%sgamecontrollerdb.txt", SDL_GetBasePath());
30+
SDL_Log("Trying to open game controller database from %s", db_filename);
31+
db_rw = SDL_RWFromFile(db_filename, "rb");
32+
}
33+
34+
if (db_rw != NULL) {
35+
int mappings = SDL_GameControllerAddMappingsFromRW(db_rw, 1);
36+
if (mappings != -1)
37+
SDL_Log("Found %d game controller mappings", mappings);
38+
else
39+
SDL_LogError(SDL_LOG_CATEGORY_INPUT, "Error loading game controller mappings.");
40+
} else {
41+
SDL_LogError(SDL_LOG_CATEGORY_INPUT, "Unable to open game controller database file.");
42+
}
43+
44+
// Open all available game controllers
45+
for (int i = 0; i < num_joysticks; i++) {
46+
if (!SDL_IsGameController(i))
47+
continue;
48+
if (controller_index >= MAX_CONTROLLERS)
49+
break;
50+
game_controllers[controller_index] = SDL_GameControllerOpen(i);
51+
SDL_Log("Controller %d: %s", controller_index + 1,
52+
SDL_GameControllerName(game_controllers[controller_index]));
53+
controller_index++;
54+
}
55+
56+
return controller_index;
57+
}
58+
59+
// Closes all open game controllers
60+
void gamecontrollers_close() {
61+
62+
for (int i = 0; i < MAX_CONTROLLERS; i++) {
63+
if (game_controllers[i])
64+
SDL_GameControllerClose(game_controllers[i]);
65+
}
66+
}
67+
68+
// Check whether a button is pressed on a gamepad and return 1 if pressed.
69+
static int get_game_controller_button(config_params_s *conf, SDL_GameController *controller,
70+
int button) {
71+
72+
const int button_mappings[8] = {conf->gamepad_up, conf->gamepad_down, conf->gamepad_left,
73+
conf->gamepad_right, conf->gamepad_opt, conf->gamepad_edit,
74+
conf->gamepad_select, conf->gamepad_start};
75+
76+
// Check digital buttons
77+
if (SDL_GameControllerGetButton(controller, button_mappings[button])) {
78+
return 1;
79+
}
80+
81+
// If digital button isn't pressed, check the corresponding analog control
82+
switch (button) {
83+
case INPUT_UP:
84+
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_updown) <
85+
-conf->gamepad_analog_threshold;
86+
case INPUT_DOWN:
87+
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_updown) >
88+
conf->gamepad_analog_threshold;
89+
case INPUT_LEFT:
90+
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_leftright) <
91+
-conf->gamepad_analog_threshold;
92+
case INPUT_RIGHT:
93+
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_leftright) >
94+
conf->gamepad_analog_threshold;
95+
case INPUT_OPT:
96+
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_opt) >
97+
conf->gamepad_analog_threshold;
98+
case INPUT_EDIT:
99+
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_edit) >
100+
conf->gamepad_analog_threshold;
101+
case INPUT_SELECT:
102+
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_select) >
103+
conf->gamepad_analog_threshold;
104+
case INPUT_START:
105+
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_start) >
106+
conf->gamepad_analog_threshold;
107+
default:
108+
return 0;
109+
}
110+
}
111+
112+
// Handle game controllers, simply check all buttons and analog axis on every
113+
// cycle
114+
int gamecontrollers_handle_buttons(config_params_s *conf) {
115+
116+
const int keycodes[8] = {key_up, key_down, key_left, key_right,
117+
key_opt, key_edit, key_select, key_start};
118+
119+
int key = 0;
120+
121+
// Cycle through every active game controller
122+
for (int gc = 0; gc < num_joysticks; gc++) {
123+
// Cycle through all M8 buttons
124+
for (int button = 0; button < INPUT_MAX; button++) {
125+
// If the button is active, add the keycode to the variable containing
126+
// active keys
127+
if (get_game_controller_button(conf, game_controllers[gc], button)) {
128+
key |= keycodes[button];
129+
}
130+
}
131+
}
132+
133+
return key;
134+
}
135+
136+
input_msg_s gamecontrollers_handle_special_messages(config_params_s *conf) {
137+
input_msg_s msg = {0};
138+
// Read special case game controller buttons quit and reset
139+
for (int gc = 0; gc < num_joysticks; gc++) {
140+
if (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_quit) &&
141+
(SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_select) ||
142+
SDL_GameControllerGetAxis(game_controllers[gc], conf->gamepad_analog_axis_select)))
143+
msg = (input_msg_s){special, msg_quit};
144+
else if (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_reset) &&
145+
(SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_select) ||
146+
SDL_GameControllerGetAxis(game_controllers[gc], conf->gamepad_analog_axis_select)))
147+
msg = (input_msg_s){special, msg_reset_display};
148+
}
149+
return msg;
150+
}

src/gamecontrollers.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// Created by jonne on 8/19/24.
3+
//
4+
5+
#ifndef GAMECONTROLLERS_H_
6+
#define GAMECONTROLLERS_H_
7+
8+
#include "config.h"
9+
#include "input.h"
10+
#include <SDL_gamecontroller.h>
11+
12+
#define MAX_CONTROLLERS 4
13+
14+
int gamecontrollers_initialize();
15+
void gamecontrollers_close();
16+
int gamecontrollers_handle_buttons(config_params_s *conf);
17+
input_msg_s gamecontrollers_handle_special_messages(config_params_s *conf);
18+
19+
#endif //GAMECONTROLLERS_H_

src/input.c

Lines changed: 5 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,13 @@
77
#include "config.h"
88
#include "input.h"
99
#include "render.h"
10-
11-
#define MAX_CONTROLLERS 4
12-
13-
SDL_GameController *game_controllers[MAX_CONTROLLERS];
14-
15-
// Bits for M8 input messages
16-
enum keycodes {
17-
key_left = 1 << 7,
18-
key_up = 1 << 6,
19-
key_down = 1 << 5,
20-
key_select = 1 << 4,
21-
key_start = 1 << 3,
22-
key_right = 1 << 2,
23-
key_opt = 1 << 1,
24-
key_edit = 1
25-
};
10+
#include "gamecontrollers.h"
2611

2712
uint8_t keyjazz_enabled = 0;
2813
uint8_t keyjazz_base_octave = 2;
2914
uint8_t keyjazz_velocity = 0x64;
3015

3116
static uint8_t keycode = 0; // value of the pressed key
32-
static int num_joysticks = 0;
3317

3418
static input_msg_s key = {normal, 0};
3519

@@ -39,60 +23,6 @@ uint8_t toggle_input_keyjazz() {
3923
return keyjazz_enabled;
4024
}
4125

42-
// Opens available game controllers and returns the amount of opened controllers
43-
int initialize_game_controllers() {
44-
45-
num_joysticks = SDL_NumJoysticks();
46-
int controller_index = 0;
47-
48-
SDL_Log("Looking for game controllers\n");
49-
SDL_Delay(10); // Some controllers like XBone wired need a little while to get ready
50-
51-
// Try to load the game controller database file
52-
char db_filename[1024] = {0};
53-
snprintf(db_filename, sizeof(db_filename), "%sgamecontrollerdb.txt", SDL_GetPrefPath("", "m8c"));
54-
SDL_Log("Trying to open game controller database from %s", db_filename);
55-
SDL_RWops *db_rw = SDL_RWFromFile(db_filename, "rb");
56-
if (db_rw == NULL) {
57-
snprintf(db_filename, sizeof(db_filename), "%sgamecontrollerdb.txt", SDL_GetBasePath());
58-
SDL_Log("Trying to open game controller database from %s", db_filename);
59-
db_rw = SDL_RWFromFile(db_filename, "rb");
60-
}
61-
62-
if (db_rw != NULL) {
63-
int mappings = SDL_GameControllerAddMappingsFromRW(db_rw, 1);
64-
if (mappings != -1)
65-
SDL_Log("Found %d game controller mappings", mappings);
66-
else
67-
SDL_LogError(SDL_LOG_CATEGORY_INPUT, "Error loading game controller mappings.");
68-
} else {
69-
SDL_LogError(SDL_LOG_CATEGORY_INPUT, "Unable to open game controller database file.");
70-
}
71-
72-
// Open all available game controllers
73-
for (int i = 0; i < num_joysticks; i++) {
74-
if (!SDL_IsGameController(i))
75-
continue;
76-
if (controller_index >= MAX_CONTROLLERS)
77-
break;
78-
game_controllers[controller_index] = SDL_GameControllerOpen(i);
79-
SDL_Log("Controller %d: %s", controller_index + 1,
80-
SDL_GameControllerName(game_controllers[controller_index]));
81-
controller_index++;
82-
}
83-
84-
return controller_index;
85-
}
86-
87-
// Closes all open game controllers
88-
void close_game_controllers() {
89-
90-
for (int i = 0; i < MAX_CONTROLLERS; i++) {
91-
if (game_controllers[i])
92-
SDL_GameControllerClose(game_controllers[i]);
93-
}
94-
}
95-
9626
static input_msg_s handle_keyjazz(SDL_Event *event, uint8_t keyvalue, config_params_s *conf) {
9727
input_msg_s key = {keyjazz, keyvalue, keyjazz_velocity, event->type};
9828
switch (event->key.keysym.scancode) {
@@ -259,75 +189,6 @@ static input_msg_s handle_normal_keys(SDL_Event *event, config_params_s *conf, u
259189
return key;
260190
}
261191

262-
// Check whether a button is pressed on a gamepad and return 1 if pressed.
263-
static int get_game_controller_button(config_params_s *conf, SDL_GameController *controller,
264-
int button) {
265-
266-
const int button_mappings[8] = {conf->gamepad_up, conf->gamepad_down, conf->gamepad_left,
267-
conf->gamepad_right, conf->gamepad_opt, conf->gamepad_edit,
268-
conf->gamepad_select, conf->gamepad_start};
269-
270-
// Check digital buttons
271-
if (SDL_GameControllerGetButton(controller, button_mappings[button])) {
272-
return 1;
273-
}
274-
275-
// If digital button isn't pressed, check the corresponding analog control
276-
switch (button) {
277-
case INPUT_UP:
278-
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_updown) <
279-
-conf->gamepad_analog_threshold;
280-
case INPUT_DOWN:
281-
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_updown) >
282-
conf->gamepad_analog_threshold;
283-
case INPUT_LEFT:
284-
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_leftright) <
285-
-conf->gamepad_analog_threshold;
286-
case INPUT_RIGHT:
287-
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_leftright) >
288-
conf->gamepad_analog_threshold;
289-
case INPUT_OPT:
290-
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_opt) >
291-
conf->gamepad_analog_threshold;
292-
case INPUT_EDIT:
293-
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_edit) >
294-
conf->gamepad_analog_threshold;
295-
case INPUT_SELECT:
296-
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_select) >
297-
conf->gamepad_analog_threshold;
298-
case INPUT_START:
299-
return SDL_GameControllerGetAxis(controller, conf->gamepad_analog_axis_start) >
300-
conf->gamepad_analog_threshold;
301-
default:
302-
return 0;
303-
}
304-
return 0;
305-
}
306-
307-
// Handle game controllers, simply check all buttons and analog axis on every
308-
// cycle
309-
static int handle_game_controller_buttons(config_params_s *conf) {
310-
311-
const int keycodes[8] = {key_up, key_down, key_left, key_right,
312-
key_opt, key_edit, key_select, key_start};
313-
314-
int key = 0;
315-
316-
// Cycle through every active game controller
317-
for (int gc = 0; gc < num_joysticks; gc++) {
318-
// Cycle through all M8 buttons
319-
for (int button = 0; button < INPUT_MAX; button++) {
320-
// If the button is active, add the keycode to the variable containing
321-
// active keys
322-
if (get_game_controller_button(conf, game_controllers[gc], button)) {
323-
key |= keycodes[button];
324-
}
325-
}
326-
}
327-
328-
return key;
329-
}
330-
331192
// Handles SDL input events
332193
void handle_sdl_events(config_params_s *conf) {
333194

@@ -336,23 +197,14 @@ void handle_sdl_events(config_params_s *conf) {
336197
SDL_Event event;
337198

338199
// Read joysticks
339-
int key_analog = handle_game_controller_buttons(conf);
200+
int key_analog = gamecontrollers_handle_buttons(conf);
340201
if (prev_key_analog != key_analog) {
341202
keycode = key_analog;
342203
prev_key_analog = key_analog;
343204
}
344205

345-
// Read special case game controller buttons quit and reset
346-
for (int gc = 0; gc < num_joysticks; gc++) {
347-
if (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_quit) &&
348-
(SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_select) ||
349-
SDL_GameControllerGetAxis(game_controllers[gc], conf->gamepad_analog_axis_select)))
350-
key = (input_msg_s){special, msg_quit};
351-
else if (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_reset) &&
352-
(SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_select) ||
353-
SDL_GameControllerGetAxis(game_controllers[gc], conf->gamepad_analog_axis_select)))
354-
key = (input_msg_s){special, msg_reset_display};
355-
}
206+
input_msg_s gcmsg = gamecontrollers_handle_special_messages(conf);
207+
if (gcmsg.type == special) { key = gcmsg; }
356208

357209
while (SDL_PollEvent(&event)) {
358210

@@ -361,7 +213,7 @@ void handle_sdl_events(config_params_s *conf) {
361213
// Reinitialize game controllers on controller add/remove/remap
362214
case SDL_CONTROLLERDEVICEADDED:
363215
case SDL_CONTROLLERDEVICEREMOVED:
364-
initialize_game_controllers();
216+
gamecontrollers_initialize();
365217
break;
366218

367219
// Handle SDL quit events (for example, window close)

0 commit comments

Comments
 (0)