Path: blob/main/RSDKv4/Input.cpp
817 views
#include "RetroEngine.hpp"12InputData keyPress = InputData();3InputData keyDown = InputData();45int touchDown[8];6int touchX[8];7int touchY[8];8int touchID[8];9float touchXF[8];10float touchYF[8];11int touches = 0;1213int hapticEffectNum = -2;1415#if !RETRO_USE_ORIGINAL_CODE16#include <algorithm>17#include <vector>1819InputButton inputDevice[INPUT_BUTTONCOUNT];20int inputType = 0;2122// mania deadzone vals lol23float LSTICK_DEADZONE = 0.3;24float RSTICK_DEADZONE = 0.3;25float LTRIGGER_DEADZONE = 0.3;26float RTRIGGER_DEADZONE = 0.3;2728int mouseHideTimer = 0;29int lastMouseX = 0;30int lastMouseY = 0;3132struct InputDevice {33#if RETRO_USING_SDL234// we need the controller index reported from SDL2's controller added event35int index;36SDL_GameController *devicePtr;37SDL_Haptic *hapticPtr;38#endif39#if RETRO_USING_SDL140SDL_Joystick *devicePtr;41#endif42int id;43};4445std::vector<InputDevice> controllers;4647#if RETRO_USING_SDL148byte keyState[SDLK_LAST];49#endif5051#define normalize(val, minVal, maxVal) ((float)(val) - (float)(minVal)) / ((float)(maxVal) - (float)(minVal))5253#if RETRO_USING_SDL254bool getControllerButton(byte buttonID)55{56bool pressed = false;5758for (int i = 0; i < controllers.size(); ++i) {59SDL_GameController *controller = controllers[i].devicePtr;6061if (SDL_GameControllerGetButton(controller, (SDL_GameControllerButton)buttonID)) {62pressed |= true;63continue;64}65else {66switch (buttonID) {67default: break;68case SDL_CONTROLLER_BUTTON_DPAD_UP: {69int axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY);70float delta = 0;71if (axis < 0)72delta = -normalize(-axis, 1, 32768);73else74delta = normalize(axis, 0, 32767);75pressed |= delta < -LSTICK_DEADZONE;76continue;77}78case SDL_CONTROLLER_BUTTON_DPAD_DOWN: {79int axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY);80float delta = 0;81if (axis < 0)82delta = -normalize(-axis, 1, 32768);83else84delta = normalize(axis, 0, 32767);85pressed |= delta > LSTICK_DEADZONE;86continue;87}88case SDL_CONTROLLER_BUTTON_DPAD_LEFT: {89int axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX);90float delta = 0;91if (axis < 0)92delta = -normalize(-axis, 1, 32768);93else94delta = normalize(axis, 0, 32767);95pressed |= delta < -LSTICK_DEADZONE;96continue;97}98case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: {99int axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX);100float delta = 0;101if (axis < 0)102delta = -normalize(-axis, 1, 32768);103else104delta = normalize(axis, 0, 32767);105pressed |= delta > LSTICK_DEADZONE;106continue;107}108}109}110111switch (buttonID) {112default: break;113case SDL_CONTROLLER_BUTTON_ZL: {114float delta = normalize(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT), 0, 32767);115pressed |= delta > LTRIGGER_DEADZONE;116continue;117}118case SDL_CONTROLLER_BUTTON_ZR: {119float delta = normalize(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT), 0, 32767);120pressed |= delta > RTRIGGER_DEADZONE;121continue;122}123case SDL_CONTROLLER_BUTTON_LSTICK_UP: {124int axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY);125float delta = 0;126if (axis < 0)127delta = -normalize(-axis, 1, 32768);128else129delta = normalize(axis, 0, 32767);130pressed |= delta < -LSTICK_DEADZONE;131continue;132}133case SDL_CONTROLLER_BUTTON_LSTICK_DOWN: {134int axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY);135float delta = 0;136if (axis < 0)137delta = -normalize(-axis, 1, 32768);138else139delta = normalize(axis, 0, 32767);140pressed |= delta > LSTICK_DEADZONE;141continue;142}143case SDL_CONTROLLER_BUTTON_LSTICK_LEFT: {144int axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX);145float delta = 0;146if (axis < 0)147delta = -normalize(-axis, 1, 32768);148else149delta = normalize(axis, 0, 32767);150pressed |= delta > LSTICK_DEADZONE;151continue;152}153case SDL_CONTROLLER_BUTTON_LSTICK_RIGHT: {154int axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX);155float delta = 0;156if (axis < 0)157delta = -normalize(-axis, 1, 32768);158else159delta = normalize(axis, 0, 32767);160pressed |= delta < -LSTICK_DEADZONE;161continue;162}163case SDL_CONTROLLER_BUTTON_RSTICK_UP: {164int axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY);165float delta = 0;166if (axis < 0)167delta = -normalize(-axis, 1, 32768);168else169delta = normalize(axis, 0, 32767);170pressed |= delta < -RSTICK_DEADZONE;171continue;172}173case SDL_CONTROLLER_BUTTON_RSTICK_DOWN: {174int axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY);175float delta = 0;176if (axis < 0)177delta = -normalize(-axis, 1, 32768);178else179delta = normalize(axis, 0, 32767);180pressed |= delta > RSTICK_DEADZONE;181continue;182}183case SDL_CONTROLLER_BUTTON_RSTICK_LEFT: {184int axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX);185float delta = 0;186if (axis < 0)187delta = -normalize(-axis, 1, 32768);188else189delta = normalize(axis, 0, 32767);190pressed |= delta > RSTICK_DEADZONE;191continue;192}193case SDL_CONTROLLER_BUTTON_RSTICK_RIGHT: {194int axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX);195float delta = 0;196if (axis < 0)197delta = -normalize(-axis, 1, 32768);198else199delta = normalize(axis, 0, 32767);200pressed |= delta < -RSTICK_DEADZONE;201continue;202}203}204}205206return pressed;207}208#endif //! RETRO_USING_SDL2209210void controllerInit(int controllerID)211{212for (int i = 0; i < controllers.size(); ++i) {213if (controllers[i].id == controllerID) {214return; // we already opened this one!215}216}217218#if RETRO_USING_SDL2219SDL_GameController *controller = SDL_GameControllerOpen(controllerID);220if (controller) {221InputDevice device;222device.id = controllerID;223device.index = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller));224device.devicePtr = controller;225device.hapticPtr = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(controller));226if (device.hapticPtr == NULL) {227PrintLog("Could not open controller haptics...\nSDL_GetError() -> %s", SDL_GetError());228}229else {230if (SDL_HapticRumbleInit(device.hapticPtr) < 0) {231printf("Unable to initialize rumble!\nSDL_GetError() -> %s", SDL_GetError());232}233}234235controllers.push_back(device);236inputType = 1;237}238else {239PrintLog("Could not open controller...\nSDL_GetError() -> %s", SDL_GetError());240}241#endif242}243244void controllerClose(int controllerID)245{246#if RETRO_USING_SDL2247SDL_GameController *controller = SDL_GameControllerFromInstanceID(controllerID);248if (controller) {249SDL_GameControllerClose(controller);250#endif251if (controllers.size() == 1) {252controllers.clear();253} else {254for (int i = 0; i < controllers.size(); ++i) {255if (controllers[i].index == controllerID) {256controllers.erase(controllers.begin() + i);257#if RETRO_USING_SDL2258if (controllers[i].hapticPtr) {259SDL_HapticClose(controllers[i].hapticPtr);260}261#endif262break;263}264}265}266#if RETRO_USING_SDL2267}268#endif269270if (controllers.empty())271inputType = 0;272}273274void InitInputDevices()275{276#if RETRO_USING_SDL2277PrintLog("Initializing gamepads...");278279// fix for issue #334 on github, not sure what's going wrong, but it seems to not be initializing the gamepad api maybe?280SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);281282int joyStickCount = SDL_NumJoysticks();283controllers.clear();284int gamepadCount = 0;285286// Count how many controllers there are287for (int i = 0; i < joyStickCount; i++)288if (SDL_IsGameController(i))289gamepadCount++;290291PrintLog("Found %d gamepads!", gamepadCount);292for (int i = 0; i < gamepadCount; i++) {293SDL_GameController *gamepad = SDL_GameControllerOpen(i);294InputDevice device;295device.id = 0;296device.index = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamepad));297device.devicePtr = gamepad;298299if (SDL_GameControllerGetAttached(gamepad))300controllers.push_back(device);301else302PrintLog("InitInputDevices() error -> %s", SDL_GetError());303}304305if (gamepadCount > 0)306SDL_GameControllerEventState(SDL_ENABLE);307#endif308}309310void ReleaseInputDevices()311{312for (int i = 0; i < controllers.size(); i++) {313#if RETRO_USING_SDL2314if (controllers[i].devicePtr)315SDL_GameControllerClose(controllers[i].devicePtr);316if (controllers[i].hapticPtr)317SDL_HapticClose(controllers[i].hapticPtr);318#endif319}320controllers.clear();321}322323void ProcessInput()324{325#if RETRO_USING_SDL2326int length = 0;327const byte *keyState = SDL_GetKeyboardState(&length);328329if (inputType == 0) {330for (int i = 0; i < INPUT_ANY; i++) {331if (keyState[inputDevice[i].keyMappings]) {332inputDevice[i].setHeld();333if (!inputDevice[INPUT_ANY].hold)334inputDevice[INPUT_ANY].setHeld();335}336else if (inputDevice[i].hold)337inputDevice[i].setReleased();338}339}340else if (inputType == 1) {341for (int i = 0; i < INPUT_ANY; i++) {342if (getControllerButton(inputDevice[i].contMappings)) {343inputDevice[i].setHeld();344if (!inputDevice[INPUT_ANY].hold)345inputDevice[INPUT_ANY].setHeld();346}347else if (inputDevice[i].hold)348inputDevice[i].setReleased();349}350}351352bool isPressed = false;353for (int i = 0; i < INPUT_BUTTONCOUNT; i++) {354if (keyState[inputDevice[i].keyMappings]) {355isPressed = true;356break;357}358}359if (isPressed)360inputType = 0;361else if (inputType == 0)362inputDevice[INPUT_ANY].setReleased();363364isPressed = false;365for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) {366if (getControllerButton(i)) {367isPressed = true;368break;369}370}371if (isPressed)372inputType = 1;373else if (inputType == 1)374inputDevice[INPUT_ANY].setReleased();375376if (inputDevice[INPUT_ANY].press || inputDevice[INPUT_ANY].hold || touches > 1) {377Engine.dimTimer = 0;378}379else if (Engine.dimTimer < Engine.dimLimit && !Engine.masterPaused) {380++Engine.dimTimer;381}382383#ifdef RETRO_USING_MOUSE384if (touches <= 0) { // Touch always takes priority over mouse385int mx = 0, my = 0;386SDL_GetMouseState(&mx, &my);387388if (mx == lastMouseX && my == lastMouseY) {389++mouseHideTimer;390if (mouseHideTimer == 120) {391SDL_ShowCursor(false);392}393}394else {395if (mouseHideTimer >= 120)396SDL_ShowCursor(true);397mouseHideTimer = 0;398Engine.dimTimer = 0;399}400401lastMouseX = mx;402lastMouseY = my;403}404#endif //! RETRO_USING_MOUSE405406#elif RETRO_USING_SDL1407if (SDL_NumJoysticks() > 0) {408controller = SDL_JoystickOpen(0);409410// There's a problem opening the joystick411if (controller == NULL) {412// Uh oh413}414else {415inputType = 1;416}417}418else {419if (controller) {420// Close the joystick421SDL_JoystickClose(controller);422}423controller = nullptr;424inputType = 0;425}426427if (inputType == 0) {428for (int i = 0; i < INPUT_BUTTONCOUNT; i++) {429if (keyState[inputDevice[i].keyMappings]) {430inputDevice[i].setHeld();431inputDevice[INPUT_ANY].setHeld();432continue;433}434else if (inputDevice[i].hold)435inputDevice[i].setReleased();436}437}438else if (inputType == 1 && controller) {439for (int i = 0; i < INPUT_BUTTONCOUNT; i++) {440if (SDL_JoystickGetButton(controller, inputDevice[i].contMappings)) {441inputDevice[i].setHeld();442inputDevice[INPUT_ANY].setHeld();443continue;444}445else if (inputDevice[i].hold)446inputDevice[i].setReleased();447}448}449450bool isPressed = false;451for (int i = 0; i < INPUT_BUTTONCOUNT; i++) {452if (keyState[inputDevice[i].keyMappings]) {453isPressed = true;454break;455}456}457if (isPressed)458inputType = 0;459else if (inputType == 0)460inputDevice[INPUT_ANY].setReleased();461462int buttonCnt = 0;463if (controller)464buttonCnt = SDL_JoystickNumButtons(controller);465bool flag = false;466for (int i = 0; i < buttonCnt; ++i) {467flag = true;468inputType = 1;469}470if (!flag && inputType == 1) {471inputDevice[INPUT_ANY].setReleased();472}473#endif //! RETRO_USING_SDL2474}475#endif //! !RETRO_USE_ORIGINAL_CODE476477// Pretty much is this code in the original, just formatted differently478void CheckKeyPress(InputData *input)479{480#if !RETRO_USE_ORIGINAL_CODE481input->up = inputDevice[INPUT_UP].press;482input->down = inputDevice[INPUT_DOWN].press;483input->left = inputDevice[INPUT_LEFT].press;484input->right = inputDevice[INPUT_RIGHT].press;485input->A = inputDevice[INPUT_BUTTONA].press;486input->B = inputDevice[INPUT_BUTTONB].press;487input->C = inputDevice[INPUT_BUTTONC].press;488input->X = inputDevice[INPUT_BUTTONX].press;489input->Y = inputDevice[INPUT_BUTTONY].press;490input->Z = inputDevice[INPUT_BUTTONZ].press;491input->L = inputDevice[INPUT_BUTTONL].press;492input->R = inputDevice[INPUT_BUTTONR].press;493input->start = inputDevice[INPUT_START].press;494input->select = inputDevice[INPUT_SELECT].press;495#endif496497#if RETRO_REV03498SetGlobalVariableByName("input.pressButton", input->A || input->B || input->C || input->X || input->Y || input->Z || input->L || input->R499|| input->start || input->select);500#endif501}502503void CheckKeyDown(InputData *input)504{505#if !RETRO_USE_ORIGINAL_CODE506input->up = inputDevice[INPUT_UP].hold;507input->down = inputDevice[INPUT_DOWN].hold;508input->left = inputDevice[INPUT_LEFT].hold;509input->right = inputDevice[INPUT_RIGHT].hold;510input->A = inputDevice[INPUT_BUTTONA].hold;511input->B = inputDevice[INPUT_BUTTONB].hold;512input->C = inputDevice[INPUT_BUTTONC].hold;513input->X = inputDevice[INPUT_BUTTONX].hold;514input->Y = inputDevice[INPUT_BUTTONY].hold;515input->Z = inputDevice[INPUT_BUTTONZ].hold;516input->L = inputDevice[INPUT_BUTTONL].hold;517input->R = inputDevice[INPUT_BUTTONR].hold;518input->start = inputDevice[INPUT_START].hold;519input->select = inputDevice[INPUT_SELECT].hold;520#endif521}522523int CheckTouchRect(float x, float y, float w, float h)524{525for (int f = 0; f < touches; ++f) {526if (touchDown[f] && touchXF[f] > (x - w) && touchYF[f] > (y - h) && touchXF[f] <= (x + w) && touchYF[f] <= (y + h)) {527return f;528}529}530return -1;531}532533int CheckTouchRectMatrix(void *m, float x, float y, float w, float h)534{535MatrixF *mat = (MatrixF *)m;536for (int f = 0; f < touches; ++f) {537float tx = touchXF[f];538float ty = touchYF[f];539if (touchDown[f]) {540float posX = (((tx * mat->values[0][0]) + (ty * mat->values[1][0])) + (mat->values[2][0] * SCREEN_YSIZE)) + mat->values[3][0];541if (posX > (x - w) && posX <= (x + w)) {542float posY = (((tx * mat->values[0][1]) + (ty * mat->values[1][1])) + (mat->values[2][1] * SCREEN_YSIZE)) + mat->values[3][1];543if (posY > (y - h) && posY <= (y + h))544return f;545}546}547}548return -1;549}550551#if RETRO_USE_HAPTICS552void HapticEffect(int *hapticID, int *a2, int *a3, int *a4)553{554if (Engine.hapticsEnabled)555hapticEffectNum = *hapticID;556}557#endif558559