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);