mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 03:25:14 -04:00
Merge GamePad_States and PadDevice
This commit is contained in:
parent
cf61ef23d3
commit
9ea54dee7c
184
src/Input.c
184
src/Input.c
@ -272,9 +272,11 @@ static cc_bool NormDevice_IsPressed(struct InputDevice* device, int key) {
|
||||
return Input.Pressed[key];
|
||||
}
|
||||
|
||||
static cc_bool PadDevice_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) {
|
||||
|
49
src/Input.h
49
src/Input.h
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user