mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-12 00:56:40 -04:00
Allow setting input override hooks, fix touch build not compiling
This commit is contained in:
parent
67566d0fb7
commit
ce7c077ca9
61
src/Input.c
61
src/Input.c
@ -25,12 +25,7 @@ static void Pointer_SetPressed(int idx, cc_bool pressed);
|
||||
*------------------------------------------------------Touch support------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
static struct TouchPointer {
|
||||
long id;
|
||||
cc_uint8 type;
|
||||
int begX, begY;
|
||||
double start;
|
||||
} touches[INPUT_MAX_POINTERS];
|
||||
struct TouchPointer touches[INPUT_MAX_POINTERS];
|
||||
|
||||
int Pointers_Count;
|
||||
int Input_TapMode = INPUT_MODE_PLACE;
|
||||
@ -40,18 +35,6 @@ cc_bool Input_TouchMode;
|
||||
static void MouseStatePress(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) {
|
||||
int i;
|
||||
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) {
|
||||
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 (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 */
|
||||
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;
|
||||
|
||||
touches[i].id = id;
|
||||
touches[i].type = TOUCH_TYPE_ALL;
|
||||
touches[i].begX = x;
|
||||
touches[i].begY = y;
|
||||
|
||||
touches[i].id = id;
|
||||
touches[i].type = TOUCH_TYPE_ALL;
|
||||
touches[i].begX = x;
|
||||
touches[i].begY = y;
|
||||
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++;
|
||||
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); }
|
||||
|
||||
/* 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) {
|
||||
int i;
|
||||
for (i = 0; i < Pointers_Count; i++) {
|
||||
|
12
src/Input.h
12
src/Input.h
@ -6,6 +6,7 @@ Manages input state and raising input related events
|
||||
Copyright 2014-2023 ClassiCube | Licensed under BSD-3
|
||||
*/
|
||||
struct IGameComponent;
|
||||
struct InputDevice;
|
||||
extern struct IGameComponent Input_Component;
|
||||
|
||||
enum InputButtons {
|
||||
@ -76,6 +77,8 @@ extern struct _InputState {
|
||||
cc_bool RawMode;
|
||||
/* Sources available for input (Mouse/Keyboard, Gamepad) */
|
||||
cc_uint8 Sources;
|
||||
/* Function that overrides all normal input handling (e.g. for virtual keyboard) */
|
||||
void (*DownHook)(int btn, struct InputDevice* device);
|
||||
} Input;
|
||||
|
||||
/* 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);
|
||||
|
||||
|
||||
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
#define INPUT_MAX_POINTERS 32
|
||||
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_UpdateTouch(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
|
||||
#define INPUT_MAX_POINTERS 1
|
||||
#define Pointers_Count 1
|
||||
|
@ -36,35 +36,6 @@ static cc_bool suppressEscape;
|
||||
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--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
@ -649,6 +620,9 @@ static void InputHandler_PickBlock(void) {
|
||||
Inventory_PickBlock(cur);
|
||||
}
|
||||
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
static cc_bool AnyBlockTouches(void);
|
||||
#endif
|
||||
void InputHandler_Tick(void) {
|
||||
cc_bool left, middle, right;
|
||||
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-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
@ -895,6 +910,11 @@ static void HookInputBinds(void) {
|
||||
static void OnPointerDown(void* obj, int idx) {
|
||||
struct Screen* s;
|
||||
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
|
||||
if (Input_TouchMode && !(touches[idx].type & TOUCH_TYPE_GUI)) return;
|
||||
#endif
|
||||
@ -943,7 +963,7 @@ static void OnInputDown(void* obj, int key, cc_bool was, struct InputDevice* dev
|
||||
struct Screen* s;
|
||||
cc_bool triggered;
|
||||
int i;
|
||||
if (Window_Main.SoftKeyboardFocus) return;
|
||||
if (Input.DownHook) { Input.DownHook(key, device); return; }
|
||||
|
||||
#ifndef CC_BUILD_WEB
|
||||
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) {
|
||||
int flags = moveFlags[0], port;
|
||||
|
||||
if (Game_NumLocalPlayers > 1) {
|
||||
if (Game_NumLocalPlayers == 1) {
|
||||
for (port = 0; port < INPUT_MAX_GAMEPADS; port++)
|
||||
flags |= moveFlags[port + 1];
|
||||
} else {
|
||||
|
@ -186,7 +186,7 @@ static cc_bool IsShutdown(int key) {
|
||||
}
|
||||
|
||||
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;
|
||||
Launcher_Active->KeyDown(Launcher_Active, key, was, device);
|
||||
|
44
src/Menus.c
44
src/Menus.c
@ -2003,19 +2003,6 @@ static void KeyBindsScreen_Update(struct KeyBindsScreen* s, int i) {
|
||||
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) {
|
||||
if (binds_gamepad) {
|
||||
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) {
|
||||
struct KeyBindsScreen* s = (struct KeyBindsScreen*)screen;
|
||||
static void KeyBindsScreen_TriggerBinding(int key, struct InputDevice* device) {
|
||||
struct KeyBindsScreen* s = &KeyBindsScreen;
|
||||
InputBind bind;
|
||||
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];
|
||||
|
||||
if (key == device->escapeButton) {
|
||||
@ -2050,7 +2038,21 @@ static int KeyBindsScreen_KeyDown(void* screen, int key, struct InputDevice* dev
|
||||
s->curI = -1;
|
||||
s->closable = true;
|
||||
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) {
|
||||
@ -2131,10 +2133,14 @@ static void KeyBindsScreen_Init(void* screen) {
|
||||
s->maxVertices = Screen_CalcDefaultMaxVertices(s);
|
||||
}
|
||||
|
||||
static void KeyBindsScreen_Free(void* screen) {
|
||||
Input.DownHook = NULL;
|
||||
}
|
||||
|
||||
static const struct ScreenVTABLE KeyBindsScreen_VTABLE = {
|
||||
KeyBindsScreen_Init, Screen_NullUpdate, Screen_NullFunc,
|
||||
KeyBindsScreen_Init, Screen_NullUpdate, KeyBindsScreen_Free,
|
||||
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,
|
||||
KeyBindsScreen_Layout, KeyBindsScreen_ContextLost, KeyBindsScreen_ContextRecreated
|
||||
};
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "Input.h"
|
||||
#include "Utils.h"
|
||||
#include "Options.h"
|
||||
#include "InputHandler.h"
|
||||
|
||||
|
||||
/* Enumeration of on-screen buttons for touch GUI */
|
||||
|
@ -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;
|
||||
Input_CalcDelta(key, &deltaX, &deltaY);
|
||||
Input_CalcDelta(key, device, &deltaX, &deltaY);
|
||||
|
||||
if (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 */
|
||||
/* the virtual keyboard in the first place gets mistakenly processed */
|
||||
kb_needsHook = false;
|
||||
|
||||
Event_Register_(&InputEvents.Down, NULL, VirtualKeyboard_ProcessDown);
|
||||
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;
|
||||
Input.DownHook = VirtualKeyboard_ProcessDown;
|
||||
}
|
||||
|
||||
static void VirtualKeyboard_SetText(const cc_string* text) {
|
||||
@ -415,12 +414,12 @@ static void VirtualKeyboard_Close(void) {
|
||||
if (KB_MarkDirty == VirtualKeyboard_MarkDirty3D)
|
||||
VirtualKeyboard_Close3D();
|
||||
|
||||
Event_Unregister_(&InputEvents.Down, NULL, VirtualKeyboard_ProcessDown);
|
||||
Event_Unregister_(&ControllerEvents.AxisUpdate, NULL, VirtualKeyboard_PadAxis);
|
||||
Window_Main.SoftKeyboardFocus = false;
|
||||
|
||||
KB_MarkDirty = NULL;
|
||||
kb_needsHook = false;
|
||||
KB_MarkDirty = NULL;
|
||||
kb_needsHook = false;
|
||||
Input.DownHook = NULL;
|
||||
|
||||
DisplayInfo.ShowingSoftKeyboard = false;
|
||||
}
|
||||
|
@ -488,6 +488,7 @@ static void UniString_WriteString(const cc_string* src, char16_t* dst) {
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
static void OnscreenKeyboard_ProcessDown(int key, struct InputDevice* device) { }
|
||||
|
||||
void OnscreenKeyboard_Open(struct OpenKeyboardArgs* args) {
|
||||
if (keyboardOpen) OnscreenKeyboard_Close();
|
||||
@ -498,6 +499,7 @@ void OnscreenKeyboard_Open(struct OpenKeyboardArgs* args) {
|
||||
kb_str.length = 0;
|
||||
keyboardOpen = true;
|
||||
Window_Main.SoftKeyboardFocus = true;
|
||||
Input.DownHook = OnscreenKeyboard_ProcessDown;
|
||||
|
||||
fs_client = (FSClient *)MEMAllocFromDefaultHeap(sizeof(FSClient));
|
||||
FSAddClient(fs_client, FS_ERROR_FLAG_NONE);
|
||||
@ -607,6 +609,7 @@ void OnscreenKeyboard_Close(void) {
|
||||
if (!keyboardOpen) return;
|
||||
keyboardOpen = false;
|
||||
Window_Main.SoftKeyboardFocus = false;
|
||||
Input.DownHook = NULL;
|
||||
|
||||
nn::swkbd::DisappearInputForm();
|
||||
nn::swkbd::Destroy();
|
||||
|
Loading…
x
Reference in New Issue
Block a user