diff --git a/assets/scripts/init.js b/assets/scripts/init.js index ad7962e3..c6ead742 100644 --- a/assets/scripts/init.js +++ b/assets/scripts/init.js @@ -1,3 +1,5 @@ +require('./input.js'); + var OverworldScene = require('./overworldscene.js'); Scene.set(new OverworldScene()); \ No newline at end of file diff --git a/assets/scripts/input.js b/assets/scripts/input.js new file mode 100644 index 00000000..5d35e389 --- /dev/null +++ b/assets/scripts/input.js @@ -0,0 +1,88 @@ +// Copyright (c) 2026 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +// Default input bindings, ported from the old +// src/duskrpg/input/inputbindmap.h (removed) -- one INPUT_BIND_MAP per +// compile-time target became one branch here on Platform.current. + +function bindAll(pairs) { + for(var i = 0; i < pairs.length; i++) { + Input.bind(pairs[i][0], pairs[i][1]); + } +} + +if(Platform.current === 'linux' || Platform.current === 'knulli') { + bindAll([ + // Keyboard + [InputButton.W, InputBind.UP], + [InputButton.S, InputBind.DOWN], + [InputButton.A, InputBind.LEFT], + [InputButton.D, InputBind.RIGHT], + [InputButton.LEFT, InputBind.LEFT], + [InputButton.RIGHT, InputBind.RIGHT], + [InputButton.UP, InputBind.UP], + [InputButton.DOWN, InputBind.DOWN], + [InputButton.ENTER, InputBind.ACCEPT], + [InputButton.E, InputBind.ACCEPT], + [InputButton.SPACE, InputBind.ACCEPT], + [InputButton.TAB, InputBind.CANCEL], + [InputButton.Q, InputBind.CANCEL], + [InputButton.ESCAPE, InputBind.RAGEQUIT], + [InputButton.ENTER, InputBind.PAUSE], + ['`', InputBind.CONSOLE], + + // Gamepad + [InputButton.GAMEPAD_UP, InputBind.UP], + [InputButton.GAMEPAD_DOWN, InputBind.DOWN], + [InputButton.GAMEPAD_LEFT, InputBind.LEFT], + [InputButton.GAMEPAD_RIGHT, InputBind.RIGHT], + [InputButton.GAMEPAD_A, InputBind.ACCEPT], + [InputButton.GAMEPAD_B, InputBind.CANCEL], + [InputButton.GAMEPAD_BACK, InputBind.RAGEQUIT], + [InputButton.GAMEPAD_START, InputBind.PAUSE], + [InputButton.GAMEPAD_LSTICK_UP, InputBind.UP], + [InputButton.GAMEPAD_LSTICK_DOWN, InputBind.DOWN], + [InputButton.GAMEPAD_LSTICK_LEFT, InputBind.LEFT], + [InputButton.GAMEPAD_LSTICK_RIGHT, InputBind.RIGHT], + + // Mouse + [InputButton.MOUSE_X, InputBind.POINTERX], + [InputButton.MOUSE_Y, InputBind.POINTERY], + ]); +} else if(Platform.current === 'psp') { + bindAll([ + [InputButton.UP, InputBind.UP], + [InputButton.DOWN, InputBind.DOWN], + [InputButton.LEFT, InputBind.LEFT], + [InputButton.RIGHT, InputBind.RIGHT], + [InputButton.ACCEPT, InputBind.ACCEPT], + [InputButton.CANCEL, InputBind.CANCEL], + [InputButton.TRIANGLE, InputBind.CONSOLE], + [InputButton.SELECT, InputBind.RAGEQUIT], + [InputButton.START, InputBind.PAUSE], + [InputButton.LSTICK_UP, InputBind.UP], + [InputButton.LSTICK_DOWN, InputBind.DOWN], + [InputButton.LSTICK_LEFT, InputBind.LEFT], + [InputButton.LSTICK_RIGHT, InputBind.RIGHT], + ]); +} else if(Platform.current === 'gamecube' || Platform.current === 'wii') { + // GameCube and Wii share the same pad layout for now. + // TODO: Wiimote, USB Keyboard, probably more. + bindAll([ + [InputButton.UP, InputBind.UP], + [InputButton.DOWN, InputBind.DOWN], + [InputButton.LEFT, InputBind.LEFT], + [InputButton.RIGHT, InputBind.RIGHT], + [InputButton.LSTICK_UP, InputBind.UP], + [InputButton.LSTICK_DOWN, InputBind.DOWN], + [InputButton.LSTICK_LEFT, InputBind.LEFT], + [InputButton.LSTICK_RIGHT, InputBind.RIGHT], + [InputButton.A, InputBind.ACCEPT], + [InputButton.B, InputBind.CANCEL], + [InputButton.Z, InputBind.CONSOLE], + [InputButton.START, InputBind.RAGEQUIT], + [InputButton.START, InputBind.PAUSE], + ]); +} diff --git a/src/dusk/script/module/CMakeLists.txt b/src/dusk/script/module/CMakeLists.txt index 9aabe48d..1dc53ad2 100644 --- a/src/dusk/script/module/CMakeLists.txt +++ b/src/dusk/script/module/CMakeLists.txt @@ -14,3 +14,4 @@ add_subdirectory(require) add_subdirectory(display) add_subdirectory(time) add_subdirectory(console) +add_subdirectory(input) diff --git a/src/dusk/script/module/input/CMakeLists.txt b/src/dusk/script/module/input/CMakeLists.txt new file mode 100644 index 00000000..fde1ea90 --- /dev/null +++ b/src/dusk/script/module/input/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2026 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +target_sources(${DUSK_LIBRARY_TARGET_NAME} + PUBLIC + moduleinput.c +) diff --git a/src/dusk/script/module/input/moduleinput.c b/src/dusk/script/module/input/moduleinput.c new file mode 100644 index 00000000..c4905d0c --- /dev/null +++ b/src/dusk/script/module/input/moduleinput.c @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "moduleinput.h" +#include "script/module/modulebase.h" +#include "input/input.h" +#include "input/inputbutton.h" +#include "input/inputbind.h" + +#define MODULE_INPUT_BUTTON_NAME_MAX 64 + +moduleBaseFunction(moduleInputBindFn) { + moduleBaseRequireArgs(2); moduleBaseRequireString(0); moduleBaseRequireNumber(1); + + char_t name[MODULE_INPUT_BUTTON_NAME_MAX]; + moduleBaseToString(args[0], name, sizeof(name)); + const inputbind_t action = (inputbind_t)moduleBaseArgInt(1); + + inputBind(inputButtonGetByName(name), action); + return jerry_undefined(); +} + +moduleBaseFunction(moduleInputValueFn) { + moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); + return jerry_number(inputGetCurrentValue((inputbind_t)moduleBaseArgInt(0))); +} + +moduleBaseFunction(moduleInputLastValueFn) { + moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); + return jerry_number(inputGetLastValue((inputbind_t)moduleBaseArgInt(0))); +} + +moduleBaseFunction(moduleInputIsDownFn) { + moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); + return jerry_boolean(inputIsDown((inputbind_t)moduleBaseArgInt(0))); +} + +moduleBaseFunction(moduleInputWasDownFn) { + moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); + return jerry_boolean(inputWasDown((inputbind_t)moduleBaseArgInt(0))); +} + +moduleBaseFunction(moduleInputPressedFn) { + moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); + return jerry_boolean(inputPressed((inputbind_t)moduleBaseArgInt(0))); +} + +moduleBaseFunction(moduleInputReleasedFn) { + moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); + return jerry_boolean(inputReleased((inputbind_t)moduleBaseArgInt(0))); +} + +void moduleInputInit(void) { + jerry_value_t inputObj = jerry_object(); + moduleBaseDefineMethod(inputObj, "bind", moduleInputBindFn); + moduleBaseDefineMethod(inputObj, "value", moduleInputValueFn); + moduleBaseDefineMethod(inputObj, "lastValue", moduleInputLastValueFn); + moduleBaseDefineMethod(inputObj, "isDown", moduleInputIsDownFn); + moduleBaseDefineMethod(inputObj, "wasDown", moduleInputWasDownFn); + moduleBaseDefineMethod(inputObj, "pressed", moduleInputPressedFn); + moduleBaseDefineMethod(inputObj, "released", moduleInputReleasedFn); + moduleBaseSetValue("Input", inputObj); + jerry_value_free(inputObj); + + jerry_value_t bindObj = jerry_object(); + for(int32_t i = INPUT_BIND_NULL + 1; i < INPUT_BIND_COUNT; i++) { + moduleBaseObjectSetNumber(bindObj, INPUT_BIND_IDS[i], (double)i); + } + moduleBaseSetValue("InputBind", bindObj); + jerry_value_free(bindObj); + + jerry_value_t buttonObj = jerry_object(); + for( + const inputbuttondata_t *data = INPUT_BUTTON_DATA; + data->name != NULL; + data++ + ) { + moduleBaseObjectSetString(buttonObj, data->name, data->name); + } + moduleBaseSetValue("InputButton", buttonObj); + jerry_value_free(buttonObj); +} + +void moduleInputDispose(void) { +} diff --git a/src/dusk/script/module/input/moduleinput.h b/src/dusk/script/module/input/moduleinput.h new file mode 100644 index 00000000..a6490342 --- /dev/null +++ b/src/dusk/script/module/input/moduleinput.h @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once + +/** + * Registers the global `Input` object (bind/value/lastValue/isDown/wasDown/ + * pressed/released), plus two constant lookup objects: `InputBind` (the + * inputbind_t action enum, e.g. InputBind.UP) and `InputButton` (every + * named physical button in the compiled platform's INPUT_BUTTON_DATA + * table, e.g. InputButton.SELECT -- the exact set varies per platform). + */ +void moduleInputInit(void); + +/** + * Disposes the input module's script resources. + */ +void moduleInputDispose(void); diff --git a/src/dusk/script/module/modulebase.h b/src/dusk/script/module/modulebase.h index 8a955d2b..42309c39 100644 --- a/src/dusk/script/module/modulebase.h +++ b/src/dusk/script/module/modulebase.h @@ -331,6 +331,45 @@ static inline void moduleBaseDefineMethod( jerry_value_free(key); } +/** + * Set a named number property directly on an object (a plain data + * property, not a getter -- see moduleBaseDefineProperty for that). + * + * @param obj Target object. + * @param name Property name. + * @param value The numeric value to set. + */ +static inline void moduleBaseObjectSetNumber( + jerry_value_t obj, + const char_t *name, + double value +) { + jerry_value_t key = jerry_string_sz(name); + jerry_value_t val = jerry_number(value); + jerry_object_set(obj, key, val); + jerry_value_free(val); + jerry_value_free(key); +} + +/** + * Set a named string property directly on an object. + * + * @param obj Target object. + * @param name Property name. + * @param value The string value to set. + */ +static inline void moduleBaseObjectSetString( + jerry_value_t obj, + const char_t *name, + const char_t *value +) { + jerry_value_t key = jerry_string_sz(name); + jerry_value_t val = jerry_string_sz(value); + jerry_object_set(obj, key, val); + jerry_value_free(val); + jerry_value_free(key); +} + /** * Define a named global function. * diff --git a/src/dusk/script/module/modulelist.c b/src/dusk/script/module/modulelist.c index d4bdf25d..bff0ff4e 100644 --- a/src/dusk/script/module/modulelist.c +++ b/src/dusk/script/module/modulelist.c @@ -15,6 +15,7 @@ #include "script/module/entity/moduleentity.h" #include "script/module/scene/modulescene.h" #include "script/module/console/moduleconsole.h" +#include "script/module/input/moduleinput.h" void moduleListInit(void) { modulePlatform(); @@ -22,6 +23,7 @@ void moduleListInit(void) { moduleMeshInit(); moduleTimeInit(); moduleConsoleInit(); + moduleInputInit(); moduleComponentInit(); moduleComponentListInit(); moduleEntityInit(); @@ -33,6 +35,7 @@ void moduleListDispose(void) { moduleEntityDispose(); moduleComponentListDispose(); moduleComponentDispose(); + moduleInputDispose(); moduleConsoleDispose(); moduleTimeDispose(); moduleMeshDispose(); diff --git a/src/dusk/script/module/modulelist.h b/src/dusk/script/module/modulelist.h index 91334815..ca4e0850 100644 --- a/src/dusk/script/module/modulelist.h +++ b/src/dusk/script/module/modulelist.h @@ -9,8 +9,8 @@ /** * Registers every script module (Component + its typed per-type - * wrappers, Entity, Scene, require(), Mesh, Time, Console, the platform - * globals). Called once by scriptManagerInit(). + * wrappers, Entity, Scene, require(), Mesh, Time, Console, Input, the + * platform globals). Called once by scriptManagerInit(). */ void moduleListInit(void); diff --git a/src/dusk/script/module/moduleplatform.h b/src/dusk/script/module/moduleplatform.h index a3dc799d..26601dbc 100644 --- a/src/dusk/script/module/moduleplatform.h +++ b/src/dusk/script/module/moduleplatform.h @@ -13,7 +13,8 @@ #error "DUSK_TARGET_SYSTEM must be defined" #endif -#define MODULE_PLATFORM_VALUE "var PLATFORM = '" DUSK_TARGET_SYSTEM "';\n" +#define MODULE_PLATFORM_VALUE \ + "var Platform = { current: '" DUSK_TARGET_SYSTEM "' };\n" static inline void modulePlatform(void) { moduleBaseEval(MODULE_PLATFORM_VALUE); diff --git a/src/duskdolphin/input/inputdolphin.c b/src/duskdolphin/input/inputdolphin.c index 37c06dce..f3883000 100644 --- a/src/duskdolphin/input/inputdolphin.c +++ b/src/duskdolphin/input/inputdolphin.c @@ -6,87 +6,86 @@ */ #include "input/input.h" -#include "input/inputbindmap.h" #include "assert/assert.h" #include "log/log.h" #include "util/string.h" inputbuttondata_t INPUT_BUTTON_DATA[] = { #ifdef DUSK_INPUT_GAMEPAD - { .name = "a", { + { .name = "A", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_A } }, - { .name = "b", { + { .name = "B", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_B } }, - { .name = "x", { + { .name = "X", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_X } }, - { .name = "y", { + { .name = "Y", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_Y } }, - { .name = "start", { + { .name = "START", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_START } }, - { .name = "up", { + { .name = "UP", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_UP } }, - { .name = "down", { + { .name = "DOWN", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_DOWN } }, - { .name = "left", { + { .name = "LEFT", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_LEFT } }, - { .name = "right", { + { .name = "RIGHT", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_RIGHT } }, - { .name = "l", { + { .name = "L", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_TRIGGER_L } }, - { .name = "r", { + { .name = "R", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_TRIGGER_R } }, - { .name = "z", { + { .name = "Z", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_TRIGGER_Z } }, - { .name = "menu", { + { .name = "MENU", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_MENU } }, - { .name = "lstick_up", { + { .name = "LSTICK_UP", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_Y, .positive = true } } }, - { .name = "lstick_down", { + { .name = "LSTICK_DOWN", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_Y, .positive = false } } }, - { .name = "lstick_left", { + { .name = "LSTICK_LEFT", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_X, .positive = false } } }, - { .name = "lstick_right", { + { .name = "LSTICK_RIGHT", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_X, .positive = true } } }, - { .name = "rstick_up", { + { .name = "RSTICK_UP", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_X, .positive = true } } }, - { .name = "rstick_down", { + { .name = "RSTICK_DOWN", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_X, .positive = false } } }, - { .name = "rstick_left", { + { .name = "RSTICK_LEFT", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_Y, .positive = true } } }, - { .name = "rstick_right", { + { .name = "RSTICK_RIGHT", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_Y, .positive = false } } }, - { .name = "lstick_right", { + { .name = "LSTICK_RIGHT", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_Y, .positive = false } } }, - { .name = "ltrigger", { + { .name = "LTRIGGER", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_TRIGGER_LEFT, .positive = true } } }, - { .name = "rtrigger", { + { .name = "RTRIGGER", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_TRIGGER_RIGHT, @@ -103,14 +102,7 @@ errorret_t inputInitDolphin(void) { #error "Unknown Dolphin platform?" #endif - for( - const inputbindmapentry_t *entry = INPUT_BIND_MAP; - entry->buttonName != NULL; - entry++ - ) { - inputBind(inputButtonGetByName(entry->buttonName), entry->bind); - } - + // Default bindings now live in assets/scripts/input.js. errorOk(); } diff --git a/src/dusklinux/input/inputlinux.c b/src/dusklinux/input/inputlinux.c index b7bd6792..d8ee16cf 100644 --- a/src/dusklinux/input/inputlinux.c +++ b/src/dusklinux/input/inputlinux.c @@ -6,82 +6,81 @@ */ #include "input/input.h" -#include "input/inputbindmap.h" inputbuttondata_t INPUT_BUTTON_DATA[] = { #ifdef DUSK_INPUT_GAMEPAD - { .name = "gamepad_a", { + { .name = "GAMEPAD_A", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_A } }, - { .name = "gamepad_b", { + { .name = "GAMEPAD_B", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_B } }, - { .name = "gamepad_x", { + { .name = "GAMEPAD_X", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_X } }, - { .name = "gamepad_y", { + { .name = "GAMEPAD_Y", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_Y } }, - { .name = "gamepad_start", { + { .name = "GAMEPAD_START", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_START } }, - { .name = "gamepad_back", { + { .name = "GAMEPAD_BACK", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_BACK } }, - { .name = "gamepad_up", { + { .name = "GAMEPAD_UP", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_DPAD_UP } }, - { .name = "gamepad_down", { + { .name = "GAMEPAD_DOWN", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_DPAD_DOWN } }, - { .name = "gamepad_left", { + { .name = "GAMEPAD_LEFT", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_DPAD_LEFT } }, - { .name = "gamepad_right", { + { .name = "GAMEPAD_RIGHT", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_DPAD_RIGHT } }, - { .name = "gamepad_l1", { + { .name = "GAMEPAD_L1", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_LEFTSHOULDER } }, - { .name = "gamepad_r1", { + { .name = "GAMEPAD_R1", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER } }, - { .name = "gamepad_l3", { + { .name = "GAMEPAD_L3", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_LEFTSTICK } }, - { .name = "gamepad_r3", { + { .name = "GAMEPAD_R3", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_RIGHTSTICK } }, - { .name = "gamepad_lstick_down", { + { .name = "GAMEPAD_LSTICK_DOWN", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_LEFTY, .positive = true } } }, - { .name = "gamepad_lstick_up", { + { .name = "GAMEPAD_LSTICK_UP", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_LEFTY, .positive = false } } }, - { .name = "gamepad_lstick_right", { + { .name = "GAMEPAD_LSTICK_RIGHT", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_LEFTX, .positive = true } } }, - { .name = "gamepad_lstick_left", { + { .name = "GAMEPAD_LSTICK_LEFT", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_LEFTX, .positive = false } } }, - { .name = "gamepad_rstick_down", { + { .name = "GAMEPAD_RSTICK_DOWN", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_RIGHTY, .positive = true } } }, - { .name = "gamepad_rstick_up", { + { .name = "GAMEPAD_RSTICK_UP", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_RIGHTY, .positive = false } } }, - { .name = "gamepad_rstick_right", { + { .name = "GAMEPAD_RSTICK_RIGHT", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_RIGHTX, .positive = true } } }, - { .name = "gamepad_rstick_left", { + { .name = "GAMEPAD_RSTICK_LEFT", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_RIGHTX, .positive = false } } }, - { .name = "gamepad_l2", { + { .name = "GAMEPAD_L2", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_TRIGGERLEFT, .positive = true } } }, - { .name = "gamepad_r2", { + { .name = "GAMEPAD_R2", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_TRIGGERRIGHT, @@ -90,97 +89,97 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = { #ifdef DUSK_INPUT_POINTER - { .name = "mouse_x", { + { .name = "MOUSE_X", { .type = INPUT_BUTTON_TYPE_POINTER, .pointerAxis = INPUT_POINTER_AXIS_X } }, - { .name = "mouse_y", { + { .name = "MOUSE_Y", { .type = INPUT_BUTTON_TYPE_POINTER, .pointerAxis = INPUT_POINTER_AXIS_Y } }, - { .name = "mouse_wheel_x", { + { .name = "MOUSE_WHEEL_X", { .type = INPUT_BUTTON_TYPE_POINTER, .pointerAxis = INPUT_POINTER_AXIS_WHEEL_X } }, - { .name = "mouse_wheel_y", { + { .name = "MOUSE_WHEEL_Y", { .type = INPUT_BUTTON_TYPE_POINTER, .pointerAxis = INPUT_POINTER_AXIS_WHEEL_Y } }, #endif #ifdef DUSK_INPUT_KEYBOARD - { .name = "a", { + { .name = "A", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_A } }, - { .name = "b", { + { .name = "B", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_B } }, - { .name = "c", { + { .name = "C", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_C } }, - { .name = "d", { + { .name = "D", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_D } }, - { .name = "e", { + { .name = "E", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_E } }, - { .name = "f", { + { .name = "F", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F } }, - { .name = "g", { + { .name = "G", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_G } }, - { .name = "h", { + { .name = "H", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_H } }, - { .name = "i", { + { .name = "I", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_I } }, - { .name = "j", { + { .name = "J", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_J } }, - { .name = "k", { + { .name = "K", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_K } }, - { .name = "l", { + { .name = "L", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_L } }, - { .name = "m", { + { .name = "M", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_M } }, - { .name = "n", { + { .name = "N", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_N } }, - { .name = "o", { + { .name = "O", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_O } }, - { .name = "p", { + { .name = "P", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_P } }, - { .name = "q", { + { .name = "Q", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_Q } }, - { .name = "r", { + { .name = "R", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_R } }, - { .name = "s", { + { .name = "S", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_S } }, - { .name = "t", { + { .name = "T", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_T } }, - { .name = "u", { + { .name = "U", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_U } }, - { .name = "v", { + { .name = "V", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_V } }, - { .name = "w", { + { .name = "W", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_W } }, - { .name = "x", { + { .name = "X", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_X } }, - { .name = "y", { + { .name = "Y", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_Y } }, - { .name = "z", { + { .name = "Z", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_Z } }, @@ -215,197 +214,197 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_9 } }, - { .name = "space", { + { .name = "SPACE", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_SPACE } }, - { .name = "shift", { + { .name = "SHIFT", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_LSHIFT } }, - { .name = "lshift", { + { .name = "LSHIFT", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_LSHIFT } }, - { .name = "rshift", { + { .name = "RSHIFT", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_RSHIFT } }, - { .name = "lctrl", { + { .name = "LCTRL", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_LCTRL } }, - { .name = "rctrl", { + { .name = "RCTRL", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_RCTRL } }, - { .name = "ctrl", { + { .name = "CTRL", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_LCTRL } }, - { .name = "lalt", { + { .name = "LALT", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_LALT } }, - { .name = "ralt", { + { .name = "RALT", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_RALT } }, - { .name = "tab", { + { .name = "TAB", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_TAB } }, - { .name = "enter", { + { .name = "ENTER", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_RETURN } }, - { .name = "backspace", { + { .name = "BACKSPACE", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_BACKSPACE } }, - { .name = "escape", { + { .name = "ESCAPE", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_ESCAPE } }, - { .name = "esc", { + { .name = "ESC", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_ESCAPE } }, - { .name = "up", { + { .name = "UP", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_UP } }, - { .name = "down", { + { .name = "DOWN", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_DOWN } }, - { .name = "left", { + { .name = "LEFT", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_LEFT } }, - { .name = "right", { + { .name = "RIGHT", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_RIGHT } }, - { .name = "pageup", { + { .name = "PAGEUP", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_PAGEUP } }, - { .name = "pagedown", { + { .name = "PAGEDOWN", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_PAGEDOWN } }, - { .name = "home", { + { .name = "HOME", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_HOME } }, - { .name = "end", { + { .name = "END", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_END } }, - { .name = "insert", { + { .name = "INSERT", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_INSERT } }, - { .name = "delete", { + { .name = "DELETE", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_DELETE } }, - { .name = "f1", { + { .name = "F1", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F1 } }, - { .name = "f2", { + { .name = "F2", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F2 } }, - { .name = "f3", { + { .name = "F3", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F3 } }, - { .name = "f4", { + { .name = "F4", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F4 } }, - { .name = "f5", { + { .name = "F5", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F5 } }, - { .name = "f6", { + { .name = "F6", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F6 } }, - { .name = "f7", { + { .name = "F7", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F7 } }, - { .name = "f8", { + { .name = "F8", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F8 } }, - { .name = "f9", { + { .name = "F9", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F9 } }, - { .name = "f10", { + { .name = "F10", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F10 } }, - { .name = "f11", { + { .name = "F11", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F11 } }, - { .name = "f12", { + { .name = "F12", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F12 } }, - { .name = "f13", { + { .name = "F13", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F13 } }, - { .name = "f14", { + { .name = "F14", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F14 } }, - { .name = "f15", { + { .name = "F15", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F15 } }, - { .name = "f16", { + { .name = "F16", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F16 } }, - { .name = "f17", { + { .name = "F17", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F17 } }, - { .name = "f18", { + { .name = "F18", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F18 } }, - { .name = "f19", { + { .name = "F19", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F19 } }, - { .name = "f20", { + { .name = "F20", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F20 } }, - { .name = "f21", { + { .name = "F21", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F21 } }, - { .name = "f22", { + { .name = "F22", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F22 } }, - { .name = "f23", { + { .name = "F23", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F23 } }, - { .name = "f24", { + { .name = "F24", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_F24 } }, - { .name = "minus", { + { .name = "MINUS", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_MINUS } }, - { .name = "equals", { + { .name = "EQUALS", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_EQUALS } }, - { .name = "leftbracket", { + { .name = "LEFTBRACKET", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_LEFTBRACKET } }, - { .name = "rightbracket", { + { .name = "RIGHTBRACKET", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_RIGHTBRACKET } }, - { .name = "backslash", { + { .name = "BACKSLASH", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_BACKSLASH } }, - { .name = "semicolon", { + { .name = "SEMICOLON", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_SEMICOLON } }, - { .name = "apostrophe", { + { .name = "APOSTROPHE", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_APOSTROPHE } }, - { .name = "grave", { + { .name = "GRAVE", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_GRAVE } }, - { .name = "comma", { + { .name = "COMMA", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_COMMA } }, - { .name = "period", { + { .name = "PERIOD", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_PERIOD } }, - { .name = "slash", { + { .name = "SLASH", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_SLASH } }, - { .name = "caps", { + { .name = "CAPS", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_CAPSLOCK } }, - { .name = "capslock", { + { .name = "CAPSLOCK", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_CAPSLOCK } }, - { .name = "numlock", { + { .name = "NUMLOCK", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_NUMLOCKCLEAR } }, - { .name = "scrollock", { + { .name = "SCROLLOCK", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_SCROLLLOCK } }, @@ -443,55 +442,55 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_SLASH } }, - { .name = "kp_0", { + { .name = "KP_0", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_0 } }, - { .name = "kp_1", { + { .name = "KP_1", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_1 } }, - { .name = "kp_2", { + { .name = "KP_2", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_2 } }, - { .name = "kp_3", { + { .name = "KP_3", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_3 } }, - { .name = "kp_4", { + { .name = "KP_4", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_4 } }, - { .name = "kp_5", { + { .name = "KP_5", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_5 } }, - { .name = "kp_6", { + { .name = "KP_6", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_6 } }, - { .name = "kp_7", { + { .name = "KP_7", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_7 } }, - { .name = "kp_8", { + { .name = "KP_8", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_8 } }, - { .name = "kp_9", { + { .name = "KP_9", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_9 } }, - { .name = "kp_period", { + { .name = "KP_PERIOD", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_PERIOD } }, - { .name = "kp_divide", { + { .name = "KP_DIVIDE", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_DIVIDE } }, - { .name = "kp_multiply", { + { .name = "KP_MULTIPLY", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_MULTIPLY } }, - { .name = "kp_minus", { + { .name = "KP_MINUS", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_MINUS } }, - { .name = "kp_plus", { + { .name = "KP_PLUS", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_PLUS } }, - { .name = "kp_enter", { + { .name = "KP_ENTER", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_ENTER } }, - { .name = "kp_equals", { + { .name = "KP_EQUALS", { .type = INPUT_BUTTON_TYPE_KEYBOARD, .scancode = SDL_SCANCODE_KP_EQUALS } }, #endif @@ -500,14 +499,7 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = { }; errorret_t inputInitLinux(void) { - for( - const inputbindmapentry_t *entry = INPUT_BIND_MAP; - entry->buttonName != NULL; - entry++ - ) { - inputBind(inputButtonGetByName(entry->buttonName), entry->bind); - } - + // Default bindings now live in assets/scripts/input.js. errorOk(); } diff --git a/src/duskpsp/input/inputpsp.c b/src/duskpsp/input/inputpsp.c index 2cde5a2f..16a0d366 100644 --- a/src/duskpsp/input/inputpsp.c +++ b/src/duskpsp/input/inputpsp.c @@ -6,67 +6,66 @@ */ #include "input/input.h" -#include "input/inputbindmap.h" // #define INPUT_PSP_GAMEPAD_BUTTON_ACCEPT INPUT_SDL2_GAMEPAD_BUTTON_CUSTOM // #define INPUT_PSP_GAMEPAD_BUTTON_CANCEL INPUT_SDL2_GAMEPAD_BUTTON_CUSTOM inputbuttondata_t INPUT_BUTTON_DATA[] = { - { .name = "triangle", { + { .name = "TRIANGLE", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_Y } }, - { .name = "cross", { + { .name = "CROSS", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_A } }, - { .name = "circle", { + { .name = "CIRCLE", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_B } }, - { .name = "square", { + { .name = "SQUARE", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_X } }, - { .name = "start", { + { .name = "START", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_START } }, - { .name = "select", { + { .name = "SELECT", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_BACK } }, - { .name = "up", { + { .name = "UP", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_DPAD_UP } }, - { .name = "down", { + { .name = "DOWN", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_DPAD_DOWN } }, - { .name = "left", { + { .name = "LEFT", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_DPAD_LEFT } }, - { .name = "right", { + { .name = "RIGHT", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_DPAD_RIGHT } }, - { .name = "l", { + { .name = "L", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_LEFTSHOULDER } }, - { .name = "r", { + { .name = "R", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER } }, // Refer to systempsp.c for some extra info. - { .name = "accept", { + { .name = "ACCEPT", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_A } }, - { .name = "cancel", { + { .name = "CANCEL", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = SDL_CONTROLLER_BUTTON_B } }, - { .name = "lstick_down", { + { .name = "LSTICK_DOWN", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_LEFTY, .positive = true } } }, - { .name = "lstick_up", { + { .name = "LSTICK_UP", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_LEFTY, .positive = false } } }, - { .name = "lstick_right", { + { .name = "LSTICK_RIGHT", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_LEFTX, .positive = true } } }, - { .name = "lstick_left", { + { .name = "LSTICK_LEFT", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = SDL_CONTROLLER_AXIS_LEFTX, .positive = false } } }, @@ -74,14 +73,7 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = { }; errorret_t inputInitPSP(void) { - for( - const inputbindmapentry_t *entry = INPUT_BIND_MAP; - entry->buttonName != NULL; - entry++ - ) { - inputBind(inputButtonGetByName(entry->buttonName), entry->bind); - } - + // Default bindings now live in assets/scripts/input.js. errorOk(); } diff --git a/src/duskrpg/input/inputbindmap.h b/src/duskrpg/input/inputbindmap.h deleted file mode 100644 index e857b1e4..00000000 --- a/src/duskrpg/input/inputbindmap.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "input/inputbind.h" - -typedef struct { - const char_t *buttonName; - inputbind_t bind; -} inputbindmapentry_t; - -#ifdef DUSK_LINUX - static const inputbindmapentry_t INPUT_BIND_MAP[] = { - #ifdef DUSK_INPUT_KEYBOARD - { .buttonName = "w", .bind = INPUT_BIND_UP }, - { .buttonName = "s", .bind = INPUT_BIND_DOWN }, - { .buttonName = "a", .bind = INPUT_BIND_LEFT }, - { .buttonName = "d", .bind = INPUT_BIND_RIGHT }, - { .buttonName = "left", .bind = INPUT_BIND_LEFT }, - { .buttonName = "right", .bind = INPUT_BIND_RIGHT }, - { .buttonName = "up", .bind = INPUT_BIND_UP }, - { .buttonName = "down", .bind = INPUT_BIND_DOWN }, - { .buttonName = "enter", .bind = INPUT_BIND_ACCEPT }, - { .buttonName = "e", .bind = INPUT_BIND_ACCEPT }, - { .buttonName = "space", .bind = INPUT_BIND_ACCEPT }, - { .buttonName = "tab", .bind = INPUT_BIND_CANCEL }, - { .buttonName = "q", .bind = INPUT_BIND_CANCEL }, - { .buttonName = "escape", .bind = INPUT_BIND_RAGEQUIT }, - { .buttonName = "enter", .bind = INPUT_BIND_PAUSE }, - { .buttonName = "`", .bind = INPUT_BIND_CONSOLE }, - #endif - - #ifdef DUSK_INPUT_GAMEPAD - { .buttonName = "gamepad_up", .bind = INPUT_BIND_UP }, - { .buttonName = "gamepad_down", .bind = INPUT_BIND_DOWN }, - { .buttonName = "gamepad_left", .bind = INPUT_BIND_LEFT }, - { .buttonName = "gamepad_right", .bind = INPUT_BIND_RIGHT }, - { .buttonName = "gamepad_a", .bind = INPUT_BIND_ACCEPT }, - { .buttonName = "gamepad_b", .bind = INPUT_BIND_CANCEL }, - { .buttonName = "gamepad_back", .bind = INPUT_BIND_RAGEQUIT }, - { .buttonName = "gamepad_start", .bind = INPUT_BIND_PAUSE }, - { .buttonName = "gamepad_lstick_up", .bind = INPUT_BIND_UP }, - { .buttonName = "gamepad_lstick_down", .bind = INPUT_BIND_DOWN }, - { .buttonName = "gamepad_lstick_left", .bind = INPUT_BIND_LEFT }, - { .buttonName = "gamepad_lstick_right", .bind = INPUT_BIND_RIGHT }, - #endif - - #ifdef DUSK_INPUT_POINTER - { .buttonName = "mouse_x", .bind = INPUT_BIND_POINTERX }, - { .buttonName = "mouse_y", .bind = INPUT_BIND_POINTERY }, - #endif - - { .buttonName = NULL, .bind = INPUT_BIND_NULL } - }; -#endif - -#ifdef DUSK_PSP - static const inputbindmapentry_t INPUT_BIND_MAP[] = { - { .buttonName = "up", .bind = INPUT_BIND_UP }, - { .buttonName = "down", .bind = INPUT_BIND_DOWN }, - { .buttonName = "left", .bind = INPUT_BIND_LEFT }, - { .buttonName = "right", .bind = INPUT_BIND_RIGHT }, - { .buttonName = "accept", .bind = INPUT_BIND_ACCEPT }, - { .buttonName = "cancel", .bind = INPUT_BIND_CANCEL }, - { .buttonName = "triangle", .bind = INPUT_BIND_CONSOLE }, - { .buttonName = "select", .bind = INPUT_BIND_RAGEQUIT }, - { .buttonName = "start", .bind = INPUT_BIND_PAUSE }, - { .buttonName = "lstick_up", .bind = INPUT_BIND_UP }, - { .buttonName = "lstick_down", .bind = INPUT_BIND_DOWN }, - { .buttonName = "lstick_left", .bind = INPUT_BIND_LEFT }, - { .buttonName = "lstick_right", .bind = INPUT_BIND_RIGHT }, - { .buttonName = NULL, .bind = INPUT_BIND_NULL } - }; -#endif - -// GameCube and Wii share the same pad layout for now. -// TODO: Wiimote, USB Keyboard, probably more. -#if defined(DUSK_GAMECUBE) || defined(DUSK_WII) - static const inputbindmapentry_t INPUT_BIND_MAP[] = { - { .buttonName = "up", .bind = INPUT_BIND_UP }, - { .buttonName = "down", .bind = INPUT_BIND_DOWN }, - { .buttonName = "left", .bind = INPUT_BIND_LEFT }, - { .buttonName = "right", .bind = INPUT_BIND_RIGHT }, - { .buttonName = "lstick_up", .bind = INPUT_BIND_UP }, - { .buttonName = "lstick_down", .bind = INPUT_BIND_DOWN }, - { .buttonName = "lstick_left", .bind = INPUT_BIND_LEFT }, - { .buttonName = "lstick_right", .bind = INPUT_BIND_RIGHT }, - { .buttonName = "a", .bind = INPUT_BIND_ACCEPT }, - { .buttonName = "b", .bind = INPUT_BIND_CANCEL }, - { .buttonName = "z", .bind = INPUT_BIND_CONSOLE }, - { .buttonName = "start", .bind = INPUT_BIND_RAGEQUIT }, - { .buttonName = "start", .bind = INPUT_BIND_PAUSE }, - { .buttonName = NULL, .bind = INPUT_BIND_NULL } - }; -#endif diff --git a/test/script/CMakeLists.txt b/test/script/CMakeLists.txt index dead9b7c..d47d4bb0 100644 --- a/test/script/CMakeLists.txt +++ b/test/script/CMakeLists.txt @@ -10,3 +10,12 @@ dusktest(test_modulerequire.c) dusktest(test_scriptdef.c) dusktest(test_moduleconsole.c) + +dusktest(test_moduleplatform.c) + +dusktest(test_moduleinput.c) + +dusktest(test_scriptinput.c) +target_compile_definitions(test_scriptinput PRIVATE + DUSK_ASSETS_DIR="${DUSK_ASSETS_DIR}" +) diff --git a/test/script/test_moduleinput.c b/test/script/test_moduleinput.c new file mode 100644 index 00000000..c7b575dc --- /dev/null +++ b/test/script/test_moduleinput.c @@ -0,0 +1,146 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "dusktest.h" +#include "script/scriptmanager.h" +#include "script/module/modulebase.h" +#include "input/input.h" +#include "input/inputbutton.h" +#include "input/inputbind.h" + +static int input_setup(void **state) { + errorret_t ret = inputInit(); + if(errorIsNotOk(ret)) { errorCatch(ret); return -1; } + + ret = scriptManagerInit(); + if(errorIsNotOk(ret)) { errorCatch(ret); return -1; } + + return 0; +} + +static int input_teardown(void **state) { + errorret_t ret = scriptManagerDispose(); + if(errorIsNotOk(ret)) errorCatch(ret); + return 0; +} + +static void test_inputbind_exposes_action_ordinals(void **state) { + jerry_value_t result; + errorret_t ret = scriptManagerExec("InputBind.UP;", &result); + assert_true(errorIsOk(ret)); + assert_true(jerry_value_is_number(result)); + assert_int_equal(moduleBaseValueInt(result), (int32_t)INPUT_BIND_UP); + jerry_value_free(result); + + ret = scriptManagerExec("InputBind.ACCEPT;", &result); + assert_true(errorIsOk(ret)); + assert_int_equal(moduleBaseValueInt(result), (int32_t)INPUT_BIND_ACCEPT); + jerry_value_free(result); +} + +static void test_inputbutton_exposes_platform_button_names(void **state) { + jerry_value_t result; + errorret_t ret = scriptManagerExec("InputButton.UP;", &result); + assert_true(errorIsOk(ret)); + assert_true(jerry_value_is_string(result)); + + char_t buf[16]; + moduleBaseToString(result, buf, sizeof(buf)); + assert_string_equal(buf, "UP"); + + jerry_value_free(result); +} + +static void test_input_bind_updates_button_action(void **state) { + jerry_value_t result; + errorret_t ret = scriptManagerExec( + "Input.bind(InputButton.UP, InputBind.ACCEPT);", &result + ); + assert_true(errorIsOk(ret)); + jerry_value_free(result); + + inputbuttondata_t *data = inputButtonGetData(inputButtonGetByName("UP")); + assert_non_null(data); + assert_int_equal(data->action, INPUT_BIND_ACCEPT); +} + +static void test_input_bind_accepts_plain_string(void **state) { + // InputButton.* values are just the button's own name string, so a bare + // string works identically -- confirms Input.bind() doesn't require the + // constant object. + jerry_value_t result; + errorret_t ret = scriptManagerExec( + "Input.bind('down', InputBind.CANCEL);", &result + ); + assert_true(errorIsOk(ret)); + jerry_value_free(result); + + inputbuttondata_t *data = inputButtonGetData(inputButtonGetByName("DOWN")); + assert_non_null(data); + assert_int_equal(data->action, INPUT_BIND_CANCEL); +} + +static void test_input_query_functions_default_to_zero(void **state) { + // No inputUpdate() has run (it would touch real SDL/platform input state, + // unavailable in this headless test), so every action still reads its + // inputInit()-zeroed default. + jerry_value_t result; + + errorret_t ret = scriptManagerExec("Input.isDown(InputBind.UP);", &result); + assert_true(errorIsOk(ret)); + assert_false(jerry_value_is_true(result)); + jerry_value_free(result); + + ret = scriptManagerExec("Input.wasDown(InputBind.UP);", &result); + assert_true(errorIsOk(ret)); + assert_false(jerry_value_is_true(result)); + jerry_value_free(result); + + ret = scriptManagerExec("Input.pressed(InputBind.UP);", &result); + assert_true(errorIsOk(ret)); + assert_false(jerry_value_is_true(result)); + jerry_value_free(result); + + ret = scriptManagerExec("Input.released(InputBind.UP);", &result); + assert_true(errorIsOk(ret)); + assert_false(jerry_value_is_true(result)); + jerry_value_free(result); + + ret = scriptManagerExec("Input.value(InputBind.UP);", &result); + assert_true(errorIsOk(ret)); + assert_true(jerry_value_is_number(result)); + assert_float_equal((float_t)jerry_value_as_number(result), 0.0f, 0.0001f); + jerry_value_free(result); + + ret = scriptManagerExec("Input.lastValue(InputBind.UP);", &result); + assert_true(errorIsOk(ret)); + assert_float_equal((float_t)jerry_value_as_number(result), 0.0f, 0.0001f); + jerry_value_free(result); +} + +int main(void) { + assertInit(); + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown( + test_inputbind_exposes_action_ordinals, input_setup, input_teardown + ), + cmocka_unit_test_setup_teardown( + test_inputbutton_exposes_platform_button_names, + input_setup, input_teardown + ), + cmocka_unit_test_setup_teardown( + test_input_bind_updates_button_action, input_setup, input_teardown + ), + cmocka_unit_test_setup_teardown( + test_input_bind_accepts_plain_string, input_setup, input_teardown + ), + cmocka_unit_test_setup_teardown( + test_input_query_functions_default_to_zero, input_setup, input_teardown + ), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/test/script/test_moduleplatform.c b/test/script/test_moduleplatform.c new file mode 100644 index 00000000..75dcdb29 --- /dev/null +++ b/test/script/test_moduleplatform.c @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "dusktest.h" +#include "script/scriptmanager.h" +#include "script/module/modulebase.h" + +static int platform_setup(void **state) { + errorret_t ret = scriptManagerInit(); + if(errorIsNotOk(ret)) { errorCatch(ret); return -1; } + return 0; +} + +static int platform_teardown(void **state) { + errorret_t ret = scriptManagerDispose(); + if(errorIsNotOk(ret)) errorCatch(ret); + return 0; +} + +static void test_platform_current_matches_target_system(void **state) { + jerry_value_t result; + errorret_t ret = scriptManagerExec("Platform.current;", &result); + assert_true(errorIsOk(ret)); + assert_true(jerry_value_is_string(result)); + + char_t buf[32]; + moduleBaseToString(result, buf, sizeof(buf)); + assert_string_equal(buf, DUSK_TARGET_SYSTEM); + + jerry_value_free(result); +} + +int main(void) { + assertInit(); + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown( + test_platform_current_matches_target_system, + platform_setup, platform_teardown + ), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/test/script/test_scriptinput.c b/test/script/test_scriptinput.c new file mode 100644 index 00000000..419a18ba --- /dev/null +++ b/test/script/test_scriptinput.c @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "dusktest.h" +#include "util/memory.h" +#include "asset/asset.h" +#include "input/input.h" +#include "input/inputbutton.h" +#include "input/inputbind.h" +#include "script/scriptmanager.h" +#include +#include +#include + +#ifndef DUSK_ASSETS_DIR + #error "DUSK_ASSETS_DIR must be defined" +#endif + +// Runs the real, shipped assets/scripts/input.js (read straight off disk, +// not a copy embedded in this test) through the real require()/asset-zip +// path, so this actually verifies what ships -- on whichever platform this +// test binary itself was built for (Platform.current === "linux" here). + +static char_t *readFile(const char_t *relativePath) { + char_t path[512]; + snprintf(path, sizeof(path), "%s/%s", DUSK_ASSETS_DIR, relativePath); + + FILE *f = fopen(path, "rb"); + assert_non_null(f); + + fseek(f, 0, SEEK_END); + long size = ftell(f); + fseek(f, 0, SEEK_SET); + + char_t *buf = (char_t *)memoryAllocate((size_t)size + 1); + size_t read = fread(buf, 1, (size_t)size, f); + fclose(f); + buf[read] = '\0'; + + return buf; +} + +static zip_t *g_zip = NULL; + +static int input_setup(void **state) { + errorret_t ret = inputInit(); + if(errorIsNotOk(ret)) { errorCatch(ret); return -1; } + + ret = scriptManagerInit(); + if(errorIsNotOk(ret)) { errorCatch(ret); return -1; } + + zip_error_t err; + zip_error_init(&err); + + zip_source_t *write_src = zip_source_buffer_create(NULL, 0, 1, &err); + if(!write_src) return -1; + + zip_t *za = zip_open_from_source(write_src, ZIP_TRUNCATE, &err); + if(!za) { zip_source_free(write_src); return -1; } + + char_t *inputJsSrc = readFile("scripts/input.js"); + zip_source_t *s = zip_source_buffer(za, inputJsSrc, strlen(inputJsSrc), 0); + if(zip_file_add(za, "scripts/input.js", s, ZIP_FL_OVERWRITE) < 0) { + zip_close(za); + return -1; + } + + zip_source_keep(write_src); + if(zip_close(za) != 0) { zip_source_free(write_src); return -1; } + memoryFree(inputJsSrc); + + zip_stat_t zs; + memset(&zs, 0, sizeof(zs)); + if(zip_source_stat(write_src, &zs) != 0 || !(zs.valid & ZIP_STAT_SIZE)) { + zip_source_free(write_src); return -1; + } + + void *zipbuf = malloc((size_t)zs.size); + if(!zipbuf) { zip_source_free(write_src); return -1; } + + if(zip_source_open(write_src) != 0) { + free(zipbuf); zip_source_free(write_src); return -1; + } + zip_source_read(write_src, zipbuf, (zip_uint64_t)zs.size); + zip_source_close(write_src); + zip_source_free(write_src); + + zip_error_init(&err); + zip_source_t *read_src = zip_source_buffer_create( + zipbuf, (zip_uint64_t)zs.size, 1, &err + ); + if(!read_src) { free(zipbuf); return -1; } + + g_zip = zip_open_from_source(read_src, 0, &err); + if(!g_zip) { zip_source_free(read_src); return -1; } + + ASSET.zip = g_zip; + return 0; +} + +static int input_teardown(void **state) { + errorret_t ret = scriptManagerDispose(); + if(errorIsNotOk(ret)) errorCatch(ret); + + if(g_zip) { zip_close(g_zip); g_zip = NULL; } + ASSET.zip = NULL; + return 0; +} + +static void test_real_input_js_binds_linux_defaults(void **state) { + errorret_t ret = scriptManagerExecFile("scripts/input.js", NULL); + assert_true(errorIsOk(ret)); + + inputbuttondata_t *data; + + data = inputButtonGetData(inputButtonGetByName("W")); + assert_non_null(data); + assert_int_equal(data->action, INPUT_BIND_UP); + + data = inputButtonGetData(inputButtonGetByName("ESCAPE")); + assert_non_null(data); + assert_int_equal(data->action, INPUT_BIND_RAGEQUIT); + + data = inputButtonGetData(inputButtonGetByName("`")); + assert_non_null(data); + assert_int_equal(data->action, INPUT_BIND_CONSOLE); + + data = inputButtonGetData(inputButtonGetByName("GAMEPAD_A")); + assert_non_null(data); + assert_int_equal(data->action, INPUT_BIND_ACCEPT); + + data = inputButtonGetData(inputButtonGetByName("GAMEPAD_LSTICK_UP")); + assert_non_null(data); + assert_int_equal(data->action, INPUT_BIND_UP); + + data = inputButtonGetData(inputButtonGetByName("MOUSE_X")); + assert_non_null(data); + assert_int_equal(data->action, INPUT_BIND_POINTERX); + + data = inputButtonGetData(inputButtonGetByName("MOUSE_Y")); + assert_non_null(data); + assert_int_equal(data->action, INPUT_BIND_POINTERY); +} + +int main(void) { + assertInit(); + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown( + test_real_input_js_binds_linux_defaults, input_setup, input_teardown + ), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/types/index.d.ts b/types/index.d.ts index 278b9caa..d4d9ad81 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -13,3 +13,5 @@ /// /// /// +/// +/// diff --git a/types/input/input.d.ts b/types/input/input.d.ts new file mode 100644 index 00000000..da067fd8 --- /dev/null +++ b/types/input/input.d.ts @@ -0,0 +1,53 @@ +// Copyright (c) 2026 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +/** + * Input action bindings (see duskrpg's input/inputbind.h). Values are the + * native inputbind_t enum ordinals. + */ +declare const InputBind: { + readonly UP: number; + readonly DOWN: number; + readonly LEFT: number; + readonly RIGHT: number; + readonly ACCEPT: number; + readonly CANCEL: number; + readonly PAUSE: number; + readonly RAGEQUIT: number; + readonly CONSOLE: number; + readonly POINTERX: number; + readonly POINTERY: number; +}; + +/** + * Every named physical button registered in the compiled platform's + * INPUT_BUTTON_DATA table (see e.g. src/duskpsp/input/inputpsp.c). The + * exact set of keys varies per platform -- e.g. InputButton.SELECT exists + * on PSP, InputButton.GAMEPAD_BACK on Linux/SDL2. Each value is just the + * button's own name string, suitable for passing straight to Input.bind(). + */ +declare const InputButton: { + readonly [name: string]: string; +}; + +/** + * Live input state, keyed by InputBind action (not by InputButton). + */ +declare const Input: { + /** Binds a named physical button (see InputButton) to an action. */ + bind(button: string, action: number): void; + /** Current value of an action (0.0-1.0, or -1.0-1.0 for pointer axes). */ + value(bind: number): number; + /** Value of an action as of the previous update. */ + lastValue(bind: number): number; + /** True if the action is currently held down. */ + isDown(bind: number): boolean; + /** True if the action was held down as of the previous update. */ + wasDown(bind: number): boolean; + /** True if the action was just pressed this update (down now, not before). */ + pressed(bind: number): boolean; + /** True if the action was just released this update (up now, down before). */ + released(bind: number): boolean; +}; diff --git a/types/platform/platform.d.ts b/types/platform/platform.d.ts new file mode 100644 index 00000000..f49992f0 --- /dev/null +++ b/types/platform/platform.d.ts @@ -0,0 +1,12 @@ +// Copyright (c) 2026 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +/** + * The engine's compile-time target system (see DUSK_TARGET_SYSTEM). + */ +declare const Platform: { + /** e.g. "linux", "psp", "wii", "gamecube", "knulli". */ + readonly current: string; +};