USIO: Added mouse and key/pad input support for shooter games

This commit is contained in:
brian218
2026-10-02 11:13:40 +02:00
committed by Megamouse
parent 0850e0ff5c
commit 96ccd89cd6
5 changed files with 92 additions and 10 deletions
+68 -10
View File
@@ -2,9 +2,11 @@
#include "stdafx.h"
#include "usio.h"
#include "MouseHandler.h"
#include "Input/pad_thread.h"
#include "Emu/Io/usio_config.h"
#include "Emu/IdManager.h"
#include "Emu/system_config.h"
LOG_CHANNEL(usio_log, "USIO");
@@ -310,8 +312,9 @@ void usb_device_usio::translate_input_tekken()
const auto translate_from_pad = [&](usz pad_number, usz player)
{
const usz shift = (player % 2) * 24ULL;
auto& status = m_io_status[player / 2];
auto& input = digital_input[player / 2];
const usz io_index = player / 2;
auto& status = m_io_status[io_index];
auto& input = digital_input[io_index];
if (const auto& pad = ::at32(handler->GetPads(), pad_number); pad->is_connected() && !pad->is_copilot() && is_input_allowed())
{
@@ -341,7 +344,7 @@ void usb_device_usio::translate_input_tekken()
case usio_btn::enter:
if (value.pressed)
{
input |= 0x800000ULL << shift;
input |= (g_cfg.io.usio_mode == usio_handler_mode::shooter_games ? 0x200ULL : 0x800000ULL) << shift;
if (player == 0)
digital_input_lm |= 0x800;
}
@@ -349,7 +352,7 @@ void usb_device_usio::translate_input_tekken()
case usio_btn::up:
if (value.pressed)
{
input |= 0x200000ULL << shift;
input |= (g_cfg.io.usio_mode == usio_handler_mode::shooter_games ? 0x2000ULL : 0x200000ULL) << shift;
if (player == 0)
digital_input_lm |= 0x200;
}
@@ -357,7 +360,7 @@ void usb_device_usio::translate_input_tekken()
case usio_btn::down:
if (value.pressed)
{
input |= 0x100000ULL << shift;
input |= (g_cfg.io.usio_mode == usio_handler_mode::shooter_games ? 0x1000ULL : 0x100000ULL) << shift;
if (player == 0)
digital_input_lm |= 0x400;
}
@@ -365,7 +368,7 @@ void usb_device_usio::translate_input_tekken()
case usio_btn::left:
if (value.pressed)
{
input |= 0x80000ULL << shift;
input |= g_cfg.io.usio_mode == usio_handler_mode::shooter_games ? (player % 2 == 0 ? 0x800000ULL : 0x100000ULL) : (0x80000ULL << shift);
if (player == 0)
digital_input_lm |= 0x2000;
}
@@ -373,12 +376,12 @@ void usb_device_usio::translate_input_tekken()
case usio_btn::right:
if (value.pressed)
{
input |= 0x40000ULL << shift;
input |= g_cfg.io.usio_mode == usio_handler_mode::shooter_games ? (player % 2 == 0 ? 0x400000ULL : 0x80000ULL) : (0x40000ULL << shift);
if (player == 0)
digital_input_lm |= 0x4000;
}
break;
case usio_btn::tekken_button1:
case usio_btn::tekken_button1: // or "2D / 3D Switch" button for shooter games
if (value.pressed)
{
input |= 0x20000ULL << shift;
@@ -386,9 +389,9 @@ void usb_device_usio::translate_input_tekken()
digital_input_lm |= 0x100;
}
break;
case usio_btn::tekken_button2:
case usio_btn::tekken_button2: // or "Start" button for shooter games
if (value.pressed)
input |= 0x10000ULL << shift;
input |= g_cfg.io.usio_mode == usio_handler_mode::shooter_games ? (player % 2 == 0 ? 0x200000ULL : 0x40000ULL) : (0x10000ULL << shift);
break;
case usio_btn::tekken_button3:
if (value.pressed)
@@ -420,11 +423,66 @@ void usb_device_usio::translate_input_tekken()
}
};
auto& mouse_handler = g_fxo->get<MouseHandlerBase>();
std::unique_lock mouse_lock(mouse_handler.mutex, std::defer_lock);
if (g_cfg.io.usio_mode == usio_handler_mode::shooter_games)
{
mouse_lock.lock();
mouse_handler.Init(4);
}
const auto translate_from_mouse = [&](usz mouse_number, usz player)
{
const usz player_index = player % 2;
const usz io_index = player / 2;
auto& status = m_io_status[io_index];
auto& input = digital_input[io_index];
const u32 mouse_index = g_cfg.io.mouse == mouse_handler::basic ? 0 : mouse_number;
if (!is_input_allowed() || mouse_index >= mouse_handler.GetMice().size())
return;
const Mouse& mouse_data = ::at32(mouse_handler.GetMice(), mouse_index);
const auto is_pressed = [&mouse_data](MouseButtonCodes button) -> bool
{
return !!(mouse_data.buttons & button);
};
s8 current_wheel = 0;
MouseDataList& data_list = mouse_handler.GetDataList(mouse_number);
if (!data_list.empty())
{
const MouseData& current_data = data_list.front();
current_wheel = current_data.wheel * 0x10;
data_list.pop_front();
}
status.vital_sensors[player_index] += current_wheel;
status.wheel_rotation += current_wheel; // Multiple players can collaborate on turning the wheel
const le_t<s16> positions[2] = {::narrow<s16>(mouse_data.x_pos), ::narrow<s16>(mouse_data.y_pos)};
std::memcpy(input_buf.data() - io_index * 0x80 + 0x100 + 32 + player_index * sizeof(s32), &positions, sizeof(s32));
std::memcpy(input_buf.data() - io_index * 0x80 + 0x100 + 41 + player_index * sizeof(s16), &status.vital_sensors[player_index], sizeof(s8));
std::memcpy(input_buf.data() - io_index * 0x80 + 0x100 + 48, &status.wheel_rotation, sizeof(s8));
if (is_pressed(CELL_MOUSE_BUTTON_1))
input |= player_index == 0 ? 0x800000ULL : 0x100000ULL; // Gun Trigger Left
if (is_pressed(CELL_MOUSE_BUTTON_2))
input |= player_index == 0 ? 0x400000ULL : 0x80000ULL; // Gun Trigger Right
if (is_pressed(CELL_MOUSE_BUTTON_3))
input |= player_index == 0 ? 0x200000ULL : 0x40000ULL; // Start
};
for (usz i = 0; i < m_io_status.size(); i++)
m_io_status[i].card_tapped = false;
for (usz i = 0; i < g_cfg_usio.players.size(); i++)
{
translate_from_pad(i, i);
if (g_cfg.io.usio_mode == usio_handler_mode::shooter_games)
translate_from_mouse(i, i);
}
for (usz i = 0; i < 2; i++)
{
std::memcpy(input_buf.data() - i * 0x80 + 0x100, &digital_input[i], sizeof(u64));
+2
View File
@@ -39,6 +39,8 @@ private:
bool card_tapped = false;
le_t<u16> coin_counter = 0;
usz card_index = 0;
s8 vital_sensors[2] = {0, 0};
s8 wheel_rotation = 0;
};
std::array<io_status, 2> m_io_status;
+1
View File
@@ -308,6 +308,7 @@ struct cfg_root : cfg::node
cfg::_bool mouse_debug_overlay{ this, "Mouse Debug overlay", false, true };
cfg::uint<1, 180> fake_move_rotation_cone_h{ this, "Fake Move Rotation Cone", 10, true };
cfg::uint<1, 180> fake_move_rotation_cone_v{ this, "Fake Move Rotation Cone (Vertical)", 10, true };
cfg::_enum<usio_handler_mode> usio_mode{this, "USIO handler mode", usio_handler_mode::fighting_games };
} io{ this };
+15
View File
@@ -518,6 +518,21 @@ void fmt_class_string<ghltar_handler>::format(std::string& out, u64 arg)
});
}
template <>
void fmt_class_string<usio_handler_mode>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto value)
{
switch (value)
{
case usio_handler_mode::fighting_games: return "Fighting Games";
case usio_handler_mode::shooter_games: return "Shooter Games";
}
return unknown;
});
}
template <>
void fmt_class_string<ppu_decoder_type>::format(std::string& out, u64 arg)
{
+6
View File
@@ -171,6 +171,12 @@ enum class ghltar_handler
two_controllers,
};
enum class usio_handler_mode
{
fighting_games,
shooter_games
};
enum class microphone_handler
{
null,