Skip to content

Commit

Permalink
Split input code from be_st_sdl.c, and occasionally move another
Browse files Browse the repository at this point in the history
declaration or definition between files.
Note that be_st_sdl_launcher.c got a couple of variables
related to tracked fingers renamed as a consequence.
  • Loading branch information
NY00123 committed Jul 18, 2021
1 parent 7aa04cf commit c7e8f01
Show file tree
Hide file tree
Showing 15 changed files with 984 additions and 792 deletions.
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ list(APPEND be_src
src/backend/filesystem/be_filesystem_root_paths.c
src/backend/gamedefs/be_gamedefs_accessors.c
src/backend/gamedefs/be_gamedefs_prep.c
src/backend/input/be_input.c
src/backend/input/be_input_controller_mappings.c
src/backend/input/be_input_sdl.c
src/backend/input/be_input_ui.c
src/backend/misc/be_misc_steamcfg.c
src/backend/startup/be_startup.c
src/backend/startup/be_startup_embedded_data.c
Expand Down
224 changes: 224 additions & 0 deletions src/backend/input/be_input.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
/* Copyright (C) 2014-2021 NY00123
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "be_features.h"
#include "be_input.h"
#include "be_st.h"

uint32_t g_sdlLastPollEventsTime;

bool g_sdlControllersButtonsStates[BE_ST_CTRL_BUT_MAX];
bool g_sdlControllersAxesStates[BE_ST_CTRL_AXIS_MAX][2];

bool g_sdlMouseButtonsStates[3];

bool g_sdlDefaultMappingBinaryState;

int g_sdlEmuMouseButtonsState;
int16_t g_sdlEmuMouseMotionAccumulatedState[2];
int16_t g_sdlEmuMouseCursorPos[2];
int16_t g_sdlEmuMouseMotionFromJoystick[2];
int16_t g_sdlVirtualMouseCursorState[2];
int g_sdlEmuJoyButtonsState;
int16_t g_sdlEmuJoyMotionState[4];

int g_sdlEmuKeyboardLastPressedScanCode;
bool g_sdlEmuKeyboardLastPressedIsSpecial;
uint32_t g_sdlEmuKeyboardLastScanCodePressTime;
uint32_t g_sdlEmuKeyboardLastScanCodePressTimeDelay;

int g_sdlOnScreenKeyboardLastPressedDirButton;
uint32_t g_sdlOnScreenKeyboardLastDirButtonPressTime;
uint32_t g_sdlOnScreenKeyboardLastDirButtonPressTimeDelay;

bool g_sdlEmuKeyboardStateByScanCode[BE_ST_SC_MAX];

static void (*g_sdlKeyboardInterruptFuncPtr)(uint8_t) = 0;

static uint8_t g_sdlLastKeyScanCodeBeforeAnyReset; // May be reset by BE_ST_BiosScanCode

void BE_ST_StartKeyboardService(void (*funcPtr)(uint8_t))
{
g_sdlKeyboardInterruptFuncPtr = funcPtr;
}

void BE_ST_StopKeyboardService(void)
{
g_sdlKeyboardInterruptFuncPtr = 0;
}

void BE_ST_ResetEmuMouse(void)
{
g_sdlEmuMouseCursorPos[0] = BE_ST_EMU_MOUSE_XRANGE/2;
g_sdlEmuMouseCursorPos[1] = BE_ST_EMU_MOUSE_YRANGE/2;
}

void BE_ST_SetEmuMousePos(int16_t x, int16_t y)
{
g_sdlEmuMouseCursorPos[0] = x;
g_sdlEmuMouseCursorPos[1] = y;

if (g_sdlEmuMouseCursorPos[0] < 0)
g_sdlEmuMouseCursorPos[0] = 0;
else if (g_sdlEmuMouseCursorPos[0] >= BE_ST_EMU_MOUSE_XRANGE)
g_sdlEmuMouseCursorPos[0] = BE_ST_EMU_MOUSE_XRANGE - 1;

if (g_sdlEmuMouseCursorPos[1] < 0)
g_sdlEmuMouseCursorPos[1] = 0;
else if (g_sdlEmuMouseCursorPos[1] >= BE_ST_EMU_MOUSE_YRANGE)
g_sdlEmuMouseCursorPos[1] = BE_ST_EMU_MOUSE_YRANGE - 1;
}

void BE_ST_GetEmuMousePos(int16_t *x, int16_t *y)
{
*x = g_sdlEmuMouseCursorPos[0];
*y = g_sdlEmuMouseCursorPos[1];
}

void BE_ST_GetEmuAccuMouseMotion(int16_t *optX, int16_t *optY)
{
BE_ST_PollEvents();

int16_t dx = g_sdlEmuMouseMotionAccumulatedState[0] + g_sdlEmuMouseMotionFromJoystick[0];
int16_t dy = g_sdlEmuMouseMotionAccumulatedState[1] + g_sdlEmuMouseMotionFromJoystick[1];

BE_ST_SetEmuMousePos(g_sdlEmuMouseCursorPos[0] + dx, g_sdlEmuMouseCursorPos[1] + dy);

if (optX)
*optX = dx;
if (optY)
*optY = dy;

g_sdlEmuMouseMotionAccumulatedState[0] = g_sdlEmuMouseMotionAccumulatedState[1] = 0;
}

uint16_t BE_ST_GetEmuMouseButtons(void)
{
BE_ST_PollEvents();

return g_sdlEmuMouseButtonsState;
}

void BE_ST_GetEmuJoyAxes(uint16_t joy, uint16_t *optX, uint16_t *optY)
{
BE_ST_PollEvents();

if (optX)
*optX = g_sdlEmuJoyMotionState[2*joy];
if (optY)
*optY = g_sdlEmuJoyMotionState[2*joy+1];
}

uint16_t BE_ST_GetEmuJoyButtons(uint16_t joy)
{
BE_ST_PollEvents();

return ((g_sdlEmuJoyButtonsState >> (2*joy)) & 3);
}

int16_t BE_ST_KbHit(void)
{
return g_sdlLastKeyScanCodeBeforeAnyReset;
}

int16_t BE_ST_BiosScanCode(int16_t command)
{
if (command == 1)
{
return g_sdlLastKeyScanCodeBeforeAnyReset;
}

while (!g_sdlLastKeyScanCodeBeforeAnyReset)
{
BE_ST_ShortSleep();
}
int16_t result = g_sdlLastKeyScanCodeBeforeAnyReset;
g_sdlLastKeyScanCodeBeforeAnyReset = 0;
return result;
}

void BEL_ST_HandleEmuKeyboardEvent(bool isPressed, bool isRepeated, emulatedDOSKeyEvent keyEvent)
{
if (keyEvent.dosScanCode == BE_ST_SC_PAUSE)
{
if (isPressed && g_sdlKeyboardInterruptFuncPtr)
{
// SPECIAL: 6 scancodes sent on key press ONLY
g_sdlKeyboardInterruptFuncPtr(0xe1);
g_sdlKeyboardInterruptFuncPtr(0x1d);
g_sdlKeyboardInterruptFuncPtr(0x45);
g_sdlKeyboardInterruptFuncPtr(0xe1);
g_sdlKeyboardInterruptFuncPtr(0x9d);
g_sdlKeyboardInterruptFuncPtr(0xc5);

g_sdlEmuKeyboardLastPressedScanCode = 0; // Reset this
}
}
else
{
if ((isPressed == g_sdlEmuKeyboardStateByScanCode[keyEvent.dosScanCode]) && !isRepeated)
return;

if (g_sdlKeyboardInterruptFuncPtr)
{
if (keyEvent.isSpecial)
{
g_sdlKeyboardInterruptFuncPtr(0xe0);
}
g_sdlKeyboardInterruptFuncPtr(keyEvent.dosScanCode | (isPressed ? 0 : 0x80));
}
else if (isPressed)
{
g_sdlLastKeyScanCodeBeforeAnyReset = keyEvent.dosScanCode;
}

// Key repeat emulation
g_sdlEmuKeyboardStateByScanCode[keyEvent.dosScanCode] = isPressed;
if (isPressed)
{
if (!isRepeated)
{
g_sdlEmuKeyboardLastPressedScanCode = keyEvent.dosScanCode;
g_sdlEmuKeyboardLastPressedIsSpecial = keyEvent.isSpecial;
g_sdlEmuKeyboardLastScanCodePressTime = g_sdlLastPollEventsTime;
g_sdlEmuKeyboardLastScanCodePressTimeDelay = BE_ST_SDL_CONTROLLER_DELAY_BEFORE_DIGIACTION_REPEAT_MS;
}
}
else
{
g_sdlEmuKeyboardLastPressedScanCode = 0; // Reset this
}
}
}

#ifdef BE_CROSS_ENABLE_FARPTR_CFG
uint16_t BE_ST_Compat_GetFarPtrRelocationSegOffset(void)
{
return g_refKeenCfg.farPtrSegOffset;
}
#endif
73 changes: 73 additions & 0 deletions src/backend/input/be_input.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#ifndef BE_INPUT_H
#define BE_INPUT_H

#include "be_st.h"

#define BE_ST_EMU_MOUSE_XRANGE 640
#define BE_ST_EMU_MOUSE_YRANGE 200

// Using example of values from here:
// http://www.intel-assembler.it/portale/5/program-joystick-port-210h/program-joystick-port-210h.asp
#define BE_ST_EMU_JOYSTICK_RANGEMIN 8
#define BE_ST_EMU_JOYSTICK_RANGECENTER 330
#define BE_ST_EMU_JOYSTICK_RANGEMAX 980
// This one is for init with no joysticks, for Keen Dreams v1.00
// (It requires a large value, while 0 will lead to division by zero)
#define BE_ST_EMU_JOYSTICK_OVERRANGEMAX 16384

#define BE_ST_SDL_CONTROLLER_DELAY_BEFORE_DIGIACTION_REPEAT_MS 500
#define BE_ST_SDL_CONTROLLER_DIGIACTION_REPEAT_RATE_MS 40

typedef enum {
BE_ST_MOUSEMODE_ABS_WITH_CURSOR, BE_ST_MOUSEMODE_ABS_WITHOUT_CURSOR, BE_ST_MOUSEMODE_REL
} BESDLMouseModeEnum;

typedef struct {
bool isSpecial; // Scancode of 0xE0 sent?
uint8_t dosScanCode;
} emulatedDOSKeyEvent;

/*** Last BE_ST_PollEvents time ***/
extern uint32_t g_sdlLastPollEventsTime;

/*** Exact values might be implementation-defined ***/
extern const int g_sdlJoystickAxisBinaryThreshold, g_sdlJoystickAxisDeadZone, g_sdlJoystickAxisMax, g_sdlJoystickAxisMaxMinusDeadZone;

/*** These represent button states, although a call to BEL_ST_AltControlScheme_CleanUp zeros these out ***/
extern bool g_sdlControllersButtonsStates[BE_ST_CTRL_BUT_MAX];
// We may optionally use analog axes as buttons (e.g., using stick as arrow keys, triggers as buttons)
extern bool g_sdlControllersAxesStates[BE_ST_CTRL_AXIS_MAX][2];

/*** These are similar states for a few mouse buttons, required as relative mouse mode is toggled on or off in the middle ***/
extern bool g_sdlMouseButtonsStates[3];

/*** Another internal state, used for default mapping action ***/
extern bool g_sdlDefaultMappingBinaryState;

/*** Emulated mouse and joysticks states (mouse motion state is split for technical reasons) ***/
extern int g_sdlEmuMouseButtonsState;
extern int16_t g_sdlEmuMouseMotionAccumulatedState[2];
extern int16_t g_sdlEmuMouseCursorPos[2];
extern int16_t g_sdlEmuMouseMotionFromJoystick[2];
extern int16_t g_sdlVirtualMouseCursorState[2]; // Used e.g., for touch input handling
extern int g_sdlEmuJoyButtonsState;
extern int16_t g_sdlEmuJoyMotionState[4];

/*** Key repeat emulation ***/
extern int g_sdlEmuKeyboardLastPressedScanCode; // 0 on release
extern bool g_sdlEmuKeyboardLastPressedIsSpecial;
extern uint32_t g_sdlEmuKeyboardLastScanCodePressTime;
extern uint32_t g_sdlEmuKeyboardLastScanCodePressTimeDelay;

/*** Similar repeat emulation for arrow movement in on-screen keyboard (key press repeats are emulated separately) ***/
/*** HACK: With debug keys, once a key is selected, key repeat is in effect! (but that's the case with actual keys.) ***/
extern int g_sdlOnScreenKeyboardLastPressedDirButton;
extern uint32_t g_sdlOnScreenKeyboardLastDirButtonPressTime;
extern uint32_t g_sdlOnScreenKeyboardLastDirButtonPressTimeDelay;

extern bool g_sdlEmuKeyboardStateByScanCode[BE_ST_SC_MAX];

void BEL_ST_HandleEmuKeyboardEvent(bool isPressed, bool isRepeated, emulatedDOSKeyEvent keyEvent);
void BEL_ST_SetMouseMode(BESDLMouseModeEnum mode);

#endif
Loading

0 comments on commit c7e8f01

Please sign in to comment.