Addressing Peachy reviews

This commit is contained in:
xLuigiGamerx 2025-11-22 19:10:42 +03:00
parent 220e336639
commit fed9b71819
28 changed files with 489 additions and 186 deletions

View file

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

View file

@ -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" ],

View file

@ -102,6 +102,7 @@ override_field_invisible = {
"DialogEntry": [ "str" ],
"ModFsFile": [ "data", "capacity" ],
"ModFs": [ "files" ],
"Gamepad": [ "controller" ],
}
override_field_deprecated = {

View file

@ -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

View file

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

View file

@ -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 = {}

View file

@ -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

View file

@ -3534,6 +3534,7 @@
<br />
## [smlua_input_utils.h](#smlua_input_utils.h)
- DATABASES_DIRECTORY
- MAX_GAMEPADS
- MAX_TOUCHPAD_FINGERS

View file

@ -8477,6 +8477,50 @@ Returns the current gamepad index in the config file
[:arrow_up_small:](#)
<br />
## [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:](#)
<br />
## [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:](#)
<br />
---

View file

@ -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)
<br />

View file

@ -52,7 +52,7 @@ The `gGamepads[]` table is an array from `0` to `(MAX_GAMEPADS - 1)` that contai
<br />
## [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:](#)

View file

@ -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 @@
<br />
## [Finger](#Finger)
| Field | Type | Access |
| ----- | ---- | ------ |
| pos | [Vec2f](structs.md#Vec2f) | read-only |
| pressure | `number` | |
| touched | `boolean` | |
[:arrow_up_small:](#)
<br />
## [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 @@
<br />
## [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 @@
<br />
## [Touchpad](#Touchpad)
| Field | Type | Access |
| ----- | ---- | ------ |
| pos | [Vec2f](structs.md#Vec2f) | read-only |
| pressure | `number` | |
| touched | `boolean` | |
[:arrow_up_small:](#)
<br />
## [Vec2f](#Vec2f)
| Field | Type | Access |

View file

@ -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!"

View file

@ -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

View file

@ -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

View file

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

View file

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

View file

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

View file

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

View file

@ -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",

View file

@ -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,

View file

@ -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"

View file

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

View file

@ -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

View file

@ -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 <stdbool.h>
#include <SDL2/SDL.h>
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

View file

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

View file

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