input: fix naomi rotary encoders

Games with multiple JVS input boards poll inputs more than once,
ignoring some relative mouse movements.

Issue #557
This commit is contained in:
Flyinghead 2022-03-06 17:57:16 +01:00
parent 830ffd0559
commit 1f61f80c92
6 changed files with 44 additions and 22 deletions

View File

@ -166,11 +166,14 @@ void MapleConfigMap::GetAbsCoordinates(int& x, int& y)
void MapleConfigMap::GetMouseInput(u8& buttons, int& x, int& y, int& wheel)
{
const MapleInputState& inputState = mapleInputState[playerNum()];
MapleInputState& inputState = mapleInputState[playerNum()];
buttons = inputState.mouseButtons;
x = inputState.relPos.x;
y = inputState.relPos.y * (invertMouseY ? -1 : 1);
wheel = inputState.relPos.wheel;
inputState.relPos.x = 0;
inputState.relPos.y = 0;
inputState.relPos.wheel = 0;
}
void MapleConfigMap::GetKeyboardInput(u8& shift, u8 keys[6])

View File

@ -1566,6 +1566,8 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou
// I can't think of any naomi multiplayer game that uses rotary encoders
rotx += mapleInputState[first_player].relPos.x * 5;
roty -= mapleInputState[first_player].relPos.y * 5;
mapleInputState[first_player].relPos.x = 0;
mapleInputState[first_player].relPos.y = 0;
LOGJVS("rotenc ");
for (int chan = 0; chan < buffer_in[cmdi + 1]; chan++)
{

View File

@ -26,9 +26,10 @@
// bit 3: Wheel button
u8 mo_buttons[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
// Relative mouse coordinates [-512:511]
f32 mo_x_delta[4];
f32 mo_y_delta[4];
f32 mo_wheel_delta[4];
float mo_x_delta[4];
float mo_y_delta[4];
float mo_wheel_delta[4];
std::mutex relPosMutex;
// Absolute mouse coordinates
// Range [0:639] [0:479]
// but may be outside this range if the pointer is offscreen or outside the 4:3 window.
@ -50,6 +51,7 @@ void Mouse::setRelPos(float deltax, float deltay) {
}
void Mouse::setWheel(int delta) {
std::lock_guard<std::mutex> lock(relPosMutex);
if (maple_port() >= 0 && maple_port() < (int)ARRAY_SIZE(mo_wheel_delta))
mo_wheel_delta[maple_port()] += delta;
}
@ -131,8 +133,9 @@ void SetMousePosition(int x, int y, int width, int height, u32 mouseId)
if (mo_x_prev[mouseId] != -1)
{
mo_x_delta[mouseId] += (f32)(x - mo_x_prev[mouseId]) * config::MouseSensitivity / 100.f;
mo_y_delta[mouseId] += (f32)(y - mo_y_prev[mouseId]) * config::MouseSensitivity / 100.f;
std::lock_guard<std::mutex> lock(relPosMutex);
mo_x_delta[mouseId] += (float)(x - mo_x_prev[mouseId]) * config::MouseSensitivity / 100.f;
mo_y_delta[mouseId] += (float)(y - mo_y_prev[mouseId]) * config::MouseSensitivity / 100.f;
}
mo_x_prev[mouseId] = x;
mo_y_prev[mouseId] = y;
@ -152,8 +155,11 @@ void SetRelativeMousePosition(float xrel, float yrel, u32 mouseId)
}
float dx = xrel * config::MouseSensitivity / 100.f;
float dy = yrel * config::MouseSensitivity / 100.f;
mo_x_delta[mouseId] += dx;
mo_y_delta[mouseId] += dy;
{
std::lock_guard<std::mutex> lock(relPosMutex);
mo_x_delta[mouseId] += dx;
mo_y_delta[mouseId] += dy;
}
int minX = -width / 32;
int minY = -height / 32;
int maxX = width + width / 32;

View File

@ -18,14 +18,16 @@
*/
#pragma once
#include "gamepad_device.h"
#include <mutex>
// Mouse position and buttons
extern u8 mo_buttons[4];
extern s32 mo_x_abs[4];
extern s32 mo_y_abs[4];
extern f32 mo_x_delta[4];
extern f32 mo_y_delta[4];
extern f32 mo_wheel_delta[4];
extern float mo_x_delta[4];
extern float mo_y_delta[4];
extern float mo_wheel_delta[4];
extern std::mutex relPosMutex;
extern s32 mo_x_prev[4];
extern s32 mo_y_prev[4];

View File

@ -34,6 +34,7 @@ static void getLocalInput(MapleInputState inputState[4])
{
if (!config::ThreadedRendering)
UpdateInputState();
std::lock_guard<std::mutex> lock(relPosMutex);
for (int player = 0; player < 4; player++)
{
MapleInputState& state = inputState[player];
@ -49,12 +50,15 @@ static void getLocalInput(MapleInputState inputState[4])
state.absPos.y = mo_y_abs[player];
state.keyboard.shift = kb_shift[player];
memcpy(state.keyboard.key, kb_key[player], sizeof(kb_key[player]));
state.relPos.x = std::round(mo_x_delta[player]);
state.relPos.y = std::round(mo_y_delta[player]);
state.relPos.wheel = std::round(mo_wheel_delta[player]);
mo_x_delta[player] -= state.relPos.x;
mo_y_delta[player] -= state.relPos.y;
mo_wheel_delta[player] -= state.relPos.wheel;
int relX = std::round(mo_x_delta[player]);
int relY = std::round(mo_y_delta[player]);
int wheel = std::round(mo_wheel_delta[player]);
state.relPos.x += relX;
state.relPos.y += relY;
state.relPos.wheel += wheel;
mo_x_delta[player] -= relX;
mo_y_delta[player] -= relY;
mo_wheel_delta[player] -= wheel;
}
}
@ -706,6 +710,7 @@ bool nextFrame()
}
else if (mouseGame)
{
std::lock_guard<std::mutex> lock(relPosMutex);
inputs.mouseButtons = ~mo_buttons[0];
inputs.u.relPos.x = std::round(mo_x_delta[0]);
inputs.u.relPos.y = std::round(mo_y_delta[0]);

View File

@ -21,6 +21,7 @@
#ifndef _WIN32
#include <sys/time.h>
#endif
#include <mutex>
#ifdef __SWITCH__
#include <stdlib.h>
@ -136,9 +137,10 @@ s8 joyrx[4], joyry[4];
// bit 3: Wheel button
u8 mo_buttons[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
// Relative mouse coordinates [-512:511]
f32 mo_x_delta[4];
f32 mo_y_delta[4];
f32 mo_wheel_delta[4];
float mo_x_delta[4];
float mo_y_delta[4];
float mo_wheel_delta[4];
std::mutex relPosMutex;
// Absolute mouse coordinates
// Range [0:639] [0:479]
// but may be outside this range if the pointer is offscreen or outside the 4:3 window.
@ -2278,8 +2280,10 @@ static void setDeviceButtonStateDirect(u32 bitmap, u32 port, int deviceType, int
static void updateMouseState(u32 port)
{
mo_x_delta[port] = input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
mo_y_delta[port] = input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
std::lock_guard<std::mutex> lock(relPosMutex);
mo_x_delta[port] += input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
mo_y_delta[port] += input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
bool btn_state = input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT);
if (btn_state)