diff --git a/source/frontends/ncurses/input.cpp b/source/frontends/ncurses/input.cpp index 1fc90ef8..6ae1ec65 100644 --- a/source/frontends/ncurses/input.cpp +++ b/source/frontends/ncurses/input.cpp @@ -9,6 +9,24 @@ #include #include "Log.h" +#include "Memory.h" +#include "Common.h" +#include "CPU.h" + +unsigned __int64 g_nJoyCntrResetCycle = 0; // Abs cycle that joystick counters were reset +const double PDL_CNTR_INTERVAL = 2816.0 / 255.0; // 11.04 (From KEGS) + +std::shared_ptr Input::ourSingleton; + +void Input::initialise(const std::string & device) +{ + ourSingleton.reset(new Input(device)); +} + +Input & Input::instance() +{ + return *ourSingleton; +} Input::Input(const std::string & device) : myButtonCodes(2), myAxisCodes(2), myAxisMins(2), myAxisMaxs(2) @@ -98,3 +116,51 @@ int Input::getAxis(int i) const } } + +BYTE __stdcall JoyReadButton(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft) +{ + addr &= 0xFF; + BOOL pressed = 0; + + switch (addr) + { + case 0x61: + pressed = Input::instance().getButton(0); + break; + case 0x62: + pressed = Input::instance().getButton(1); + break; + case 0x63: + break; + } + return MemReadFloatingBus(pressed, nCyclesLeft); +} + +BYTE __stdcall JoyReadPosition(WORD pc, WORD address, BYTE bWrite, BYTE d, ULONG nCyclesLeft) +{ + const int nJoyNum = (address & 2) ? 1 : 0; // $C064..$C067 + + CpuCalcCycles(nCyclesLeft); + BOOL nPdlCntrActive = 0; + + if (nJoyNum == 0) + { + int axis = address & 1; + int pdl = Input::instance().getAxis(axis); + // This is from KEGS. It helps games like Championship Lode Runner & Boulderdash + if (pdl >= 255) + pdl = 280; + + nPdlCntrActive = g_nCumulativeCycles <= (g_nJoyCntrResetCycle + (unsigned __int64) ((double)pdl * PDL_CNTR_INTERVAL)); + } + + return MemReadFloatingBus(nPdlCntrActive, nCyclesLeft); +} + +BYTE __stdcall JoyResetPosition(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft) +{ + CpuCalcCycles(nCyclesLeft); + g_nJoyCntrResetCycle = g_nCumulativeCycles; + + return MemReadFloatingBus(nCyclesLeft); +} diff --git a/source/frontends/ncurses/input.h b/source/frontends/ncurses/input.h index 79a2b806..01592dc3 100644 --- a/source/frontends/ncurses/input.h +++ b/source/frontends/ncurses/input.h @@ -16,6 +16,10 @@ public: bool getButton(int i) const; int getAxis(int i) const; + static void initialise(const std::string & device); + + static Input & instance(); + private: int myFD; std::shared_ptr myDev; @@ -26,4 +30,6 @@ private: std::vector myAxisCodes; std::vector myAxisMins; std::vector myAxisMaxs; + + static std::shared_ptr ourSingleton; }; diff --git a/source/frontends/ncurses/world.cpp b/source/frontends/ncurses/world.cpp index 0d11017a..2b4832a1 100644 --- a/source/frontends/ncurses/world.cpp +++ b/source/frontends/ncurses/world.cpp @@ -25,7 +25,6 @@ namespace std::shared_ptr frame; std::shared_ptr colors; std::shared_ptr asciiArt; - std::shared_ptr input; int g_nTrackDrive1 = -1; int g_nTrackDrive2 = -1; @@ -55,8 +54,6 @@ namespace bool keyReady = false; bool g_bTextFlashState = false; - unsigned __int64 g_nJoyCntrResetCycle = 0; // Abs cycle that joystick counters were reset - const double PDL_CNTR_INTERVAL = 2816.0 / 255.0; // 11.04 (From KEGS) double alpha = 10.0; double F = 0; @@ -375,7 +372,7 @@ void VideoInitialize() frame.reset(new Frame()); asciiArt.reset(new ASCIIArt()); - input.reset(new Input("/dev/input/by-id/usb-©Microsoft_Corporation_Controller_1BBE3DB-event-joystick")); + Input::initialise("/dev/input/by-id/usb-©Microsoft_Corporation_Controller_1BBE3DB-event-joystick"); signal(SIGINT, sig_handler); } @@ -518,7 +515,7 @@ int ProcessKeyboard() void ProcessInput() { - input->poll(); + Input::instance().poll(); } BYTE KeybGetKeycode () @@ -538,54 +535,6 @@ BYTE __stdcall KeybReadFlag (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyc return result; } -BYTE __stdcall JoyReadButton(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft) -{ - addr &= 0xFF; - BOOL pressed = 0; - - switch (addr) - { - case 0x61: - pressed = input->getButton(0); - break; - case 0x62: - pressed = input->getButton(1); - break; - case 0x63: - break; - } - return MemReadFloatingBus(pressed, nCyclesLeft); -} - -BYTE __stdcall JoyReadPosition(WORD pc, WORD address, BYTE bWrite, BYTE d, ULONG nCyclesLeft) -{ - const int nJoyNum = (address & 2) ? 1 : 0; // $C064..$C067 - - CpuCalcCycles(nCyclesLeft); - BOOL nPdlCntrActive = 0; - - if (nJoyNum == 0) - { - int axis = address & 1; - int pdl = input->getAxis(axis); - // This is from KEGS. It helps games like Championship Lode Runner & Boulderdash - if (pdl >= 255) - pdl = 280; - - nPdlCntrActive = g_nCumulativeCycles <= (g_nJoyCntrResetCycle + (unsigned __int64) ((double)pdl * PDL_CNTR_INTERVAL)); - } - - return MemReadFloatingBus(nPdlCntrActive, nCyclesLeft); -} - -BYTE __stdcall JoyResetPosition(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft) -{ - CpuCalcCycles(nCyclesLeft); - g_nJoyCntrResetCycle = g_nCumulativeCycles; - - return MemReadFloatingBus(nCyclesLeft); -} - // Speaker BYTE __stdcall SpkrToggle (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)