From fed9b718198ce36bb1f81a1a139e1aecb8a00016 Mon Sep 17 00:00:00 2001
From: xLuigiGamerx <88401287+xLuigiGamerx@users.noreply.github.com>
Date: Sat, 22 Nov 2025 19:10:42 +0300
Subject: [PATCH] Addressing Peachy reviews
---
Makefile | 11 +-
autogen/convert_functions.py | 1 +
autogen/convert_structs.py | 1 +
autogen/lua_definitions/constants.lua | 3 +
autogen/lua_definitions/functions.lua | 12 ++
autogen/lua_definitions/manual.lua | 2 +-
autogen/lua_definitions/structs.lua | 25 +--
.../controller_gamepad.db | 0
docs/lua/constants.md | 1 +
docs/lua/functions-6.md | 44 +++++
docs/lua/functions.md | 2 +
docs/lua/globals.md | 2 +-
docs/lua/structs.md | 43 ++---
lang/English.ini | 1 +
src/pc/controller/controller_keyboard.c | 19 +--
src/pc/controller/controller_keyboard.h | 4 +
src/pc/controller/controller_sdl2.c | 108 ++++++------
src/pc/gfx/gfx_sdl1.c | 4 +-
src/pc/gfx/gfx_sdl2.c | 4 +-
src/pc/lua/smlua_cobject.c | 2 +-
src/pc/lua/smlua_cobject_autogen.c | 71 ++++----
src/pc/lua/smlua_cobject_autogen.h | 4 +-
src/pc/lua/smlua_constants_autogen.c | 1 +
src/pc/lua/smlua_functions_autogen.c | 34 ++++
src/pc/lua/utils/smlua_input_utils.c | 156 +++++++++++++++++-
src/pc/lua/utils/smlua_input_utils.h | 36 +++-
src/pc/mods/mod_import.c | 56 +++++++
src/pc/network/network.c | 28 ----
28 files changed, 489 insertions(+), 186 deletions(-)
rename {src/pc/controller => databases}/controller_gamepad.db (100%)
diff --git a/Makefile b/Makefile
index 94eb9478f..740b2d543 100644
--- a/Makefile
+++ b/Makefile
@@ -632,6 +632,11 @@ PALETTES_DIR := palettes
# Remove old palettes dir
_ := $(shell rm -rf ./$(BUILD_DIR)/$(PALETTES_DIR))
+DATABASES_DIR := databases
+
+# Remove old databases dir
+_ := $(shell rm -rf ./$(BUILD_DIR)/$(DATABASES_DIR))
+
# Automatic dependency files
DEP_FILES := $(O_FILES:.o=.d) $(ULTRA_O_FILES:.o=.d) $(GODDARD_O_FILES:.o=.d) $(BUILD_DIR)/$(LD_SCRIPT).d
@@ -1226,6 +1231,9 @@ $(BUILD_DIR)/$(MOD_DIR):
$(BUILD_DIR)/$(PALETTES_DIR):
@$(CP) -f -r $(PALETTES_DIR) $(BUILD_DIR)
+$(BUILD_DIR)/$(DATABASES_DIR):
+ @$(CP) -f -r $(DATABASES_DIR) $(BUILD_DIR)
+
# Extra object file dependencies
ifeq ($(TARGET_N64),1)
@@ -1565,7 +1573,7 @@ ifeq ($(TARGET_N64),1)
$(BUILD_DIR)/$(TARGET).objdump: $(ELF)
$(OBJDUMP) -D $< > $@
else
- $(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS) $(BUILD_DIR)/$(DISCORD_SDK_LIBS) $(BUILD_DIR)/$(COOPNET_LIBS) $(BUILD_DIR)/$(LANG_DIR) $(BUILD_DIR)/$(MOD_DIR) $(BUILD_DIR)/$(PALETTES_DIR)
+ $(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS) $(BUILD_DIR)/$(DISCORD_SDK_LIBS) $(BUILD_DIR)/$(COOPNET_LIBS) $(BUILD_DIR)/$(LANG_DIR) $(BUILD_DIR)/$(MOD_DIR) $(BUILD_DIR)/$(PALETTES_DIR) $(BUILD_DIR)/$(DATABASES_DIR)
@$(PRINT) "$(GREEN)Linking executable: $(BLUE)$@ $(NO_COL)\n"
$(V)$(LD) $(PROF_FLAGS) -L $(BUILD_DIR) -o $@ $(O_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS)
endif
@@ -1600,6 +1608,7 @@ all:
cp -r build/us_pc/lang $(APP_RESOURCES_DIR); \
cp -r build/us_pc/dynos $(APP_RESOURCES_DIR); \
cp -r build/us_pc/palettes $(APP_RESOURCES_DIR); \
+ cp -r build/us_pc/databases $(APP_RESOURCES_DIR); \
cp build/us_pc/discord_game_sdk.dylib $(APP_MACOS_DIR); \
cp build/us_pc/libdiscord_game_sdk.dylib $(APP_MACOS_DIR); \
cp build/us_pc/libcoopnet.dylib $(APP_MACOS_DIR); \
diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py
index 9aaed763f..ebde65ed4 100644
--- a/autogen/convert_functions.py
+++ b/autogen/convert_functions.py
@@ -134,6 +134,7 @@ override_disallowed_functions = {
"src/pc/lua/utils/smlua_text_utils.h": [ "smlua_text_utils_init", "smlua_text_utils_shutdown", "smlua_text_utils_dialog_get_unmodified"],
"src/pc/lua/utils/smlua_anim_utils.h": [ "smlua_anim_util_reset", "smlua_anim_util_register_animation" ],
"src/pc/lua/utils/smlua_gfx_utils.h": [ "gfx_allocate_internal", "vtx_allocate_internal", "gfx_get_length_no_sentinel" ],
+ "src/pc/lua/utils/smlua_input_utils.h": [ "clear_gamepad_input_data", "controller_maps_load" ],
"src/pc/network/lag_compensation.h": [ "lag_compensation_clear" ],
"src/game/first_person_cam.h": [ "first_person_update" ],
"src/pc/lua/utils/smlua_collision_utils.h": [ "collision_find_surface_on_ray" ],
diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py
index 15d083e40..5750ab7f7 100644
--- a/autogen/convert_structs.py
+++ b/autogen/convert_structs.py
@@ -102,6 +102,7 @@ override_field_invisible = {
"DialogEntry": [ "str" ],
"ModFsFile": [ "data", "capacity" ],
"ModFs": [ "files" ],
+ "Gamepad": [ "controller" ],
}
override_field_deprecated = {
diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua
index 091d5c532..9f8a9296e 100644
--- a/autogen/lua_definitions/constants.lua
+++ b/autogen/lua_definitions/constants.lua
@@ -8483,6 +8483,9 @@ HOOK_MAX = 62 --- @type LuaHookedEventType
--- | `HOOK_ON_TEXT_EDITING`
--- | `HOOK_MAX`
+--- @type string
+DATABASES_DIRECTORY = "databases"
+
--- @type integer
MAX_GAMEPADS = 256
diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index e3be6d32c..8e9d7e05f 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -10937,6 +10937,18 @@ function get_current_gamepad_index()
-- ...
end
+--- @return string
+--- Returns the clipboard text
+function get_clipboard_text()
+ -- ...
+end
+
+--- @param text string
+--- Sets the clipboard text
+function set_clipboard_text(text)
+ -- ...
+end
+
--- @param areaIndex integer
--- Instantly changes the current area to `areaIndex`
function smlua_level_util_change_area(areaIndex)
diff --git a/autogen/lua_definitions/manual.lua b/autogen/lua_definitions/manual.lua
index a08f2a781..59b9daff3 100644
--- a/autogen/lua_definitions/manual.lua
+++ b/autogen/lua_definitions/manual.lua
@@ -35,7 +35,7 @@ gControllers = {}
--- Array of every gamepad, from 0 to `MAX_GAMEPADS` - 1
gGamepads = {}
---- @type Keyboard[]
+--- @type Key[]
--- Array of every SDL scancode, from 0 to `SDL_NUM_SCANCODES` - 1
gKeyboard = {}
diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua
index 4e97289d7..a93200d65 100644
--- a/autogen/lua_definitions/structs.lua
+++ b/autogen/lua_definitions/structs.lua
@@ -585,6 +585,11 @@
--- @field public model ModelExtendedId
--- @field public behavior BehaviorId
+--- @class Finger
+--- @field public pos Vec2f
+--- @field public pressure number
+--- @field public touched boolean
+
--- @class FirstPersonCamera
--- @field public enabled boolean
--- @field public forcePitch boolean
@@ -615,9 +620,10 @@
--- @field public rightGyro Vec3f
--- @field public leftAccelerometer Vec3f
--- @field public rightAccelerometer Vec3f
---- @field public touchpad Touchpad[]
---- @field public loRumble integer
---- @field public hiRumble integer
+--- @field public touchpad Finger[]
+--- @field public rumbleLowFreq integer
+--- @field public rumbleHighFreq integer
+--- @field public rumbleDurationMs integer
--- @field public ledColor Color
--- @class Gfx
@@ -987,10 +993,10 @@
--- @field public area integer
--- @field public displacement Vec3s
---- @class Keyboard
---- @field public keyDown boolean
---- @field public keyPressed boolean
---- @field public keyReleased boolean
+--- @class Key
+--- @field public down boolean
+--- @field public pressed boolean
+--- @field public released boolean
--- @class LakituState
--- @field public curFocus Vec3f
@@ -2288,11 +2294,6 @@
--- @field public format integer
--- @field public size integer
---- @class Touchpad
---- @field public pos Vec2f
---- @field public pressure number
---- @field public touched boolean
-
--- @class Vtx
--- @field public x number
--- @field public y number
diff --git a/src/pc/controller/controller_gamepad.db b/databases/controller_gamepad.db
similarity index 100%
rename from src/pc/controller/controller_gamepad.db
rename to databases/controller_gamepad.db
diff --git a/docs/lua/constants.md b/docs/lua/constants.md
index 6e5372c6d..378d18dd1 100644
--- a/docs/lua/constants.md
+++ b/docs/lua/constants.md
@@ -3534,6 +3534,7 @@
## [smlua_input_utils.h](#smlua_input_utils.h)
+- DATABASES_DIRECTORY
- MAX_GAMEPADS
- MAX_TOUCHPAD_FINGERS
diff --git a/docs/lua/functions-6.md b/docs/lua/functions-6.md
index e2d323c2b..4807e1046 100644
--- a/docs/lua/functions-6.md
+++ b/docs/lua/functions-6.md
@@ -8477,6 +8477,50 @@ Returns the current gamepad index in the config file
[:arrow_up_small:](#)
+
+
+## [get_clipboard_text](#get_clipboard_text)
+
+### Description
+Returns the clipboard text
+
+### Lua Example
+`local stringValue = get_clipboard_text()`
+
+### Parameters
+- None
+
+### Returns
+- `string`
+
+### C Prototype
+`const char* get_clipboard_text(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_clipboard_text](#set_clipboard_text)
+
+### Description
+Sets the clipboard text
+
+### Lua Example
+`set_clipboard_text(text)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| text | `string` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_clipboard_text(const char* text);`
+
+[:arrow_up_small:](#)
+
---
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index cfd3b7430..49aece4a9 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -1961,6 +1961,8 @@
- smlua_input_utils.h
- [get_current_gamepad_index](functions-6.md#get_current_gamepad_index)
+ - [get_clipboard_text](functions-6.md#get_clipboard_text)
+ - [set_clipboard_text](functions-6.md#set_clipboard_text)
diff --git a/docs/lua/globals.md b/docs/lua/globals.md
index 90df58454..2ed3c5ae1 100644
--- a/docs/lua/globals.md
+++ b/docs/lua/globals.md
@@ -52,7 +52,7 @@ The `gGamepads[]` table is an array from `0` to `(MAX_GAMEPADS - 1)` that contai
## [gKeyboard](#gKeyboard)
-The `gKeyboard[]` table is an array from `0` to `(SDL_NUM_SCANCODES - 1)` that contains a [Keyboard](structs.md#Keyboard) struct for each possible scancode.
+The `gKeyboard[]` table is an array from `0` to `(SDL_NUM_SCANCODES - 1)` that contains a [Key](structs.md#Key) struct for each possible scancode.
[:arrow_up_small:](#)
diff --git a/docs/lua/structs.md b/docs/lua/structs.md
index 7e002c93c..3c2202f87 100644
--- a/docs/lua/structs.md
+++ b/docs/lua/structs.md
@@ -22,6 +22,7 @@
- [DjuiTheme](#DjuiTheme)
- [DjuiThreePanelTheme](#DjuiThreePanelTheme)
- [ExclamationBoxContent](#ExclamationBoxContent)
+- [Finger](#Finger)
- [FirstPersonCamera](#FirstPersonCamera)
- [FnGraphNode](#FnGraphNode)
- [Gamepad](#Gamepad)
@@ -56,7 +57,7 @@
- [GraphNodeTranslationRotation](#GraphNodeTranslationRotation)
- [HudUtilsRotation](#HudUtilsRotation)
- [InstantWarp](#InstantWarp)
-- [Keyboard](#Keyboard)
+- [Key](#Key)
- [LakituState](#LakituState)
- [LevelValues](#LevelValues)
- [MarioAnimation](#MarioAnimation)
@@ -87,7 +88,6 @@
- [StaticObjectCollision](#StaticObjectCollision)
- [Surface](#Surface)
- [TextureInfo](#TextureInfo)
-- [Touchpad](#Touchpad)
- [Vec2f](#Vec2f)
- [Vec2i](#Vec2i)
- [Vec2s](#Vec2s)
@@ -843,6 +843,18 @@
+## [Finger](#Finger)
+
+| Field | Type | Access |
+| ----- | ---- | ------ |
+| pos | [Vec2f](structs.md#Vec2f) | read-only |
+| pressure | `number` | |
+| touched | `boolean` | |
+
+[:arrow_up_small:](#)
+
+
+
## [FirstPersonCamera](#FirstPersonCamera)
| Field | Type | Access |
@@ -890,9 +902,10 @@
| rightGyro | [Vec3f](structs.md#Vec3f) | read-only |
| leftAccelerometer | [Vec3f](structs.md#Vec3f) | read-only |
| rightAccelerometer | [Vec3f](structs.md#Vec3f) | read-only |
-| touchpad | `Array` <`Touchpad`> | read-only |
-| loRumble | `integer` | |
-| hiRumble | `integer` | |
+| touchpad | `Array` <`Finger`> | read-only |
+| rumbleLowFreq | `integer` | |
+| rumbleHighFreq | `integer` | |
+| rumbleDurationMs | `integer` | |
| ledColor | [Color](structs.md#Color) | read-only |
[:arrow_up_small:](#)
@@ -1483,13 +1496,13 @@
-## [Keyboard](#Keyboard)
+## [Key](#Key)
| Field | Type | Access |
| ----- | ---- | ------ |
-| keyDown | `boolean` | |
-| keyPressed | `boolean` | |
-| keyReleased | `boolean` | |
+| down | `boolean` | |
+| pressed | `boolean` | |
+| released | `boolean` | |
[:arrow_up_small:](#)
@@ -3034,18 +3047,6 @@
-## [Touchpad](#Touchpad)
-
-| Field | Type | Access |
-| ----- | ---- | ------ |
-| pos | [Vec2f](structs.md#Vec2f) | read-only |
-| pressure | `number` | |
-| touched | `boolean` | |
-
-[:arrow_up_small:](#)
-
-
-
## [Vec2f](#Vec2f)
| Field | Type | Access |
diff --git a/lang/English.ini b/lang/English.ini
index 14ec1d462..620a01bb0 100644
--- a/lang/English.ini
+++ b/lang/English.ini
@@ -18,6 +18,7 @@ DEBUG_FLY = "@ entered debug free-fly mode"
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#dcdcdc\\'@'"
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#dcdcdc\\'@'"
IMPORT_PALETTE_SUCCESS = "\\#a0ffa0\\Imported palette preset\n\\#dcdcdc\\'@'"
+IMPORT_DATABASE_SUCCESS = "\\#a0ffa0\\Imported controller mapping database\n\\#dcdcdc\\'@'"
IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#dcdcdc\\'@'"
IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game"
COOPNET_CONNECTION_FAILED = "\\#ffa0a0\\Could not connect to CoopNet!"
diff --git a/src/pc/controller/controller_keyboard.c b/src/pc/controller/controller_keyboard.c
index 573ea448d..5ce251f89 100644
--- a/src/pc/controller/controller_keyboard.c
+++ b/src/pc/controller/controller_keyboard.c
@@ -19,7 +19,7 @@
static int keyboard_buttons_down;
#if defined(CAPI_SDL1) || defined(CAPI_SDL2)
-bool keyboard_keys_prev_down[SDL_NUM_SCANCODES];
+bool kb_keys_curr_down[SDL_NUM_SCANCODES];
#endif
#define MAX_KEYBINDS 64
@@ -67,9 +67,9 @@ void keyboard_on_all_keys_up(void) {
keyboard_buttons_down = 0;
#if defined(CAPI_SDL1) || defined(CAPI_SDL2)
for (int scancode = 0; scancode < SDL_NUM_SCANCODES; ++scancode) {
- gKeyboard[scancode].keyDown = false;
- gKeyboard[scancode].keyPressed = false;
- gKeyboard[scancode].keyReleased = false;
+ gKeyboard[scancode].down = false;
+ gKeyboard[scancode].pressed = false;
+ gKeyboard[scancode].released = false;
}
#endif
}
@@ -126,13 +126,12 @@ static void keyboard_init(void) {
static void keyboard_read(OSContPad *pad) {
#if defined(CAPI_SDL1) || defined(CAPI_SDL2)
for (int scancode = 0; scancode < SDL_NUM_SCANCODES; ++scancode) {
- bool prev = keyboard_keys_prev_down[scancode];
- bool curr = gKeyboard[scancode].keyDown;
+ bool prev = gKeyboard[scancode].down;
+ bool curr = kb_keys_curr_down[scancode];
- gKeyboard[scancode].keyPressed = (!prev && curr);
- gKeyboard[scancode].keyReleased = (prev && !curr);
-
- keyboard_keys_prev_down[scancode] = curr;
+ gKeyboard[scancode].down = curr;
+ gKeyboard[scancode].pressed = (!prev && curr);
+ gKeyboard[scancode].released = (prev && !curr);
}
#endif
diff --git a/src/pc/controller/controller_keyboard.h b/src/pc/controller/controller_keyboard.h
index b1dabcc40..f0be796b3 100644
--- a/src/pc/controller/controller_keyboard.h
+++ b/src/pc/controller/controller_keyboard.h
@@ -44,6 +44,10 @@ void keyboard_on_all_keys_up(void);
void keyboard_on_text_input(char* text);
void keyboard_on_text_editing(char* text, int cursorPos);
+#if defined(CAPI_SDL1) || defined(CAPI_SDL2)
+extern bool kb_keys_curr_down[SDL_NUM_SCANCODES];
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/src/pc/controller/controller_sdl2.c b/src/pc/controller/controller_sdl2.c
index 654150ef8..ed05c5c65 100644
--- a/src/pc/controller/controller_sdl2.c
+++ b/src/pc/controller/controller_sdl2.c
@@ -35,16 +35,12 @@
#define MAX_JOYBUTTONS 32 // arbitrary; includes virtual keys for triggers
#define AXIS_THRESHOLD (30 * 256)
-static s32 num_gamepads;
-
static bool init_ok = false;
static bool haptics_enabled = false;
static SDL_GameController *sdl_cntrl = NULL;
static SDL_Joystick *sdl_joystick = NULL;
static SDL_Haptic *sdl_haptic = NULL;
-static SDL_GameController *sOpenControllers[MAX_GAMEPADS];
-
static bool sBackgroundGamepad = false;
static u32 num_joy_binds = 0;
@@ -62,8 +58,8 @@ static s16 invert_s16(s16 val) {
return (s16)(-(s32)val);
}
-// This uses the code from the comment in SDL2 SDL_gamecontroller.h
-static int SDL_NumGameControllers(void) {
+// This uses the code from the comment in SDL2 SDL_gamecontroller.h https://github.com/libsdl-org/SDL/blob/SDL2/include/SDL_gamecontroller.h#L110
+static int get_gamepad_num(void) {
int nJoysticks = SDL_NumJoysticks();
int nGameControllers = 0;
for (int i = 0; i < nJoysticks; i++) {
@@ -172,18 +168,11 @@ static void controller_sdl_init(void) {
haptics_enabled = (SDL_InitSubSystem(SDL_INIT_HAPTIC) == 0);
- // Loading a controller mapping file
- uint64_t gcsize = 0;
- void *gcdata = fs_load_file("controller_gamepad.db", &gcsize);
- if (gcdata && gcsize) {
- SDL_RWops *rw = SDL_RWFromConstMem(gcdata, gcsize);
- if (rw) {
- int nummaps = SDL_GameControllerAddMappingsFromRW(rw, SDL_TRUE);
- if (nummaps >= 0)
- printf("Successfully loaded %d controller mappings from 'controller_gamepad.db'\n", nummaps);
- }
- free(gcdata);
+ if (!fs_sys_dir_exists(fs_get_write_path(DATABASES_DIRECTORY))) {
+ fs_sys_mkdir(fs_get_write_path(DATABASES_DIRECTORY));
}
+ controller_maps_load(sys_resource_path(), true);
+ controller_maps_load(fs_get_write_path(DATABASES_DIRECTORY), false);
if (gNewCamera.isMouse) { controller_mouse_enter_relative(); }
controller_mouse_read_relative();
@@ -255,44 +244,50 @@ static void controller_sdl_read(OSContPad *pad) {
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, sBackgroundGamepad ? "1" : "0");
}
- num_gamepads = SDL_NumGameControllers();
-
- for (int i = 0; i < num_gamepads; ++i) {
+ for (int i = 0; i < get_gamepad_num() && i < MAX_GAMEPADS; ++i) {
gGamepads[i].index = i;
- SDL_GameController *sSDLGameController = NULL;
- if (sOpenControllers[i] == NULL) sSDLGameController = SDL_GameControllerOpen(i);
- else sSDLGameController = sOpenControllers[i];
- if (sSDLGameController == NULL) continue;
- sOpenControllers[i] = sSDLGameController;
- gGamepads[i].name = SDL_GameControllerName(sSDLGameController);
- SDL_GameControllerSetPlayerIndex(sSDLGameController, (int32_t)gGamepads[i].playerIndex);
- for (int j = 0; j < SDL_CONTROLLER_BUTTON_MAX; ++j) {
- gGamepads[i].buttons[j] = SDL_GameControllerGetButton(sSDLGameController, j);
+ SDL_GameController *sdl_gamepad = NULL;
+ if (gGamepads[i].controller == NULL) {
+ sdl_gamepad = SDL_GameControllerOpen(i);
+ } else {
+ sdl_gamepad = gGamepads[i].controller;
}
- gGamepads[i].leftStick[0] = SDL_GameControllerGetAxis(sSDLGameController, SDL_CONTROLLER_AXIS_LEFTX);
- gGamepads[i].leftStick[1] = SDL_GameControllerGetAxis(sSDLGameController, SDL_CONTROLLER_AXIS_LEFTY);
- gGamepads[i].rightStick[0] = SDL_GameControllerGetAxis(sSDLGameController, SDL_CONTROLLER_AXIS_RIGHTX);
- gGamepads[i].rightStick[1] = SDL_GameControllerGetAxis(sSDLGameController, SDL_CONTROLLER_AXIS_RIGHTY);
- gGamepads[i].leftTrigger = SDL_GameControllerGetAxis(sSDLGameController, SDL_CONTROLLER_AXIS_TRIGGERLEFT);
- gGamepads[i].rightTrigger = SDL_GameControllerGetAxis(sSDLGameController, SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
- SDL_GameControllerSetSensorEnabled(sSDLGameController, SDL_SENSOR_ACCEL, 3);
- SDL_GameControllerSetSensorEnabled(sSDLGameController, SDL_SENSOR_GYRO, 3);
- SDL_GameControllerSetSensorEnabled(sSDLGameController, SDL_SENSOR_ACCEL_L, 3);
- SDL_GameControllerSetSensorEnabled(sSDLGameController, SDL_SENSOR_GYRO_L, 3);
- SDL_GameControllerSetSensorEnabled(sSDLGameController, SDL_SENSOR_ACCEL_R, 3);
- SDL_GameControllerSetSensorEnabled(sSDLGameController, SDL_SENSOR_GYRO_R, 3);
- SDL_GameControllerGetSensorData(sSDLGameController, SDL_SENSOR_ACCEL, gGamepads[i].accelerometer, 3);
- SDL_GameControllerGetSensorData(sSDLGameController, SDL_SENSOR_GYRO, gGamepads[i].gyro, 3);
- SDL_GameControllerGetSensorData(sSDLGameController, SDL_SENSOR_ACCEL_L, gGamepads[i].leftAccelerometer, 3);
- SDL_GameControllerGetSensorData(sSDLGameController, SDL_SENSOR_GYRO_L, gGamepads[i].leftGyro, 3);
- SDL_GameControllerGetSensorData(sSDLGameController, SDL_SENSOR_ACCEL_R, gGamepads[i].rightAccelerometer, 3);
- SDL_GameControllerGetSensorData(sSDLGameController, SDL_SENSOR_GYRO_R, gGamepads[i].rightGyro, 3);
- SDL_GameControllerRumble(sSDLGameController, gGamepads[i].loRumble, gGamepads[i].hiRumble, 1000);
- SDL_GameControllerSetLED(sSDLGameController, gGamepads[i].ledColor[0], gGamepads[i].ledColor[1], gGamepads[i].ledColor[2]);
+ if (sdl_gamepad == NULL) continue;
+ gGamepads[i].controller = sdl_gamepad;
+ gGamepads[i].name = SDL_GameControllerName(sdl_gamepad);
+ SDL_GameControllerSetPlayerIndex(sdl_gamepad, (int32_t)gGamepads[i].playerIndex);
+ for (int j = 0; j < SDL_CONTROLLER_BUTTON_MAX; ++j) {
+ gGamepads[i].buttons[j] = SDL_GameControllerGetButton(sdl_gamepad, j);
+ }
+ gGamepads[i].leftStick[0] = SDL_GameControllerGetAxis(sdl_gamepad, SDL_CONTROLLER_AXIS_LEFTX);
+ gGamepads[i].leftStick[1] = SDL_GameControllerGetAxis(sdl_gamepad, SDL_CONTROLLER_AXIS_LEFTY);
+ gGamepads[i].rightStick[0] = SDL_GameControllerGetAxis(sdl_gamepad, SDL_CONTROLLER_AXIS_RIGHTX);
+ gGamepads[i].rightStick[1] = SDL_GameControllerGetAxis(sdl_gamepad, SDL_CONTROLLER_AXIS_RIGHTY);
+ gGamepads[i].leftTrigger = SDL_GameControllerGetAxis(sdl_gamepad, SDL_CONTROLLER_AXIS_TRIGGERLEFT);
+ gGamepads[i].rightTrigger = SDL_GameControllerGetAxis(sdl_gamepad, SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
+ SDL_GameControllerSetSensorEnabled(sdl_gamepad, SDL_SENSOR_ACCEL, SDL_TRUE);
+ SDL_GameControllerSetSensorEnabled(sdl_gamepad, SDL_SENSOR_GYRO, SDL_TRUE);
+ SDL_GameControllerSetSensorEnabled(sdl_gamepad, SDL_SENSOR_ACCEL_L, SDL_TRUE);
+ SDL_GameControllerSetSensorEnabled(sdl_gamepad, SDL_SENSOR_GYRO_L, SDL_TRUE);
+ SDL_GameControllerSetSensorEnabled(sdl_gamepad, SDL_SENSOR_ACCEL_R, SDL_TRUE);
+ SDL_GameControllerSetSensorEnabled(sdl_gamepad, SDL_SENSOR_GYRO_R, SDL_TRUE);
+ SDL_GameControllerGetSensorData(sdl_gamepad, SDL_SENSOR_ACCEL, gGamepads[i].accelerometer, 3);
+ SDL_GameControllerGetSensorData(sdl_gamepad, SDL_SENSOR_GYRO, gGamepads[i].gyro, 3);
+ SDL_GameControllerGetSensorData(sdl_gamepad, SDL_SENSOR_ACCEL_L, gGamepads[i].leftAccelerometer, 3);
+ SDL_GameControllerGetSensorData(sdl_gamepad, SDL_SENSOR_GYRO_L, gGamepads[i].leftGyro, 3);
+ SDL_GameControllerGetSensorData(sdl_gamepad, SDL_SENSOR_ACCEL_R, gGamepads[i].rightAccelerometer, 3);
+ SDL_GameControllerGetSensorData(sdl_gamepad, SDL_SENSOR_GYRO_R, gGamepads[i].rightGyro, 3);
+ if (gGamepads[i].rumbleDurationMs > 0) {
+ SDL_GameControllerRumble(sdl_gamepad, gGamepads[i].rumbleLowFreq, gGamepads[i].rumbleHighFreq, gGamepads[i].rumbleDurationMs);
+ gGamepads[i].rumbleLowFreq = 0;
+ gGamepads[i].rumbleHighFreq = 0;
+ gGamepads[i].rumbleDurationMs = 0;
+ }
+ SDL_GameControllerSetLED(sdl_gamepad, gGamepads[i].ledColor[0], gGamepads[i].ledColor[1], gGamepads[i].ledColor[2]);
for (int j = 0; j < MAX_TOUCHPAD_FINGERS; ++j) {
- uint8_t state;
- float_t x, y, pressure;
- SDL_GameControllerGetTouchpadFinger(sSDLGameController, 0, j, &state, &x, &y, &pressure);
+ Uint8 state;
+ float x, y, pressure;
+ SDL_GameControllerGetTouchpadFinger(sdl_gamepad, 0, j, &state, &x, &y, &pressure);
gGamepads[i].touchpad[j].touched = state;
gGamepads[i].touchpad[j].pos[0] = x;
gGamepads[i].touchpad[j].pos[1] = y;
@@ -472,10 +467,11 @@ static void controller_sdl_shutdown(void) {
sdl_joystick = NULL;
}
for (int i = 0; i < MAX_GAMEPADS; ++i) {
- if (sOpenControllers[i] != NULL) {
- SDL_GameControllerSetLED(sOpenControllers[i], 0x0, 0x0, 0x0);
- SDL_GameControllerClose(sOpenControllers[i]);
- sOpenControllers[i] = NULL;
+ if (gGamepads[i].controller != NULL) {
+ SDL_GameControllerSetLED(gGamepads[i].controller, 0x0, 0x0, 0x0);
+ SDL_GameControllerSetPlayerIndex(gGamepads[i].controller, 0);
+ SDL_GameControllerClose(gGamepads[i].controller);
+ gGamepads[i].controller = NULL;
}
}
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
diff --git a/src/pc/gfx/gfx_sdl1.c b/src/pc/gfx/gfx_sdl1.c
index 7fcf452d0..d8eb61f91 100644
--- a/src/pc/gfx/gfx_sdl1.c
+++ b/src/pc/gfx/gfx_sdl1.c
@@ -134,14 +134,14 @@ static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) {
static void gfx_sdl_onkeydown(int scancode) {
if (kb_key_down) {
kb_key_down(translate_bind_to_name(scancode));
- gKeyboard[scancode].keyDown = true;
+ kb_keys_curr_down[scancode] = true;
}
}
static void gfx_sdl_onkeyup(int scancode) {
if (kb_key_up) {
kb_key_up(translate_bind_to_name(scancode));
- gKeyboard[scancode].keyDown = false;
+ kb_keys_curr_down[scancode] = false;
}
}
diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c
index 4ae20219f..0591e14c3 100644
--- a/src/pc/gfx/gfx_sdl2.c
+++ b/src/pc/gfx/gfx_sdl2.c
@@ -180,14 +180,14 @@ static void gfx_sdl_onkeydown(int scancode) {
if (kb_key_down) {
kb_key_down(translate_sdl_scancode(scancode));
- gKeyboard[scancode].keyDown = true;
+ kb_keys_curr_down[scancode] = true;
}
}
static void gfx_sdl_onkeyup(int scancode) {
if (kb_key_up) {
kb_key_up(translate_sdl_scancode(scancode));
- gKeyboard[scancode].keyDown = false;
+ kb_keys_curr_down[scancode] = false;
}
}
diff --git a/src/pc/lua/smlua_cobject.c b/src/pc/lua/smlua_cobject.c
index 017ec2915..f5bff161f 100644
--- a/src/pc/lua/smlua_cobject.c
+++ b/src/pc/lua/smlua_cobject.c
@@ -766,7 +766,7 @@ void smlua_cobject_init_globals(void) {
#if defined(CAPI_SDL1) || defined(CAPI_SDL2)
EXPOSE_GLOBAL_ARRAY(LOT_GAMEPAD, gGamepads, MAX_GAMEPADS);
- EXPOSE_GLOBAL_ARRAY(LOT_KEYBOARD, gKeyboard, SDL_NUM_SCANCODES);
+ EXPOSE_GLOBAL_ARRAY(LOT_KEY, gKeyboard, SDL_NUM_SCANCODES);
#endif
EXPOSE_GLOBAL_ARRAY(LOT_MAT4, gMatStack, MATRIX_STACK_SIZE);
diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c
index 13aaf2e02..37ed133d2 100644
--- a/src/pc/lua/smlua_cobject_autogen.c
+++ b/src/pc/lua/smlua_cobject_autogen.c
@@ -794,6 +794,13 @@ static struct LuaObjectField sExclamationBoxContentFields[LUA_EXCLAMATION_BOX_CO
{ "unused", LVT_U8, offsetof(struct ExclamationBoxContent, unused), false, LOT_NONE, 1, sizeof(u8) },
};
+#define LUA_FINGER_FIELD_COUNT 3
+static struct LuaObjectField sFingerFields[LUA_FINGER_FIELD_COUNT] = {
+ { "pos", LVT_COBJECT, offsetof(struct Finger, pos), true, LOT_VEC2F, 1, sizeof(Vec2f) },
+ { "pressure", LVT_F32, offsetof(struct Finger, pressure), false, LOT_NONE, 1, sizeof(f32) },
+ { "touched", LVT_BOOL, offsetof(struct Finger, touched), false, LOT_NONE, 1, sizeof(bool) },
+};
+
#define LUA_FIRST_PERSON_CAMERA_FIELD_COUNT 10
static struct LuaObjectField sFirstPersonCameraFields[LUA_FIRST_PERSON_CAMERA_FIELD_COUNT] = {
{ "centerL", LVT_BOOL, offsetof(struct FirstPersonCamera, centerL), false, LOT_NONE, 1, sizeof(bool) },
@@ -814,26 +821,27 @@ static struct LuaObjectField sFnGraphNodeFields[LUA_FN_GRAPH_NODE_FIELD_COUNT] =
{ "node", LVT_COBJECT, offsetof(struct FnGraphNode, node), true, LOT_GRAPHNODE, 1, sizeof(struct GraphNode) },
};
-#define LUA_GAMEPAD_FIELD_COUNT 18
+#define LUA_GAMEPAD_FIELD_COUNT 19
static struct LuaObjectField sGamepadFields[LUA_GAMEPAD_FIELD_COUNT] = {
- { "accelerometer", LVT_COBJECT, offsetof(struct Gamepad, accelerometer), true, LOT_VEC3F, 1, sizeof(Vec3f) },
- { "buttons", LVT_BOOL, offsetof(struct Gamepad, buttons), true, LOT_NONE, SDL_CONTROLLER_BUTTON_MAX, sizeof(bool) },
- { "gyro", LVT_COBJECT, offsetof(struct Gamepad, gyro), true, LOT_VEC3F, 1, sizeof(Vec3f) },
- { "hiRumble", LVT_U16, offsetof(struct Gamepad, hiRumble), false, LOT_NONE, 1, sizeof(u16) },
- { "index", LVT_S32, offsetof(struct Gamepad, index), true, LOT_NONE, 1, sizeof(s32) },
- { "ledColor", LVT_COBJECT, offsetof(struct Gamepad, ledColor), true, LOT_COLOR, 1, sizeof(Color) },
- { "leftAccelerometer", LVT_COBJECT, offsetof(struct Gamepad, leftAccelerometer), true, LOT_VEC3F, 1, sizeof(Vec3f) },
- { "leftGyro", LVT_COBJECT, offsetof(struct Gamepad, leftGyro), true, LOT_VEC3F, 1, sizeof(Vec3f) },
- { "leftStick", LVT_COBJECT, offsetof(struct Gamepad, leftStick), true, LOT_VEC2S, 1, sizeof(Vec2s) },
- { "leftTrigger", LVT_S16, offsetof(struct Gamepad, leftTrigger), true, LOT_NONE, 1, sizeof(s16) },
- { "loRumble", LVT_U16, offsetof(struct Gamepad, loRumble), false, LOT_NONE, 1, sizeof(u16) },
- { "name", LVT_STRING_P, offsetof(struct Gamepad, name), true, LOT_NONE, 1, sizeof(const char*) },
- { "playerIndex", LVT_U8, offsetof(struct Gamepad, playerIndex), false, LOT_NONE, 1, sizeof(u8) },
- { "rightAccelerometer", LVT_COBJECT, offsetof(struct Gamepad, rightAccelerometer), true, LOT_VEC3F, 1, sizeof(Vec3f) },
- { "rightGyro", LVT_COBJECT, offsetof(struct Gamepad, rightGyro), true, LOT_VEC3F, 1, sizeof(Vec3f) },
- { "rightStick", LVT_COBJECT, offsetof(struct Gamepad, rightStick), true, LOT_VEC2S, 1, sizeof(Vec2s) },
- { "rightTrigger", LVT_S16, offsetof(struct Gamepad, rightTrigger), true, LOT_NONE, 1, sizeof(s16) },
- { "touchpad", LVT_COBJECT, offsetof(struct Gamepad, touchpad), true, LOT_TOUCHPAD, MAX_TOUCHPAD_FINGERS, sizeof(struct Touchpad) },
+ { "accelerometer", LVT_COBJECT, offsetof(struct Gamepad, accelerometer), true, LOT_VEC3F, 1, sizeof(Vec3f) },
+ { "buttons", LVT_BOOL, offsetof(struct Gamepad, buttons), true, LOT_NONE, SDL_CONTROLLER_BUTTON_MAX, sizeof(bool) },
+ { "gyro", LVT_COBJECT, offsetof(struct Gamepad, gyro), true, LOT_VEC3F, 1, sizeof(Vec3f) },
+ { "index", LVT_S32, offsetof(struct Gamepad, index), true, LOT_NONE, 1, sizeof(s32) },
+ { "ledColor", LVT_COBJECT, offsetof(struct Gamepad, ledColor), true, LOT_COLOR, 1, sizeof(Color) },
+ { "leftAccelerometer", LVT_COBJECT, offsetof(struct Gamepad, leftAccelerometer), true, LOT_VEC3F, 1, sizeof(Vec3f) },
+ { "leftGyro", LVT_COBJECT, offsetof(struct Gamepad, leftGyro), true, LOT_VEC3F, 1, sizeof(Vec3f) },
+ { "leftStick", LVT_COBJECT, offsetof(struct Gamepad, leftStick), true, LOT_VEC2S, 1, sizeof(Vec2s) },
+ { "leftTrigger", LVT_S16, offsetof(struct Gamepad, leftTrigger), true, LOT_NONE, 1, sizeof(s16) },
+ { "name", LVT_STRING_P, offsetof(struct Gamepad, name), true, LOT_NONE, 1, sizeof(const char*) },
+ { "playerIndex", LVT_U8, offsetof(struct Gamepad, playerIndex), false, LOT_NONE, 1, sizeof(u8) },
+ { "rightAccelerometer", LVT_COBJECT, offsetof(struct Gamepad, rightAccelerometer), true, LOT_VEC3F, 1, sizeof(Vec3f) },
+ { "rightGyro", LVT_COBJECT, offsetof(struct Gamepad, rightGyro), true, LOT_VEC3F, 1, sizeof(Vec3f) },
+ { "rightStick", LVT_COBJECT, offsetof(struct Gamepad, rightStick), true, LOT_VEC2S, 1, sizeof(Vec2s) },
+ { "rightTrigger", LVT_S16, offsetof(struct Gamepad, rightTrigger), true, LOT_NONE, 1, sizeof(s16) },
+ { "rumbleDurationMs", LVT_U32, offsetof(struct Gamepad, rumbleDurationMs), false, LOT_NONE, 1, sizeof(u32) },
+ { "rumbleHighFreq", LVT_U16, offsetof(struct Gamepad, rumbleHighFreq), false, LOT_NONE, 1, sizeof(u16) },
+ { "rumbleLowFreq", LVT_U16, offsetof(struct Gamepad, rumbleLowFreq), false, LOT_NONE, 1, sizeof(u16) },
+ { "touchpad", LVT_COBJECT, offsetof(struct Gamepad, touchpad), true, LOT_FINGER, MAX_TOUCHPAD_FINGERS, sizeof(struct Finger) },
};
#define LUA_GFX_FIELD_COUNT 2
@@ -1267,11 +1275,11 @@ static struct LuaObjectField sInstantWarpFields[LUA_INSTANT_WARP_FIELD_COUNT] =
{ "id", LVT_U8, offsetof(struct InstantWarp, id), false, LOT_NONE, 1, sizeof(u8) },
};
-#define LUA_KEYBOARD_FIELD_COUNT 3
-static struct LuaObjectField sKeyboardFields[LUA_KEYBOARD_FIELD_COUNT] = {
- { "keyDown", LVT_BOOL, offsetof(struct Keyboard, keyDown), false, LOT_NONE, 1, sizeof(bool) },
- { "keyPressed", LVT_BOOL, offsetof(struct Keyboard, keyPressed), false, LOT_NONE, 1, sizeof(bool) },
- { "keyReleased", LVT_BOOL, offsetof(struct Keyboard, keyReleased), false, LOT_NONE, 1, sizeof(bool) },
+#define LUA_KEY_FIELD_COUNT 3
+static struct LuaObjectField sKeyFields[LUA_KEY_FIELD_COUNT] = {
+ { "down", LVT_BOOL, offsetof(struct Key, down), false, LOT_NONE, 1, sizeof(bool) },
+ { "pressed", LVT_BOOL, offsetof(struct Key, pressed), false, LOT_NONE, 1, sizeof(bool) },
+ { "released", LVT_BOOL, offsetof(struct Key, released), false, LOT_NONE, 1, sizeof(bool) },
};
#define LUA_LAKITU_STATE_FIELD_COUNT 38
@@ -2675,13 +2683,6 @@ static struct LuaObjectField sTextureInfoFields[LUA_TEXTURE_INFO_FIELD_COUNT] =
{ "width", LVT_U32, offsetof(struct TextureInfo, width), true, LOT_NONE, 1, sizeof(u32) },
};
-#define LUA_TOUCHPAD_FIELD_COUNT 3
-static struct LuaObjectField sTouchpadFields[LUA_TOUCHPAD_FIELD_COUNT] = {
- { "pos", LVT_COBJECT, offsetof(struct Touchpad, pos), true, LOT_VEC2F, 1, sizeof(Vec2f) },
- { "pressure", LVT_F32, offsetof(struct Touchpad, pressure), false, LOT_NONE, 1, sizeof(f32) },
- { "touched", LVT_BOOL, offsetof(struct Touchpad, touched), false, LOT_NONE, 1, sizeof(bool) },
-};
-
#define LUA_VTX_FIELD_COUNT 13
static struct LuaObjectField sVtxFields[LUA_VTX_FIELD_COUNT] = {
{ "a", LVT_U8, offsetof(Vtx_L, a), false, LOT_NONE, 1, sizeof(unsigned char) },
@@ -2769,6 +2770,7 @@ struct LuaObjectTable sLuaObjectAutogenTable[LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN]
{ LOT_DJUITHEME, sDjuiThemeFields, LUA_DJUI_THEME_FIELD_COUNT },
{ LOT_DJUITHREEPANELTHEME, sDjuiThreePanelThemeFields, LUA_DJUI_THREE_PANEL_THEME_FIELD_COUNT },
{ LOT_EXCLAMATIONBOXCONTENT, sExclamationBoxContentFields, LUA_EXCLAMATION_BOX_CONTENT_FIELD_COUNT },
+ { LOT_FINGER, sFingerFields, LUA_FINGER_FIELD_COUNT },
{ LOT_FIRSTPERSONCAMERA, sFirstPersonCameraFields, LUA_FIRST_PERSON_CAMERA_FIELD_COUNT },
{ LOT_FNGRAPHNODE, sFnGraphNodeFields, LUA_FN_GRAPH_NODE_FIELD_COUNT },
{ LOT_GAMEPAD, sGamepadFields, LUA_GAMEPAD_FIELD_COUNT },
@@ -2803,7 +2805,7 @@ struct LuaObjectTable sLuaObjectAutogenTable[LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN]
{ LOT_GRAPHNODETRANSLATIONROTATION, sGraphNodeTranslationRotationFields, LUA_GRAPH_NODE_TRANSLATION_ROTATION_FIELD_COUNT },
{ LOT_HUDUTILSROTATION, sHudUtilsRotationFields, LUA_HUD_UTILS_ROTATION_FIELD_COUNT },
{ LOT_INSTANTWARP, sInstantWarpFields, LUA_INSTANT_WARP_FIELD_COUNT },
- { LOT_KEYBOARD, sKeyboardFields, LUA_KEYBOARD_FIELD_COUNT },
+ { LOT_KEY, sKeyFields, LUA_KEY_FIELD_COUNT },
{ LOT_LAKITUSTATE, sLakituStateFields, LUA_LAKITU_STATE_FIELD_COUNT },
{ LOT_LEVELVALUES, sLevelValuesFields, LUA_LEVEL_VALUES_FIELD_COUNT },
{ LOT_MARIOANIMATION, sMarioAnimationFields, LUA_MARIO_ANIMATION_FIELD_COUNT },
@@ -2833,7 +2835,6 @@ struct LuaObjectTable sLuaObjectAutogenTable[LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN]
{ LOT_STATICOBJECTCOLLISION, sStaticObjectCollisionFields, LUA_STATIC_OBJECT_COLLISION_FIELD_COUNT },
{ LOT_SURFACE, sSurfaceFields, LUA_SURFACE_FIELD_COUNT },
{ LOT_TEXTUREINFO, sTextureInfoFields, LUA_TEXTURE_INFO_FIELD_COUNT },
- { LOT_TOUCHPAD, sTouchpadFields, LUA_TOUCHPAD_FIELD_COUNT },
{ LOT_VTX, sVtxFields, LUA_VTX_FIELD_COUNT },
{ LOT_WALLCOLLISIONDATA, sWallCollisionDataFields, LUA_WALL_COLLISION_DATA_FIELD_COUNT },
{ LOT_WARPNODE, sWarpNodeFields, LUA_WARP_NODE_FIELD_COUNT },
@@ -2878,6 +2879,7 @@ const char *sLuaLotNames[] = {
[LOT_DJUITHEME] = "DjuiTheme",
[LOT_DJUITHREEPANELTHEME] = "DjuiThreePanelTheme",
[LOT_EXCLAMATIONBOXCONTENT] = "ExclamationBoxContent",
+ [LOT_FINGER] = "Finger",
[LOT_FIRSTPERSONCAMERA] = "FirstPersonCamera",
[LOT_FNGRAPHNODE] = "FnGraphNode",
[LOT_GAMEPAD] = "Gamepad",
@@ -2912,7 +2914,7 @@ const char *sLuaLotNames[] = {
[LOT_GRAPHNODETRANSLATIONROTATION] = "GraphNodeTranslationRotation",
[LOT_HUDUTILSROTATION] = "HudUtilsRotation",
[LOT_INSTANTWARP] = "InstantWarp",
- [LOT_KEYBOARD] = "Keyboard",
+ [LOT_KEY] = "Key",
[LOT_LAKITUSTATE] = "LakituState",
[LOT_LEVELVALUES] = "LevelValues",
[LOT_MARIOANIMATION] = "MarioAnimation",
@@ -2942,7 +2944,6 @@ const char *sLuaLotNames[] = {
[LOT_STATICOBJECTCOLLISION] = "StaticObjectCollision",
[LOT_SURFACE] = "Surface",
[LOT_TEXTUREINFO] = "TextureInfo",
- [LOT_TOUCHPAD] = "Touchpad",
[LOT_VTX] = "Vtx",
[LOT_WALLCOLLISIONDATA] = "WallCollisionData",
[LOT_WARPNODE] = "WarpNode",
diff --git a/src/pc/lua/smlua_cobject_autogen.h b/src/pc/lua/smlua_cobject_autogen.h
index 6719aef82..20a07a680 100644
--- a/src/pc/lua/smlua_cobject_autogen.h
+++ b/src/pc/lua/smlua_cobject_autogen.h
@@ -43,6 +43,7 @@ enum LuaObjectAutogenType {
LOT_DJUITHEME,
LOT_DJUITHREEPANELTHEME,
LOT_EXCLAMATIONBOXCONTENT,
+ LOT_FINGER,
LOT_FIRSTPERSONCAMERA,
LOT_FNGRAPHNODE,
LOT_GAMEPAD,
@@ -77,7 +78,7 @@ enum LuaObjectAutogenType {
LOT_GRAPHNODETRANSLATIONROTATION,
LOT_HUDUTILSROTATION,
LOT_INSTANTWARP,
- LOT_KEYBOARD,
+ LOT_KEY,
LOT_LAKITUSTATE,
LOT_LEVELVALUES,
LOT_MARIOANIMATION,
@@ -107,7 +108,6 @@ enum LuaObjectAutogenType {
LOT_STATICOBJECTCOLLISION,
LOT_SURFACE,
LOT_TEXTUREINFO,
- LOT_TOUCHPAD,
LOT_VTX,
LOT_WALLCOLLISIONDATA,
LOT_WARPNODE,
diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c
index 1e91ac34a..e5772ea91 100644
--- a/src/pc/lua/smlua_constants_autogen.c
+++ b/src/pc/lua/smlua_constants_autogen.c
@@ -3773,6 +3773,7 @@ char gSmluaConstants[] = ""
"HOOK_ON_TEXT_INPUT=60\n"
"HOOK_ON_TEXT_EDITING=61\n"
"HOOK_MAX=62\n"
+"DATABASES_DIRECTORY='databases'\n"
"MAX_GAMEPADS=256\n"
"MAX_TOUCHPAD_FINGERS=10\n"
"HUD_DISPLAY_LIVES=0\n"
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index b73648804..588c8fdc8 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -32945,6 +32945,38 @@ int smlua_func_get_current_gamepad_index(UNUSED lua_State* L) {
return 1;
}
+int smlua_func_get_clipboard_text(UNUSED lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 0) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_clipboard_text", 0, top);
+ return 0;
+ }
+
+
+ lua_pushstring(L, get_clipboard_text());
+
+ return 1;
+}
+
+int smlua_func_set_clipboard_text(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "set_clipboard_text", 1, top);
+ return 0;
+ }
+
+ const char* text = smlua_to_string(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "set_clipboard_text"); return 0; }
+
+ set_clipboard_text(text);
+
+ return 1;
+}
+
/////////////////////////
// smlua_level_utils.h //
/////////////////////////
@@ -38738,6 +38770,8 @@ void smlua_bind_functions_autogen(void) {
// smlua_input_utils.h
smlua_bind_function(L, "get_current_gamepad_index", smlua_func_get_current_gamepad_index);
+ smlua_bind_function(L, "get_clipboard_text", smlua_func_get_clipboard_text);
+ smlua_bind_function(L, "set_clipboard_text", smlua_func_set_clipboard_text);
// smlua_level_utils.h
smlua_bind_function(L, "smlua_level_util_change_area", smlua_func_smlua_level_util_change_area);
diff --git a/src/pc/lua/utils/smlua_input_utils.c b/src/pc/lua/utils/smlua_input_utils.c
index 397122efb..2cd7cc1be 100644
--- a/src/pc/lua/utils/smlua_input_utils.c
+++ b/src/pc/lua/utils/smlua_input_utils.c
@@ -1,18 +1,164 @@
#if defined(CAPI_SDL1) || defined(CAPI_SDL2)
-#include "types.h"
-
-#include "pc/controller/controller_sdl.h"
-#include "pc/controller/controller_keyboard.h"
#include "smlua_input_utils.h"
+#include "engine/math_util.h"
+
#include "pc/configfile.h"
+#include "pc/pc_main.h"
+
+#include "pc/mods/mods.h"
+#include "pc/mods/mods_utils.h"
struct Gamepad gGamepads[MAX_GAMEPADS];
-struct Keyboard gKeyboard[SDL_NUM_SCANCODES];
+struct Key gKeyboard[SDL_NUM_SCANCODES];
u32 get_current_gamepad_index(void) {
return configGamepadNumber;
}
+const char* get_clipboard_text(void) {
+ return wm_api->get_clipboard_text();
+}
+
+void set_clipboard_text(const char* text) {
+ wm_api->set_clipboard_text(text);
+}
+
+void clear_gamepad_input_data(void) {
+ for (int i = 0; i < MAX_GAMEPADS; ++i) {
+ for (int j = 0; j < SDL_CONTROLLER_BUTTON_MAX; ++j) {
+ gGamepads[i].buttons[j] = false;
+ }
+ vec2s_set(gGamepads[i].leftStick, 0, 0);
+ vec2s_set(gGamepads[i].rightStick, 0, 0);
+ gGamepads[i].leftTrigger = 0;
+ gGamepads[i].rightTrigger = 0;
+ vec3f_set(gGamepads[i].accelerometer, 0.0f, 0.0f, 0.0f);
+ vec3f_set(gGamepads[i].gyro, 0.0f, 0.0f, 0.0f);
+ vec3f_set(gGamepads[i].leftAccelerometer, 0.0f, 0.0f, 0.0f);
+ vec3f_set(gGamepads[i].leftGyro, 0.0f, 0.0f, 0.0f);
+ vec3f_set(gGamepads[i].rightAccelerometer, 0.0f, 0.0f, 0.0f);
+ vec3f_set(gGamepads[i].rightGyro, 0.0f, 0.0f, 0.0f);
+ gGamepads[i].rumbleLowFreq = 0;
+ gGamepads[i].rumbleHighFreq = 0;
+ gGamepads[i].rumbleDurationMs = 0;
+ for (int j = 0; j < MAX_TOUCHPAD_FINGERS; ++j) {
+ vec2f_set(gGamepads[i].touchpad[j].pos, 0.0f, 0.0f);
+ gGamepads[i].touchpad[j].pressure = 0.0f;
+ gGamepads[i].touchpad[j].touched = false;
+ }
+ gGamepads[i].ledColor[0] = 0x0;
+ gGamepads[i].ledColor[1] = 0x0;
+ gGamepads[i].ledColor[2] = 0x0;
+ }
+}
+
+void controller_maps_load(const char* mapsPath, bool appendMaps) {
+ // construct databases path
+ char dbpath[SYS_MAX_PATH] = "";
+ if (appendMaps) {
+ snprintf(dbpath, SYS_MAX_PATH, "%s/databases", mapsPath);
+ } else {
+ snprintf(dbpath, SYS_MAX_PATH, "%s", mapsPath);
+ }
+
+ // open directory
+ struct dirent* dir = NULL;
+
+ DIR* d = opendir(dbpath);
+ if (!d) { return; }
+
+ // iterate
+ char path[SYS_MAX_PATH] = { 0 };
+ while ((dir = readdir(d)) != NULL) {
+ // sanity check / fill path[]
+ if (!directory_sanity_check(dir, dbpath, path)) { continue; }
+
+ snprintf(path, SYS_MAX_PATH, "%s", dir->d_name);
+
+ // strip the name before the .
+ char* c = path;
+ while (*c != '\0') {
+ if (*c == '.') { *c = '\0'; break; }
+ c++;
+ }
+ if (strlen(path) == 0) { continue; }
+
+ // get the fullpath
+ char fullpath[SYS_MAX_PATH] = "";
+ snprintf(fullpath, SYS_MAX_PATH, "%s/%s.db", dbpath, path);
+
+ // open file
+ FILE* f = fopen(fullpath, "rb");
+ if (!f) {
+#ifdef DEVELOPMENT
+ printf("Failed to load controller map '%s.db'\n", path);
+#endif
+ continue;
+ }
+
+ // get file size
+ fseek(f, 0, SEEK_END);
+ int64_t size = ftell(f);
+ fseek(f, 0, SEEK_SET);
+
+ if (size <= 0) {
+#ifdef DEVELOPMENT
+ printf("Controller map empty or invalid: '%s.db'\n", path);
+#endif
+ fclose(f);
+ continue;
+ }
+
+ void* data = malloc(size);
+ if (!data) {
+ fclose(f);
+ continue;
+ }
+
+ if (fread(data, 1, size, f) != (size_t)size) {
+ free(data);
+ fclose(f);
+ continue;
+ }
+
+ fclose(f);
+
+ // SDL_RWFromConstMem uses int size
+ if (size > INT_MAX) {
+#ifdef DEVELOPMENT
+ printf("Controller map too large: '%s.db'\n", path);
+#endif
+ free(data);
+ continue;
+ }
+
+ SDL_RWops* rw = SDL_RWFromConstMem(data, (int)size);
+ if (!rw) {
+#ifdef DEVELOPMENT
+ printf("SDL_RWFromConstMem failed for '%s.db'\n", path);
+#endif
+ free(data);
+ continue;
+ }
+
+ // Load into SDL
+ int loadedMaps = SDL_GameControllerAddMappingsFromRW(rw, SDL_FALSE);
+
+ SDL_RWclose(rw);
+ free(data);
+
+ if (loadedMaps >= 0) {
+#ifdef DEVELOPMENT
+ printf("Controller Database: Loaded %d controller mapping(s) from '%s.db'\n", loadedMaps, path);
+ } else {
+ printf("Controller Database: Failed to load controller map from '%s.db'\n", path);
+#endif
+ }
+ }
+
+ closedir(d);
+}
+
#endif
\ No newline at end of file
diff --git a/src/pc/lua/utils/smlua_input_utils.h b/src/pc/lua/utils/smlua_input_utils.h
index 07249b852..3acf0425b 100644
--- a/src/pc/lua/utils/smlua_input_utils.h
+++ b/src/pc/lua/utils/smlua_input_utils.h
@@ -1,12 +1,20 @@
+
+#ifndef SMLUA_INPUT_UTILS_H
+#define SMLUA_INPUT_UTILS_H
+
+#define DATABASES_DIRECTORY "databases"
+
#define MAX_GAMEPADS 256
#define MAX_TOUCHPAD_FINGERS 10
#if defined(CAPI_SDL1) || defined(CAPI_SDL2)
+#include "types.h"
+
#include
#include
-struct Touchpad {
+struct Finger {
Vec2f pos;
f32 pressure;
bool touched;
@@ -16,6 +24,8 @@ struct Gamepad {
/* Misc Data */
+ SDL_GameController *controller; // Shouldn't be exposed, used to check if the controller exists
+
const char *name;
s32 index;
u8 playerIndex; // Used specifically for player LEDs, 0 by default, can also be used to assign controllers to players
@@ -48,12 +58,13 @@ struct Gamepad {
/* Touchpad */
- struct Touchpad touchpad[MAX_TOUCHPAD_FINGERS];
+ struct Finger touchpad[MAX_TOUCHPAD_FINGERS];
/* Rumble */
- u16 loRumble;
- u16 hiRumble;
+ u16 rumbleLowFreq;
+ u16 rumbleHighFreq;
+ u32 rumbleDurationMs;
/* LED Color */
@@ -61,20 +72,27 @@ struct Gamepad {
};
-struct Keyboard {
+struct Key {
/* Scancodes */
- bool keyDown;
- bool keyPressed;
- bool keyReleased;
+ bool down;
+ bool pressed;
+ bool released;
};
extern struct Gamepad gGamepads[MAX_GAMEPADS];
-extern struct Keyboard gKeyboard[SDL_NUM_SCANCODES];
+extern struct Key gKeyboard[SDL_NUM_SCANCODES];
/* |description|Returns the current gamepad index in the config file|descriptionEnd| */
u32 get_current_gamepad_index(void);
+/* |description|Returns the clipboard text|descriptionEnd| */
+const char* get_clipboard_text(void);
+/* |description|Sets the clipboard text|descriptionEnd| */
+void set_clipboard_text(const char* text);
+void clear_gamepad_input_data(void);
+void controller_maps_load(const char* mapsPath, bool appendMaps);
+#endif
#endif
\ No newline at end of file
diff --git a/src/pc/mods/mod_import.c b/src/pc/mods/mod_import.c
index ad9de35c7..370100ac9 100644
--- a/src/pc/mods/mod_import.c
+++ b/src/pc/mods/mod_import.c
@@ -6,6 +6,7 @@
#include "data/dynos.c.h"
#include "pc/djui/djui_language.h"
#include "pc/djui/djui_popup.h"
+#include "pc/lua/utils/smlua_input_utils.h"
#include "mods.h"
#include "mods_utils.h"
@@ -102,6 +103,54 @@ static bool mod_import_palette(char* src) {
return true;
}
+static bool mod_import_database(char* src) {
+ const char* databasesDirectory = fs_get_write_path(DATABASES_DIRECTORY);
+ fs_sys_mkdir(databasesDirectory);
+
+ char dst[SYS_MAX_PATH] = { 0 };
+ if (!concat_path(dst, (char*)databasesDirectory, path_basename(src))) {
+ LOG_ERROR("Failed to concat path for database db import");
+ return false;
+ }
+
+ FILE* fin = fopen(src, "rb");
+ if (fin == NULL) {
+ LOG_ERROR("Failed to open src path for database db import");
+ return false;
+ }
+
+ FILE* fout = fopen(dst, "wb");
+ if (fout == NULL) {
+ LOG_ERROR("Failed to open dst path for database db import");
+ fclose(fin);
+ return false;
+ }
+
+ size_t rbytes;
+ size_t wbytes;
+ unsigned char buff[8192];
+ do {
+ rbytes = fread(buff, 1, sizeof(buff), fin);
+ if (rbytes > 0) {
+ wbytes = fwrite(buff, 1, rbytes, fout);
+ } else {
+ wbytes = 0;
+ }
+ } while ((rbytes > 0) && (rbytes == wbytes));
+
+ fclose(fout);
+ fclose(fin);
+
+ if (wbytes) {
+ LOG_ERROR("Write error on database db import");
+ return false;
+ }
+
+ LOG_INFO("Imported database db: '%s' -> '%s'", src, dst);
+
+ return true;
+}
+
static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) {
LOG_INFO("Importing zip mod: %s", path);
@@ -256,6 +305,7 @@ bool mod_import_file(char* path) {
bool isLua = false;
bool isDynos = false;
bool isPalette = false;
+ bool isDatabase = false;
bool ret = false;
if (gNetworkType != NT_NONE && !path_ends_with(path, ".ini")) {
@@ -269,6 +319,9 @@ bool mod_import_file(char* path) {
} else if (path_ends_with(path, ".ini")) {
isPalette = true;
ret = mod_import_palette(path);
+ } else if (path_ends_with(path, ".db")) {
+ isDatabase = true;
+ ret = mod_import_database(path);
} else if (path_ends_with(path, ".zip")) {
ret = mod_import_zip(path, &isLua, &isDynos);
}
@@ -288,6 +341,9 @@ bool mod_import_file(char* path) {
} else if (isPalette) {
djui_language_replace(DLANG(NOTIF, IMPORT_PALETTE_SUCCESS), msg, SYS_MAX_PATH, '@', basename);
djui_popup_create(msg, 2);
+ } else if (isDatabase) {
+ djui_language_replace(DLANG(NOTIF, IMPORT_DATABASE_SUCCESS), msg, SYS_MAX_PATH, '@', basename);
+ djui_popup_create(msg, 2);
}
} else {
djui_language_replace(DLANG(NOTIF, IMPORT_FAIL), msg, SYS_MAX_PATH, '@', basename);
diff --git a/src/pc/network/network.c b/src/pc/network/network.c
index e550f99a6..4791caf53 100644
--- a/src/pc/network/network.c
+++ b/src/pc/network/network.c
@@ -667,34 +667,6 @@ void network_mod_dev_mode_reload(void) {
LOG_CONSOLE("===================================================");
}
-#if defined(CAPI_SDL1) || defined(CAPI_SDL2)
-static void clear_gamepad_input_data(void) {
- for (int i = 0; i < MAX_GAMEPADS; ++i) {
- for (int j = 0; j < SDL_CONTROLLER_BUTTON_MAX; ++j) {
- gGamepads[i].buttons[j] = false;
- }
- vec2s_set(gGamepads[i].leftStick, 0, 0);
- vec2s_set(gGamepads[i].rightStick, 0, 0);
- gGamepads[i].leftTrigger = 0;
- gGamepads[i].rightTrigger = 0;
- vec3f_set(gGamepads[i].accelerometer, 0.0f, 0.0f, 0.0f);
- vec3f_set(gGamepads[i].gyro, 0.0f, 0.0f, 0.0f);
- vec3f_set(gGamepads[i].leftAccelerometer, 0.0f, 0.0f, 0.0f);
- vec3f_set(gGamepads[i].leftGyro, 0.0f, 0.0f, 0.0f);
- vec3f_set(gGamepads[i].rightAccelerometer, 0.0f, 0.0f, 0.0f);
- vec3f_set(gGamepads[i].rightGyro, 0.0f, 0.0f, 0.0f);
- gGamepads[i].loRumble = 0;
- gGamepads[i].hiRumble = 0;
- for (int j = 0; j < MAX_TOUCHPAD_FINGERS; ++j) {
- vec2f_set(gGamepads[i].touchpad[j].pos, 0.0f, 0.0f);
- gGamepads[i].touchpad[j].pressure = 0.0f;
- gGamepads[i].touchpad[j].touched = false;
- }
- color_set(gGamepads[i].ledColor, 0x0, 0x0, 0x0);
- }
-}
-#endif
-
void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnecting) {
smlua_call_event_hooks(HOOK_ON_EXIT);