Added support for multiple controllers (Keyboard, Xbox)

Author Mitja Felicijan <mitja.felicijan@gmail.com> 2025-08-09 11:14:14 +0200
Committer Mitja Felicijan <mitja.felicijan@gmail.com> 2025-08-09 11:14:14 +0200
Commit 08939fb0a1e58a57118d28bb3f949fe4821c09d7 (patch)
-rw-r--r-- README.md 1
-rw-r--r-- main.c 74
-rw-r--r-- stdlib/button.lua 20
3 files changed, 81 insertions, 14 deletions
diff --git a/README.md b/README.md
...
136
## Cool tools
136
## Cool tools
137
  
137
  
138
- https://hardwaretester.com/gamepad
138
- https://hardwaretester.com/gamepad
  
139
- https://www.raylib.com/examples/core/loader.html?name=core_input_gamepad
139
  
140
  
140
## Development references
141
## Development references
141
  
142
  
...
diff --git a/main.c b/main.c
...
19
#define DEBUG_LEVEL LOG_DEBUG
19
#define DEBUG_LEVEL LOG_DEBUG
20
#define FONT_IMPORT_SIZE 30
20
#define FONT_IMPORT_SIZE 30
21
#define UID_LENGTH 36
21
#define UID_LENGTH 36
  
22
#define GAMEPAD_INDEX 0
  
23
#define XBOX_ALIAS_1 "xbox"
  
24
#define XBOX_ALIAS_2 "x-box"
  
25
#define PS_ALIAS "playstation"
22
  
26
  
23
typedef struct {
27
typedef struct {
24
	char uid[UID_LENGTH + 1];
28
	char uid[UID_LENGTH + 1];
...
302
}
306
}
303
  
307
  
304
static int l_button_down(lua_State *L) {
308
static int l_button_down(lua_State *L) {
305
	int button = luaL_checknumber(L, 1);
309
	luaL_checktype(L, 1, LUA_TTABLE);
306
	lua_pushboolean(L, IsKeyDown(button));
310
	int keyboard = (int)lua_getfield_int(L, 1, "keyboard");
  
311
	int xbox = (int)lua_getfield_int(L, 1, "xbox");
  
312
	int playstation = (int)lua_getfield_int(L, 1, "playstation");
  
313
	bool is_active = false;
  
314
  
  
315
	// Check keyboard first.
  
316
	if (IsKeyDown(keyboard)) {
  
317
		is_active = true;
  
318
	} else {
  
319
		// FIXME: This does not work currently due to a bug in GLFW that Raylib
  
320
		// is using. SDL could be used to compile Raylib but that doesn't
  
321
		// statically link against SDL so it's not ideal.
  
322
  
  
323
		// Check for controllers otherwise.
  
324
		if (IsGamepadAvailable(GAMEPAD_INDEX)) {
  
325
			// Xbox controller.
  
326
			if (TextFindIndex(TextToLower(GetGamepadName(GAMEPAD_INDEX)), XBOX_ALIAS_1) > -1 || TextFindIndex(TextToLower(GetGamepadName(GAMEPAD_INDEX)), XBOX_ALIAS_2) > -1) {
  
327
				if (IsGamepadButtonDown(GAMEPAD_INDEX, xbox)) {
  
328
					is_active = true;
  
329
				}
  
330
			}
  
331
  
  
332
			// Playstation controller.
  
333
			if (TextFindIndex(TextToLower(GetGamepadName(GAMEPAD_INDEX)), PS_ALIAS) > -1) {
  
334
				if (IsGamepadButtonDown(GAMEPAD_INDEX, playstation)) {
  
335
					is_active = true;
  
336
				}
  
337
			}
  
338
		}
  
339
	}
  
340
  
  
341
	lua_pushboolean(L, is_active);
307
	return 1;
342
	return 1;
308
}
343
}
309
  
344
  
310
static int l_button_pressed(lua_State *L) {
345
static int l_button_pressed(lua_State *L) {
311
	int button = luaL_checknumber(L, 1);
346
	luaL_checktype(L, 1, LUA_TTABLE);
312
	lua_pushboolean(L, IsKeyPressed(button));
347
	int keyboard = (int)lua_getfield_int(L, 1, "keyboard");
  
348
	int xbox = (int)lua_getfield_int(L, 1, "xbox");
  
349
	int playstation = (int)lua_getfield_int(L, 1, "playstation");
  
350
	bool is_active = false;
  
351
  
  
352
	// Check keyboard first.
  
353
	if (IsKeyPressed(keyboard)) {
  
354
		is_active = true;
  
355
	} else {
  
356
		// FIXME: This does not work currently due to a bug in GLFW that Raylib
  
357
		// is using. SDL could be used to compile Raylib but that doesn't
  
358
		// statically link against SDL so it's not ideal.
  
359
  
  
360
		// Check for controllers otherwise.
  
361
		if (IsGamepadAvailable(GAMEPAD_INDEX)) {
  
362
			// Xbox controller.
  
363
			if (TextFindIndex(TextToLower(GetGamepadName(GAMEPAD_INDEX)), XBOX_ALIAS_1) > -1 || TextFindIndex(TextToLower(GetGamepadName(GAMEPAD_INDEX)), XBOX_ALIAS_2) > -1) {
  
364
				if (IsGamepadButtonPressed(GAMEPAD_INDEX, xbox)) {
  
365
					is_active = true;
  
366
				}
  
367
			}
  
368
  
  
369
			// Playstation controller.
  
370
			if (TextFindIndex(TextToLower(GetGamepadName(GAMEPAD_INDEX)), PS_ALIAS) > -1) {
  
371
				if (IsGamepadButtonPressed(GAMEPAD_INDEX, playstation)) {
  
372
					is_active = true;
  
373
				}
  
374
			}
  
375
		}
  
376
	}
  
377
  
  
378
	lua_pushboolean(L, is_active);
313
	return 1;
379
	return 1;
314
}
380
}
315
  
381
  
...
diff --git a/stdlib/button.lua b/stdlib/button.lua
1
local button = {}
1
local button = {}
2
  
2
  
3
button.PAD_UP    = 87  -- Key: W
3
button.PAD_UP    = { keyboard = 87, xbox = 1,  playstation = 0 }  -- Key: W
4
button.PAD_DOWN  = 83  -- Key: S
4
button.PAD_DOWN  = { keyboard = 83, xbox = 3,  playstation = 0 }  -- Key: S
5
button.PAD_LEFT  = 65  -- Key: A
5
button.PAD_LEFT  = { keyboard = 65, xbox = 4,  playstation = 0 }  -- Key: A
6
button.PAD_RIGHT = 68  -- Key: D
6
button.PAD_RIGHT = { keyboard = 68, xbox = 2,  playstation = 0 }  -- Key: D
7
  
7
  
8
button.A         = 76  -- Key: L
8
button.A         = { keyboard = 76, xbox = 7,  playstation = 0 }  -- Key: L
9
button.B         = 80  -- Key: P
9
button.B         = { keyboard = 80, xbox = 6,  playstation = 0 }  -- Key: P
10
button.X         = 75  -- Key: K
10
button.X         = { keyboard = 75, xbox = 8,  playstation = 0 }  -- Key: K
11
button.Y         = 79  -- Key: O
11
button.Y         = { keyboard = 79, xbox = 5,  playstation = 0 }  -- Key: O
12
  
12
  
13
button.SELECT    = 81  -- Key: Q
13
button.SELECT    = { keyboard = 81, xbox = 13, playstation = 0 }  -- Key: Q
14
button.START     = 69  -- Key: E
14
button.START     = { keyboard = 69, xbox = 15, playstation = 0 }  -- Key: E
15
  
15
  
16
return button
16
return button