Merge pull request #1065 from UnknownShadow200/MultiBindInputSources

Support multiple sources of input
This commit is contained in:
UnknownShadow200 2023-09-01 21:03:05 +10:00 committed by GitHub
commit b836fc6cb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 244 additions and 98 deletions

View File

@ -7,6 +7,7 @@ concurrency:
jobs:
build-3DS:
if: github.ref_name == github.event.repository.default_branch
runs-on: ubuntu-latest
container:
image: devkitpro/devkitarm:latest

View File

@ -7,6 +7,7 @@ concurrency:
jobs:
build-haiku:
if: github.ref_name == github.event.repository.default_branch
runs-on: ubuntu-latest
container:
image: haiku/cross-compiler:x86_64-r1beta4

View File

@ -7,6 +7,7 @@ concurrency:
jobs:
build-PSP:
if: github.ref_name == github.event.repository.default_branch
runs-on: ubuntu-latest
container:
image: pspdev/pspdev:latest

View File

@ -7,6 +7,7 @@ concurrency:
jobs:
build:
if: github.ref_name == github.event.repository.default_branch
runs-on: ubuntu-latest
container:
image: devkitpro/devkitppc:latest

View File

@ -820,8 +820,8 @@ static void LocalPlayer_InputSet(int key, cc_bool pressed) {
struct HacksComp* hacks = &LocalPlayer_Instance.Hacks;
if (pressed && !hacks->Enabled) return;
if (key == KeyBinds[KEYBIND_SPEED]) hacks->Speeding = pressed;
if (key == KeyBinds[KEYBIND_HALF_SPEED]) hacks->HalfSpeeding = pressed;
if (KeyBind_Claims(KEYBIND_SPEED, key)) hacks->Speeding = pressed;
if (KeyBind_Claims(KEYBIND_HALF_SPEED, key)) hacks->HalfSpeeding = pressed;
}
static void LocalPlayer_InputDown(void* obj, int key, cc_bool was) {

View File

@ -321,15 +321,16 @@ void Pointer_SetPosition(int idx, int x, int y) {
/*########################################################################################################################*
*---------------------------------------------------------Keybinds--------------------------------------------------------*
*#########################################################################################################################*/
cc_uint8 KeyBinds[KEYBIND_COUNT];
/* TODO find a better way than this. maybe alternative keybinds? */
cc_uint8 KeyBinds_Gamepad[KEYBIND_COUNT];
cc_uint8 KeyBinds_Normal[KEYBIND_COUNT];
const cc_uint8 KeyBind_GamepadDefaults[KEYBIND_COUNT] = {
CCPAD_UP, CCPAD_DOWN, CCPAD_LEFT, CCPAD_RIGHT, /* Movement */
CCPAD_A, 0, CCPAD_START, CCPAD_Y, /* Jump, SetSpawn, OpenChat */
CCPAD_X, 0, CCPAD_START, 0, /* Inventory, EnterChat */
CCKEY_LSHIFT, 'X', 'Z', 'Q', 'E', /* Hacks */
0, 0, 0, 0,
CCKEY_F5, 0, 0, 0,
0, 0, 0, 0, 0, /* Hacks */
0, 0, 0, 0, /* LAlt - F11 */
0, 0, 0, 0, /* F5 - C */
0, CCPAD_L, 0, CCPAD_R,
0, 0, 0,
0,0,0, 0,0,0,0,
@ -368,49 +369,45 @@ static const char* const keybindNames[KEYBIND_COUNT] = {
"HotbarLeft", "HotbarRight"
};
cc_bool KeyBind_IsPressed(KeyBind binding) { return Input.Pressed[KeyBinds[binding]]; }
cc_bool KeyBind_IsPressed(KeyBind binding) {
return Input.Pressed[KeyBinds_Normal[binding]] ||
Input.Pressed[KeyBinds_Gamepad[binding]];
}
static void KeyBind_Load(void) {
static void KeyBind_Load(const char* prefix, cc_uint8* keybinds, const cc_uint8* defaults) {
cc_string name; char nameBuffer[STRING_SIZE + 1];
const cc_uint8* defaults;
int mapping;
int i;
int mapping, i;
defaults = KeyBind_GetDefaults();
String_InitArray_NT(name, nameBuffer);
for (i = 0; i < KEYBIND_COUNT; i++)
{
name.length = 0;
String_Format1(&name, "key-%c", keybindNames[i]);
String_Format1(&name, prefix, keybindNames[i]);
name.buffer[name.length] = '\0';
mapping = Options_GetEnum(name.buffer, defaults[i], storageNames, INPUT_COUNT);
if (mapping != CCKEY_ESCAPE) KeyBinds[i] = mapping;
if (mapping == CCKEY_ESCAPE) mapping = defaults[i];
keybinds[i] = mapping;
}
}
void KeyBind_Set(KeyBind binding, int key) {
void KeyBind_Set(KeyBind binding, int key, cc_uint8* binds) {
cc_string name; char nameBuffer[STRING_SIZE];
cc_string value;
String_InitArray(name, nameBuffer);
String_Format1(&name, "key-%c", keybindNames[binding]);
String_Format1(&name, binds == KeyBinds_Gamepad ? "pad-%c" : "key-%c",
keybindNames[binding]);
value = String_FromReadonly(storageNames[key]);
Options_SetString(&name, &value);
KeyBinds[binding] = key;
binds[binding] = key;
}
/* Initialises and loads key bindings from options */
static void KeyBind_Init(void) {
const cc_uint8* defaults;
int i;
defaults = KeyBind_GetDefaults();
for (i = 0; i < KEYBIND_COUNT; i++)
{
KeyBinds[i] = defaults[i];
}
KeyBind_Load();
KeyBind_Load("key-%c", KeyBinds_Normal, KeyBind_NormalDefaults);
KeyBind_Load("pad-%c", KeyBinds_Gamepad, KeyBind_GamepadDefaults);
}
@ -904,13 +901,13 @@ static void InputHandler_CheckZoomFov(void* obj) {
static cc_bool HandleBlockKey(int key) {
if (Gui.InputGrab) return false;
if (key == KeyBinds[KEYBIND_DELETE_BLOCK]) {
if (KeyBind_Claims(KEYBIND_DELETE_BLOCK, key)) {
MouseStatePress(MOUSE_LEFT);
InputHandler_DeleteBlock();
} else if (key == KeyBinds[KEYBIND_PLACE_BLOCK]) {
} else if (KeyBind_Claims(KEYBIND_PLACE_BLOCK, key)) {
MouseStatePress(MOUSE_RIGHT);
InputHandler_PlaceBlock();
} else if (key == KeyBinds[KEYBIND_PICK_BLOCK]) {
} else if (KeyBind_Claims(KEYBIND_PICK_BLOCK, key)) {
MouseStatePress(MOUSE_MIDDLE);
InputHandler_PickBlock();
} else {
@ -920,32 +917,32 @@ static cc_bool HandleBlockKey(int key) {
}
static cc_bool HandleNonClassicKey(int key) {
if (key == KeyBinds[KEYBIND_HIDE_GUI]) {
if (KeyBind_Claims(KEYBIND_HIDE_GUI, key)) {
Game_HideGui = !Game_HideGui;
} else if (key == KeyBinds[KEYBIND_SMOOTH_CAMERA]) {
} else if (KeyBind_Claims(KEYBIND_SMOOTH_CAMERA, key)) {
InputHandler_Toggle(key, &Camera.Smooth,
" &eSmooth camera is &aenabled",
" &eSmooth camera is &cdisabled");
} else if (key == KeyBinds[KEYBIND_AXIS_LINES]) {
} else if (KeyBind_Claims(KEYBIND_AXIS_LINES, key)) {
InputHandler_Toggle(key, &AxisLinesRenderer_Enabled,
" &eAxis lines (&4X&e, &2Y&e, &1Z&e) now show",
" &eAxis lines no longer show");
} else if (key == KeyBinds[KEYBIND_AUTOROTATE]) {
} else if (KeyBind_Claims(KEYBIND_AUTOROTATE, key)) {
InputHandler_Toggle(key, &AutoRotate_Enabled,
" &eAuto rotate is &aenabled",
" &eAuto rotate is &cdisabled");
} else if (key == KeyBinds[KEYBIND_THIRD_PERSON]) {
} else if (KeyBind_Claims(KEYBIND_THIRD_PERSON, key)) {
Camera_CycleActive();
} else if (key == KeyBinds[KEYBIND_DROP_BLOCK]) {
} else if (KeyBind_Claims(KEYBIND_DROP_BLOCK, key)) {
if (Inventory_CheckChangeSelected() && Inventory_SelectedBlock != BLOCK_AIR) {
/* Don't assign SelectedIndex directly, because we don't want held block
switching positions if they already have air in their inventory hotbar. */
Inventory_Set(Inventory.SelectedIndex, BLOCK_AIR);
Event_RaiseVoid(&UserEvents.HeldBlockChanged);
}
} else if (key == KeyBinds[KEYBIND_IDOVERLAY]) {
} else if (KeyBind_Claims(KEYBIND_IDOVERLAY, key)) {
TexIdsOverlay_Show();
} else if (key == KeyBinds[KEYBIND_BREAK_LIQUIDS]) {
} else if (KeyBind_Claims(KEYBIND_BREAK_LIQUIDS, key)) {
InputHandler_Toggle(key, &Game_BreakableLiquids,
" &eBreakable liquids is &aenabled",
" &eBreakable liquids is &cdisabled");
@ -956,11 +953,11 @@ static cc_bool HandleNonClassicKey(int key) {
}
static cc_bool HandleCoreKey(int key) {
if (key == KeyBinds[KEYBIND_HIDE_FPS]) {
if (KeyBind_Claims(KEYBIND_HIDE_FPS, key)) {
Gui.ShowFPS = !Gui.ShowFPS;
} else if (key == KeyBinds[KEYBIND_FULLSCREEN]) {
} else if (KeyBind_Claims(KEYBIND_FULLSCREEN, key)) {
Game_ToggleFullscreen();
} else if (key == KeyBinds[KEYBIND_FOG]) {
} else if (KeyBind_Claims(KEYBIND_FOG, key)) {
Game_CycleViewDistance();
} else if (key == CCKEY_F5 && Game_ClassicMode) {
int weather = Env.Weather == WEATHER_SUNNY ? WEATHER_RAINY : WEATHER_SUNNY;
@ -989,15 +986,15 @@ static void HandleHotkeyDown(int key) {
}
static cc_bool HandleLocalPlayerKey(int key) {
if (key == KeyBinds[KEYBIND_RESPAWN]) {
if (KeyBind_Claims(KEYBIND_RESPAWN, key)) {
return LocalPlayer_HandleRespawn();
} else if (key == KeyBinds[KEYBIND_SET_SPAWN]) {
} else if (KeyBind_Claims(KEYBIND_SET_SPAWN, key)) {
return LocalPlayer_HandleSetSpawn();
} else if (key == KeyBinds[KEYBIND_FLY]) {
} else if (KeyBind_Claims(KEYBIND_FLY, key)) {
return LocalPlayer_HandleFly();
} else if (key == KeyBinds[KEYBIND_NOCLIP]) {
} else if (KeyBind_Claims(KEYBIND_NOCLIP, key)) {
return LocalPlayer_HandleNoclip();
} else if (key == KeyBinds[KEYBIND_JUMP]) {
} else if (KeyBind_Claims(KEYBIND_JUMP, key)) {
return LocalPlayer_HandleJump();
}
return false;
@ -1091,7 +1088,7 @@ static void OnInputDown(void* obj, int key, cc_bool was) {
if (InputHandler_IsShutdown(key)) {
/* TODO: Do we need a separate exit function in Game class? */
Window_Close(); return;
} else if (key == KeyBinds[KEYBIND_SCREENSHOT] && !was) {
} else if (KeyBind_Claims(KEYBIND_SCREENSHOT, key) && !was) {
Game_ScreenshotRequested = true; return;
}
@ -1101,7 +1098,7 @@ static void OnInputDown(void* obj, int key, cc_bool was) {
if (s->VTABLE->HandlesInputDown(s, key)) return;
}
if ((Input_IsEscapeButton(key) || key == CCKEY_PAUSE) && !Gui.InputGrab) {
if (Input_IsPauseButton(key) && !Gui.InputGrab) {
#ifdef CC_BUILD_WEB
/* Can't do this in KeyUp, because pressing escape without having */
/* explicitly disabled mouse lock means a KeyUp event isn't sent. */
@ -1125,7 +1122,7 @@ static void OnInputUp(void* obj, int key) {
struct Screen* s;
int i;
if (key == KeyBinds[KEYBIND_ZOOM_SCROLL]) Camera_SetFov(Camera.DefaultFov);
if (KeyBind_Claims(KEYBIND_ZOOM_SCROLL, key)) Camera_SetFov(Camera.DefaultFov);
#ifdef CC_BUILD_WEB
/* When closing menus (which reacquires mouse focus) in key down, */
/* this still leaves the cursor visible. But if this is instead */
@ -1143,9 +1140,9 @@ static void OnInputUp(void* obj, int key) {
}
if (Gui.InputGrab) return;
if (key == KeyBinds[KEYBIND_DELETE_BLOCK]) MouseStateRelease(MOUSE_LEFT);
if (key == KeyBinds[KEYBIND_PLACE_BLOCK]) MouseStateRelease(MOUSE_RIGHT);
if (key == KeyBinds[KEYBIND_PICK_BLOCK]) MouseStateRelease(MOUSE_MIDDLE);
if (KeyBind_Claims(KEYBIND_DELETE_BLOCK, key)) MouseStateRelease(MOUSE_LEFT);
if (KeyBind_Claims(KEYBIND_PLACE_BLOCK, key)) MouseStateRelease(MOUSE_RIGHT);
if (KeyBind_Claims(KEYBIND_PICK_BLOCK, key)) MouseStateRelease(MOUSE_MIDDLE);
}
static void OnFocusChanged(void* obj) { if (!WindowInfo.Focused) Input_Clear(); }

View File

@ -62,14 +62,17 @@ extern struct _InputState {
cc_bool Pressed[INPUT_COUNT];
/* Whether raw mouse/touch input is currently being listened for */
cc_bool RawMode;
/* Whether a gamepad is available as an input source */
cc_bool GamepadSource;
/* Sources available for input (Mouse/Keyboard, Gamepad) */
cc_uint8 Sources;
/* Whether a gamepad joystick is being used to control player movement */
cc_bool JoystickMovement;
/* Angle of the gamepad joystick being used to control player movement */
float JoystickAngle;
} Input;
#define INPUT_SOURCE_NORMAL (1 << 0)
#define INPUT_SOURCE_GAMEPAD (1 << 1)
/* Sets Input_Pressed[key] to true and raises InputEvents.Down */
void Input_SetPressed(int key);
/* Sets Input_Pressed[key] to false and raises InputEvents.Up */
@ -90,7 +93,9 @@ void Input_Clear(void);
#define Input_IsDownButton(btn) ((btn) == CCKEY_DOWN || (btn) == CCPAD_DOWN)
#define Input_IsLeftButton(btn) ((btn) == CCKEY_LEFT || (btn) == CCPAD_LEFT)
#define Input_IsRightButton(btn) ((btn) == CCKEY_RIGHT || (btn) == CCPAD_RIGHT)
#define Input_IsEnterButton(btn) ((btn) == CCKEY_ENTER || (btn) == CCPAD_START || (btn) == CCKEY_KP_ENTER)
#define Input_IsPauseButton(btn) ((btn) == CCKEY_ESCAPE || (btn) == CCPAD_START || (btn) == CCKEY_PAUSE)
#define Input_IsEscapeButton(btn) ((btn) == CCKEY_ESCAPE || (btn) == CCPAD_SELECT)
#if defined CC_BUILD_HAIKU
@ -159,18 +164,22 @@ enum KeyBind_ {
};
typedef int KeyBind;
/* The keys that are bound to each key binding. */
extern cc_uint8 KeyBinds[KEYBIND_COUNT];
/* The keyboard/mouse buttons that are bound to each key binding */
extern cc_uint8 KeyBinds_Normal[KEYBIND_COUNT];
/* The gamepad buttons that are bound to each key binding */
extern cc_uint8 KeyBinds_Gamepad[KEYBIND_COUNT];
/* Default keyboard/mouse button that each key binding is bound to */
extern const cc_uint8 KeyBind_NormalDefaults[KEYBIND_COUNT];
/* Default gamepad button that each key binding is bound to */
extern const cc_uint8 KeyBind_GamepadDefaults[KEYBIND_COUNT];
#define KeyBind_GetDefaults() (Input.GamepadSource ? KeyBind_GamepadDefaults : KeyBind_NormalDefaults)
/* Whether the given keyboard/mouse or gamepad button is bound to the given keybinding */
#define KeyBind_Claims(binding, btn) (KeyBinds_Normal[binding] == (btn) || KeyBinds_Gamepad[binding] == (btn))
/* Gets whether the key bound to the given key binding is pressed. */
CC_API cc_bool KeyBind_IsPressed(KeyBind binding);
/* Set the key that the given key binding is bound to. (also updates options list) */
void KeyBind_Set(KeyBind binding, int key);
void KeyBind_Set(KeyBind binding, int key, cc_uint8* binds);
/* whether to leave text input open for user to enter further input */
#define HOTKEY_FLAG_STAYS_OPEN 0x01

View File

@ -20,8 +20,8 @@
#include "Http.h"
#define LAYOUTS static const struct LLayout
#define IsEnterButton(btn) (Input_IsEnterButton(btn) || btn == CCPAD_A)
#define IsEscapeButton(btn) (Input_IsEscapeButton(btn) || btn == CCPAD_B)
#define IsEnterButton(btn) (btn == CCKEY_ENTER || btn == CCPAD_START || btn == CCPAD_A || btn == CCKEY_KP_ENTER)
#define IsBackButton(btn) (btn == CCKEY_ESCAPE || btn == CCPAD_SELECT || btn == CCPAD_B)
/*########################################################################################################################*
*---------------------------------------------------------Screen base-----------------------------------------------------*
@ -109,7 +109,7 @@ static void LScreen_KeyDown(struct LScreen* s, int key, cc_bool was) {
LScreen_CycleSelected(s, -1);
} else if (Input_IsDownButton(key)) {
LScreen_CycleSelected(s, 1);
} else if (IsEscapeButton(key) && s->onEscapeWidget) {
} else if (IsBackButton(key) && s->onEscapeWidget) {
s->onEscapeWidget->OnClick(s->onEscapeWidget);
}
}

View File

@ -209,6 +209,7 @@ static void Menu_SwitchBindsHacks(void* a, void* b) { HacksBindingsScreen
static void Menu_SwitchBindsOther(void* a, void* b) { OtherBindingsScreen_Show(); }
static void Menu_SwitchBindsMouse(void* a, void* b) { MouseBindingsScreen_Show(); }
static void Menu_SwitchBindsHotbar(void* a, void* b) { HotbarBindingsScreen_Show(); }
static void SwitchBindsMain(void* s, void* w);
static void Menu_SwitchMisc(void* a, void* b) { MiscOptionsScreen_Show(); }
static void Menu_SwitchChat(void* a, void* b) { ChatOptionsScreen_Show(); }
@ -696,7 +697,7 @@ static const struct SimpleButtonDesc optsGroup_btns[8] = {
{ -160, -100, "Misc options...", Menu_SwitchMisc },
{ -160, -50, "Gui options...", Menu_SwitchGui },
{ -160, 0, "Graphics options...", Menu_SwitchGfx },
{ -160, 50, "Controls...", Menu_SwitchBindsNormal },
{ -160, 50, "Controls...", SwitchBindsMain },
{ 160, -100, "Chat options...", Menu_SwitchChat },
{ 160, -50, "Hacks settings...", Menu_SwitchHacks },
{ 160, 0, "Env settings...", Menu_SwitchEnv },
@ -1812,6 +1813,93 @@ void LoadLevelScreen_Show(void) {
}
/*########################################################################################################################*
*----------------------------------------------------EditHotkeyScreen-----------------------------------------------------*
*#########################################################################################################################*/
static struct BindsSourceScreen {
Screen_Body
struct ButtonWidget btns[2], cancel;
} BindsSourceScreen;
static int binds_gamepad; /* Default to Normal (Keyboard/Mouse) */
static struct Widget* bindsSource_widgets[] = {
(struct Widget*)&BindsSourceScreen.btns[0], (struct Widget*)&BindsSourceScreen.btns[1],
(struct Widget*)&BindsSourceScreen.cancel
};
#define BINDSSOURCE_MAX_VERTICES (BUTTONWIDGET_MAX * 3)
static void BindsSourceScreen_ModeNormal(void* screen, void* b) {
binds_gamepad = false;
NormalBindingsScreen_Show();
}
static void BindsSourceScreen_ModeGamepad(void* screen, void* b) {
binds_gamepad = true;
NormalBindingsScreen_Show();
}
static void BindsSourceScreen_ContextRecreated(void* screen) {
struct BindsSourceScreen* s = (struct BindsSourceScreen*)screen;
struct FontDesc font;
Gui_MakeTitleFont(&font);
Screen_UpdateVb(screen);
ButtonWidget_SetConst(&s->btns[0], "Keyboard/Mouse", &font);
ButtonWidget_SetConst(&s->btns[1], "Gamepad/Controller", &font);
ButtonWidget_SetConst(&s->cancel, "Cancel", &font);
Font_Free(&font);
}
static void BindsSourceScreen_Layout(void* screen) {
struct BindsSourceScreen* s = (struct BindsSourceScreen*)screen;
Widget_SetLocation(&s->btns[0], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -25);
Widget_SetLocation(&s->btns[1], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 25);
Menu_LayoutBack(&s->cancel);
}
static void BindsSourceScreen_Init(void* screen) {
struct BindsSourceScreen* s = (struct BindsSourceScreen*)screen;
s->widgets = bindsSource_widgets;
s->numWidgets = Array_Elems(bindsSource_widgets);
s->selectedI = -1;
s->maxVertices = BINDSSOURCE_MAX_VERTICES;
ButtonWidget_Init(&s->btns[0], 300, BindsSourceScreen_ModeNormal);
ButtonWidget_Init(&s->btns[1], 300, BindsSourceScreen_ModeGamepad);
ButtonWidget_Init(&s->cancel, 400, Menu_SwitchPause);
}
static const struct ScreenVTABLE BindsSourceScreen_VTABLE = {
BindsSourceScreen_Init, Screen_NullUpdate, Screen_NullFunc,
MenuScreen_Render2, Screen_BuildMesh,
Menu_InputDown, Screen_InputUp, Screen_TKeyPress, Screen_TText,
Menu_PointerDown, Screen_PointerUp, Menu_PointerMove, Screen_TMouseScroll,
BindsSourceScreen_Layout, Screen_ContextLost, BindsSourceScreen_ContextRecreated
};
void BindsSourceScreen_Show(void) {
struct BindsSourceScreen* s = &BindsSourceScreen;
s->grabsInput = true;
s->closable = true;
s->VTABLE = &BindsSourceScreen_VTABLE;
Gui_Add((struct Screen*)s, GUI_PRIORITY_MENU);
}
static void SwitchBindsMain(void* s, void* w) {
if (Input.Sources == (INPUT_SOURCE_NORMAL | INPUT_SOURCE_GAMEPAD)) {
/* User needs to decide whether to configure mouse/keyboard or gamepad */
BindsSourceScreen_Show();
} else if (Input.Sources == INPUT_SOURCE_GAMEPAD) {
binds_gamepad = true;
NormalBindingsScreen_Show();
} else {
binds_gamepad = false;
NormalBindingsScreen_Show();
}
}
/*########################################################################################################################*
*---------------------------------------------------KeyBindsScreen-----------------------------------------------------*
*#########################################################################################################################*/
@ -1844,10 +1932,13 @@ static struct Widget* key_widgets[KEYBINDS_MAX_BTNS + 5] = {
static void KeyBindsScreen_Update(struct KeyBindsScreen* s, int i) {
cc_string text; char textBuffer[STRING_SIZE];
const cc_uint8* curBinds;
String_InitArray(text, textBuffer);
curBinds = binds_gamepad ? KeyBinds_Gamepad : KeyBinds_Normal;
String_Format2(&text, s->curI == i ? "> %c: %c <" : "%c: %c",
s->descs[i], Input_DisplayNames[KeyBinds[s->binds[i]]]);
s->descs[i], Input_DisplayNames[curBinds[s->binds[i]]]);
ButtonWidget_Set(&s->buttons[i], &text, &s->titleFont);
s->dirty = true;
}
@ -1866,15 +1957,17 @@ static void KeyBindsScreen_OnBindingClick(void* screen, void* widget) {
static int KeyBindsScreen_KeyDown(void* screen, int key) {
struct KeyBindsScreen* s = (struct KeyBindsScreen*)screen;
const cc_uint8* defaults;
cc_uint8* curBinds;
KeyBind bind;
int idx;
if (s->curI == -1) return Menu_InputDown(s, key);
defaults = KeyBind_GetDefaults();
curBinds = binds_gamepad ? KeyBinds_Gamepad : KeyBinds_Normal;
defaults = binds_gamepad ? KeyBind_GamepadDefaults : KeyBind_NormalDefaults;
bind = s->binds[s->curI];
if (Input_IsEscapeButton(key)) key = defaults[bind];
KeyBind_Set(bind, key);
KeyBind_Set(bind, key, curBinds);
idx = s->curI;
s->curI = -1;
@ -2000,6 +2093,7 @@ static void KeyBindsScreen_Show(int bindsCount, const cc_uint8* binds, const cha
void ClassicBindingsScreen_Show(void) {
static const cc_uint8 binds[] = { KEYBIND_FORWARD, KEYBIND_BACK, KEYBIND_JUMP, KEYBIND_CHAT, KEYBIND_SET_SPAWN, KEYBIND_LEFT, KEYBIND_RIGHT, KEYBIND_INVENTORY, KEYBIND_FOG, KEYBIND_RESPAWN };
static const char* const descs[] = { "Forward", "Back", "Jump", "Chat", "Save location", "Left", "Right", "Build", "Toggle fog", "Load location" };
binds_gamepad = false;
if (Game_ClassicHacks) {
KeyBindsScreen_Reset(NULL, Menu_SwitchBindsClassicHacks, 260);
@ -2018,6 +2112,7 @@ void ClassicBindingsScreen_Show(void) {
void ClassicHacksBindingsScreen_Show(void) {
static const cc_uint8 binds[6] = { KEYBIND_SPEED, KEYBIND_NOCLIP, KEYBIND_HALF_SPEED, KEYBIND_FLY, KEYBIND_FLY_UP, KEYBIND_FLY_DOWN };
static const char* const descs[6] = { "Speed", "Noclip", "Half speed", "Fly", "Fly up", "Fly down" };
binds_gamepad = false;
KeyBindsScreen_Reset(Menu_SwitchBindsClassic, NULL, 260);
KeyBindsScreen_SetLayout(-90, -40, 3);
@ -3582,7 +3677,7 @@ static void TexIdsOverlay_Render(void* screen, double delta) {
static int TexIdsOverlay_KeyDown(void* screen, int key) {
struct Screen* s = (struct Screen*)screen;
if (key == KeyBinds[KEYBIND_IDOVERLAY]) { Gui_Remove(s); return true; }
if (KeyBind_Claims(KEYBIND_IDOVERLAY, key)) { Gui_Remove(s); return true; }
return false;
}

View File

@ -77,8 +77,8 @@ static int RunProgram(int argc, char** argv) {
#ifdef _MSC_VER
/* NOTE: Make sure to comment this out before pushing a commit */
//cc_string rawArgs = String_FromConst("UnknownShadow200 fffff 127.0.0.1 25565");
//cc_string rawArgs = String_FromConst("UnknownShadow200");
//argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4);
cc_string rawArgs = String_FromConst("UnknownShadow200");
argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4);
#endif
if (argsCount == 0) {

View File

@ -708,7 +708,7 @@ static int TabListOverlay_PointerDown(void* screen, int id, int x, int y) {
static void TabListOverlay_KeyUp(void* screen, int key) {
struct TabListOverlay* s = (struct TabListOverlay*)screen;
if (key != KeyBinds[KEYBIND_TABLIST] || s->staysOpen) return;
if (!KeyBind_Claims(KEYBIND_TABLIST, key) || s->staysOpen) return;
Gui_Remove((struct Screen*)s);
}
@ -1206,10 +1206,10 @@ static int ChatScreen_TextChanged(void* screen, const cc_string* str) {
static int ChatScreen_KeyDown(void* screen, int key) {
static const cc_string slash = String_FromConst("/");
struct ChatScreen* s = (struct ChatScreen*)screen;
int playerListKey = KeyBinds[KEYBIND_TABLIST];
int playerListKey = KeyBinds_Normal[KEYBIND_TABLIST];
cc_bool handlesList = playerListKey != CCKEY_TAB || !Gui.TabAutocomplete || !s->grabsInput;
if (key == playerListKey && handlesList) {
if (KeyBind_Claims(KEYBIND_TABLIST, key) && handlesList) {
if (!tablist_active && !Server.IsSinglePlayer) {
TabListOverlay_Show();
}
@ -1221,10 +1221,10 @@ static int ChatScreen_KeyDown(void* screen, int key) {
if (s->grabsInput) {
#ifdef CC_BUILD_WEB
/* See reason for this in HandleInputUp */
if (key == KeyBinds[KEYBIND_SEND_CHAT] || key == CCKEY_KP_ENTER) {
if (KeyBind_Claims(KEYBIND_SEND_CHAT, key) || key == CCKEY_KP_ENTER) {
ChatScreen_EnterChatInput(s, false);
#else
if (key == KeyBinds[KEYBIND_SEND_CHAT] || key == CCKEY_KP_ENTER || Input_IsEscapeButton(key)) {
if (KeyBind_Claims(KEYBIND_SEND_CHAT, key) || key == CCKEY_KP_ENTER || Input_IsEscapeButton(key)) {
ChatScreen_EnterChatInput(s, Input_IsEscapeButton(key));
#endif
} else if (key == CCKEY_PAGEUP) {
@ -1237,11 +1237,11 @@ static int ChatScreen_KeyDown(void* screen, int key) {
return key < CCKEY_F1 || key > CCKEY_F24;
}
if (key == KeyBinds[KEYBIND_CHAT]) {
if (KeyBind_Claims(KEYBIND_CHAT, key)) {
ChatScreen_OpenInput(&String_Empty);
} else if (key == CCKEY_SLASH) {
ChatScreen_OpenInput(&slash);
} else if (key == KeyBinds[KEYBIND_INVENTORY]) {
} else if (KeyBind_Claims(KEYBIND_INVENTORY, key)) {
InventoryScreen_Show();
} else {
return false;
@ -1263,7 +1263,7 @@ static void ChatScreen_KeyUp(void* screen, int key) {
if (key == CCKEY_ESCAPE) ChatScreen_EnterChatInput(s, true);
#endif
if (Server.SupportsFullCP437 && key == KeyBinds[KEYBIND_EXT_INPUT]) {
if (Server.SupportsFullCP437 && KeyBind_Claims(KEYBIND_EXT_INPUT, key)) {
if (!WindowInfo.Focused) return;
ChatScreen_ToggleAltInput(s);
}
@ -1592,7 +1592,7 @@ static int InventoryScreen_KeyDown(void* screen, int key) {
struct InventoryScreen* s = (struct InventoryScreen*)screen;
struct TableWidget* table = &s->table;
if (key == KeyBinds[KEYBIND_INVENTORY] && s->releasedInv) {
if (KeyBind_Claims(KEYBIND_INVENTORY, key) && s->releasedInv) {
Gui_Remove((struct Screen*)s);
} else if (Input_IsEnterButton(key) && table->selectedIndex != -1) {
Inventory_SetSelectedBlock(table->blocks[table->selectedIndex]);
@ -1612,7 +1612,7 @@ static cc_bool InventoryScreen_IsHotbarActive(void) {
static void InventoryScreen_KeyUp(void* screen, int key) {
struct InventoryScreen* s = (struct InventoryScreen*)screen;
if (key == KeyBinds[KEYBIND_INVENTORY]) s->releasedInv = true;
if (KeyBind_Claims(KEYBIND_INVENTORY, key)) s->releasedInv = true;
}
static int InventoryScreen_PointerDown(void* screen, int id, int x, int y) {
@ -2151,7 +2151,7 @@ static void TouchScreen_HalfClick(void* s, void* w) {
static void TouchScreen_BindClick(void* screen, void* widget) {
struct TouchScreen* s = (struct TouchScreen*)screen;
int i = Screen_Index(screen, widget) - ONSCREEN_MAX_BTNS;
Input_Set(KeyBinds[s->descs[i].bind], true);
Input_Set(KeyBinds_Normal[s->descs[i].bind], true);
}
static const struct TouchButtonDesc onscreenDescs[ONSCREEN_MAX_BTNS] = {
@ -2283,7 +2283,7 @@ static void TouchScreen_PointerUp(void* screen, int id, int x, int y) {
if (!(s->btns[i].active & id)) continue;
if (s->descs[i].bind < KEYBIND_COUNT) {
Input_Set(KeyBinds[s->descs[i].bind], false);
Input_Set(KeyBinds_Normal[s->descs[i].bind], false);
}
s->btns[i].active &= ~id;
return;

View File

@ -512,7 +512,7 @@ static int HotbarWidget_MapKey(int key) {
int i;
for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR; i++)
{
if (key == KeyBinds[KEYBIND_HOTBAR_1 + i]) return i;
if (KeyBind_Claims(KEYBIND_HOTBAR_1 + i, key)) return i;
}
return -1;
}
@ -532,9 +532,9 @@ static int HotbarWidget_KeyDown(void* widget, int key) {
int index = HotbarWidget_MapKey(key);
if (index == -1) {
if (key == KeyBinds[KEYBIND_HOTBAR_LEFT])
if (KeyBind_Claims(KEYBIND_HOTBAR_LEFT, key))
return HotbarWidget_CycleIndex(-1);
if (key == KeyBinds[KEYBIND_HOTBAR_RIGHT])
if (KeyBind_Claims(KEYBIND_HOTBAR_RIGHT, key))
return HotbarWidget_CycleIndex(+1);
return false;
}
@ -555,7 +555,7 @@ static void HotbarWidget_InputUp(void* widget, int key) {
a) user presses alt then number
b) user presses alt
We only do case b) if case a) did not happen */
if (key != KeyBinds[KEYBIND_HOTBAR_SWITCH]) return;
if (!KeyBind_Claims(KEYBIND_HOTBAR_SWITCH, key)) return;
if (w->altHandled) { w->altHandled = false; return; } /* handled already */
/* Don't switch hotbar when alt+tabbing to another window */

View File

@ -50,7 +50,7 @@ void Window_Init(void) {
WindowInfo.Focused = true;
WindowInfo.Exists = true;
Input.GamepadSource = true;
Input.Sources = INPUT_SOURCE_GAMEPAD;
irrst_result = irrstInit();
}

View File

@ -31,7 +31,7 @@ void Window_Init(void) {
WindowInfo.Focused = true;
WindowInfo.Exists = true;
Input.GamepadSource = true;
Input.Sources = INPUT_SOURCE_GAMEPAD;
}
void Window_Create2D(int width, int height) {

View File

@ -72,7 +72,7 @@ void Window_Init(void) {
WindowInfo.Focused = true;
WindowInfo.Exists = true;
Input.GamepadSource = true;
Input.Sources = INPUT_SOURCE_GAMEPAD;
#if defined HW_RVL
WPAD_Init();
WPAD_SetDataFormat(0, WPAD_FMT_BTNS_ACC_IR);
@ -259,14 +259,14 @@ static void ProcessNunchuck_Game(int mods, double delta) {
Input_SetNonRepeatable(CCPAD_START, mods & WPAD_BUTTON_HOME);
Input_SetNonRepeatable(CCPAD_SELECT, mods & WPAD_BUTTON_MINUS);
Input_SetNonRepeatable(KeyBinds[KEYBIND_FLY], mods & WPAD_BUTTON_LEFT);
Input_SetNonRepeatable(KeyBinds_Normal[KEYBIND_FLY], mods & WPAD_BUTTON_LEFT);
if (mods & WPAD_BUTTON_RIGHT) {
Mouse_ScrollWheel(1.0*delta);
}
Input_SetNonRepeatable(KeyBinds[KEYBIND_THIRD_PERSON], mods & WPAD_BUTTON_UP);
Input_SetNonRepeatable(KeyBinds[KEYBIND_FLY_DOWN], mods & WPAD_BUTTON_DOWN);
Input_SetNonRepeatable(KeyBinds_Normal[KEYBIND_THIRD_PERSON], mods & WPAD_BUTTON_UP);
Input_SetNonRepeatable(KeyBinds_Normal[KEYBIND_FLY_DOWN], mods & WPAD_BUTTON_DOWN);
const float ANGLE_DELTA = 50;
bool nunchuckUp = (analog.ang > -ANGLE_DELTA) && (analog.ang < ANGLE_DELTA) && (analog.mag > 0.5);

View File

@ -37,7 +37,7 @@ void Window_Init(void) {
WindowInfo.Focused = true;
WindowInfo.Exists = true;
Input.GamepadSource = true;
Input.Sources = INPUT_SOURCE_GAMEPAD;
sceCtrlSetSamplingCycle(0);
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
}

View File

@ -37,7 +37,7 @@ void Window_Init(void) {
WindowInfo.Focused = true;
WindowInfo.Exists = true;
Input.GamepadSource = true;
Input.Sources = INPUT_SOURCE_GAMEPAD;
sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG);
sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
sceTouchSetSamplingState(SCE_TOUCH_PORT_BACK, SCE_TOUCH_SAMPLING_STATE_START);

View File

@ -513,9 +513,7 @@ void Window_Close(void) {
}
extern void interop_RequestCanvasResize(void);
void Window_ProcessEvents(double delta) {
if (!needResize) return;
needResize = false;
static void ProcessPendingResize(void) {
if (!WindowInfo.Exists) return;
if (Window_GetWindowState() == WINDOW_STATE_FULLSCREEN) {
@ -527,6 +525,49 @@ void Window_ProcessEvents(double delta) {
UpdateWindowBounds();
}
#define GetGamePadButton(i) i < numButtons ? ev->digitalButton[i] : 0
static void ProcessGamePadInput(EmscriptenGamepadEvent* ev) {
int numButtons = ev->numButtons;
Input.Sources |= INPUT_SOURCE_GAMEPAD;
/* https://www.w3.org/TR/gamepad/#dfn-standard-gamepad */
Input_SetNonRepeatable(CCPAD_A, GetGamePadButton(0));
Input_SetNonRepeatable(CCPAD_B, GetGamePadButton(1));
Input_SetNonRepeatable(CCPAD_X, GetGamePadButton(2));
Input_SetNonRepeatable(CCPAD_Y, GetGamePadButton(3));
Input_SetNonRepeatable(CCPAD_L, GetGamePadButton(4));
Input_SetNonRepeatable(CCPAD_R, GetGamePadButton(5));
Input_SetNonRepeatable(CCPAD_SELECT, GetGamePadButton(8));
Input_SetNonRepeatable(CCPAD_START, GetGamePadButton(9));
Input_SetNonRepeatable(CCPAD_UP, GetGamePadButton(12));
Input_SetNonRepeatable(CCPAD_DOWN, GetGamePadButton(13));
Input_SetNonRepeatable(CCPAD_LEFT, GetGamePadButton(14));
Input_SetNonRepeatable(CCPAD_RIGHT, GetGamePadButton(15));
}
void Window_ProcessEvents(double delta) {
int i, res, count;
Input.Sources = INPUT_SOURCE_NORMAL;
if (emscripten_sample_gamepad_data() == 0) {
count = emscripten_get_num_gamepads();
for (i = 0; i < count; i++)
{
EmscriptenGamepadEvent ev;
res = emscripten_get_gamepad_status(i, &ev);
if (res == 0) ProcessGamePadInput(&ev);
}
}
if (!needResize) return;
needResize = false;
ProcessPendingResize();
}
/* Not needed because browser provides relative mouse and touch events */
static void Cursor_GetRawPos(int* x, int* y) { *x = 0; *y = 0; }
/* Not allowed to move cursor from javascript */

View File

@ -75,7 +75,7 @@ void Window_Init(void) {
WindowInfo.Focused = true;
WindowInfo.Exists = true;
Input.GamepadSource = true;
Input.Sources = INPUT_SOURCE_GAMEPAD;
usbh_core_init();
usbh_xid_init();