From 1df3b9b9057254ddec24b1091cd239f4fa0214d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 27 Nov 2024 09:15:03 +0100 Subject: [PATCH 1/3] Add config save/load for imdebugger, move the imgui.ini to PSP/SYSTEM --- Core/Config.cpp | 9 ++--- UI/EmuScreen.cpp | 1 + UI/ImDebugger/ImDebugger.cpp | 66 ++++++++++++++++++++++++++++++- UI/ImDebugger/ImDebugger.h | 45 ++++++++++++--------- ext/imgui/imgui_impl_platform.cpp | 8 ++++ ext/imgui/imgui_impl_platform.h | 3 ++ gradle.properties | 1 + 7 files changed, 107 insertions(+), 26 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 3792308eec..1663b29aa4 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1677,11 +1677,10 @@ const Path Config::FindConfigFile(const std::string &baseFilename) { } // Make sure at least the directory it's supposed to be in exists. - Path path = filename.NavigateUp(); - // This check is just to avoid logging. - if (!File::Exists(path)) { - File::CreateFullPath(path); - } + Path parent = filename.NavigateUp(); + + // We try to create the path and ignore if it fails (already exists). + File::CreateFullPath(parent); return filename; } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 19183362ad..12ec9a6432 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1670,6 +1670,7 @@ void EmuScreen::renderImDebugger() { Draw::DrawContext *draw = screenManager()->getDrawContext(); if (!imguiInited_) { imguiInited_ = true; + ImGui_ImplPlatform_Init(GetSysDirectory(DIRECTORY_SYSTEM) / "imgui.ini"); imDebugger_ = std::make_unique(); // Read the TTF font diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 6742423dee..46867d2e5f 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -607,8 +607,14 @@ void DrawHLEModules(ImConfig &config) { ImDebugger::ImDebugger() { reqToken_ = g_requestManager.GenerateRequesterToken(); + cfg_.LoadConfig(ConfigPath()); } +ImDebugger::~ImDebugger() { + cfg_.SaveConfig(ConfigPath()); +} + + void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebug) { // Snapshot the coreState to avoid inconsistency. const CoreState coreState = ::coreState; @@ -921,6 +927,62 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, bool *open, CoreState c ImGui::End(); } -void ImDebugger::LoadConfig() { - IniFile ini; +Path ImDebugger::ConfigPath() { + return GetSysDirectory(DIRECTORY_SYSTEM) / "imdebugger.ini"; +} + +// TODO: Move this into the main config at some point. +// But, I don't really want Core to know about the ImDebugger.. + +void ImConfig::LoadConfig(const Path &iniFile) { + IniFile ini; + ini.Load(iniFile); // Ignore return value, might not exist yet. In that case we'll end up loading defaults. + SyncConfig(&ini, false); +} + +void ImConfig::SaveConfig(const Path &iniFile) { + IniFile ini; + ini.Load(iniFile); // ignore return value, might not exist yet + SyncConfig(&ini, true); + ini.Save(iniFile); +} + +class Syncer { +public: + explicit Syncer(bool save) : save_(save) {} + void SetSection(Section *section) { section_ = section; } + template + void Sync(std::string_view key, T *value, T defaultValue) { + if (save_) { + section_->Set(key, *value); + } else { + section_->Get(key, value, defaultValue); + } + } +private: + Section *section_ = nullptr; + bool save_; +}; + +void ImConfig::SyncConfig(IniFile *ini, bool save) { + Syncer sync(save); + sync.SetSection(ini->GetOrCreateSection("Windows")); + sync.Sync("disasmOpen", &disasmOpen, true); + sync.Sync("demoOpen ", &demoOpen, false); + sync.Sync("regsOpen", ®sOpen, true); + sync.Sync("threadsOpen", &threadsOpen, false); + sync.Sync("callstackOpen", &callstackOpen, false); + sync.Sync("breakpointsOpen", &breakpointsOpen, false); + sync.Sync("modulesOpen", &modulesOpen, false); + sync.Sync("hleModulesOpen", &hleModulesOpen, false); + sync.Sync("atracOpen", &atracOpen, false); + sync.Sync("structViewerOpen", &structViewerOpen, false); + sync.Sync("framebuffersOpen", &framebuffersOpen, false); + sync.Sync("displayOpen", &displayOpen, true); + sync.Sync("styleEditorOpen", &styleEditorOpen, false); + sync.Sync("filesystemBrowserOpen", &filesystemBrowserOpen, false); + sync.Sync("kernelObjectsOpen", &kernelObjectsOpen, false); + + sync.SetSection(ini->GetOrCreateSection("Settings")); + sync.Sync("displayLatched", &displayLatched, false); } diff --git a/UI/ImDebugger/ImDebugger.h b/UI/ImDebugger/ImDebugger.h index ee2ed91ccc..374966675b 100644 --- a/UI/ImDebugger/ImDebugger.h +++ b/UI/ImDebugger/ImDebugger.h @@ -58,21 +58,23 @@ private: }; struct ImConfig { - bool disasmOpen = true; - bool demoOpen = false; - bool regsOpen = true; - bool threadsOpen = true; - bool callstackOpen = true; - bool breakpointsOpen = false; - bool modulesOpen = true; - bool hleModulesOpen = false; - bool atracOpen = true; - bool structViewerOpen = false; - bool framebuffersOpen = false; - bool displayOpen = false; - bool styleEditorOpen = false; - bool filesystemBrowserOpen = false; - bool kernelObjectsOpen = false; + // Defaults for saved settings are set in SyncConfig. + + bool disasmOpen; + bool demoOpen; + bool regsOpen; + bool threadsOpen; + bool callstackOpen; + bool breakpointsOpen; + bool modulesOpen; + bool hleModulesOpen; + bool atracOpen; + bool structViewerOpen; + bool framebuffersOpen; + bool displayOpen; + bool styleEditorOpen; + bool filesystemBrowserOpen; + bool kernelObjectsOpen; // HLE explorer settings // bool filterByUsed = true; @@ -85,6 +87,12 @@ struct ImConfig { int selectedMemCheck = -1; bool displayLatched = false; + + // We use a separate ini file from the main PPSSPP config. + void LoadConfig(const Path &iniFile); + void SaveConfig(const Path &iniFile); + + void SyncConfig(IniFile *ini, bool save); }; enum ImUiCmd { @@ -98,13 +106,12 @@ struct ImUiCommand { class ImDebugger { public: ImDebugger(); + ~ImDebugger(); void Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebug); private: - // We use a separate ini file from the main PPSSPP config. - void LoadConfig(); - void SaveConfig(); + Path ConfigPath(); RequesterToken reqToken_; @@ -112,5 +119,5 @@ private: ImStructViewer structViewer_; // Open variables. - ImConfig cfg_; + ImConfig cfg_{}; }; diff --git a/ext/imgui/imgui_impl_platform.cpp b/ext/imgui/imgui_impl_platform.cpp index 957800d4da..f69c2c02ab 100644 --- a/ext/imgui/imgui_impl_platform.cpp +++ b/ext/imgui/imgui_impl_platform.cpp @@ -1,8 +1,10 @@ #include "ext/imgui/imgui.h" +#include "Common/File/Path.h" #include "Common/Input/KeyCodes.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/System/Display.h" #include "Common/TimeUtil.h" +#include "Common/StringUtils.h" #include "Common/Log.h" #include "imgui_impl_platform.h" @@ -73,6 +75,12 @@ void ImGui_ImplPlatform_TouchEvent(const TouchInput &touch) { } } +void ImGui_ImplPlatform_Init(const Path &configPath) { + static char path[1024]; + truncate_cpy(path, configPath.ToString()); + ImGui::GetIO().IniFilename = path; +} + void ImGui_ImplPlatform_AxisEvent(const AxisInput &axis) { // Ignore for now. } diff --git a/ext/imgui/imgui_impl_platform.h b/ext/imgui/imgui_impl_platform.h index 65a8bf2e94..73090114fd 100644 --- a/ext/imgui/imgui_impl_platform.h +++ b/ext/imgui/imgui_impl_platform.h @@ -4,8 +4,11 @@ #include "Common/Input/KeyCodes.h" #include "Common/Input/InputState.h" +class Path; + ImGuiKey KeyCodeToImGui(InputKeyCode keyCode); +void ImGui_ImplPlatform_Init(const Path &configPath); void ImGui_ImplPlatform_NewFrame(); void ImGui_ImplPlatform_KeyEvent(const KeyInput &key); diff --git a/gradle.properties b/gradle.properties index 3b9f2d19b8..bd03bfddc7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,3 +2,4 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.nonTransitiveRClass=true android.nonFinalResIds=true +android.ndk.suppressMinSdkVersionError=21 From 20542b962ebb7370667b54296554139541513f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 27 Nov 2024 09:43:26 +0100 Subject: [PATCH 2/3] ImDebugger: Add new Raw audio channels window --- UI/ImDebugger/ImDebugger.cpp | 136 ++++++++++++++++++++++++++++------- UI/ImDebugger/ImDebugger.h | 3 +- 2 files changed, 112 insertions(+), 27 deletions(-) diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 46867d2e5f..e134d5de74 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -21,6 +21,7 @@ #include "Common/System/Request.h" #include "Core/HLE/sceAtrac.h" +#include "Core/HLE/sceAudio.h" #include "Core/HLE/AtracCtx.h" // Threads window @@ -439,38 +440,112 @@ static void DrawBreakpointsView(MIPSDebugInterface *mipsDebug, ImConfig &cfg) { ImGui::End(); } -void DrawAtracView(ImConfig &cfg) { - if (!ImGui::Begin("sceAtrac contexts", &cfg.atracOpen)) { +void DrawAudioDecodersView(ImConfig &cfg) { + if (!ImGui::Begin("Audio decoding contexts", &cfg.audioDecodersOpen)) { ImGui::End(); return; } - if (ImGui::BeginTable("atracs", 5, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) { - ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("OutChans", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("CurrentSample", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("RemainingFrames", ImGuiTableColumnFlags_WidthFixed); + if (ImGui::CollapsingHeader("sceAtrac", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("atracs", 5, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) { + ImGui::TableSetupColumn("Index", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("OutChans", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("CurrentSample", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("RemainingFrames", ImGuiTableColumnFlags_WidthFixed); + + ImGui::TableHeadersRow(); + + for (int i = 0; i < PSP_NUM_ATRAC_IDS; i++) { + u32 type = 0; + const AtracBase *atracBase = __AtracGetCtx(i, &type); + if (!atracBase) { + continue; + } + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("%d", i); + ImGui::TableNextColumn(); + switch (type) { + case PSP_MODE_AT_3_PLUS: + ImGui::TextUnformatted("Atrac3+"); + break; + case PSP_MODE_AT_3: + ImGui::TextUnformatted("Atrac3"); + break; + default: + ImGui::Text("%04x", type); + break; + } + ImGui::TableNextColumn(); + ImGui::Text("%d", atracBase->GetOutputChannels()); + ImGui::TableNextColumn(); + ImGui::Text("%d", atracBase->CurrentSample()); + ImGui::TableNextColumn(); + ImGui::Text("%d", atracBase->RemainingFrames()); + // TODO: Add more. + } + + ImGui::EndTable(); + } + } + ImGui::End(); +} + +void DrawAudioChannels(ImConfig &cfg) { + if (!ImGui::Begin("Raw audio channels", &cfg.audioChannelsOpen)) { + ImGui::End(); + return; + } + + if (ImGui::BeginTable("audios", 6, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) { + ImGui::TableSetupColumn("Index", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("SampleAddr", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("SampleCount", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Volume", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Format", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Waiting Thread", ImGuiTableColumnFlags_WidthFixed); ImGui::TableHeadersRow(); - for (int i = 0; i < PSP_NUM_ATRAC_IDS; i++) { - u32 type = 0; - const AtracBase *atracBase = __AtracGetCtx(i, &type); - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - - if (!atracBase) { - ImGui::Text("-", type); + // vaudio / output2 uses channel 8. + for (int i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++) { + if (!chans[i].reserved) { continue; } - - ImGui::Text("%d", type); + ImGui::TableNextRow(); ImGui::TableNextColumn(); - ImGui::Text("%d", atracBase->GetOutputChannels()); + if (i == 8) { + ImGui::TextUnformatted("audio2"); + } else { + ImGui::Text("%d", i); + } ImGui::TableNextColumn(); - ImGui::Text("%d", atracBase->CurrentSample()); + ImGui::Text("%08x", chans[i].sampleAddress); ImGui::TableNextColumn(); - ImGui::Text("%d", atracBase->RemainingFrames()); + ImGui::Text("%08x", chans[i].sampleCount); + ImGui::TableNextColumn(); + ImGui::Text("%d | %d", chans[i].leftVolume, chans[i].rightVolume); + ImGui::TableNextColumn(); + switch (chans[i].format) { + case PSP_AUDIO_FORMAT_STEREO: + ImGui::TextUnformatted("Stereo"); + break; + case PSP_AUDIO_FORMAT_MONO: + ImGui::TextUnformatted("Mono"); + break; + default: + ImGui::TextUnformatted("UNK: %04x"); + break; + } + ImGui::TableNextColumn(); + for (auto t : chans[i].waitingThreads) { + KernelObject *thread = kernelObjects.GetFast(t.threadID); + if (thread) { + ImGui::Text("%s: %d", thread->GetName(), t.numSamples); + } + } } ImGui::EndTable(); @@ -689,20 +764,24 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu ImGui::MenuItem("Breakpoints", nullptr, &cfg_.breakpointsOpen); ImGui::EndMenu(); } - if (ImGui::BeginMenu("OS HLE")) { + if (ImGui::BeginMenu("HLE")) { ImGui::MenuItem("File System Browser", nullptr, &cfg_.filesystemBrowserOpen); ImGui::MenuItem("Kernel Objects", nullptr, &cfg_.kernelObjectsOpen); ImGui::MenuItem("Threads", nullptr, &cfg_.threadsOpen); ImGui::MenuItem("Modules",nullptr, &cfg_.modulesOpen); - ImGui::MenuItem("sceAtrac", nullptr, &cfg_.atracOpen); ImGui::EndMenu(); } - if (ImGui::BeginMenu("Ge (GPU)")) { + if (ImGui::BeginMenu("Graphics")) { ImGui::MenuItem("Display Output", nullptr, &cfg_.displayOpen); ImGui::MenuItem("Framebuffers", nullptr, &cfg_.framebuffersOpen); // More to come here... ImGui::EndMenu(); } + if (ImGui::BeginMenu("Audio")) { + ImGui::MenuItem("Raw audio channels", nullptr, &cfg_.audioChannelsOpen); + ImGui::MenuItem("Decoder contexts", nullptr, &cfg_.audioDecodersOpen); + ImGui::EndMenu(); + } if (ImGui::BeginMenu("Tools")) { ImGui::MenuItem("Struct viewer", nullptr, &cfg_.structViewerOpen); ImGui::EndMenu(); @@ -742,6 +821,10 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu DrawFilesystemBrowser(cfg_); } + if (cfg_.audioChannelsOpen) { + DrawAudioChannels(cfg_); + } + if (cfg_.kernelObjectsOpen) { DrawKernelObjects(cfg_); } @@ -758,8 +841,8 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu DrawModules(mipsDebug, cfg_); } - if (cfg_.atracOpen) { - DrawAtracView(cfg_); + if (cfg_.audioDecodersOpen) { + DrawAudioDecodersView(cfg_); } if (cfg_.hleModulesOpen) { @@ -975,13 +1058,14 @@ void ImConfig::SyncConfig(IniFile *ini, bool save) { sync.Sync("breakpointsOpen", &breakpointsOpen, false); sync.Sync("modulesOpen", &modulesOpen, false); sync.Sync("hleModulesOpen", &hleModulesOpen, false); - sync.Sync("atracOpen", &atracOpen, false); + sync.Sync("audioDecodersOpen", &audioDecodersOpen, false); sync.Sync("structViewerOpen", &structViewerOpen, false); sync.Sync("framebuffersOpen", &framebuffersOpen, false); sync.Sync("displayOpen", &displayOpen, true); sync.Sync("styleEditorOpen", &styleEditorOpen, false); sync.Sync("filesystemBrowserOpen", &filesystemBrowserOpen, false); sync.Sync("kernelObjectsOpen", &kernelObjectsOpen, false); + sync.Sync("audioChannelsOpen", &audioChannelsOpen, false); sync.SetSection(ini->GetOrCreateSection("Settings")); sync.Sync("displayLatched", &displayLatched, false); diff --git a/UI/ImDebugger/ImDebugger.h b/UI/ImDebugger/ImDebugger.h index 374966675b..387fa59e2a 100644 --- a/UI/ImDebugger/ImDebugger.h +++ b/UI/ImDebugger/ImDebugger.h @@ -68,13 +68,14 @@ struct ImConfig { bool breakpointsOpen; bool modulesOpen; bool hleModulesOpen; - bool atracOpen; + bool audioDecodersOpen; bool structViewerOpen; bool framebuffersOpen; bool displayOpen; bool styleEditorOpen; bool filesystemBrowserOpen; bool kernelObjectsOpen; + bool audioChannelsOpen; // HLE explorer settings // bool filterByUsed = true; From 2a05dce105a119f849742897a1ec5fa1f688890b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 27 Nov 2024 10:21:18 +0100 Subject: [PATCH 3/3] Show sceMp3 in audio codecs window --- Core/HLE/sceAudiocodec.cpp | 30 +++++++++++----------- Core/HLE/sceAudiocodec.h | 5 ++++ Core/HLE/sceMp3.cpp | 4 +-- Core/HLE/sceMp3.h | 6 +++++ Core/HLE/sceMpeg.cpp | 3 ++- UI/ImDebugger/ImDebugger.cpp | 49 ++++++++++++++++++++++++++++++++++++ 6 files changed, 79 insertions(+), 18 deletions(-) diff --git a/Core/HLE/sceAudiocodec.cpp b/Core/HLE/sceAudiocodec.cpp index fdcae2bb47..09b91aa73f 100644 --- a/Core/HLE/sceAudiocodec.cpp +++ b/Core/HLE/sceAudiocodec.cpp @@ -36,15 +36,15 @@ struct AudioCodecContext { u32_le inDataSizeAgain; // 10 ?? }; -// audioList is to store current playing audios. -static std::map audioList; +// g_audioDecoderContexts is to store current playing audios. +std::map g_audioDecoderContexts; static bool oldStateLoaded = false; // find the audio decoder for corresponding ctxPtr in audioList static AudioDecoder *findDecoder(u32 ctxPtr) { - auto it = audioList.find(ctxPtr); - if (it != audioList.end()) { + auto it = g_audioDecoderContexts.find(ctxPtr); + if (it != g_audioDecoderContexts.end()) { return it->second; } return NULL; @@ -52,20 +52,20 @@ static AudioDecoder *findDecoder(u32 ctxPtr) { // remove decoder from audioList static bool removeDecoder(u32 ctxPtr) { - auto it = audioList.find(ctxPtr); - if (it != audioList.end()) { + auto it = g_audioDecoderContexts.find(ctxPtr); + if (it != g_audioDecoderContexts.end()) { delete it->second; - audioList.erase(it); + g_audioDecoderContexts.erase(it); return true; } return false; } static void clearDecoders() { - for (const auto &[_, decoder] : audioList) { + for (const auto &[_, decoder] : g_audioDecoderContexts) { delete decoder; } - audioList.clear(); + g_audioDecoderContexts.clear(); } void __AudioCodecInit() { @@ -86,9 +86,9 @@ static int sceAudiocodecInit(u32 ctxPtr, int codec) { } AudioDecoder *decoder = CreateAudioDecoder(audioType); decoder->SetCtxPtr(ctxPtr); - audioList[ctxPtr] = decoder; + g_audioDecoderContexts[ctxPtr] = decoder; INFO_LOG(Log::ME, "sceAudiocodecInit(%08x, %i (%s))", ctxPtr, codec, GetCodecName(audioType)); - DEBUG_LOG(Log::ME, "Number of playing sceAudioCodec audios : %d", (int)audioList.size()); + DEBUG_LOG(Log::ME, "Number of playing sceAudioCodec audios : %d", (int)g_audioDecoderContexts.size()); return 0; } ERROR_LOG_REPORT(Log::ME, "sceAudiocodecInit(%08x, %i (%s)): Unknown audio codec %i", ctxPtr, codec, GetCodecName(audioType), codec); @@ -111,7 +111,7 @@ static int sceAudiocodecDecode(u32 ctxPtr, int codec) { // Fake it by creating the desired context. decoder = CreateAudioDecoder(audioType); decoder->SetCtxPtr(ctxPtr); - audioList[ctxPtr] = decoder; + g_audioDecoderContexts[ctxPtr] = decoder; } if (decoder != NULL) { @@ -175,7 +175,7 @@ void __sceAudiocodecDoState(PointerWrap &p){ return; } - int count = (int)audioList.size(); + int count = (int)g_audioDecoderContexts.size(); Do(p, count); if (count > 0) { @@ -200,7 +200,7 @@ void __sceAudiocodecDoState(PointerWrap &p){ for (int i = 0; i < count; i++) { auto decoder = CreateAudioDecoder((PSPAudioType)codec_[i]); decoder->SetCtxPtr(ctxPtr_[i]); - audioList[ctxPtr_[i]] = decoder; + g_audioDecoderContexts[ctxPtr_[i]] = decoder; } #ifdef __clang__ #pragma clang diagnostic pop @@ -217,7 +217,7 @@ void __sceAudiocodecDoState(PointerWrap &p){ auto codec_ = new int[count]; auto ctxPtr_ = new u32[count]; int i = 0; - for (auto iter : audioList) { + for (auto iter : g_audioDecoderContexts) { const AudioDecoder *decoder = iter.second; codec_[i] = decoder->GetAudioType(); ctxPtr_[i] = decoder->GetCtxPtr(); diff --git a/Core/HLE/sceAudiocodec.h b/Core/HLE/sceAudiocodec.h index 21d9106e82..c8965f83ee 100644 --- a/Core/HLE/sceAudiocodec.h +++ b/Core/HLE/sceAudiocodec.h @@ -17,6 +17,8 @@ #pragma once +#include + class PointerWrap; typedef struct { @@ -61,3 +63,6 @@ void __AudioCodecInit(); void __AudioCodecShutdown(); void Register_sceAudiocodec(); void __sceAudiocodecDoState(PointerWrap &p); + +class AudioDecoder; +extern std::map g_audioDecoderContexts; diff --git a/Core/HLE/sceMp3.cpp b/Core/HLE/sceMp3.cpp index 48c3ede269..37202d807b 100644 --- a/Core/HLE/sceMp3.cpp +++ b/Core/HLE/sceMp3.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -// Games known to support custom music and almost certainly use sceMp3: +// Games known to support custom music and almost certainly use sceMp3, unless they use sceAudiocodec: // // * ATV Offroad Fury: Blazin' Trails // * Beats (/PSP/MUSIC) @@ -147,7 +147,7 @@ public: }; }; -static std::map mp3Map; +std::map mp3Map; static const int mp3DecodeDelay = 2400; static bool resourceInited = false; diff --git a/Core/HLE/sceMp3.h b/Core/HLE/sceMp3.h index d1aa4fa3b5..5127b57187 100644 --- a/Core/HLE/sceMp3.h +++ b/Core/HLE/sceMp3.h @@ -17,6 +17,10 @@ #pragma once +#include + +class AuCtx; + class PointerWrap; void Register_sceMp3(); @@ -24,3 +28,5 @@ void Register_sceMp3(); void __Mp3Init(); void __Mp3Shutdown(); void __Mp3DoState(PointerWrap &p); + +extern std::map mp3Map; diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index ed8bf37833..7893c40768 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -1532,7 +1532,8 @@ void PostPutAction::run(MipsCall &call) { } if (invalid) { // Bail out early - don't accept any of the packets, even the good ones. - ERROR_LOG_REPORT(Log::ME, "sceMpegRingbufferPut(): invalid mpeg data"); + // This happens during legit playback at the Burnout Legends menu! + ERROR_LOG(Log::ME, "sceMpegRingbufferPut(): invalid mpeg data"); call.setReturnValue(ERROR_MPEG_INVALID_VALUE); if (mpegLibVersion <= 0x0103) { diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index e134d5de74..676ab23f2d 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -14,6 +14,7 @@ #include "Core/Debugger/Breakpoints.h" #include "Core/MIPS/MIPSDebugInterface.h" #include "Core/MIPS/MIPSTables.h" +#include "Core/HW/SimpleAudioDec.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/Debugger/SymbolMap.h" #include "Core/MemMap.h" @@ -22,6 +23,8 @@ #include "Core/HLE/sceAtrac.h" #include "Core/HLE/sceAudio.h" +#include "Core/HLE/sceAudiocodec.h" +#include "Core/HLE/sceMp3.h" #include "Core/HLE/AtracCtx.h" // Threads window @@ -490,6 +493,52 @@ void DrawAudioDecodersView(ImConfig &cfg) { ImGui::EndTable(); } } + + if (ImGui::CollapsingHeader("sceAudiocodec", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("codecs", 2, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) { + ImGui::TableSetupColumn("CtxAddr", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed); + + for (auto &iter : g_audioDecoderContexts) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("%08x", iter.first); + ImGui::TableNextColumn(); + switch (iter.second->GetAudioType()) { + case PSP_CODEC_AAC: ImGui::TextUnformatted("AAC"); break; + case PSP_CODEC_MP3: ImGui::TextUnformatted("MP3"); break; + case PSP_CODEC_AT3PLUS: ImGui::TextUnformatted("Atrac3+"); break; + case PSP_CODEC_AT3: ImGui::TextUnformatted("Atrac3"); break; + default: ImGui::Text("%08x", iter.second->GetAudioType()); break; + } + } + ImGui::EndTable(); + } + } + + if (ImGui::CollapsingHeader("sceMp3", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::BeginTable("mp3", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) { + ImGui::TableSetupColumn("Handle", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Channels", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("StartPos", ImGuiTableColumnFlags_WidthFixed); + // TODO: more.. + + for (auto &iter : mp3Map) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("%d", iter.first); + if (!iter.second) { + continue; + } + ImGui::TableNextColumn(); + ImGui::Text("%d", iter.second->Channels); + ImGui::TableNextColumn(); + ImGui::Text("%d", iter.second->startPos); + } + ImGui::EndTable(); + } + } + ImGui::End(); }