From a8d9b77c983396a9be8c313ace98b4a63f6a2a1c Mon Sep 17 00:00:00 2001 From: Sour Date: Fri, 15 Mar 2019 14:16:27 -0400 Subject: [PATCH] Input: Added snes mouse support --- Core/ControlManager.cpp | 3 +- Core/Core.vcxproj | 1 + Core/Core.vcxproj.filters | 3 ++ Core/KeyManager.cpp | 34 +++++++------ Core/KeyManager.h | 6 ++- Core/SnesMouse.h | 89 ++++++++++++++++++++++++++++++++++ InteropDLL/InputApiWrapper.cpp | 4 +- 7 files changed, 120 insertions(+), 20 deletions(-) create mode 100644 Core/SnesMouse.h diff --git a/Core/ControlManager.cpp b/Core/ControlManager.cpp index 95bb4d5..61e5dd3 100644 --- a/Core/ControlManager.cpp +++ b/Core/ControlManager.cpp @@ -8,6 +8,7 @@ #include "IInputProvider.h" #include "IInputRecorder.h" #include "SnesController.h" +#include "SnesMouse.h" #include "../Utilities/Serializer.h" ControlManager::ControlManager(shared_ptr console) @@ -100,7 +101,7 @@ shared_ptr ControlManager::CreateControllerDevice(ControllerT switch(type) { case ControllerType::None: break; case ControllerType::SnesController: device.reset(new SnesController(console, port, cfg.Controllers[port].Keys)); break; - case ControllerType::SnesMouse: break; + case ControllerType::SnesMouse: device.reset(new SnesMouse(console, port)); break; case ControllerType::SuperScope: break; } diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 71b822a..52af0cd 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -114,6 +114,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index ab37802..b5bd25b 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -248,6 +248,9 @@ Misc + + SNES\Input + diff --git a/Core/KeyManager.cpp b/Core/KeyManager.cpp index 137d7a5..42167b8 100644 --- a/Core/KeyManager.cpp +++ b/Core/KeyManager.cpp @@ -1,6 +1,9 @@ #include "stdafx.h" #include "KeyManager.h" #include "IKeyManager.h" +#include "EmuSettings.h" +#include "Console.h" +#include "VideoDecoder.h" IKeyManager* KeyManager::_keyManager = nullptr; MousePosition KeyManager::_mousePosition = { 0, 0 }; @@ -31,10 +34,10 @@ bool KeyManager::IsKeyPressed(uint32_t keyCode) bool KeyManager::IsMouseButtonPressed(MouseButton button) { - //TODO - /*if(_keyManager != nullptr) { - return _settings->InputEnabled() && _keyManager->IsMouseButtonPressed(button); - }*/ + if(_keyManager != nullptr) { + //TODO return _settings->InputEnabled() && + return _keyManager->IsMouseButtonPressed(button); + } return false; } @@ -75,30 +78,29 @@ void KeyManager::SetMouseMovement(int16_t x, int16_t y) _yMouseMovement += y; } -MouseMovement KeyManager::GetMouseMovement(double mouseSensitivity) +MouseMovement KeyManager::GetMouseMovement(double videoScale, double mouseSensitivity) { - //TODO - //double factor = _settings->GetVideoScale() / mouseSensitivity; + double factor = videoScale / mouseSensitivity; MouseMovement mov = {}; - /*mov.dx = (int16_t)(_xMouseMovement / factor); + mov.dx = (int16_t)(_xMouseMovement / factor); mov.dy = (int16_t)(_yMouseMovement / factor); _xMouseMovement -= (int16_t)(mov.dx * factor); - _yMouseMovement -= (int16_t)(mov.dy * factor);*/ + _yMouseMovement -= (int16_t)(mov.dy * factor); return mov; } -void KeyManager::SetMousePosition(double x, double y) +void KeyManager::SetMousePosition(shared_ptr console, double x, double y) { - //TODO - /*if(x < 0 || y < 0) { + if(x < 0 || y < 0) { _mousePosition.X = -1; _mousePosition.Y = -1; } else { - OverscanDimensions overscan = _settings->GetOverscanDimensions(); - _mousePosition.X = (int32_t)(x * (PPU::ScreenWidth - overscan.Left - overscan.Right) + overscan.Left); - _mousePosition.Y = (int32_t)(y * (PPU::ScreenHeight - overscan.Top - overscan.Bottom) + overscan.Top); - }*/ + OverscanDimensions overscan = console->GetSettings()->GetOverscan(); + ScreenSize size = console->GetVideoDecoder()->GetScreenSize(false); + _mousePosition.X = (int32_t)(x*size.Width + overscan.Left); + _mousePosition.Y = (int32_t)(y*size.Height + overscan.Top); + } } MousePosition KeyManager::GetMousePosition() diff --git a/Core/KeyManager.h b/Core/KeyManager.h index c062bac..16351ae 100644 --- a/Core/KeyManager.h +++ b/Core/KeyManager.h @@ -2,6 +2,8 @@ #include "stdafx.h" #include "IKeyManager.h" +class Console; + class KeyManager { private: @@ -23,8 +25,8 @@ public: static void UpdateDevices(); static void SetMouseMovement(int16_t x, int16_t y); - static MouseMovement GetMouseMovement(double mouseSensitivity); + static MouseMovement GetMouseMovement(double videoScale, double mouseSensitivity); - static void SetMousePosition(double x, double y); + static void SetMousePosition(shared_ptr console, double x, double y); static MousePosition GetMousePosition(); }; \ No newline at end of file diff --git a/Core/SnesMouse.h b/Core/SnesMouse.h new file mode 100644 index 0000000..530eaf0 --- /dev/null +++ b/Core/SnesMouse.h @@ -0,0 +1,89 @@ +#pragma once +#include "stdafx.h" +#include "BaseControlDevice.h" +#include "IKeyManager.h" +#include "KeyManager.h" +#include "Console.h" +#include "EmuSettings.h" +#include "../Utilities/Serializer.h" + +class SnesMouse : public BaseControlDevice +{ +private: + uint32_t _stateBuffer = 0; + uint8_t _sensitivity = 0; + +protected: + bool HasCoordinates() override { return true; } + + enum Buttons { Left = 0, Right }; + + void Serialize(Serializer &s) override + { + BaseControlDevice::Serialize(s); + s.Stream(_stateBuffer, _sensitivity); + } + + string GetKeyNames() override + { + return "LR"; + } + + void InternalSetStateFromInput() override + { + SetPressedState(Buttons::Left, KeyManager::IsMouseButtonPressed(MouseButton::LeftButton)); + SetPressedState(Buttons::Right, KeyManager::IsMouseButtonPressed(MouseButton::RightButton)); + SetMovement(KeyManager::GetMouseMovement( + _console->GetSettings()->GetVideoConfig().VideoScale, + _console->GetSettings()->GetInputConfig().MouseSensitivity + 1 + )); + } + +public: + SnesMouse(shared_ptr console, uint8_t port) : BaseControlDevice(console, port) + { + } + + void WriteRam(uint16_t addr, uint8_t value) override + { + StrobeProcessWrite(value); + } + + uint8_t ReadRam(uint16_t addr) override + { + uint8_t output = 0; + if((addr == 0x4016 && (_port & 0x01) == 0) || (addr == 0x4017 && (_port & 0x01) == 1)) { + if(_strobe) { + _sensitivity = (_sensitivity + 1) % 3; + } + + output = (_stateBuffer & 0x80000000) >> 31; + if(_port >= 2) { + output <<= 1; + } + _stateBuffer <<= 1; + StrobeProcessRead(); + } + return output; + } + + void RefreshStateBuffer() override + { + MouseMovement mov = GetMovement(); + int32_t dx = mov.dx * (1 + _sensitivity); + int32_t dy = mov.dy * (1 + _sensitivity); + + uint32_t upFlag = dy < 0 ? 0x80 : 0; + uint32_t leftFlag = dx < 0 ? 0x80 : 0; + + dx = std::min(std::abs(dx), 127); + dy = std::min(std::abs(dy), 127); + + uint8_t byte1 = 0; + uint8_t byte2 = 0x01 | ((_sensitivity & 0x03) << 4) | (IsPressed(SnesMouse::Buttons::Left) ? 0x40 : 0) | (IsPressed(SnesMouse::Buttons::Right) ? 0x80 : 0); + uint8_t byte3 = dy | upFlag; + uint8_t byte4 = dx | leftFlag; + + _stateBuffer = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4; + } +}; \ No newline at end of file diff --git a/InteropDLL/InputApiWrapper.cpp b/InteropDLL/InputApiWrapper.cpp index 26408eb..8b56a84 100644 --- a/InteropDLL/InputApiWrapper.cpp +++ b/InteropDLL/InputApiWrapper.cpp @@ -1,9 +1,11 @@ #include "stdafx.h" +#include "../Core/Console.h" #include "../Core/KeyManager.h" #include "../Core/ShortcutKeyHandler.h" extern unique_ptr _keyManager; extern unique_ptr _shortcutKeyHandler; +extern shared_ptr _console; static string _returnString; @@ -11,7 +13,7 @@ extern "C" { DllExport void __stdcall SetMousePosition(double x, double y) { - KeyManager::SetMousePosition(x, y); + KeyManager::SetMousePosition(_console, x, y); } DllExport void __stdcall SetMouseMovement(int16_t x, int16_t y)