Allow setting input override hooks, fix touch build not compiling

This commit is contained in:
UnknownShadow200 2024-07-09 21:34:58 +10:00
parent 67566d0fb7
commit ce7c077ca9
8 changed files with 108 additions and 110 deletions

View File

@ -25,12 +25,7 @@ static void Pointer_SetPressed(int idx, cc_bool pressed);
*------------------------------------------------------Touch support------------------------------------------------------* *------------------------------------------------------Touch support------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
#ifdef CC_BUILD_TOUCH #ifdef CC_BUILD_TOUCH
static struct TouchPointer { struct TouchPointer touches[INPUT_MAX_POINTERS];
long id;
cc_uint8 type;
int begX, begY;
double start;
} touches[INPUT_MAX_POINTERS];
int Pointers_Count; int Pointers_Count;
int Input_TapMode = INPUT_MODE_PLACE; int Input_TapMode = INPUT_MODE_PLACE;
@ -40,18 +35,6 @@ cc_bool Input_TouchMode;
static void MouseStatePress(int button); static void MouseStatePress(int button);
static void MouseStateRelease(int button); static void MouseStateRelease(int button);
static cc_bool AnyBlockTouches(void) {
int i;
for (i = 0; i < Pointers_Count; i++) {
if (!(touches[i].type & TOUCH_TYPE_BLOCKS)) continue;
/* Touch might be an 'all' type - remove 'gui' type */
touches[i].type &= TOUCH_TYPE_BLOCKS | TOUCH_TYPE_CAMERA;
return true;
}
return false;
}
static void ClearTouches(void) { static void ClearTouches(void) {
int i; int i;
for (i = 0; i < INPUT_MAX_POINTERS; i++) touches[i].type = 0; for (i = 0; i < INPUT_MAX_POINTERS; i++) touches[i].type = 0;
@ -70,7 +53,8 @@ static cc_bool MovedFromBeg(int i, int x, int y) {
static cc_bool TryUpdateTouch(long id, int x, int y) { static cc_bool TryUpdateTouch(long id, int x, int y) {
int i; int i;
for (i = 0; i < Pointers_Count; i++) { for (i = 0; i < Pointers_Count; i++)
{
if (touches[i].id != id || !touches[i].type) continue; if (touches[i].id != id || !touches[i].type) continue;
if (Input.RawMode && (touches[i].type & TOUCH_TYPE_CAMERA)) { if (Input.RawMode && (touches[i].type & TOUCH_TYPE_CAMERA)) {
@ -95,19 +79,15 @@ void Input_AddTouch(long id, int x, int y) {
/* Check if already existing pointer with same ID */ /* Check if already existing pointer with same ID */
if (TryUpdateTouch(id, x, y)) return; if (TryUpdateTouch(id, x, y)) return;
for (i = 0; i < INPUT_MAX_POINTERS; i++) { for (i = 0; i < INPUT_MAX_POINTERS; i++)
{
if (touches[i].type) continue; if (touches[i].type) continue;
touches[i].id = id; touches[i].id = id;
touches[i].type = TOUCH_TYPE_ALL; touches[i].type = TOUCH_TYPE_ALL;
touches[i].begX = x; touches[i].begX = x;
touches[i].begY = y; touches[i].begY = y;
touches[i].start = Game.Time; touches[i].start = Game.Time;
/* Also set last click time, otherwise quickly tapping */
/* sometimes triggers a 'delete' in InputHandler_Tick, */
/* and then another 'delete' in CheckBlockTap. */
input_lastClick = Game.Time;
if (i == Pointers_Count) Pointers_Count++; if (i == Pointers_Count) Pointers_Count++;
Pointer_SetPosition(i, x, y); Pointer_SetPosition(i, x, y);
@ -117,29 +97,6 @@ void Input_AddTouch(long id, int x, int y) {
} }
void Input_UpdateTouch(long id, int x, int y) { TryUpdateTouch(id, x, y); } void Input_UpdateTouch(long id, int x, int y) { TryUpdateTouch(id, x, y); }
/* Quickly tapping should trigger a block place/delete */
static void CheckBlockTap(int i) {
int btn, pressed;
if (Game.Time > touches[i].start + 0.25) return;
if (touches[i].type != TOUCH_TYPE_ALL) return;
if (Input_TapMode == INPUT_MODE_PLACE) {
btn = MOUSE_RIGHT;
} else if (Input_TapMode == INPUT_MODE_DELETE) {
btn = MOUSE_LEFT;
} else { return; }
pressed = input_buttonsDown[btn];
MouseStatePress(btn);
if (btn == MOUSE_LEFT) {
InputHandler_DeleteBlock();
} else {
InputHandler_PlaceBlock();
}
if (!pressed) MouseStateRelease(btn);
}
void Input_RemoveTouch(long id, int x, int y) { void Input_RemoveTouch(long id, int x, int y) {
int i; int i;
for (i = 0; i < Pointers_Count; i++) { for (i = 0; i < Pointers_Count; i++) {

View File

@ -6,6 +6,7 @@ Manages input state and raising input related events
Copyright 2014-2023 ClassiCube | Licensed under BSD-3 Copyright 2014-2023 ClassiCube | Licensed under BSD-3
*/ */
struct IGameComponent; struct IGameComponent;
struct InputDevice;
extern struct IGameComponent Input_Component; extern struct IGameComponent Input_Component;
enum InputButtons { enum InputButtons {
@ -76,6 +77,8 @@ extern struct _InputState {
cc_bool RawMode; cc_bool RawMode;
/* Sources available for input (Mouse/Keyboard, Gamepad) */ /* Sources available for input (Mouse/Keyboard, Gamepad) */
cc_uint8 Sources; cc_uint8 Sources;
/* Function that overrides all normal input handling (e.g. for virtual keyboard) */
void (*DownHook)(int btn, struct InputDevice* device);
} Input; } Input;
/* Sets Input_Pressed[key] to true and raises InputEvents.Down */ /* Sets Input_Pressed[key] to true and raises InputEvents.Down */
@ -132,6 +135,7 @@ extern struct InputDevice TouchDevice;
void Input_CalcDelta(int btn, struct InputDevice* device, int* horDelta, int* verDelta); void Input_CalcDelta(int btn, struct InputDevice* device, int* horDelta, int* verDelta);
#ifdef CC_BUILD_TOUCH #ifdef CC_BUILD_TOUCH
#define INPUT_MAX_POINTERS 32 #define INPUT_MAX_POINTERS 32
enum INPUT_MODE { INPUT_MODE_PLACE, INPUT_MODE_DELETE, INPUT_MODE_NONE, INPUT_MODE_COUNT }; enum INPUT_MODE { INPUT_MODE_PLACE, INPUT_MODE_DELETE, INPUT_MODE_NONE, INPUT_MODE_COUNT };
@ -145,6 +149,14 @@ void Input_SetTouchMode(cc_bool enabled);
void Input_AddTouch(long id, int x, int y); void Input_AddTouch(long id, int x, int y);
void Input_UpdateTouch(long id, int x, int y); void Input_UpdateTouch(long id, int x, int y);
void Input_RemoveTouch(long id, int x, int y); void Input_RemoveTouch(long id, int x, int y);
struct TouchPointer {
long id;
cc_uint8 type;
int begX, begY;
double start;
};
extern struct TouchPointer touches[INPUT_MAX_POINTERS];
#else #else
#define INPUT_MAX_POINTERS 1 #define INPUT_MAX_POINTERS 1
#define Pointers_Count 1 #define Pointers_Count 1

View File

@ -36,35 +36,6 @@ static cc_bool suppressEscape;
enum MouseButton_ { MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE }; enum MouseButton_ { MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE };
/*########################################################################################################################*
*------------------------------------------------------Touch support------------------------------------------------------*
*#########################################################################################################################*/
#ifdef CC_BUILD_TOUCH
/* Quickly tapping should trigger a block place/delete */
static void CheckBlockTap(int i) {
int btn, pressed;
if (Game.Time > touches[i].start + 0.25) return;
if (touches[i].type != TOUCH_TYPE_ALL) return;
if (Input_TapMode == INPUT_MODE_PLACE) {
btn = MOUSE_RIGHT;
} else if (Input_TapMode == INPUT_MODE_DELETE) {
btn = MOUSE_LEFT;
} else { return; }
pressed = input_buttonsDown[btn];
MouseStatePress(btn);
if (btn == MOUSE_LEFT) {
InputHandler_DeleteBlock();
} else {
InputHandler_PlaceBlock();
}
if (!pressed) MouseStateRelease(btn);
}
#endif
/*########################################################################################################################* /*########################################################################################################################*
*---------------------------------------------------------Keybinds--------------------------------------------------------* *---------------------------------------------------------Keybinds--------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
@ -649,6 +620,9 @@ static void InputHandler_PickBlock(void) {
Inventory_PickBlock(cur); Inventory_PickBlock(cur);
} }
#ifdef CC_BUILD_TOUCH
static cc_bool AnyBlockTouches(void);
#endif
void InputHandler_Tick(void) { void InputHandler_Tick(void) {
cc_bool left, middle, right; cc_bool left, middle, right;
double now, delta; double now, delta;
@ -692,6 +666,47 @@ void InputHandler_Tick(void) {
} }
/*########################################################################################################################*
*------------------------------------------------------Touch support------------------------------------------------------*
*#########################################################################################################################*/
#ifdef CC_BUILD_TOUCH
static cc_bool AnyBlockTouches(void) {
int i;
for (i = 0; i < Pointers_Count; i++) {
if (!(touches[i].type & TOUCH_TYPE_BLOCKS)) continue;
/* Touch might be an 'all' type - remove 'gui' type */
touches[i].type &= TOUCH_TYPE_BLOCKS | TOUCH_TYPE_CAMERA;
return true;
}
return false;
}
/* Quickly tapping should trigger a block place/delete */
static void CheckBlockTap(int i) {
int btn, pressed;
if (Game.Time > touches[i].start + 0.25) return;
if (touches[i].type != TOUCH_TYPE_ALL) return;
if (Input_TapMode == INPUT_MODE_PLACE) {
btn = MOUSE_RIGHT;
} else if (Input_TapMode == INPUT_MODE_DELETE) {
btn = MOUSE_LEFT;
} else { return; }
pressed = input_buttonsDown[btn];
MouseStatePress(btn);
if (btn == MOUSE_LEFT) {
InputHandler_DeleteBlock();
} else {
InputHandler_PlaceBlock();
}
if (!pressed) MouseStateRelease(btn);
}
#endif
/*########################################################################################################################* /*########################################################################################################################*
*-----------------------------------------------------Input helpers-------------------------------------------------------* *-----------------------------------------------------Input helpers-------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
@ -895,6 +910,11 @@ static void HookInputBinds(void) {
static void OnPointerDown(void* obj, int idx) { static void OnPointerDown(void* obj, int idx) {
struct Screen* s; struct Screen* s;
int i, x, y, mask; int i, x, y, mask;
/* Always set last click time, otherwise quickly tapping */
/* sometimes triggers a 'delete' in InputHandler_Tick, */
/* and then another 'delete' in CheckBlockTap. */
input_lastClick = Game.Time;
#ifdef CC_BUILD_TOUCH #ifdef CC_BUILD_TOUCH
if (Input_TouchMode && !(touches[idx].type & TOUCH_TYPE_GUI)) return; if (Input_TouchMode && !(touches[idx].type & TOUCH_TYPE_GUI)) return;
#endif #endif
@ -943,7 +963,7 @@ static void OnInputDown(void* obj, int key, cc_bool was, struct InputDevice* dev
struct Screen* s; struct Screen* s;
cc_bool triggered; cc_bool triggered;
int i; int i;
if (Window_Main.SoftKeyboardFocus) return; if (Input.DownHook) { Input.DownHook(key, device); return; }
#ifndef CC_BUILD_WEB #ifndef CC_BUILD_WEB
if (key == device->escapeButton && (s = Gui_GetClosable())) { if (key == device->escapeButton && (s = Gui_GetClosable())) {
@ -1066,7 +1086,7 @@ static void Player_ReleaseDown(int key, struct InputDevice* device) {
static void PlayerInputNormal(struct LocalPlayer* p, float* xMoving, float* zMoving) { static void PlayerInputNormal(struct LocalPlayer* p, float* xMoving, float* zMoving) {
int flags = moveFlags[0], port; int flags = moveFlags[0], port;
if (Game_NumLocalPlayers > 1) { if (Game_NumLocalPlayers == 1) {
for (port = 0; port < INPUT_MAX_GAMEPADS; port++) for (port = 0; port < INPUT_MAX_GAMEPADS; port++)
flags |= moveFlags[port + 1]; flags |= moveFlags[port + 1];
} else { } else {

View File

@ -186,7 +186,7 @@ static cc_bool IsShutdown(int key) {
} }
static void OnInputDown(void* obj, int key, cc_bool was, struct InputDevice* device) { static void OnInputDown(void* obj, int key, cc_bool was, struct InputDevice* device) {
if (Window_Main.SoftKeyboardFocus) return; if (Input.DownHook) { Input.DownHook(key, device); return; }
if (IsShutdown(key)) Launcher_ShouldExit = true; if (IsShutdown(key)) Launcher_ShouldExit = true;
Launcher_Active->KeyDown(Launcher_Active, key, was, device); Launcher_Active->KeyDown(Launcher_Active, key, was, device);

View File

@ -2003,19 +2003,6 @@ static void KeyBindsScreen_Update(struct KeyBindsScreen* s, int i) {
s->dirty = true; s->dirty = true;
} }
static void KeyBindsScreen_OnBindingClick(void* screen, void* widget) {
struct KeyBindsScreen* s = (struct KeyBindsScreen*)screen;
struct ButtonWidget* btn = (struct ButtonWidget*)widget;
int old = s->curI;
s->curI = (int)btn->meta.val;
s->closable = false;
KeyBindsScreen_Update(s, s->curI);
/* previously selected a different button for binding */
if (old >= 0) KeyBindsScreen_Update(s, old);
}
static void KeyBindsScreen_ResetBinding(InputBind bind) { static void KeyBindsScreen_ResetBinding(InputBind bind) {
if (binds_gamepad) { if (binds_gamepad) {
PadBind_Reset(bind); PadBind_Reset(bind);
@ -2032,12 +2019,13 @@ static void KeyBindsScreen_UpdateBinding(InputBind bind, int key, struct InputDe
} }
} }
static int KeyBindsScreen_KeyDown(void* screen, int key, struct InputDevice* device) { static void KeyBindsScreen_TriggerBinding(int key, struct InputDevice* device) {
struct KeyBindsScreen* s = (struct KeyBindsScreen*)screen; struct KeyBindsScreen* s = &KeyBindsScreen;
InputBind bind; InputBind bind;
int idx; int idx;
if (s->curI == -1) return Menu_InputDown(s, key, device); Input.DownHook = NULL;
if (s->curI == -1) return;
bind = s->binds[s->curI]; bind = s->binds[s->curI];
if (key == device->escapeButton) { if (key == device->escapeButton) {
@ -2050,7 +2038,21 @@ static int KeyBindsScreen_KeyDown(void* screen, int key, struct InputDevice* dev
s->curI = -1; s->curI = -1;
s->closable = true; s->closable = true;
KeyBindsScreen_Update(s, idx); KeyBindsScreen_Update(s, idx);
return true; }
static void KeyBindsScreen_OnBindingClick(void* screen, void* widget) {
struct KeyBindsScreen* s = (struct KeyBindsScreen*)screen;
struct ButtonWidget* btn = (struct ButtonWidget*)widget;
Input.DownHook = NULL;
int old = s->curI;
s->curI = (int)btn->meta.val;
s->closable = false;
KeyBindsScreen_Update(s, s->curI);
/* previously selected a different button for binding */
if (old >= 0) KeyBindsScreen_Update(s, old);
Input.DownHook = KeyBindsScreen_TriggerBinding;
} }
static void KeyBindsScreen_ContextLost(void* screen) { static void KeyBindsScreen_ContextLost(void* screen) {
@ -2131,10 +2133,14 @@ static void KeyBindsScreen_Init(void* screen) {
s->maxVertices = Screen_CalcDefaultMaxVertices(s); s->maxVertices = Screen_CalcDefaultMaxVertices(s);
} }
static void KeyBindsScreen_Free(void* screen) {
Input.DownHook = NULL;
}
static const struct ScreenVTABLE KeyBindsScreen_VTABLE = { static const struct ScreenVTABLE KeyBindsScreen_VTABLE = {
KeyBindsScreen_Init, Screen_NullUpdate, Screen_NullFunc, KeyBindsScreen_Init, Screen_NullUpdate, KeyBindsScreen_Free,
MenuScreen_Render2, Screen_BuildMesh, MenuScreen_Render2, Screen_BuildMesh,
KeyBindsScreen_KeyDown, Screen_InputUp, Screen_TKeyPress, Screen_TText, Menu_InputDown, Screen_InputUp, Screen_TKeyPress, Screen_TText,
Menu_PointerDown, Screen_PointerUp, Menu_PointerMove, Screen_TMouseScroll, Menu_PointerDown, Screen_PointerUp, Menu_PointerMove, Screen_TMouseScroll,
KeyBindsScreen_Layout, KeyBindsScreen_ContextLost, KeyBindsScreen_ContextRecreated KeyBindsScreen_Layout, KeyBindsScreen_ContextLost, KeyBindsScreen_ContextRecreated
}; };

View File

@ -23,6 +23,7 @@
#include "Input.h" #include "Input.h"
#include "Utils.h" #include "Utils.h"
#include "Options.h" #include "Options.h"
#include "InputHandler.h"
/* Enumeration of on-screen buttons for touch GUI */ /* Enumeration of on-screen buttons for touch GUI */

View File

@ -247,9 +247,9 @@ static void VirtualKeyboard_ClickSelected(void) {
} }
} }
static void VirtualKeyboard_ProcessDown(void* obj, int key, cc_bool was) { static void VirtualKeyboard_ProcessDown(int key, struct InputDevice* device) {
int deltaX, deltaY; int deltaX, deltaY;
Input_CalcDelta(key, &deltaX, &deltaY); Input_CalcDelta(key, device, &deltaX, &deltaY);
if (deltaX || deltaY) { if (deltaX || deltaY) {
VirtualKeyboard_Scroll(deltaX, deltaY); VirtualKeyboard_Scroll(deltaX, deltaY);
@ -370,8 +370,6 @@ static void VirtualKeyboard_Hook(void) {
/* Don't hook immediately into events, otherwise the initial up/down press that opened */ /* Don't hook immediately into events, otherwise the initial up/down press that opened */
/* the virtual keyboard in the first place gets mistakenly processed */ /* the virtual keyboard in the first place gets mistakenly processed */
kb_needsHook = false; kb_needsHook = false;
Event_Register_(&InputEvents.Down, NULL, VirtualKeyboard_ProcessDown);
Event_Register_(&ControllerEvents.AxisUpdate, NULL, VirtualKeyboard_PadAxis); Event_Register_(&ControllerEvents.AxisUpdate, NULL, VirtualKeyboard_PadAxis);
} }
@ -401,6 +399,7 @@ static void VirtualKeyboard_Open(struct OpenKeyboardArgs* args, cc_bool launcher
} }
Window_Main.SoftKeyboardFocus = true; Window_Main.SoftKeyboardFocus = true;
Input.DownHook = VirtualKeyboard_ProcessDown;
} }
static void VirtualKeyboard_SetText(const cc_string* text) { static void VirtualKeyboard_SetText(const cc_string* text) {
@ -415,12 +414,12 @@ static void VirtualKeyboard_Close(void) {
if (KB_MarkDirty == VirtualKeyboard_MarkDirty3D) if (KB_MarkDirty == VirtualKeyboard_MarkDirty3D)
VirtualKeyboard_Close3D(); VirtualKeyboard_Close3D();
Event_Unregister_(&InputEvents.Down, NULL, VirtualKeyboard_ProcessDown);
Event_Unregister_(&ControllerEvents.AxisUpdate, NULL, VirtualKeyboard_PadAxis); Event_Unregister_(&ControllerEvents.AxisUpdate, NULL, VirtualKeyboard_PadAxis);
Window_Main.SoftKeyboardFocus = false; Window_Main.SoftKeyboardFocus = false;
KB_MarkDirty = NULL; KB_MarkDirty = NULL;
kb_needsHook = false; kb_needsHook = false;
Input.DownHook = NULL;
DisplayInfo.ShowingSoftKeyboard = false; DisplayInfo.ShowingSoftKeyboard = false;
} }

View File

@ -488,6 +488,7 @@ static void UniString_WriteString(const cc_string* src, char16_t* dst) {
*dst = '\0'; *dst = '\0';
} }
static void OnscreenKeyboard_ProcessDown(int key, struct InputDevice* device) { }
void OnscreenKeyboard_Open(struct OpenKeyboardArgs* args) { void OnscreenKeyboard_Open(struct OpenKeyboardArgs* args) {
if (keyboardOpen) OnscreenKeyboard_Close(); if (keyboardOpen) OnscreenKeyboard_Close();
@ -498,6 +499,7 @@ void OnscreenKeyboard_Open(struct OpenKeyboardArgs* args) {
kb_str.length = 0; kb_str.length = 0;
keyboardOpen = true; keyboardOpen = true;
Window_Main.SoftKeyboardFocus = true; Window_Main.SoftKeyboardFocus = true;
Input.DownHook = OnscreenKeyboard_ProcessDown;
fs_client = (FSClient *)MEMAllocFromDefaultHeap(sizeof(FSClient)); fs_client = (FSClient *)MEMAllocFromDefaultHeap(sizeof(FSClient));
FSAddClient(fs_client, FS_ERROR_FLAG_NONE); FSAddClient(fs_client, FS_ERROR_FLAG_NONE);
@ -607,6 +609,7 @@ void OnscreenKeyboard_Close(void) {
if (!keyboardOpen) return; if (!keyboardOpen) return;
keyboardOpen = false; keyboardOpen = false;
Window_Main.SoftKeyboardFocus = false; Window_Main.SoftKeyboardFocus = false;
Input.DownHook = NULL;
nn::swkbd::DisappearInputForm(); nn::swkbd::DisappearInputForm();
nn::swkbd::Destroy(); nn::swkbd::Destroy();