diff --git a/Utilities/bin_patch.cpp b/Utilities/bin_patch.cpp index 1a10a2b517..ba25cf5368 100644 --- a/Utilities/bin_patch.cpp +++ b/Utilities/bin_patch.cpp @@ -1046,7 +1046,7 @@ static usz apply_modification(std::basic_string& applied, patch_engine::pat auto ptr = mem_translate(offset, memory_size); - if (!ptr && memory_size != 0) + if (!ptr && memory_size != 0 && !relocate_instructions_at) { // Memory translation failed continue; @@ -1076,7 +1076,7 @@ static usz apply_modification(std::basic_string& applied, patch_engine::pat } case patch_type::code_alloc: { - const u32 out_branch = vm::try_get_addr(mem_translate(offset & -4, 4)).first; + const u32 out_branch = vm::try_get_addr(relocate_instructions_at ? vm::get_super_ptr(offset & -4) : mem_translate(offset & -4, 4)).first; // Allow only if points to a PPU executable instruction if (out_branch < 0x10000 || out_branch >= 0x4000'0000 || !vm::check_addr<4>(out_branch, vm::page_executable)) @@ -1160,7 +1160,7 @@ static usz apply_modification(std::basic_string& applied, patch_engine::pat case patch_type::jump: case patch_type::jump_link: { - const u32 out_branch = vm::try_get_addr(mem_translate(offset & -4, 4)).first; + const u32 out_branch = vm::try_get_addr(relocate_instructions_at ? vm::get_super_ptr(offset & -4) : mem_translate(offset & -4, 4)).first; const u32 dest = static_cast(p.value.long_value); // Allow only if points to a PPU executable instruction @@ -1176,7 +1176,7 @@ static usz apply_modification(std::basic_string& applied, patch_engine::pat { const std::string& str = p.original_value; - const u32 out_branch = vm::try_get_addr(mem_translate(offset & -4, 4)).first; + const u32 out_branch = vm::try_get_addr(relocate_instructions_at ? vm::get_super_ptr(offset & -4) : mem_translate(offset & -4, 4)).first; const usz sep_pos = str.find_first_of(':'); // Must contain only a single ':' or none diff --git a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp index f8f02ed820..474696f000 100644 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp @@ -864,7 +864,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v if (listSet->fixedListNum > CELL_SAVEDATA_LISTITEM_MAX) { // ****** sysutil savedata parameter error : 38 ****** - return {CELL_SAVEDATA_ERROR_PARAM, "38"}; + return {CELL_SAVEDATA_ERROR_PARAM, "38 (fixedListNum=%d)", listSet->fixedListNum}; } if (listSet->fixedListNum && !listSet->fixedList) @@ -921,7 +921,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v default: { // ****** sysutil savedata parameter error : 43 ****** - return {CELL_SAVEDATA_ERROR_PARAM, "43"}; + return {CELL_SAVEDATA_ERROR_PARAM, "43 (iconPosition=0x%x)", listSet->newData->iconPosition}; } } @@ -1316,7 +1316,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v default : // ****** sysutil savedata parameter error : 81 ****** - return {CELL_SAVEDATA_ERROR_PARAM, "81"}; + return {CELL_SAVEDATA_ERROR_PARAM, "81 (option=0x%x)", fixedSet->option}; } if (selected == -1) @@ -1542,7 +1542,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v if (statSet->setParam->attribute > CELL_SAVEDATA_ATTR_NODUPLICATE) { // ****** sysutil savedata parameter error : 57 ****** - return {CELL_SAVEDATA_ERROR_PARAM, "57"}; + return {CELL_SAVEDATA_ERROR_PARAM, "57 (attribute=0x%x)", statSet->setParam->attribute}; } if (g_ps3_process_info.sdk_ver > 0x36FFFF) @@ -1551,7 +1551,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v if (statSet->setParam->parental_level) { // ****** sysutil savedata parameter error : 58 ****** - return {CELL_SAVEDATA_ERROR_PARAM, "58"}; + return {CELL_SAVEDATA_ERROR_PARAM, "58 (sdk_ver=0x%x, parental_level=%d)", g_ps3_process_info.sdk_ver, statSet->setParam->parental_level}; } } else @@ -1559,7 +1559,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v if (statSet->setParam->parental_level > 11) { // ****** sysutil savedata parameter error : 58 ****** - return {CELL_SAVEDATA_ERROR_PARAM, "58"}; + return {CELL_SAVEDATA_ERROR_PARAM, "58 (sdk_ver=0x%x, parental_level=%d)", g_ps3_process_info.sdk_ver, statSet->setParam->parental_level}; } } @@ -2045,7 +2045,7 @@ static NEVER_INLINE error_code savedata_get_list_item(vm::cptr dirName, vm else if (userId > CELL_USERINFO_USER_MAX) { // ****** sysutil savedata parameter error : 137 ****** - return {CELL_SAVEDATA_ERROR_PARAM, "137"}; + return {CELL_SAVEDATA_ERROR_PARAM, "137 (userId=0x%x)", userId}; } if (!dirName) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index b7e5fa0dde..c50e8c1b1a 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -1084,7 +1084,7 @@ void ppu_remove_hle_instructions(u32 addr, u32 size) } } -atomic_t g_debugger_pause_all_threads_on_bp = true; +atomic_t g_debugger_pause_all_threads_on_bp = false; // Breakpoint entry point static void ppu_break(ppu_thread& ppu, ppu_opcode_t, be_t* this_op, ppu_intrp_func* next_fn) @@ -3741,7 +3741,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only) { if (g_cfg.core.ppu_decoder != ppu_decoder_type::llvm) { - if (check_only) + if (check_only || vm::base(info.segs[0].addr) != info.segs[0].ptr) { return false; } @@ -3761,7 +3761,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only) if (g_cfg.core.ppu_debug && func.size && func.toc != umax) { - ppu_toc.emplace(func.addr, func.toc); + ppu_toc[func.addr] = func.toc; ppu_ref(func.addr) = &ppu_check_toc; } } @@ -4316,7 +4316,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only) ppu_register_function_at(func.addr, 4, addr); if (g_cfg.core.ppu_debug) - ppu_log.notice("Installing function %s at 0x%x: %p (reloc = 0x%x)", name, func.addr, ppu_ref(func.addr), reloc); + ppu_log.trace("Installing function %s at 0x%x: %p (reloc = 0x%x)", name, func.addr, ppu_ref(func.addr), reloc); } jit_mod.init = true; @@ -4335,7 +4335,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only) ppu_register_function_at(func.addr, 4, addr); if (g_cfg.core.ppu_debug) - ppu_log.notice("Reinstalling function at 0x%x: %p (reloc=0x%x)", func.addr, ppu_ref(func.addr), reloc); + ppu_log.trace("Reinstalling function at 0x%x: %p (reloc=0x%x)", func.addr, ppu_ref(func.addr), reloc); } index = 0; diff --git a/rpcs3/Emu/Io/usio.cpp b/rpcs3/Emu/Io/usio.cpp index 287ad3b718..0da11170fc 100644 --- a/rpcs3/Emu/Io/usio.cpp +++ b/rpcs3/Emu/Io/usio.cpp @@ -277,6 +277,7 @@ void usb_device_usio::translate_input_tekken() std::vector input_buf(256); le_t digital_input = 0; + le_t digital_input_lm = 0; auto translate_from_pad = [&](usz pad_number, usz player) { @@ -301,14 +302,14 @@ void usb_device_usio::translate_input_tekken() case usio_btn::test: if (player != 0) break; - if (pressed && !test_key_pressed) // Solve the need to hold the Test key + if (pressed && !test_key_pressed) // Solve the need to hold the Test button test_on = !test_on; test_key_pressed = pressed; break; case usio_btn::coin: if (player != 0) break; - if (pressed && !coin_key_pressed) // Ensure only one coin is inserted each time the Coin key is pressed + if (pressed && !coin_key_pressed) // Ensure only one coin is inserted each time the Coin button is pressed coin_counter++; coin_key_pressed = pressed; break; @@ -318,27 +319,51 @@ void usb_device_usio::translate_input_tekken() break; case usio_btn::enter: if (pressed) + { digital_input |= 0x800000ULL << shift; + if (player == 0) + digital_input_lm |= 0x800; + } break; case usio_btn::up: if (pressed) + { digital_input |= 0x200000ULL << shift; + if (player == 0) + digital_input_lm |= 0x200; + } break; case usio_btn::down: if ( pressed) + { digital_input |= 0x100000ULL << shift; + if (player == 0) + digital_input_lm |= 0x400; + } break; case usio_btn::left: if (pressed) + { digital_input |= 0x80000ULL << shift; + if (player == 0) + digital_input_lm |= 0x2000; + } break; case usio_btn::right: if (pressed) + { digital_input |= 0x40000ULL << shift; + if (player == 0) + digital_input_lm |= 0x4000; + } break; case usio_btn::tekken_button1: if (pressed) + { digital_input |= 0x20000ULL << shift; + if (player == 0) + digital_input_lm |= 0x100; + } break; case usio_btn::tekken_button2: if (pressed) @@ -365,9 +390,15 @@ void usb_device_usio::translate_input_tekken() for (usz i = 0; i < g_cfg_usio.players.size(); i++) translate_from_pad(i, i); - digital_input |= test_on ? 0x80 : 0x00; + if (test_on) + { + digital_input |= 0x80; + digital_input_lm |= 0x1000; + } + std::memcpy(input_buf.data() + 128, &digital_input, sizeof(u64)); std::memcpy(input_buf.data() + 128 + 16, &coin_counter, sizeof(u16)); + std::memcpy(input_buf.data(), &digital_input_lm, sizeof(u16)); input_buf[2] = 0b00010000; // DIP Switches, 8 in total @@ -486,18 +517,13 @@ void usb_device_usio::usio_read(u8 channel, u16 reg, u16 size) break; } case 0x1800: - { - // Firmware - // "NBGI.;USIO01;Ver1.00;JPN,Multipurpose with PPG." - response = {0x4E, 0x42, 0x47, 0x49, 0x2E, 0x3B, 0x55, 0x53, 0x49, 0x4F, 0x30, 0x31, 0x3B, 0x56, 0x65, 0x72, 0x31, 0x2E, 0x30, 0x30, 0x3B, 0x4A, 0x50, 0x4E, 0x2C, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x75, 0x72, 0x70, 0x6F, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x50, 0x50, 0x47, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x42, 0x47, 0x49, 0x2E, 0x3B, 0x55, 0x53, 0x49, 0x4F, 0x30, 0x31, 0x3B, 0x56, 0x65, 0x72, 0x31, 0x2E, 0x30, 0x30, 0x3B, 0x4A, 0x50, 0x4E, 0x2C, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x75, 0x72, 0x70, 0x6F, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x50, 0x50, 0x47, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x13, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x75, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - break; - } case 0x1880: { // Seems to contain a few extra bytes of info in addition to the firmware string // Firmware // "NBGI.;USIO01;Ver1.00;JPN,Multipurpose with PPG." - response = {0x4E, 0x42, 0x47, 0x49, 0x2E, 0x3B, 0x55, 0x53, 0x49, 0x4F, 0x30, 0x31, 0x3B, 0x56, 0x65, 0x72, 0x31, 0x2E, 0x30, 0x30, 0x3B, 0x4A, 0x50, 0x4E, 0x2C, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x75, 0x72, 0x70, 0x6F, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x50, 0x50, 0x47, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x13, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x75, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + constexpr std::array info {0x4E, 0x42, 0x47, 0x49, 0x2E, 0x3B, 0x55, 0x53, 0x49, 0x4F, 0x30, 0x31, 0x3B, 0x56, 0x65, 0x72, 0x31, 0x2E, 0x30, 0x30, 0x3B, 0x4A, 0x50, 0x4E, 0x2C, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x75, 0x72, 0x70, 0x6F, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x50, 0x50, 0x47, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x42, 0x47, 0x49, 0x2E, 0x3B, 0x55, 0x53, 0x49, 0x4F, 0x30, 0x31, 0x3B, 0x56, 0x65, 0x72, 0x31, 0x2E, 0x30, 0x30, 0x3B, 0x4A, 0x50, 0x4E, 0x2C, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x75, 0x72, 0x70, 0x6F, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x50, 0x50, 0x47, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x13, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x75, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + response = {info.begin() + (reg - 0x1800), info.end()}; break; } default: diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index c005e67371..1ff8e22e1b 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -2977,23 +2977,36 @@ void Emulator::Kill(bool allow_autoexit, bool savestate) game_boot_result Emulator::Restart(bool graceful) { + if (m_state == system_state::stopping) + { + // Emulation stop is in progress + return game_boot_result::still_running; + } + + Emu.after_kill_callback = [this] + { + // Reload with prior configs. + if (const auto error = Load(m_title_id); error != game_boot_result::no_errors) + { + sys_log.error("Restart failed: %s", error); + } + }; + if (!IsStopped()) { - auto save_args = std::make_tuple(argv, envp, data, disc, klic, hdd1, m_config_mode, m_config_mode); + auto save_args = std::make_tuple(argv, envp, data, disc, klic, hdd1, m_config_mode, m_config_path); if (graceful) GracefulShutdown(false, false); else Kill(false); - std::tie(argv, envp, data, disc, klic, hdd1, m_config_mode, m_config_mode) = std::move(save_args); + std::tie(argv, envp, data, disc, klic, hdd1, m_config_mode, m_config_path) = std::move(save_args); } - - // Reload with prior configs. - if (const auto error = Load(m_title_id); error != game_boot_result::no_errors) + else { - sys_log.error("Restart failed: %s", error); - return error; + // Execute and empty the callback + ::as_rvalue(std::move(Emu.after_kill_callback))(); } return game_boot_result::no_errors;