diff --git a/Core/Core.cpp b/Core/Core.cpp index d220dfff5d67..e7a256b28104 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -158,21 +158,25 @@ void Core_Stop() { } void Core_UpdateState(CoreState newState) { - if ((coreState == CORE_RUNNING_CPU || coreState == CORE_NEXTFRAME) && newState != CORE_RUNNING_CPU) + const CoreState state = coreState; + if ((state == CORE_RUNNING_CPU || state == CORE_NEXTFRAME) && newState != CORE_RUNNING_CPU) coreStatePending = true; coreState = newState; } bool Core_IsStepping() { - return coreState == CORE_STEPPING_CPU || coreState == CORE_POWERDOWN; + const CoreState state = coreState; + return state == CORE_STEPPING_CPU || state == CORE_STEPPING_GE || state == CORE_POWERDOWN; } bool Core_IsActive() { - return coreState == CORE_RUNNING_CPU || coreState == CORE_NEXTFRAME || coreStatePending; + const CoreState state = coreState; + return state == CORE_RUNNING_CPU || state == CORE_NEXTFRAME || coreStatePending; } bool Core_IsInactive() { - return coreState != CORE_RUNNING_CPU && coreState != CORE_NEXTFRAME && !coreStatePending; + const CoreState state = coreState; + return state != CORE_RUNNING_CPU && state != CORE_NEXTFRAME && !coreStatePending; } void Core_StateProcessed() { @@ -422,7 +426,12 @@ static bool Core_ProcessStepping(MIPSDebugInterface *cpu) { void Core_Break(BreakReason reason, u32 relatedAddress) { const CoreState state = coreState; if (state != CORE_RUNNING_CPU) { - ERROR_LOG(Log::CPU, "Core_Break(%s) only works in the CORE_RUNNING_CPU state (was in state %s)", BreakReasonToString(reason), CoreStateToString(state)); + if (state == CORE_STEPPING_CPU) { + // Already stepping. + INFO_LOG(Log::CPU, "Core_Break(%s), already in break mode", BreakReasonToString(reason)); + return; + } + WARN_LOG(Log::CPU, "Core_Break(%s) only works in the CORE_RUNNING_CPU state (was in state %s)", BreakReasonToString(reason), CoreStateToString(state)); return; } diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index b56aaed0e02f..50ac2737a53a 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -1283,9 +1283,11 @@ static int Hook_omertachinmokunookitethelegacy_download_frame() { // Function at 0886665C in US version (Persona 1) // Function at 08807DC4 in EU version (Persona 2) static int Hook_persona_download_frame() { - const u32 fb_address = 0x04088000; // hardcoded at 088666D8 - // const u32 dest_address = currentMIPS->r[MIPS_REG_A1]; // not relevant - if (Memory::IsVRAMAddress(fb_address)) { + // Depending on a global (curframe kind of thing), this either reads from + // 0x04088000 or 0x04000000 (the two addresses are hardcoded). + // We'd have to do some gnarly stuff to get this address, so let's just download both. + for (int i = 0; i < 2; i++) { + const u32 fb_address = i == 0 ? 0x04000000 : 0x04088000; gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "persona1_download_frame"); } diff --git a/Core/HW/SasReverb.cpp b/Core/HW/SasReverb.cpp index 090cb5667bc1..2b7199dca277 100644 --- a/Core/HW/SasReverb.cpp +++ b/Core/HW/SasReverb.cpp @@ -225,7 +225,7 @@ void SasReverb::ProcessReverb(int16_t *output, const int16_t *input, size_t inpu // Standard volume is 10, which pairs with a normal shift of 15. if (reverbVolumeMultiplier <= 0.0f) { // Force to zero output, which is not the same as "Off." - memset(output, 0, inputSize * 4); + memset(output, 0, inputSize * 4 * sizeof(int16_t)); return; } else { volLeft *= reverbVolumeMultiplier; diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index b3906beb9c95..31bd2029ad85 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -120,10 +120,11 @@ void JitBlockCache::Shutdown() { // This clears the JIT cache. It's called from JitCache.cpp when the JIT cache // is full and when saving and loading states. void JitBlockCache::Clear() { + for (int i = 0; i < num_blocks_; i++) { + DestroyBlock(i, DestroyType::CLEAR); + } block_map_.clear(); proxyBlockMap_.clear(); - for (int i = 0; i < num_blocks_; i++) - DestroyBlock(i, DestroyType::CLEAR); links_to_.clear(); num_blocks_ = 0; diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index fd81dec00897..47c6f202a34b 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -9,8 +9,10 @@ #include "Common/Data/Format/IniFile.h" #include "Common/Data/Text/Parsers.h" #include "Common/Log/LogManager.h" +#include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/System.h" +#include "Core/SaveState.h" #include "Core/Debugger/MemBlockInfo.h" #include "Core/RetroAchievements.h" #include "Core/Core.h" @@ -45,6 +47,7 @@ #include "Core/HLE/sceSas.h" #include "Core/HW/SasAudio.h" #include "Core/HW/Display.h" +#include "Core/Dialog/PSPSaveDialog.h" #include "Core/CoreTiming.h" // Threads window @@ -703,6 +706,11 @@ static void DrawInternals(ImConfig &cfg) { ImGui::Text("WantTextInput: %s", BoolStr(io.WantTextInput)); } + if (ImGui::CollapsingHeader("Save detection")) { + ImGui::Text("Last in-game save/load: %0.1f seconds ago", SecondsSinceLastGameSave()); + ImGui::Text("Last save/load state: %0.1f seconds ago", SaveState::SecondsSinceLastSavestate()); + } + ImGui::End(); } diff --git a/UI/ImDebugger/ImDisasmView.cpp b/UI/ImDebugger/ImDisasmView.cpp index e7d743885645..239e67a9bf25 100644 --- a/UI/ImDebugger/ImDisasmView.cpp +++ b/UI/ImDebugger/ImDisasmView.cpp @@ -1205,7 +1205,7 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, ImConfig &cfg, ImContro ImGui::Text("Step: "); ImGui::SameLine(); - if (ImGui::SmallButton("Into")) { + if (ImGui::RepeatButtonShift("Into")) { u32 stepSize = disasmView_.getInstructionSizeAt(mipsDebug->GetPC()); Core_RequestCPUStep(CPUStepType::Into, stepSize); } @@ -1239,12 +1239,6 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, ImConfig &cfg, ImContro Core_Resume(); } - ImGui::SameLine(); - if (ImGui::RepeatButton("Skim")) { - u32 stepSize = disasmView_.getInstructionSizeAt(mipsDebug->GetPC()); - Core_RequestCPUStep(CPUStepType::Into, stepSize); - } - ImGui::EndDisabled(); ImGui::SameLine(); diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index ea8039c06ad0..00901a3ba8d3 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -287,7 +287,7 @@ void MainThreadFunc() { while (GetUIState() != UISTATE_EXIT) { // && GetUIState() != UISTATE_EXCEPTION // We're here again, so the game quit. Restart Run() which controls the UI. // This way they can load a new game. - if (!Core_IsActive()) + if (!(Core_IsActive() || Core_IsStepping())) UpdateUIState(UISTATE_MENU); Core_StateProcessed(); NativeFrame(graphicsContext);