Merge GamePad_States and PadDevice

This commit is contained in:
UnknownShadow200 2024-07-13 11:00:18 +10:00
parent cf61ef23d3
commit 9ea54dee7c
5 changed files with 242 additions and 237 deletions

View File

@ -273,8 +273,10 @@ static cc_bool NormDevice_IsPressed(struct InputDevice* device, int key) {
}
static cc_bool PadDevice_IsPressed(struct InputDevice* device, int key) {
struct GamepadDevice* gamepad = (struct GamepadDevice*)device;
if (!Input_IsPadButton(key)) return false;
return Gamepad_States[device->index].pressed[key - GAMEPAD_BEG_BTN];
return gamepad->pressed[key - GAMEPAD_BEG_BTN];
}
static cc_bool TouchDevice_IsPressed(struct InputDevice* device, int key) {
@ -293,9 +295,9 @@ struct InputDevice NormDevice = {
/* Launcher buttons */
CCKEY_TAB,
/* Bindings */
"key-%c", NULL, NULL
"key-%c", KeyBind_Defaults, KeyBind_Mappings
};
struct InputDevice PadDevice = {
static const struct InputDevice padDevice = {
INPUT_DEVICE_GAMEPAD, 0,
PadDevice_IsPressed,
/* General buttons */
@ -307,7 +309,7 @@ struct InputDevice PadDevice = {
/* Launcher buttons */
CCPAD_3,
/* Bindings */
"pad-%c", NULL, NULL
"pad-%c", PadBind_Defaults, PadBind_Mappings
};
struct InputDevice TouchDevice = {
INPUT_DEVICE_TOUCH, 0,
@ -378,21 +380,20 @@ int Gamepad_AxisBehaviour[2] = { AXIS_BEHAVIOUR_MOVEMENT, AXIS_BEHAVIOUR_CAMER
int Gamepad_AxisSensitivity[2] = { AXIS_SENSI_NORMAL, AXIS_SENSI_NORMAL };
static const float axis_sensiFactor[] = { 0.25f, 0.5f, 1.0f, 2.0f, 4.0f };
struct GamepadState Gamepad_States[INPUT_MAX_GAMEPADS];
struct GamepadDevice Gamepad_Devices[INPUT_MAX_GAMEPADS];
static void Gamepad_Apply(int port, int btn, cc_bool was, int pressed) {
struct InputDevice device = PadDevice;
device.index = port;
struct InputDevice* device = &Gamepad_Devices[port].base;
if (pressed) {
Event_RaiseInput(&InputEvents.Down, btn + GAMEPAD_BEG_BTN, was, &device);
Event_RaiseInput(&InputEvents.Down, btn + GAMEPAD_BEG_BTN, was, device);
} else {
Event_RaiseInput(&InputEvents.Up, btn + GAMEPAD_BEG_BTN, was, &device);
Event_RaiseInput(&InputEvents.Up, btn + GAMEPAD_BEG_BTN, was, device);
}
}
static void Gamepad_Update(int port, float delta) {
struct GamepadState* pad = &Gamepad_States[port];
struct GamepadDevice* pad = &Gamepad_Devices[port];
int btn;
for (btn = 0; btn < GAMEPAD_BTN_COUNT; btn++)
@ -408,7 +409,7 @@ static void Gamepad_Update(int port, float delta) {
}
void Gamepad_SetButton(int port, int btn, int pressed) {
struct GamepadState* pad = &Gamepad_States[port];
struct GamepadDevice* pad = &Gamepad_Devices[port];
btn -= GAMEPAD_BEG_BTN;
/* Repeat down is handled in Gamepad_Update instead */
if (pressed && pad->pressed[btn]) return;
@ -421,8 +422,8 @@ void Gamepad_SetButton(int port, int btn, int pressed) {
}
void Gamepad_SetAxis(int port, int axis, float x, float y, float delta) {
Gamepad_States[port].axisX[axis] = x;
Gamepad_States[port].axisY[axis] = y;
Gamepad_Devices[port].axisX[axis] = x;
Gamepad_Devices[port].axisY[axis] = y;
if (x == 0 && y == 0) return;
int sensi = Gamepad_AxisSensitivity[axis];
@ -445,10 +446,10 @@ int Gamepad_MapPort(long deviceID) {
for (port = 0; port < INPUT_MAX_GAMEPADS; port++)
{
if (Gamepad_States[port].deviceID == deviceID) return port;
if (Gamepad_Devices[port].deviceID == deviceID) return port;
if (Gamepad_States[port].deviceID != 0) continue;
Gamepad_States[port].deviceID = deviceID;
if (Gamepad_Devices[port].deviceID != 0) continue;
Gamepad_Devices[port].deviceID = deviceID;
return port;
}
@ -457,16 +458,163 @@ int Gamepad_MapPort(long deviceID) {
}
/*########################################################################################################################*
*---------------------------------------------------------Keybinds--------------------------------------------------------*
*#########################################################################################################################*/
BindMapping PadBind_Mappings[BIND_COUNT];
BindMapping KeyBind_Mappings[BIND_COUNT];
const BindMapping PadBind_Defaults[BIND_COUNT] = {
{ CCPAD_UP, 0 }, { CCPAD_DOWN, 0 }, /* BIND_FORWARD, BIND_BACK */
{ CCPAD_LEFT, 0 }, { CCPAD_RIGHT, 0 }, /* BIND_LEFT, BIND_RIGHT */
{ CCPAD_1, 0 }, { 0, 0 }, /* BIND_JUMP, BIND_RESPAWN */
{ CCPAD_START, 0 }, { CCPAD_4, 0 }, /* BIND_SET_SPAWN, BIND_CHAT */
{ CCPAD_3, 0 }, { 0, 0 }, /* BIND_INVENTORY, BIND_FOG */
{ CCPAD_START, 0 }, { 0, 0 }, /* BIND_SEND_CHAT, BIND_TABLIST */
{ CCPAD_2, CCPAD_L},{ CCPAD_2, CCPAD_3},/* BIND_SPEED, BIND_NOCLIP */
{ CCPAD_2, CCPAD_R }, /* BIND_FLY */
{CCPAD_2,CCPAD_UP},{CCPAD_2,CCPAD_DOWN},/* BIND_FLY_UP, BIND_FLY_DOWN */
{ 0, 0 }, { 0, 0 }, /* BIND_EXT_INPUT, BIND_HIDE_FPS */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_SCREENSHOT, BIND_FULLSCREEN, BIND_THIRD_PERSON, BIND_HIDE_GUI */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_AXIS_LINES, BIND_ZOOM_SCROLL, BIND_HALF_SPEED */
{ CCPAD_L, 0 }, { 0, 0 },{ CCPAD_R, 0 },/* BIND_DELETE_BLOCK, BIND_PICK_BLOCK, BIND_PLACE_BLOCK */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_AUTOROTATE, BIND_HOTBAR_SWITCH, BIND_SMOOTH_CAMERA */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_DROP_BLOCK, BIND_IDOVERLAY, BIND_BREAK_LIQUIDS */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_LOOK_UP, BIND_LOOK_DOWN, BIND_LOOK_RIGHT, BIND_LOOK_LEFT */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_HOTBAR_1, BIND_HOTBAR_2, BIND_HOTBAR_3 */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_HOTBAR_4, BIND_HOTBAR_5, BIND_HOTBAR_6 */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_HOTBAR_7, BIND_HOTBAR_8, BIND_HOTBAR_9 */
{ CCPAD_ZL, 0 }, { CCPAD_ZR, 0 } /* BIND_HOTBAR_LEFT, BIND_HOTBAR_RIGHT */
};
const BindMapping KeyBind_Defaults[BIND_COUNT] = {
{ 'W', 0 }, { 'S', 0 }, { 'A', 0 }, { 'D', 0 }, /* BIND_FORWARD - BIND_RIGHT */
{ CCKEY_SPACE, 0 }, { 'R', 0 }, /* BIND_JUMP, BIND_RESPAWN */
{ CCKEY_ENTER, 0 }, { 'T', 0 }, /* BIND_SET_SPAWN, BIND_CHAT */
{ 'B', 0 }, { 'F', 0 }, /* BIND_INVENTORY, BIND_FOG */
{ CCKEY_ENTER, 0 }, { CCKEY_TAB, 0 }, /* BIND_SEND_CHAT, BIND_TABLIST */
{ CCKEY_LSHIFT, 0 }, { 'X', 0}, { 'Z', 0 }, /* BIND_SPEED, BIND_NOCLIP, BIND_FLY */
{ 'Q', 0 }, { 'E', 0 }, /* BIND_FLY_UP, BIND_FLY_DOWN */
{ CCKEY_LALT, 0 }, { CCKEY_F3, 0 }, /* BIND_EXT_INPUT, BIND_HIDE_FPS */
{ CCKEY_F12, 0 }, { CCKEY_F11, 0 }, /* BIND_SCREENSHOT, BIND_FULLSCREEN */
{ CCKEY_F5, 0 }, { CCKEY_F1, 0 }, /* BIND_THIRD_PERSON, BIND_HIDE_GUI */
{ CCKEY_F7, 0 }, { 'C', 0 }, { CCKEY_LCTRL, 0 },/* BIND_AXIS_LINES, BIND_ZOOM_SCROLL, BIND_HALF_SPEED */
{ CCMOUSE_L, 0},{ CCMOUSE_M, 0},{ CCMOUSE_R, 0},/* BIND_DELETE_BLOCK, BIND_PICK_BLOCK, BIND_PLACE_BLOCK */
{ CCKEY_F6, 0 }, { CCKEY_LALT, 0 }, /* BIND_AUTOROTATE, BIND_HOTBAR_SWITCH */
{ CCKEY_F8, 0 }, { 'G', 0 }, /* BIND_SMOOTH_CAMERA, BIND_DROP_BLOCK */
{ CCKEY_F10, 0 }, { 0, 0 }, /* BIND_IDOVERLAY, BIND_BREAK_LIQUIDS */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_LOOK_UP, BIND_LOOK_DOWN, BIND_LOOK_RIGHT, BIND_LOOK_LEFT */
{ '1', 0 }, { '2', 0 }, { '3', 0 }, /* BIND_HOTBAR_1, BIND_HOTBAR_2, BIND_HOTBAR_3 */
{ '4', 0 }, { '5', 0 }, { '6', 0 }, /* BIND_HOTBAR_4, BIND_HOTBAR_5, BIND_HOTBAR_6 */
{ '7', 0 }, { '8', 0 }, { '9', 0 }, /* BIND_HOTBAR_7, BIND_HOTBAR_8, BIND_HOTBAR_9 */
{ 0, 0 }, { 0, 0 } /* BIND_HOTBAR_LEFT, BIND_HOTBAR_RIGHT */
};
static const char* const bindNames[BIND_COUNT] = {
"Forward", "Back", "Left", "Right",
"Jump", "Respawn", "SetSpawn", "Chat", "Inventory",
"ToggleFog", "SendChat", "PlayerList",
"Speed", "NoClip", "Fly", "FlyUp", "FlyDown",
"ExtInput", "HideFPS", "Screenshot", "Fullscreen",
"ThirdPerson", "HideGUI", "AxisLines", "ZoomScrolling",
"HalfSpeed", "DeleteBlock", "PickBlock", "PlaceBlock",
"AutoRotate", "HotbarSwitching", "SmoothCamera",
"DropBlock", "IDOverlay", "BreakableLiquids",
"LookUp", "LookDown", "LookRight", "LookLeft",
"Hotbar1", "Hotbar2", "Hotbar3",
"Hotbar4", "Hotbar5", "Horbar6",
"Hotbar7", "Hotbar8", "Hotbar9",
"HotbarLeft", "HotbarRight"
};
#define BindMapping2_Claims(mapping, btn) (device->IsPressed(device, (mapping)->button1) && (mapping)->button2 == btn)
cc_bool InputBind_Claims(InputBind binding, int btn, struct InputDevice* device) {
BindMapping* mappings = device->currentBinds;
BindMapping* bind = &mappings[binding];
int i;
if (bind->button2) return BindMapping2_Claims(bind, btn);
/* Two button mappings takes priority over one button mappings */
for (i = 0; i < BIND_COUNT; i++)
{
if (mappings[i].button2 && BindMapping2_Claims(&mappings[i], btn)) return false;
}
return bind->button1 == btn;
}
void InputBind_Load(const struct InputDevice* device) {
cc_string name; char nameBuffer[STRING_SIZE + 1];
const BindMapping* defaults = device->defaultBinds;
BindMapping* keybinds = device->currentBinds;
BindMapping mapping;
cc_string str, part1, part2;
int i;
String_InitArray_NT(name, nameBuffer);
for (i = 0; i < BIND_COUNT; i++)
{
name.length = 0;
String_Format1(&name, device->bindPrefix, bindNames[i]);
name.buffer[name.length] = '\0';
if (!Options_UNSAFE_Get(name.buffer, &str)) {
keybinds[i] = defaults[i];
continue;
}
String_UNSAFE_Separate(&str, ',', &part1, &part2);
mapping.button1 = Utils_ParseEnum(&part1, defaults[i].button1, Input_StorageNames, INPUT_COUNT);
mapping.button2 = Utils_ParseEnum(&part2, defaults[i].button2, Input_StorageNames, INPUT_COUNT);
if (mapping.button1 == CCKEY_ESCAPE) keybinds[i] = defaults[i];
keybinds[i] = mapping;
}
}
void InputBind_Set(InputBind binding, int btn, const struct InputDevice* device) {
cc_string name; char nameBuffer[STRING_SIZE];
cc_string value;
String_InitArray(name, nameBuffer);
String_Format1(&name, device->bindPrefix, bindNames[binding]);
value = String_FromReadonly(Input_StorageNames[btn]);
Options_SetString(&name, &value);
BindMapping_Set(&device->currentBinds[binding], btn, 0);
}
void InputBind_Reset(InputBind binding, const struct InputDevice* device) {
cc_string name; char nameBuffer[STRING_SIZE];
String_InitArray(name, nameBuffer);
String_Format1(&name, device->bindPrefix, bindNames[binding]);
Options_SetString(&name, &String_Empty);
device->currentBinds[binding] = device->defaultBinds[binding];
}
/*########################################################################################################################*
*-----------------------------------------------------Base handlers-------------------------------------------------------*
*#########################################################################################################################*/
static void OnFocusChanged(void* obj) { if (!Window_Main.Focused) Input_Clear(); }
static void OnInit(void) {
int i;
Event_Register_(&WindowEvents.FocusChanged, NULL, OnFocusChanged);
/* Fix issue with Android where if you double click in server list to join, a touch */
/* pointer is stuck down when the game loads (so you instantly start deleting blocks) */
ClearTouches();
for (i = 0; i < INPUT_MAX_GAMEPADS; i++)
{
Mem_Copy(&Gamepad_Devices[i].base, &padDevice, sizeof(struct InputDevice));
Gamepad_Devices[i].base.index = i;
}
InputBind_Load(&NormDevice);
InputBind_Load(&padDevice);
}
static void OnFree(void) {

View File

@ -118,7 +118,6 @@ struct InputDevice {
#define INPUT_DEVICE_GAMEPAD 0x04
extern struct InputDevice NormDevice;
extern struct InputDevice PadDevice;
extern struct InputDevice TouchDevice;
#define InputDevice_IsEnter(key, dev) ((key) == (dev)->enterButton1 || (key) == (dev)->enterButton2)
@ -207,13 +206,57 @@ void Gamepad_Tick(float delta);
#define GAMEPAD_BEG_BTN CCPAD_1
#define GAMEPAD_BTN_COUNT (INPUT_COUNT - GAMEPAD_BEG_BTN)
struct GamepadState {
struct GamepadDevice {
struct InputDevice base;
long deviceID;
float axisX[2], axisY[2];
cc_bool pressed[GAMEPAD_BTN_COUNT];
float holdtime[GAMEPAD_BTN_COUNT];
};
extern struct GamepadState Gamepad_States[INPUT_MAX_GAMEPADS];
extern struct GamepadDevice Gamepad_Devices[INPUT_MAX_GAMEPADS];
int Gamepad_MapPort(long deviceID);
/* Enumeration of all input bindings. */
enum InputBind_ {
BIND_FORWARD, BIND_BACK, BIND_LEFT, BIND_RIGHT,
BIND_JUMP, BIND_RESPAWN, BIND_SET_SPAWN, BIND_CHAT,
BIND_INVENTORY, BIND_FOG, BIND_SEND_CHAT, BIND_TABLIST,
BIND_SPEED, BIND_NOCLIP, BIND_FLY, BIND_FLY_UP, BIND_FLY_DOWN,
BIND_EXT_INPUT, BIND_HIDE_FPS, BIND_SCREENSHOT, BIND_FULLSCREEN,
BIND_THIRD_PERSON, BIND_HIDE_GUI, BIND_AXIS_LINES, BIND_ZOOM_SCROLL,
BIND_HALF_SPEED, BIND_DELETE_BLOCK, BIND_PICK_BLOCK, BIND_PLACE_BLOCK,
BIND_AUTOROTATE, BIND_HOTBAR_SWITCH, BIND_SMOOTH_CAMERA,
BIND_DROP_BLOCK, BIND_IDOVERLAY, BIND_BREAK_LIQUIDS,
BIND_LOOK_UP, BIND_LOOK_DOWN, BIND_LOOK_RIGHT, BIND_LOOK_LEFT,
BIND_HOTBAR_1, BIND_HOTBAR_2, BIND_HOTBAR_3,
BIND_HOTBAR_4, BIND_HOTBAR_5, BIND_HOTBAR_6,
BIND_HOTBAR_7, BIND_HOTBAR_8, BIND_HOTBAR_9,
BIND_HOTBAR_LEFT, BIND_HOTBAR_RIGHT,
BIND_COUNT
};
typedef int InputBind;
typedef struct BindMapping_ { cc_uint8 button1, button2; } BindMapping;
#define BindMapping_Set(mapping, btn1, btn2) (mapping)->button1 = btn1; (mapping)->button2 = btn2;
/* The keyboard/mouse buttons that are bound to each input binding */
extern BindMapping KeyBind_Mappings[BIND_COUNT];
/* The gamepad buttons that are bound to each input binding */
extern BindMapping PadBind_Mappings[BIND_COUNT];
/* Default keyboard/mouse button that each input binding is bound to */
extern const BindMapping KeyBind_Defaults[BIND_COUNT];
/* Default gamepad button that each input binding is bound to */
extern const BindMapping PadBind_Defaults[BIND_COUNT];
/* Whether the given binding should be triggered in response to given input button being pressed */
cc_bool InputBind_Claims(InputBind binding, int btn, struct InputDevice* device);
/* Sets the button that the given input binding is bound to */
void InputBind_Set(InputBind binding, int btn, const struct InputDevice* device);
/* Resets the button that the given input binding is bound to */
void InputBind_Reset(InputBind binding, const struct InputDevice* device);
/* Loads the bindings for the given device from either options or its defaults */
void InputBind_Load(const struct InputDevice* device);
#endif

View File

@ -36,164 +36,6 @@ static cc_bool suppressEscape;
enum MouseButton_ { MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE };
/*########################################################################################################################*
*---------------------------------------------------------Keybinds--------------------------------------------------------*
*#########################################################################################################################*/
BindMapping PadBind_Mappings[BIND_COUNT];
BindMapping KeyBind_Mappings[BIND_COUNT];
BindTriggered Bind_OnTriggered[BIND_COUNT];
BindReleased Bind_OnReleased[BIND_COUNT];
cc_uint8 Bind_IsTriggered[BIND_COUNT];
const BindMapping PadBind_Defaults[BIND_COUNT] = {
{ CCPAD_UP, 0 }, { CCPAD_DOWN, 0 }, /* BIND_FORWARD, BIND_BACK */
{ CCPAD_LEFT, 0 }, { CCPAD_RIGHT, 0 }, /* BIND_LEFT, BIND_RIGHT */
{ CCPAD_1, 0 }, { 0, 0 }, /* BIND_JUMP, BIND_RESPAWN */
{ CCPAD_START, 0 }, { CCPAD_4, 0 }, /* BIND_SET_SPAWN, BIND_CHAT */
{ CCPAD_3, 0 }, { 0, 0 }, /* BIND_INVENTORY, BIND_FOG */
{ CCPAD_START, 0 }, { 0, 0 }, /* BIND_SEND_CHAT, BIND_TABLIST */
{ CCPAD_2, CCPAD_L},{ CCPAD_2, CCPAD_3},/* BIND_SPEED, BIND_NOCLIP */
{ CCPAD_2, CCPAD_R }, /* BIND_FLY */
{CCPAD_2,CCPAD_UP},{CCPAD_2,CCPAD_DOWN},/* BIND_FLY_UP, BIND_FLY_DOWN */
{ 0, 0 }, { 0, 0 }, /* BIND_EXT_INPUT, BIND_HIDE_FPS */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_SCREENSHOT, BIND_FULLSCREEN, BIND_THIRD_PERSON, BIND_HIDE_GUI */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_AXIS_LINES, BIND_ZOOM_SCROLL, BIND_HALF_SPEED */
{ CCPAD_L, 0 }, { 0, 0 },{ CCPAD_R, 0 },/* BIND_DELETE_BLOCK, BIND_PICK_BLOCK, BIND_PLACE_BLOCK */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_AUTOROTATE, BIND_HOTBAR_SWITCH, BIND_SMOOTH_CAMERA */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_DROP_BLOCK, BIND_IDOVERLAY, BIND_BREAK_LIQUIDS */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_LOOK_UP, BIND_LOOK_DOWN, BIND_LOOK_RIGHT, BIND_LOOK_LEFT */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_HOTBAR_1, BIND_HOTBAR_2, BIND_HOTBAR_3 */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_HOTBAR_4, BIND_HOTBAR_5, BIND_HOTBAR_6 */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_HOTBAR_7, BIND_HOTBAR_8, BIND_HOTBAR_9 */
{ CCPAD_ZL, 0 }, { CCPAD_ZR, 0 } /* BIND_HOTBAR_LEFT, BIND_HOTBAR_RIGHT */
};
const BindMapping KeyBind_Defaults[BIND_COUNT] = {
{ 'W', 0 }, { 'S', 0 }, { 'A', 0 }, { 'D', 0 }, /* BIND_FORWARD - BIND_RIGHT */
{ CCKEY_SPACE, 0 }, { 'R', 0 }, /* BIND_JUMP, BIND_RESPAWN */
{ CCKEY_ENTER, 0 }, { 'T', 0 }, /* BIND_SET_SPAWN, BIND_CHAT */
{ 'B', 0 }, { 'F', 0 }, /* BIND_INVENTORY, BIND_FOG */
{ CCKEY_ENTER, 0 }, { CCKEY_TAB, 0 }, /* BIND_SEND_CHAT, BIND_TABLIST */
{ CCKEY_LSHIFT, 0 }, { 'X', 0}, { 'Z', 0 }, /* BIND_SPEED, BIND_NOCLIP, BIND_FLY */
{ 'Q', 0 }, { 'E', 0 }, /* BIND_FLY_UP, BIND_FLY_DOWN */
{ CCKEY_LALT, 0 }, { CCKEY_F3, 0 }, /* BIND_EXT_INPUT, BIND_HIDE_FPS */
{ CCKEY_F12, 0 }, { CCKEY_F11, 0 }, /* BIND_SCREENSHOT, BIND_FULLSCREEN */
{ CCKEY_F5, 0 }, { CCKEY_F1, 0 }, /* BIND_THIRD_PERSON, BIND_HIDE_GUI */
{ CCKEY_F7, 0 }, { 'C', 0 }, { CCKEY_LCTRL, 0 },/* BIND_AXIS_LINES, BIND_ZOOM_SCROLL, BIND_HALF_SPEED */
{ CCMOUSE_L, 0},{ CCMOUSE_M, 0},{ CCMOUSE_R, 0},/* BIND_DELETE_BLOCK, BIND_PICK_BLOCK, BIND_PLACE_BLOCK */
{ CCKEY_F6, 0 }, { CCKEY_LALT, 0 }, /* BIND_AUTOROTATE, BIND_HOTBAR_SWITCH */
{ CCKEY_F8, 0 }, { 'G', 0 }, /* BIND_SMOOTH_CAMERA, BIND_DROP_BLOCK */
{ CCKEY_F10, 0 }, { 0, 0 }, /* BIND_IDOVERLAY, BIND_BREAK_LIQUIDS */
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* BIND_LOOK_UP, BIND_LOOK_DOWN, BIND_LOOK_RIGHT, BIND_LOOK_LEFT */
{ '1', 0 }, { '2', 0 }, { '3', 0 }, /* BIND_HOTBAR_1, BIND_HOTBAR_2, BIND_HOTBAR_3 */
{ '4', 0 }, { '5', 0 }, { '6', 0 }, /* BIND_HOTBAR_4, BIND_HOTBAR_5, BIND_HOTBAR_6 */
{ '7', 0 }, { '8', 0 }, { '9', 0 }, /* BIND_HOTBAR_7, BIND_HOTBAR_8, BIND_HOTBAR_9 */
{ 0, 0 }, { 0, 0 } /* BIND_HOTBAR_LEFT, BIND_HOTBAR_RIGHT */
};
static const char* const bindNames[BIND_COUNT] = {
"Forward", "Back", "Left", "Right",
"Jump", "Respawn", "SetSpawn", "Chat", "Inventory",
"ToggleFog", "SendChat", "PlayerList",
"Speed", "NoClip", "Fly", "FlyUp", "FlyDown",
"ExtInput", "HideFPS", "Screenshot", "Fullscreen",
"ThirdPerson", "HideGUI", "AxisLines", "ZoomScrolling",
"HalfSpeed", "DeleteBlock", "PickBlock", "PlaceBlock",
"AutoRotate", "HotbarSwitching", "SmoothCamera",
"DropBlock", "IDOverlay", "BreakableLiquids",
"LookUp", "LookDown", "LookRight", "LookLeft",
"Hotbar1", "Hotbar2", "Hotbar3",
"Hotbar4", "Hotbar5", "Horbar6",
"Hotbar7", "Hotbar8", "Hotbar9",
"HotbarLeft", "HotbarRight"
};
#define BindMapping2_Claims(mapping, btn) (device->IsPressed(device, (mapping)->button1) && (mapping)->button2 == btn)
static cc_bool Mappings_DoesClaim(InputBind binding, int btn, BindMapping* mappings, struct InputDevice* device) {
BindMapping* bind = &mappings[binding];
int i;
if (bind->button2) return BindMapping2_Claims(bind, btn);
/* Two button mapping takes priority over one button mapping */
for (i = 0; i < BIND_COUNT; i++)
{
if (mappings[i].button2 && BindMapping2_Claims(&mappings[i], btn)) return false;
}
return bind->button1 == btn;
}
cc_bool InputBind_Claims(InputBind binding, int btn, struct InputDevice* device) {
return Mappings_DoesClaim(binding, btn, KeyBind_Mappings, device) ||
Mappings_DoesClaim(binding, btn, PadBind_Mappings, device);
}
cc_bool KeyBind_IsPressed(InputBind binding) { return Bind_IsTriggered[binding]; }
static void KeyBind_Load(struct InputDevice* device) {
cc_string name; char nameBuffer[STRING_SIZE + 1];
const BindMapping* defaults = device->defaultBinds;
BindMapping* keybinds = device->currentBinds;
BindMapping mapping;
cc_string str, part1, part2;
int i;
String_InitArray_NT(name, nameBuffer);
for (i = 0; i < BIND_COUNT; i++)
{
name.length = 0;
String_Format1(&name, device->bindPrefix, bindNames[i]);
name.buffer[name.length] = '\0';
if (!Options_UNSAFE_Get(name.buffer, &str)) {
keybinds[i] = defaults[i];
continue;
}
String_UNSAFE_Separate(&str, ',', &part1, &part2);
mapping.button1 = Utils_ParseEnum(&part1, defaults[i].button1, Input_StorageNames, INPUT_COUNT);
mapping.button2 = Utils_ParseEnum(&part2, defaults[i].button2, Input_StorageNames, INPUT_COUNT);
if (mapping.button1 == CCKEY_ESCAPE) keybinds[i] = defaults[i];
keybinds[i] = mapping;
}
}
void InputBind_Set(InputBind binding, int btn, struct InputDevice* device) {
cc_string name; char nameBuffer[STRING_SIZE];
cc_string value;
String_InitArray(name, nameBuffer);
String_Format1(&name, device->bindPrefix, bindNames[binding]);
value = String_FromReadonly(Input_StorageNames[btn]);
Options_SetString(&name, &value);
BindMapping_Set(&device->currentBinds[binding], btn, 0);
}
void InputBind_Reset(InputBind binding, struct InputDevice* device) {
cc_string name; char nameBuffer[STRING_SIZE];
String_InitArray(name, nameBuffer);
String_Format1(&name, device->bindPrefix, bindNames[binding]);
Options_SetString(&name, &String_Empty);
device->currentBinds[binding] = device->defaultBinds[binding];
}
/* Initialises and loads input bindings from options */
static void KeyBind_Init(void) {
NormDevice.defaultBinds = KeyBind_Defaults;
PadDevice.defaultBinds = PadBind_Defaults;
NormDevice.currentBinds = KeyBind_Mappings;
PadDevice.currentBinds = PadBind_Mappings;
KeyBind_Load(&NormDevice);
KeyBind_Load(&PadDevice);
}
/*########################################################################################################################*
*---------------------------------------------------------Gamepad---------------------------------------------------------*
*#########################################################################################################################*/
@ -201,8 +43,8 @@ static void PlayerInputPad(int port, int axis, struct LocalPlayer* p, float* xMo
float x, y, angle;
if (Gamepad_AxisBehaviour[axis] != AXIS_BEHAVIOUR_MOVEMENT) return;
x = Gamepad_States[port].axisX[axis];
y = Gamepad_States[port].axisY[axis];
x = Gamepad_Devices[port].axisX[axis];
y = Gamepad_Devices[port].axisY[axis];
if (x != 0 || y != 0) {
angle = Math_Atan2f(x, y);
@ -895,6 +737,16 @@ static void HookInputBinds(void) {
}
/*########################################################################################################################*
*---------------------------------------------------------Keybinds--------------------------------------------------------*
*#########################################################################################################################*/
BindTriggered Bind_OnTriggered[BIND_COUNT];
BindReleased Bind_OnReleased[BIND_COUNT];
cc_uint8 Bind_IsTriggered[BIND_COUNT];
cc_bool KeyBind_IsPressed(InputBind binding) { return Bind_IsTriggered[binding]; }
/*########################################################################################################################*
*-----------------------------------------------------Base handlers-------------------------------------------------------*
*#########################################################################################################################*/
@ -1101,7 +953,6 @@ static void OnInit(void) {
Event_Register_(&InputEvents.Up, NULL, OnInputUp);
Event_Register_(&UserEvents.HackPermsChanged, NULL, InputHandler_CheckZoomFov);
KeyBind_Init();
StoredHotkeys_LoadAll();
Bind_OnTriggered[BIND_FORWARD] = Player_TriggerUp;

View File

@ -1,6 +1,6 @@
#ifndef CC_INPUTHANDLER_H
#define CC_INPUTHANDLER_H
#include "Core.h"
#include "Input.h"
/*
Manages base game input handling
Copyright 2014-2023 ClassiCube | Licensed under BSD-3
@ -11,56 +11,6 @@ struct InputDevice;
extern struct IGameComponent InputHandler_Component;
/* Enumeration of all input bindings. */
enum InputBind_ {
BIND_FORWARD, BIND_BACK, BIND_LEFT, BIND_RIGHT,
BIND_JUMP, BIND_RESPAWN, BIND_SET_SPAWN, BIND_CHAT,
BIND_INVENTORY, BIND_FOG, BIND_SEND_CHAT, BIND_TABLIST,
BIND_SPEED, BIND_NOCLIP, BIND_FLY, BIND_FLY_UP, BIND_FLY_DOWN,
BIND_EXT_INPUT, BIND_HIDE_FPS, BIND_SCREENSHOT, BIND_FULLSCREEN,
BIND_THIRD_PERSON, BIND_HIDE_GUI, BIND_AXIS_LINES, BIND_ZOOM_SCROLL,
BIND_HALF_SPEED, BIND_DELETE_BLOCK, BIND_PICK_BLOCK, BIND_PLACE_BLOCK,
BIND_AUTOROTATE, BIND_HOTBAR_SWITCH, BIND_SMOOTH_CAMERA,
BIND_DROP_BLOCK, BIND_IDOVERLAY, BIND_BREAK_LIQUIDS,
BIND_LOOK_UP, BIND_LOOK_DOWN, BIND_LOOK_RIGHT, BIND_LOOK_LEFT,
BIND_HOTBAR_1, BIND_HOTBAR_2, BIND_HOTBAR_3,
BIND_HOTBAR_4, BIND_HOTBAR_5, BIND_HOTBAR_6,
BIND_HOTBAR_7, BIND_HOTBAR_8, BIND_HOTBAR_9,
BIND_HOTBAR_LEFT, BIND_HOTBAR_RIGHT,
BIND_COUNT
};
typedef int InputBind;
typedef struct BindMapping_ { cc_uint8 button1, button2; } BindMapping;
typedef cc_bool (*BindTriggered)(int key, struct InputDevice* device);
typedef void (*BindReleased)(int key, struct InputDevice* device);
#define BindMapping_Set(mapping, btn1, btn2) (mapping)->button1 = btn1; (mapping)->button2 = btn2;
/* The keyboard/mouse buttons that are bound to each input binding */
extern BindMapping KeyBind_Mappings[BIND_COUNT];
/* The gamepad buttons that are bound to each input binding */
extern BindMapping PadBind_Mappings[BIND_COUNT];
/* Default keyboard/mouse button that each input binding is bound to */
extern const BindMapping KeyBind_Defaults[BIND_COUNT];
/* Default gamepad button that each input binding is bound to */
extern const BindMapping PadBind_Defaults[BIND_COUNT];
/* Callback behaviour for when the given input binding is triggered */
extern BindTriggered Bind_OnTriggered[BIND_COUNT];
/* Callback behaviour for when the given input binding is released */
extern BindReleased Bind_OnReleased[BIND_COUNT];
/* Whether the given input binding is activated by one or more devices */
extern cc_uint8 Bind_IsTriggered[BIND_COUNT];
/* Whether the given binding should be triggered in response to given input button being pressed */
cc_bool InputBind_Claims(InputBind binding, int btn, struct InputDevice* device);
/* Gets whether the given input binding is currently being triggered */
CC_API cc_bool KeyBind_IsPressed(InputBind binding);
/* Sets the button that the given input binding is bound to */
void InputBind_Set(InputBind binding, int btn, struct InputDevice* device);
/* Resets the button that the given input binding is bound to */
void InputBind_Reset(InputBind binding, struct InputDevice* device);
/* whether to leave text input open for user to enter further input */
#define HOTKEY_FLAG_STAYS_OPEN 0x01
/* Whether the hotkey was auto defined (e.g. by server) */
@ -100,4 +50,17 @@ cc_bool InputHandler_SetFOV(int fov);
cc_bool Input_HandleMouseWheel(float delta);
void InputHandler_Tick(void);
void InputHandler_OnScreensChanged(void);
typedef cc_bool (*BindTriggered)(int key, struct InputDevice* device);
typedef void (*BindReleased)(int key, struct InputDevice* device);
/* Gets whether the given input binding is currently being triggered */
CC_API cc_bool KeyBind_IsPressed(InputBind binding);
/* Callback behaviour for when the given input binding is triggered */
extern BindTriggered Bind_OnTriggered[BIND_COUNT];
/* Callback behaviour for when the given input binding is released */
extern BindReleased Bind_OnReleased[BIND_COUNT];
/* Whether the given input binding is activated by one or more devices */
extern cc_uint8 Bind_IsTriggered[BIND_COUNT];
#endif

View File

@ -1863,7 +1863,7 @@ static void BindsSourceScreen_ModeNormal(void* screen, void* b) {
}
static void BindsSourceScreen_ModeGamepad(void* screen, void* b) {
bind_device = &PadDevice;
bind_device = &Gamepad_Devices[0].base;
NormalBindingsScreen_Show();
}
@ -1921,7 +1921,7 @@ static void SwitchBindsMain(void* s, void* w) {
/* User needs to decide whether to configure mouse/keyboard or gamepad */
BindsSourceScreen_Show();
} else if (Input.Sources == INPUT_SOURCE_GAMEPAD) {
bind_device = &PadDevice;
bind_device = &Gamepad_Devices[0].base;
NormalBindingsScreen_Show();
} else {
bind_device = &NormDevice;
@ -2131,7 +2131,7 @@ static void KeyBindsScreen_Show(int bindsCount, const cc_uint8* binds, const cha
void ClassicBindingsScreen_Show(void) {
static const cc_uint8 binds[] = { BIND_FORWARD, BIND_BACK, BIND_JUMP, BIND_CHAT, BIND_SET_SPAWN, BIND_LEFT, BIND_RIGHT, BIND_INVENTORY, BIND_FOG, BIND_RESPAWN };
static const char* const descs[] = { "Forward", "Back", "Jump", "Chat", "Save location", "Left", "Right", "Build", "Toggle fog", "Load location" };
bind_device = Input.Sources == INPUT_SOURCE_GAMEPAD ? &PadDevice : &NormDevice;
bind_device = Input.Sources == INPUT_SOURCE_GAMEPAD ? &Gamepad_Devices[0].base : &NormDevice;
if (Game_ClassicHacks) {
KeyBindsScreen_Reset(NULL, Menu_SwitchBindsClassicHacks, 260);
@ -2150,7 +2150,7 @@ void ClassicBindingsScreen_Show(void) {
void ClassicHacksBindingsScreen_Show(void) {
static const cc_uint8 binds[6] = { BIND_SPEED, BIND_NOCLIP, BIND_HALF_SPEED, BIND_FLY, BIND_FLY_UP, BIND_FLY_DOWN };
static const char* const descs[6] = { "Speed", "Noclip", "Half speed", "Fly", "Fly up", "Fly down" };
bind_device = Input.Sources == INPUT_SOURCE_GAMEPAD ? &PadDevice : &NormDevice;
bind_device = Input.Sources == INPUT_SOURCE_GAMEPAD ? &Gamepad_Devices[0].base : &NormDevice;
KeyBindsScreen_Reset(Menu_SwitchBindsClassic, NULL, 260);
KeyBindsScreen_SetLayout(-90, -40, 3);