📄 control.c
字号:
/* * control.c * MACT library controller handling * * Derived from MACT386.LIB disassembly by Jonathon Fowler * */#include "compat.h"#include "types.h"#include "keyboard.h"#include "mouse.h"#include "control.h"#include "_control.h"#include "util_lib.h"#include "baselayer.h"#include "osd.h"#include "pragmas.h"boolean CONTROL_JoyPresent = false;boolean CONTROL_JoystickEnabled = false;boolean CONTROL_MousePresent = false;boolean CONTROL_MouseEnabled = false;uint64 CONTROL_ButtonState = 0;uint64 CONTROL_ButtonHeldState = 0;// static int32 CONTROL_UserInputDelay = -1;static int32 CONTROL_MouseSensitivity = DEFAULTMOUSESENSITIVITY;static int32 CONTROL_NumMouseButtons = 0;static int32 CONTROL_NumMouseAxes = 0;static int32 CONTROL_NumJoyButtons = 0;static int32 CONTROL_NumJoyAxes = 0;static controlflags CONTROL_Flags[CONTROL_NUM_FLAGS];static controlbuttontype CONTROL_MouseButtonMapping[MAXMOUSEBUTTONS],CONTROL_JoyButtonMapping[MAXJOYBUTTONS];static controlkeymaptype CONTROL_KeyMapping[CONTROL_NUM_FLAGS];static controlaxismaptype CONTROL_MouseAxesMap[MAXMOUSEAXES], // maps physical axes onto virtual onesCONTROL_JoyAxesMap[MAXJOYAXES];static controlaxistype CONTROL_MouseAxes[MAXMOUSEAXES], // physical axesCONTROL_JoyAxes[MAXJOYAXES];static controlaxistype CONTROL_LastMouseAxes[MAXMOUSEAXES],CONTROL_LastJoyAxes[MAXJOYAXES];static int32 CONTROL_MouseAxesScale[MAXMOUSEAXES], CONTROL_JoyAxesScale[MAXJOYAXES];static int32 CONTROL_MouseButtonState[MAXMOUSEBUTTONS], CONTROL_JoyButtonState[MAXJOYBUTTONS];static int32 CONTROL_MouseButtonClickedTime[MAXMOUSEBUTTONS], CONTROL_JoyButtonClickedTime[MAXJOYBUTTONS];static boolean CONTROL_MouseButtonClickedState[MAXMOUSEBUTTONS], CONTROL_JoyButtonClickedState[MAXJOYBUTTONS];static boolean CONTROL_MouseButtonClicked[MAXMOUSEBUTTONS], CONTROL_JoyButtonClicked[MAXJOYBUTTONS];static byte CONTROL_MouseButtonClickedCount[MAXMOUSEBUTTONS], CONTROL_JoyButtonClickedCount[MAXJOYBUTTONS];static boolean CONTROL_UserInputCleared[3];static int32(*GetTime)(void);static boolean CONTROL_Started = false;static int32 ticrate;static int32 CONTROL_DoubleClickSpeed;int32_t extinput[CONTROL_NUM_FLAGS];keybind KeyBindings[MAXBOUNDKEYS], MouseBindings[MAXMOUSEBUTTONS];int32_t bindsenabled = 0;int32_t control_smoothmouse = 0;void CONTROL_GetMouseDelta(void){ int32 x,y; MOUSE_GetDelta(&x, &y); if (control_smoothmouse) { static int32 lastx = 0, lasty = 0; CONTROL_MouseAxes[0].analog = (((x + lastx) / 2) * (CONTROL_MouseSensitivity<<1)); CONTROL_MouseAxes[1].analog = (((y + lasty) / 2) * (CONTROL_MouseSensitivity<<1))<<1; lastx = x; lasty = y; return; } CONTROL_MouseAxes[0].analog = (x * (CONTROL_MouseSensitivity<<1)); CONTROL_MouseAxes[1].analog = (y * (CONTROL_MouseSensitivity<<1))<<1;}int32 CONTROL_GetMouseSensitivity(void){ return (CONTROL_MouseSensitivity);}void CONTROL_SetMouseSensitivity(int32 newsensitivity){ CONTROL_MouseSensitivity = newsensitivity;}boolean CONTROL_StartMouse(void){ CONTROL_NumMouseButtons = MAXMOUSEBUTTONS; return MOUSE_Init();}void CONTROL_GetJoyAbs(void){}void CONTROL_FilterJoyDelta(void){}void CONTROL_GetJoyDelta(void){ int32 i; for (i=0; i<joynumaxes; i++) CONTROL_JoyAxes[i].analog = joyaxis[i] >> 5;}boolean CONTROL_StartJoy(int32 joy){ UNREFERENCED_PARAMETER(joy); return (inputdevices & 4) == 4;}void CONTROL_ShutJoy(int32 joy){ UNREFERENCED_PARAMETER(joy); CONTROL_JoyPresent = false;}int32 CONTROL_GetTime(void){ static int32 t = 0; t += 5; return t;}static inline boolean CONTROL_CheckRange(int32 which){ if ((uint32)which >= (uint32)CONTROL_NUM_FLAGS) return true; //Error("CONTROL_CheckRange: Index %d out of valid range for %d control flags.", // which, CONTROL_NUM_FLAGS); return false;}void CONTROL_SetFlag(int32 which, boolean active){ if (CONTROL_CheckRange(which)) return; if (CONTROL_Flags[which].toggle == INSTANT_ONOFF) { CONTROL_Flags[which].active = active; return; } if (active) { CONTROL_Flags[which].buttonheld = false; } else if (CONTROL_Flags[which].buttonheld == false) { CONTROL_Flags[which].buttonheld = true; CONTROL_Flags[which].active = (CONTROL_Flags[which].active ? false : true); }}boolean CONTROL_KeyboardFunctionPressed(int32 which){ boolean key1 = 0, key2 = 0; if (CONTROL_CheckRange(which)) return false; if (!CONTROL_Flags[which].used) return false; if (CONTROL_KeyMapping[which].key1 != KEYUNDEFINED && !KeyBindings[CONTROL_KeyMapping[which].key1].cmd[0]) key1 = KB_KeyDown[ CONTROL_KeyMapping[which].key1 ] ? true : false; if (CONTROL_KeyMapping[which].key2 != KEYUNDEFINED && !KeyBindings[CONTROL_KeyMapping[which].key2].cmd[0]) key2 = KB_KeyDown[ CONTROL_KeyMapping[which].key2 ] ? true : false; return (key1 | key2);}void CONTROL_ClearKeyboardFunction(int32 which){ if (CONTROL_CheckRange(which)) return; if (!CONTROL_Flags[which].used) return; if (CONTROL_KeyMapping[which].key1 != KEYUNDEFINED) KB_KeyDown[ CONTROL_KeyMapping[which].key1 ] = 0; if (CONTROL_KeyMapping[which].key2 != KEYUNDEFINED) KB_KeyDown[ CONTROL_KeyMapping[which].key2 ] = 0;}void CONTROL_DefineFlag(int32 which, boolean toggle){ if (CONTROL_CheckRange(which)) return; CONTROL_Flags[which].active = false; CONTROL_Flags[which].used = true; CONTROL_Flags[which].toggle = toggle; CONTROL_Flags[which].buttonheld = false; CONTROL_Flags[which].cleared = 0;}boolean CONTROL_FlagActive(int32 which){ if (CONTROL_CheckRange(which)) return false; return CONTROL_Flags[which].used;}void CONTROL_MapKey(int32 which, kb_scancode key1, kb_scancode key2){ if (CONTROL_CheckRange(which)) return; CONTROL_KeyMapping[which].key1 = key1 ? key1 : KEYUNDEFINED; CONTROL_KeyMapping[which].key2 = key2 ? key2 : KEYUNDEFINED;}void CONTROL_PrintKeyMap(void){ int32 i; for (i=0;i<CONTROL_NUM_FLAGS;i++) { initprintf("function %2ld key1=%3x key2=%3x\n", i, CONTROL_KeyMapping[i].key1, CONTROL_KeyMapping[i].key2); }}void CONTROL_PrintControlFlag(int32 which){ initprintf("function %2ld active=%d used=%d toggle=%d buttonheld=%d cleared=%d\n", which, CONTROL_Flags[which].active, CONTROL_Flags[which].used, CONTROL_Flags[which].toggle, CONTROL_Flags[which].buttonheld, CONTROL_Flags[which].cleared);}void CONTROL_PrintAxes(void){ int32 i; initprintf("nummouseaxes=%d\n", CONTROL_NumMouseAxes); for (i=0;i<CONTROL_NumMouseAxes;i++) { initprintf("axis=%d analog=%d digital1=%d digital2=%d\n", i, CONTROL_MouseAxesMap[i].analogmap, CONTROL_MouseAxesMap[i].minmap, CONTROL_MouseAxesMap[i].maxmap); } initprintf("numjoyaxes=%d\n", CONTROL_NumJoyAxes); for (i=0;i<CONTROL_NumJoyAxes;i++) { initprintf("axis=%d analog=%d digital1=%d digital2=%d\n", i, CONTROL_JoyAxesMap[i].analogmap, CONTROL_JoyAxesMap[i].minmap, CONTROL_JoyAxesMap[i].maxmap); }}void CONTROL_MapButton(int32 whichfunction, int32 whichbutton, boolean doubleclicked, controldevice device){ controlbuttontype *set; if (CONTROL_CheckRange(whichfunction)) whichfunction = BUTTONUNDEFINED; switch (device) { case controldevice_mouse: if ((uint32)whichbutton >= (uint32)MAXMOUSEBUTTONS) { //Error("CONTROL_MapButton: button %d out of valid range for %d mouse buttons.", // whichbutton, CONTROL_NumMouseButtons); return; } set = CONTROL_MouseButtonMapping; break; case controldevice_joystick: if ((uint32)whichbutton >= (uint32)MAXJOYBUTTONS) { //Error("CONTROL_MapButton: button %d out of valid range for %d joystick buttons.", // whichbutton, CONTROL_NumJoyButtons); return; } set = CONTROL_JoyButtonMapping; break; default: //Error("CONTROL_MapButton: invalid controller device type"); return; } if (doubleclicked) set[whichbutton].doubleclicked = whichfunction; else set[whichbutton].singleclicked = whichfunction;}void CONTROL_MapAnalogAxis(int32 whichaxis, int32 whichanalog, controldevice device){ controlaxismaptype *set; if ((uint32)whichanalog >= (uint32)analog_maxtype) { //Error("CONTROL_MapAnalogAxis: analog function %d out of valid range for %d analog functions.", // whichanalog, analog_maxtype); return; } switch (device) { case controldevice_mouse: if ((uint32)whichaxis >= (uint32)MAXMOUSEAXES) { //Error("CONTROL_MapAnalogAxis: axis %d out of valid range for %d mouse axes.", // whichaxis, MAXMOUSEAXES); return; } set = CONTROL_MouseAxesMap; break; case controldevice_joystick: if ((uint32)whichaxis >= (uint32)MAXJOYAXES) { //Error("CONTROL_MapAnalogAxis: axis %d out of valid range for %d joystick axes.", // whichaxis, MAXJOYAXES); return; } set = CONTROL_JoyAxesMap; break; default: //Error("CONTROL_MapAnalogAxis: invalid controller device type"); return; } set[whichaxis].analogmap = whichanalog;}void CONTROL_SetAnalogAxisScale(int32 whichaxis, int32 axisscale, controldevice device){ int32 *set; switch (device) { case controldevice_mouse: if ((uint32)whichaxis >= (uint32)MAXMOUSEAXES) { //Error("CONTROL_SetAnalogAxisScale: axis %d out of valid range for %d mouse axes.", // whichaxis, MAXMOUSEAXES); return; } set = CONTROL_MouseAxesScale; break; case controldevice_joystick: if ((uint32)whichaxis >= (uint32)MAXJOYAXES) { //Error("CONTROL_SetAnalogAxisScale: axis %d out of valid range for %d joystick axes.", // whichaxis, MAXJOYAXES); return; } set = CONTROL_JoyAxesScale; break; default: //Error("CONTROL_SetAnalogAxisScale: invalid controller device type"); return; } set[whichaxis] = axisscale;}void CONTROL_MapDigitalAxis(int32 whichaxis, int32 whichfunction, int32 direction, controldevice device){ controlaxismaptype *set; if (CONTROL_CheckRange(whichfunction)) whichfunction = AXISUNDEFINED; switch (device) { case controldevice_mouse: if ((uint32)whichaxis >= (uint32)MAXMOUSEAXES) { //Error("CONTROL_MapDigitalAxis: axis %d out of valid range for %d mouse axes.", // whichaxis, MAXMOUSEAXES); return; } set = CONTROL_MouseAxesMap; break; case controldevice_joystick: if ((uint32)whichaxis >= (uint32)MAXJOYAXES) { //Error("CONTROL_MapDigitalAxis: axis %d out of valid range for %d joystick axes.", // whichaxis, MAXJOYAXES); return; } set = CONTROL_JoyAxesMap; break; default: //Error("CONTROL_MapDigitalAxis: invalid controller device type"); return; } switch (direction) // JBF: this is all very much a guess. The ASM puzzles me. { case axis_up: case axis_left: set[whichaxis].minmap = whichfunction; break; case axis_down: case axis_right: set[whichaxis].maxmap = whichfunction; break; default: break; }}void CONTROL_ClearAssignments(void){ int32 i; memset(CONTROL_MouseButtonMapping, BUTTONUNDEFINED, sizeof(CONTROL_MouseButtonMapping)); memset(CONTROL_JoyButtonMapping, BUTTONUNDEFINED, sizeof(CONTROL_JoyButtonMapping)); memset(CONTROL_KeyMapping, KEYUNDEFINED, sizeof(CONTROL_KeyMapping)); memset(CONTROL_MouseAxesMap, AXISUNDEFINED, sizeof(CONTROL_MouseAxesMap)); memset(CONTROL_JoyAxesMap, AXISUNDEFINED, sizeof(CONTROL_JoyAxesMap)); memset(CONTROL_MouseAxes, 0, sizeof(CONTROL_MouseAxes)); memset(CONTROL_JoyAxes, 0, sizeof(CONTROL_JoyAxes)); memset(CONTROL_LastMouseAxes, 0, sizeof(CONTROL_LastMouseAxes)); memset(CONTROL_LastJoyAxes, 0, sizeof(CONTROL_LastJoyAxes)); for (i=0;i<MAXMOUSEAXES;i++) CONTROL_MouseAxesScale[i] = NORMALAXISSCALE; for (i=0;i<MAXJOYAXES;i++) CONTROL_JoyAxesScale[i] = NORMALAXISSCALE;}static void DoGetDeviceButtons( int32 buttons, int32 tm, int32 NumButtons, int32 *DeviceButtonState, int32 *ButtonClickedTime, boolean *ButtonClickedState, boolean *ButtonClicked, byte *ButtonClickedCount){ int32 i=NumButtons-1, bs; for (;i>=0;i--) { bs = (buttons >> i) & 1; DeviceButtonState[i] = bs; ButtonClickedState[i] = false; if (bs) { if (ButtonClicked[i] == false) { ButtonClicked[i] = true; if (ButtonClickedCount[i] == 0 || tm > ButtonClickedTime[i]) { ButtonClickedTime[i] = tm + CONTROL_DoubleClickSpeed; ButtonClickedCount[i] = 1; } else if (tm < ButtonClickedTime[i]) { ButtonClickedState[i] = true; ButtonClickedTime[i] = 0; ButtonClickedCount[i] = 2; } } else if (ButtonClickedCount[i] == 2) { ButtonClickedState[i] = true; } continue; } if (ButtonClickedCount[i] == 2) ButtonClickedCount[i] = 0; ButtonClicked[i] = false; }}void CONTROL_GetDeviceButtons(void){ int32 t; t = GetTime(); if (CONTROL_MouseEnabled) { DoGetDeviceButtons( MOUSE_GetButtons(), t,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -