Skip to content

Commit 17b72ae

Browse files
Wiimote to GunCon3 PR review updates
1 parent e20e74e commit 17b72ae

File tree

6 files changed

+148
-153
lines changed

6 files changed

+148
-153
lines changed

rpcs3/Emu/Io/GunCon3.cpp

Lines changed: 64 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -229,88 +229,83 @@ void usb_device_guncon3::interrupt_transfer(u32 buf_size, u8* buf, u32 endpoint,
229229
GunCon3_data gc{};
230230
gc.stick_ax = gc.stick_ay = gc.stick_bx = gc.stick_by = 0x7f;
231231

232-
if (auto* wm = WiimoteManager::get_instance())
233-
{
234-
auto states = wm->get_states();
232+
auto* wm = wiimote_manager::get_instance()
233+
auto states = wm->get_states();
235234

236-
// Determine which Wiimote to use based on our ordinal position among all GunCons
237-
int my_wiimote_index = -1;
235+
// Determine which Wiimote to use based on our ordinal position among all GunCons
236+
int my_wiimote_index = -1;
237+
{
238+
std::lock_guard lock(s_instances_mutex);
239+
// Since we sort by pointer adress/controller_index in add, and search by this ptr
240+
// Actually lower_bound needs a value. std::find is safer for pointer identity.
241+
auto found = std::find(s_instances.begin(), s_instances.end(), this);
242+
if (found != s_instances.end())
238243
{
239-
std::lock_guard lock(s_instances_mutex);
240-
auto it = std::lower_bound(s_instances.begin(), s_instances.end(), this, [](auto* a, auto* b) {
241-
return a->m_controller_index < b->m_controller_index;
242-
});
243-
// Since we sort by pointer adress/controller_index in add, and search by this ptr
244-
// Actually lower_bound needs a value. std::find is safer for pointer identity.
245-
auto found = std::find(s_instances.begin(), s_instances.end(), this);
246-
if (found != s_instances.end())
247-
{
248-
my_wiimote_index = std::distance(s_instances.begin(), found);
249-
}
244+
my_wiimote_index = std::distance(s_instances.begin(), found);
250245
}
246+
}
251247

252-
if (my_wiimote_index >= 0 && static_cast<size_t>(my_wiimote_index) < states.size())
253-
{
254-
const auto& ws = states[my_wiimote_index];
255-
const auto map = wm->get_mapping();
248+
if (my_wiimote_index >= 0 && static_cast<size_t>(my_wiimote_index) < states.size())
249+
{
250+
const auto& ws = states[my_wiimote_index];
251+
const auto map = wm->get_mapping();
256252

257-
auto is_pressed = [&](WiimoteButton btn) { return (ws.buttons & static_cast<u16>(btn)) != 0; };
253+
auto is_pressed = [&](wiimote_button btn) { return (ws.buttons & static_cast<u16>(btn)) != 0; };
258254

259-
if (is_pressed(map.trigger)) gc.btn_trigger = 1;
255+
if (is_pressed(map.trigger)) gc.btn_trigger = 1;
260256

261-
// Wiimote to GunCon3 Button Mapping
262-
if (is_pressed(map.a1)) gc.btn_a1 = 1;
263-
if (is_pressed(map.a2)) gc.btn_a2 = 1;
264-
if (is_pressed(map.a3)) gc.btn_a3 = 1;
265-
if (is_pressed(map.b1)) gc.btn_b1 = 1;
266-
if (is_pressed(map.b2)) gc.btn_b2 = 1;
267-
if (is_pressed(map.b3)) gc.btn_b3 = 1;
268-
if (is_pressed(map.c1)) gc.btn_c1 = 1;
269-
if (is_pressed(map.c2)) gc.btn_c2 = 1;
257+
// Wiimote to GunCon3 Button Mapping
258+
if (is_pressed(map.a1)) gc.btn_a1 = 1;
259+
if (is_pressed(map.a2)) gc.btn_a2 = 1;
260+
if (is_pressed(map.a3)) gc.btn_a3 = 1;
261+
if (is_pressed(map.b1)) gc.btn_b1 = 1;
262+
if (is_pressed(map.b2)) gc.btn_b2 = 1;
263+
if (is_pressed(map.b3)) gc.btn_b3 = 1;
264+
if (is_pressed(map.c1)) gc.btn_c1 = 1;
265+
if (is_pressed(map.c2)) gc.btn_c2 = 1;
270266

271-
// Secondary / Hardcoded Alts (if kept in mapping struct)
272-
if (is_pressed(map.b1_alt)) gc.btn_b1 = 1;
273-
if (is_pressed(map.b2_alt)) gc.btn_b2 = 1;
267+
// Secondary / Hardcoded Alts (if kept in mapping struct)
268+
if (is_pressed(map.b1_alt)) gc.btn_b1 = 1;
269+
if (is_pressed(map.b2_alt)) gc.btn_b2 = 1;
274270

275-
if (ws.ir[0].x < 1023)
271+
if (ws.ir[0].x < 1023)
272+
{
273+
// Only use the primary pointer to avoid jumping between multiple IR points
274+
s32 raw_x = ws.ir[0].x;
275+
s32 raw_y = ws.ir[0].y;
276+
277+
// Map to GunCon3 range (-32768..32767)
278+
// X calculation (Right = 32767, Left = -32768)
279+
s32 x_res = 32767 - (raw_x * 65535 / 1023);
280+
// Y calculation (Top = 32767, Bottom = -32768)
281+
// Swapping to inverted mapping as per user feedback
282+
s32 y_res = 32767 - (raw_y * 65535 / 767);
283+
284+
gc.gun_x = static_cast<int16_t>(std::clamp(x_res, -32768, 32767));
285+
gc.gun_y = static_cast<int16_t>(std::clamp(y_res, -32768, 32767));
286+
287+
// Draw the actual GunCon3 output to the overlay
288+
// Mapping GunCon3 range back to virtual_width/height
289+
s16 ax = static_cast<s16>((gc.gun_x + 32768) * rsx::overlays::overlay::virtual_width / 65535);
290+
s16 ay = static_cast<s16>((32767 - gc.gun_y) * rsx::overlays::overlay::virtual_height / 65535);
291+
292+
if (g_cfg.io.show_move_cursor)
276293
{
277-
// Only use the primary pointer to avoid jumping between multiple IR points
278-
s32 raw_x = ws.ir[0].x;
279-
s32 raw_y = ws.ir[0].y;
280-
281-
// Map to GunCon3 range (-32768..32767)
282-
// X calculation (Right = 32767, Left = -32768)
283-
s32 x_res = 32767 - (raw_x * 65535 / 1023);
284-
// Y calculation (Top = 32767, Bottom = -32768)
285-
// Swapping to inverted mapping as per user feedback
286-
s32 y_res = 32767 - (raw_y * 65535 / 767);
287-
288-
gc.gun_x = static_cast<int16_t>(std::clamp(x_res, -32768, 32767));
289-
gc.gun_y = static_cast<int16_t>(std::clamp(y_res, -32768, 32767));
290-
291-
// Draw the actual GunCon3 output to the overlay
292-
// Mapping GunCon3 range back to virtual_width/height
293-
s16 ax = static_cast<s16>((gc.gun_x + 32768) * rsx::overlays::overlay::virtual_width / 65535);
294-
s16 ay = static_cast<s16>((32767 - gc.gun_y) * rsx::overlays::overlay::virtual_height / 65535);
295-
296-
if (g_cfg.io.show_move_cursor)
297-
{
298-
// Use my_wiimote_index for color/cursor selection (0=Red, 1=Green...)
299-
rsx::overlays::set_cursor(rsx::overlays::cursor_offset::cell_gem + my_wiimote_index, ax, ay, { 1.0f, 1.0f, 1.0f, 1.0f }, 100'000, false);
300-
}
301-
302-
if (ws.ir[1].x < 1023)
303-
{
304-
// Calculate "Z" (distance) based on spread of first two points to emulate depth sensor
305-
s32 dx = static_cast<s32>(ws.ir[0].x) - ws.ir[1].x;
306-
s32 dy = static_cast<s32>(ws.ir[0].y) - ws.ir[1].y;
307-
gc.gun_z = static_cast<int16_t>(std::sqrt(dx * dx + dy * dy));
308-
}
294+
// Use my_wiimote_index for color/cursor selection (0=Red, 1=Green...)
295+
rsx::overlays::set_cursor(rsx::overlays::cursor_offset::cell_gem + my_wiimote_index, ax, ay, { 1.0f, 1.0f, 1.0f, 1.0f }, 100'000, false);
309296
}
310297

311-
guncon3_encode(&gc, buf, m_key.data());
312-
return;
298+
if (ws.ir[1].x < 1023)
299+
{
300+
// Calculate "Z" (distance) based on spread of first two points to emulate depth sensor
301+
s32 dx = static_cast<s32>(ws.ir[0].x) - ws.ir[1].x;
302+
s32 dy = static_cast<s32>(ws.ir[0].y) - ws.ir[1].y;
303+
gc.gun_z = static_cast<int16_t>(std::sqrt(dx * dx + dy * dy));
304+
}
313305
}
306+
307+
guncon3_encode(&gc, buf, m_key.data());
308+
return;
314309
}
315310

316311
if (!is_input_allowed())

rpcs3/Emu/Io/WiimoteManager.cpp

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ static constexpr u16 VID_MAYFLASH = 0x0079;
1616
static constexpr u16 PID_DOLPHINBAR_START = 0x1800;
1717
static constexpr u16 PID_DOLPHINBAR_END = 0x1803;
1818

19-
WiimoteDevice::WiimoteDevice(hid_device_info* info)
19+
wiimote_device::wiimote_device(hid_device_info* info)
2020
: m_path(info->path)
2121
, m_serial(info->serial_number ? info->serial_number : L"")
2222
{
@@ -45,12 +45,12 @@ WiimoteDevice::WiimoteDevice(hid_device_info* info)
4545
}
4646
}
4747

48-
WiimoteDevice::~WiimoteDevice()
48+
wiimote_device::~wiimote_device()
4949
{
5050
if (m_handle) hid_close(m_handle);
5151
}
5252

53-
bool WiimoteDevice::initialize_ir()
53+
bool wiimote_device::initialize_ir()
5454
{
5555
auto write_reg = [&](u32 addr, const std::vector<u8>& data) {
5656
u8 buf[22] = {0};
@@ -92,7 +92,7 @@ bool WiimoteDevice::initialize_ir()
9292
return true;
9393
}
9494

95-
bool WiimoteDevice::update()
95+
bool wiimote_device::update()
9696
{
9797
if (!m_handle) return false;
9898

@@ -135,24 +135,24 @@ bool WiimoteDevice::update()
135135
return true;
136136
}
137137

138-
static WiimoteManager* s_instance = nullptr;
138+
static wiimote_manager* s_instance = nullptr;
139139

140140
static std::string get_config_path()
141141
{
142142
return fs::get_config_dir(true) + "wiimote.yml";
143143
}
144144

145-
void WiimoteManager::load_config()
145+
void wiimote_manager::load_config()
146146
{
147147
fs::file f(get_config_path(), fs::read);
148148
if (!f) return;
149149

150150
std::string line;
151151
std::stringstream ss(f.to_string());
152-
WiimoteGunConMapping map;
152+
wiimote_guncon_mapping map;
153153

154-
auto parse_btn = [](const std::string& val) -> WiimoteButton {
155-
return static_cast<WiimoteButton>(std::strtoul(val.c_str(), nullptr, 0));
154+
auto parse_btn = [](const std::string& val) -> wiimote_button {
155+
return static_cast<wiimote_button>(std::strtoul(val.c_str(), nullptr, 0));
156156
};
157157

158158
while (std::getline(ss, line))
@@ -184,14 +184,14 @@ void WiimoteManager::load_config()
184184
m_mapping = map;
185185
}
186186

187-
void WiimoteManager::save_config()
187+
void wiimote_manager::save_config()
188188
{
189189
fs::file f(get_config_path(), fs::write + fs::create + fs::trunc);
190190
if (!f) return;
191191

192192
std::stringstream ss;
193193
// Helper to write lines
194-
auto write_line = [&](const char* key, WiimoteButton btn) {
194+
auto write_line = [&](const char* key, wiimote_button btn) {
195195
ss << key << ": " << static_cast<u16>(btn) << "\n";
196196
};
197197

@@ -211,59 +211,59 @@ void WiimoteManager::save_config()
211211
f.write(ss.str());
212212
}
213213

214-
WiimoteManager::WiimoteManager()
214+
wiimote_manager::wiimote_manager()
215215
{
216216
if (!s_instance)
217217
s_instance = this;
218218

219219
// Set default mapping explicitly to match user preference: C1=Plus, A3=Left
220220
// (Struct default constructor might have different values if I didn't edit header defaults)
221221
// Let's force it here before loading config.
222-
m_mapping.c1 = WiimoteButton::Plus;
223-
m_mapping.a3 = WiimoteButton::Left;
222+
m_mapping.c1 = wiimote_button::Plus;
223+
m_mapping.a3 = wiimote_button::Left;
224224
// Defaults for others from struct:
225225
// a1=A, a2=Minus, etc.
226226

227227
load_config();
228228
}
229229

230-
WiimoteManager::~WiimoteManager()
230+
wiimote_manager::~wiimote_manager()
231231
{
232232
stop();
233233
if (s_instance == this)
234234
s_instance = nullptr;
235235
}
236236

237-
WiimoteManager* WiimoteManager::get_instance()
237+
wiimote_manager* wiimote_manager::get_instance()
238238
{
239239
return s_instance;
240240
}
241241

242-
void WiimoteManager::start()
242+
void wiimote_manager::start()
243243
{
244244
if (m_running) return;
245245

246246
// Note: hid_init() is not thread-safe. ideally should be called once at app startup.
247247
if (hid_init() != 0) return;
248248

249249
m_running = true;
250-
m_thread = std::thread(&WiimoteManager::thread_proc, this);
250+
m_thread = std::thread(&wiimote_manager::thread_proc, this);
251251
}
252252

253-
void WiimoteManager::stop()
253+
void wiimote_manager::stop()
254254
{
255255
m_running = false;
256256
if (m_thread.joinable()) m_thread.join();
257257
hid_exit();
258258
}
259259

260-
size_t WiimoteManager::get_device_count()
260+
size_t wiimote_manager::get_device_count()
261261
{
262262
std::shared_lock lock(m_mutex);
263263
return m_devices.size();
264264
}
265265

266-
void WiimoteManager::set_mapping(const WiimoteGunConMapping& mapping)
266+
void wiimote_manager::set_mapping(const wiimote_guncon_mapping& mapping)
267267
{
268268
{
269269
std::unique_lock lock(m_mutex);
@@ -272,16 +272,16 @@ void WiimoteManager::set_mapping(const WiimoteGunConMapping& mapping)
272272
save_config();
273273
}
274274

275-
WiimoteGunConMapping WiimoteManager::get_mapping() const
275+
wiimote_guncon_mapping wiimote_manager::get_mapping() const
276276
{
277277
// shared_lock not strictly needed for trivial copy but good practice if it becomes complex
278278
return m_mapping;
279279
}
280280

281-
std::vector<WiimoteState> WiimoteManager::get_states()
281+
std::vector<wiimote_state> wiimote_manager::get_states()
282282
{
283283
std::shared_lock lock(m_mutex);
284-
std::vector<WiimoteState> states;
284+
std::vector<wiimote_state> states;
285285
states.reserve(m_devices.size());
286286

287287
for (const auto& dev : m_devices)
@@ -292,7 +292,7 @@ std::vector<WiimoteState> WiimoteManager::get_states()
292292
}
293293

294294

295-
void WiimoteManager::thread_proc()
295+
void wiimote_manager::thread_proc()
296296
{
297297
u32 counter = 0;
298298
while (m_running)
@@ -324,7 +324,7 @@ void WiimoteManager::thread_proc()
324324

325325
if (!already_owned)
326326
{
327-
auto dev = std::make_unique<WiimoteDevice>(cur);
327+
auto dev = std::make_unique<wiimote_device>(cur);
328328
if (dev->get_state().connected)
329329
{
330330
std::unique_lock lock(m_mutex);
@@ -351,7 +351,7 @@ void WiimoteManager::thread_proc()
351351
std::unique_lock lock(m_mutex);
352352
m_devices.erase(std::remove_if(m_devices.begin(), m_devices.end(), [](const auto& d)
353353
{
354-
return !const_cast<WiimoteDevice&>(*d).update();
354+
return !const_cast<wiimote_device&>(*d).update();
355355
}), m_devices.end());
356356
}
357357

0 commit comments

Comments
 (0)