From b117a6d4cdae0c6f395eaa64671cc49ca2ea4204 Mon Sep 17 00:00:00 2001 From: brian218 Date: Mon, 10 Oct 2022 00:10:41 +0800 Subject: [PATCH] Improved the compatibility of USIO for old versions of games --- rpcs3/Emu/Io/usio.cpp | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/rpcs3/Emu/Io/usio.cpp b/rpcs3/Emu/Io/usio.cpp index b8c77cdbc9..5dfa082d09 100644 --- a/rpcs3/Emu/Io/usio.cpp +++ b/rpcs3/Emu/Io/usio.cpp @@ -221,10 +221,10 @@ void usb_device_usio::translate_input() void usb_device_usio::usio_write(u8 channel, u16 reg, const std::vector& data) { - auto write_memory = [&](std::vector& memory) + auto write_memory = [&](std::vector& memory, bool exact_size = true) { - ensure(data.size() == memory.size()); - memcpy(memory.data(), data.data(), memory.size()); + ensure(data.size() == memory.size() || (data.size() <= memory.size() && !exact_size)); + memcpy(memory.data(), data.data(), data.size()); }; const auto get_u16 = [&](std::string_view usio_func) -> u16 @@ -289,7 +289,7 @@ void usb_device_usio::usio_write(u8 channel, u16 reg, const std::vector& dat { case 0x0000: { - write_memory(g_fxo->get().backup_memory); + write_memory(g_fxo->get().backup_memory, false); break; } case 0x0180: @@ -324,6 +324,20 @@ void usb_device_usio::usio_read(u8 channel, u16 reg, u16 size) } }; + auto push_vector = [&](std::vector& memory) + { + std::vector buffer; + u16 left = size; + while (left > 0) + { + u16 to_push = std::min(left, static_cast(64)); + buffer.resize(to_push); + memcpy(buffer.data(), memory.data() + (size - left), buffer.size()); + q_replies.push(buffer); + left -= to_push; + } + }; + if (channel == 0) { switch (reg) @@ -389,20 +403,14 @@ void usb_device_usio::usio_read(u8 channel, u16 reg, u16 size) { case 0x0000: { - ensure(size == 0xB8); - std::vector buffer[3]; - for (int i = 0; i < 3; i++) - { - buffer[i].resize(i < 2 ? 64 : 56); - memcpy(buffer[i].data(), g_fxo->get().backup_memory.data() + i * 64, buffer[i].size()); - q_replies.push(buffer[i]); - } + ensure(size <= 0xB8); + push_vector(g_fxo->get().backup_memory); break; } case 0x0180: { ensure(size == 0x28); - q_replies.push(g_fxo->get().last_game_status); + push_vector(g_fxo->get().last_game_status); break; } case 0x0200: