Address review comments

This commit is contained in:
Barış Hamil 2026-02-11 15:23:51 +03:00
parent 7e325a353c
commit d009e899c8
9 changed files with 131 additions and 98 deletions

View file

@ -402,6 +402,7 @@ target_sources(rpcs3_emu PRIVATE
Io/GHLtar.cpp
Io/GunCon3.cpp
Io/Infinity.cpp
Io/wiimote_config.cpp
Io/interception.cpp
Io/KamenRider.cpp
Io/KeyboardHandler.cpp

View file

@ -0,0 +1,34 @@
#include "stdafx.h"
#include "wiimote_config.h"
#include "Utilities/File.h"
LOG_CHANNEL(wiimote_log, "Wiimote");
cfg_wiimote& get_wiimote_config()
{
static cfg_wiimote instance;
return instance;
}
cfg_wiimote::cfg_wiimote()
: cfg::node()
, path(fs::get_config_dir(true) + "wiimote.yml")
{
}
bool cfg_wiimote::load()
{
if (fs::file f{path, fs::read})
{
return from_string(f.to_string());
}
return false;
}
void cfg_wiimote::save() const
{
if (!cfg::node::save(path))
{
wiimote_log.error("Failed to save wiimote config to '%s'", path);
}
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "Utilities/Config.h"
struct cfg_wiimote final : cfg::node
{
cfg_wiimote();
bool load();
void save() const;
struct node_mapping : cfg::node
{
node_mapping(cfg::node* _parent) : cfg::node(_parent, "Mapping") {}
cfg::uint<0, 0xFFFF> trigger{ this, "Trigger", 0x0400 };
cfg::uint<0, 0xFFFF> a1{ this, "A1", 0x0800 };
cfg::uint<0, 0xFFFF> a2{ this, "A2", 0x1000 };
cfg::uint<0, 0xFFFF> a3{ this, "A3", 0x0001 };
cfg::uint<0, 0xFFFF> b1{ this, "B1", 0x0200 };
cfg::uint<0, 0xFFFF> b2{ this, "B2", 0x0100 };
cfg::uint<0, 0xFFFF> b3{ this, "B3", 0x8000 };
cfg::uint<0, 0xFFFF> c1{ this, "C1", 0x0010 };
cfg::uint<0, 0xFFFF> c2{ this, "C2", 0x0002 };
cfg::uint<0, 0xFFFF> b1_alt{ this, "B1_Alt", 0x0008 };
cfg::uint<0, 0xFFFF> b2_alt{ this, "B2_Alt", 0x0004 };
} mapping{ this };
const std::string path;
};
cfg_wiimote& get_wiimote_config();

View file

@ -42,19 +42,11 @@ bool hid_instance::initialize()
#if defined(__APPLE__)
int error_code = 0;
if (thread_ctrl::is_main())
Emu.BlockingCallFromMainThread([&error_code]()
{
error_code = hid_init();
hid_darwin_set_open_exclusive(0);
}
else
{
Emu.BlockingCallFromMainThread([&error_code]()
{
error_code = hid_init();
hid_darwin_set_open_exclusive(0);
}, false);
}
}, false);
#else
const int error_code = hid_init();
#endif
@ -72,14 +64,12 @@ hid_device_info* hid_instance::enumerate(u16 vid, u16 pid)
{
std::lock_guard lock(g_hid_mutex);
#if defined(__APPLE__)
if (!thread_ctrl::is_main())
{
hid_device_info* devs = nullptr;
Emu.BlockingCallFromMainThread([&]() { devs = hid_enumerate(vid, pid); }, false);
return devs;
}
#endif
hid_device_info* devs = nullptr;
Emu.BlockingCallFromMainThread([&]() { devs = hid_enumerate(vid, pid); }, false);
return devs;
#else
return hid_enumerate(vid, pid);
#endif
}
void hid_instance::free_enumeration(hid_device_info* devs)
@ -88,13 +78,10 @@ void hid_instance::free_enumeration(hid_device_info* devs)
std::lock_guard lock(g_hid_mutex);
#if defined(__APPLE__)
if (!thread_ctrl::is_main())
{
Emu.BlockingCallFromMainThread([&]() { hid_free_enumeration(devs); }, false);
return;
}
#endif
Emu.BlockingCallFromMainThread([&]() { hid_free_enumeration(devs); }, false);
#else
hid_free_enumeration(devs);
#endif
}
hid_device* hid_instance::open_path(const char* path)
@ -117,11 +104,8 @@ void hid_instance::close(hid_device* dev)
std::lock_guard lock(g_hid_mutex);
#if defined(__APPLE__)
if (!thread_ctrl::is_main())
{
Emu.BlockingCallFromMainThread([&]() { hid_close(dev); }, false);
return;
}
#endif
Emu.BlockingCallFromMainThread([&]() { hid_close(dev); }, false);
#else
hid_close(dev);
#endif
}

View file

@ -2,8 +2,7 @@
#include "wiimote_handler.h"
#include "Input/hid_instance.h"
#include "Emu/System.h"
#include "Utilities/File.h"
#include "util/yaml.hpp"
#include "Emu/Io/wiimote_config.h"
#include "util/logs.hpp"
#include <algorithm>
#include <initializer_list>
@ -208,66 +207,44 @@ bool wiimote_device::update()
static wiimote_handler* s_instance = nullptr;
static std::string get_config_path()
{
return fs::get_config_dir(true) + "wiimote.yml";
}
void wiimote_handler::load_config()
{
const std::string path = get_config_path();
fs::file f(path, fs::read);
if (!f) return;
auto [root, error] = yaml_load(f.to_string());
if (!error.empty())
auto& cfg = get_wiimote_config();
if (cfg.load())
{
wiimote_log.error("Failed to load wiimote config: %s", error);
return;
std::unique_lock lock(m_mutex);
m_mapping.trigger = static_cast<wiimote_button>(cfg.mapping.trigger.get());
m_mapping.a1 = static_cast<wiimote_button>(cfg.mapping.a1.get());
m_mapping.a2 = static_cast<wiimote_button>(cfg.mapping.a2.get());
m_mapping.a3 = static_cast<wiimote_button>(cfg.mapping.a3.get());
m_mapping.b1 = static_cast<wiimote_button>(cfg.mapping.b1.get());
m_mapping.b2 = static_cast<wiimote_button>(cfg.mapping.b2.get());
m_mapping.b3 = static_cast<wiimote_button>(cfg.mapping.b3.get());
m_mapping.c1 = static_cast<wiimote_button>(cfg.mapping.c1.get());
m_mapping.c2 = static_cast<wiimote_button>(cfg.mapping.c2.get());
m_mapping.b1_alt = static_cast<wiimote_button>(cfg.mapping.b1_alt.get());
m_mapping.b2_alt = static_cast<wiimote_button>(cfg.mapping.b2_alt.get());
}
wiimote_guncon_mapping map;
auto parse_btn = [&](const char* key, wiimote_button& btn)
{
if (root[key])
{
btn = static_cast<wiimote_button>(root[key].as<u16>(static_cast<u16>(btn)));
}
};
parse_btn("trigger", map.trigger);
parse_btn("a1", map.a1);
parse_btn("a2", map.a2);
parse_btn("a3", map.a3);
parse_btn("b1", map.b1);
parse_btn("b2", map.b2);
parse_btn("b3", map.b3);
parse_btn("c1", map.c1);
parse_btn("c2", map.c2);
std::unique_lock lock(m_mutex);
m_mapping = map;
}
void wiimote_handler::save_config()
{
YAML::Node root;
{
std::shared_lock lock(m_mutex);
root["trigger"] = static_cast<u16>(m_mapping.trigger);
root["a1"] = static_cast<u16>(m_mapping.a1);
root["a2"] = static_cast<u16>(m_mapping.a2);
root["a3"] = static_cast<u16>(m_mapping.a3);
root["b1"] = static_cast<u16>(m_mapping.b1);
root["b2"] = static_cast<u16>(m_mapping.b2);
root["b3"] = static_cast<u16>(m_mapping.b3);
root["c1"] = static_cast<u16>(m_mapping.c1);
root["c2"] = static_cast<u16>(m_mapping.c2);
auto& cfg = get_wiimote_config();
cfg.mapping.trigger.set(static_cast<u16>(m_mapping.trigger));
cfg.mapping.a1.set(static_cast<u16>(m_mapping.a1));
cfg.mapping.a2.set(static_cast<u16>(m_mapping.a2));
cfg.mapping.a3.set(static_cast<u16>(m_mapping.a3));
cfg.mapping.b1.set(static_cast<u16>(m_mapping.b1));
cfg.mapping.b2.set(static_cast<u16>(m_mapping.b2));
cfg.mapping.b3.set(static_cast<u16>(m_mapping.b3));
cfg.mapping.c1.set(static_cast<u16>(m_mapping.c1));
cfg.mapping.c2.set(static_cast<u16>(m_mapping.c2));
cfg.mapping.b1_alt.set(static_cast<u16>(m_mapping.b1_alt));
cfg.mapping.b2_alt.set(static_cast<u16>(m_mapping.b2_alt));
}
YAML::Emitter emitter;
emitter << root;
fs::write_file(get_config_path(), fs::rewrite, emitter.c_str(), emitter.size());
get_wiimote_config().save();
}
wiimote_handler::wiimote_handler()
@ -321,7 +298,7 @@ void wiimote_handler::stop()
m_thread.reset();
}
size_t wiimote_handler::get_device_count()
usz wiimote_handler::get_device_count()
{
std::shared_lock lock(m_mutex);
return m_devices.size();
@ -358,10 +335,8 @@ std::vector<wiimote_state> wiimote_handler::get_states()
void wiimote_handler::thread_proc()
{
thread_ctrl::set_name("WiiMoteManager");
u32 counter = 0;
while (m_running)
while (m_running && thread_ctrl::state() != thread_state::aborting)
{
// Scan every 2 seconds
if (counter++ % 200 == 0)
@ -418,7 +393,7 @@ void wiimote_handler::thread_proc()
{
// Generic Wiimote: Find first available slot
std::shared_lock lock(m_mutex);
for (size_t i = 0; i < m_devices.size(); i++)
for (usz i = 0; i < m_devices.size(); i++)
{
if (!m_devices[i]->get_state().connected)
{
@ -471,6 +446,6 @@ void wiimote_handler::thread_proc()
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
thread_ctrl::wait_for(10'000);
}
}

View file

@ -100,7 +100,7 @@ public:
void stop();
std::vector<wiimote_state> get_states();
size_t get_device_count();
usz get_device_count();
void set_mapping(const wiimote_guncon_mapping& mapping);
wiimote_guncon_mapping get_mapping() const;

View file

@ -88,6 +88,7 @@
<ClCompile Include="Emu\Io\GameTablet.cpp" />
<ClCompile Include="Emu\Io\GHLtar.cpp" />
<ClCompile Include="Emu\Io\GunCon3.cpp" />
<ClCompile Include="Emu\Io\wiimote_config.cpp" />
<ClCompile Include="Emu\Io\midi_config_types.cpp" />
<ClCompile Include="Emu\Io\MouseHandler.cpp" />
<ClCompile Include="Emu\Io\pad_types.cpp" />
@ -602,6 +603,7 @@
<ClInclude Include="Emu\Io\GHLtar.h" />
<ClInclude Include="Emu\Io\ghltar_config.h" />
<ClInclude Include="Emu\Io\guncon3_config.h" />
<ClInclude Include="Emu\Io\wiimote_config.h" />
<ClInclude Include="Emu\Io\GunCon3.h" />
<ClInclude Include="Emu\Io\interception.h" />
<ClInclude Include="Emu\Io\Keyboard.h" />

View file

@ -957,6 +957,9 @@
<ClCompile Include="Emu\Io\GunCon3.cpp">
<Filter>Emu\Io</Filter>
</ClCompile>
<ClCompile Include="Emu\Io\wiimote_config.cpp">
<Filter>Emu\Io</Filter>
</ClCompile>
<ClCompile Include="Emu\Io\Buzz.cpp">
<Filter>Emu\Io</Filter>
</ClCompile>
@ -2590,6 +2593,9 @@
<ClInclude Include="Emu\Io\guncon3_config.h">
<Filter>Emu\Io</Filter>
</ClInclude>
<ClInclude Include="Emu\Io\wiimote_config.h">
<Filter>Emu\Io</Filter>
</ClInclude>
<ClInclude Include="Emu\Io\topshotelite_config.h">
<Filter>Emu\Io</Filter>
</ClInclude>

View file

@ -1,6 +1,5 @@
#include "stdafx.h"
#include "wiimote_settings_dialog.h"
#include "Emu/System.h"
#include "Input/wiimote_handler.h"
#include <QTimer>
#include <QPainter>
@ -66,7 +65,7 @@ void wiimote_settings_dialog::populate_mappings()
}
// Set current selection
int index = boxes[i]->findData(QVariant::fromValue(static_cast<u16>(*targets[i])));
const int index = boxes[i]->findData(QVariant::fromValue(static_cast<u16>(*targets[i])));
if (index >= 0) boxes[i]->setCurrentIndex(index);
// Connect change signal
@ -162,8 +161,8 @@ void wiimote_settings_dialog::update_state()
return;
}
auto states = wm->get_states();
if (static_cast<size_t>(index) >= states.size())
const auto states = wm->get_states();
if (static_cast<usz>(index) >= states.size())
{
ui->connectionStatus->setText(tr("N/A"));
ui->buttonState->setText(tr("N/A"));
@ -215,8 +214,8 @@ void wiimote_settings_dialog::update_state()
// Map 0..1023 X and 0..767 Y to pixmap coordinates
// Wiimote X/Y are inverted relative to pointing direction
float x = ((1023 - state.ir[i].x) / 1023.0f) * pixmap.width();
float y = (state.ir[i].y / 767.0f) * pixmap.height();
const float x = ((1023 - state.ir[i].x) / 1023.0f) * pixmap.width();
const float y = (state.ir[i].y / 767.0f) * pixmap.height();
painter.setPen(colors[i]);
painter.setBrush(colors[i]);
@ -241,15 +240,15 @@ void wiimote_settings_dialog::update_list()
return;
}
auto states = wm->get_states();
const auto states = wm->get_states();
// Only update if the list content actually changed (avoid flicker)
if (static_cast<size_t>(ui->wiimoteList->count()) != states.size())
if (static_cast<usz>(ui->wiimoteList->count()) != states.size())
{
int current_row = ui->wiimoteList->currentRow();
const int current_row = ui->wiimoteList->currentRow();
ui->wiimoteList->clear();
for (size_t i = 0; i < states.size(); i++)
for (usz i = 0; i < states.size(); i++)
{
QString label = tr("Wiimote #%1").arg(i + 1);
if (!states[i].connected) label += " (" + tr("Disconnected") + ")";
@ -268,7 +267,7 @@ void wiimote_settings_dialog::update_list()
else
{
// Just update connection status labels without clearing
for (size_t i = 0; i < states.size(); i++)
for (usz i = 0; i < states.size(); i++)
{
QString label = tr("Wiimote #%1").arg(i + 1);
if (!states[i].connected) label += " (" + tr("Disconnected") + ")";