From 17d7dcdd6c04438f1dd1276ddb73bbf3f4f04132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Mar 2025 17:40:24 +0100 Subject: [PATCH 1/4] Make sceUtilityLoadAvModule work correctly --- Core/HLE/sceAtrac.cpp | 13 +++++- Core/HLE/sceAtrac.h | 4 +- Core/HLE/sceKernelModule.cpp | 13 +++--- Core/HLE/sceUtility.cpp | 80 +++++++++++++++++++++++------------- 4 files changed, 73 insertions(+), 37 deletions(-) diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index c3b0a3c5dd..e488cb360c 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -95,7 +95,11 @@ const AtracBase *__AtracGetCtx(int i, u32 *type) { void __AtracInit() { _assert_(sizeof(SceAtracContext) == 256); - atracInited = true; + atracLibVersion = 0; + atracLibCrc = 0; + + atracInited = true; // TODO: This should probably only happen in __AtracNotifyLoadModule. + memset(atracContexts, 0, sizeof(atracContexts)); // Start with 2 of each in this order. @@ -114,13 +118,18 @@ void __AtracShutdown() { } } -void __AtracLoadModule(int version, u32 crc, u32 bssAddr, int bssSize) { +void __AtracNotifyLoadModule(int version, u32 crc, u32 bssAddr, int bssSize) { atracLibVersion = version; atracLibCrc = crc; INFO_LOG(Log::ME, "Atrac module loaded: atracLibVersion 0x%0x, atracLibcrc %x, bss: %x (%x bytes)", atracLibVersion, atracLibCrc, bssAddr, bssSize); // Later, save bssAddr/bssSize and use them to return context addresses. } +void __AtracNotifyUnloadModule() { + atracLibVersion = 0; + atracLibCrc = 0; +} + void __AtracDoState(PointerWrap &p) { auto s = p.Section("sceAtrac", 1, 2); if (!s) diff --git a/Core/HLE/sceAtrac.h b/Core/HLE/sceAtrac.h index e77bac86c7..ad776f25e3 100644 --- a/Core/HLE/sceAtrac.h +++ b/Core/HLE/sceAtrac.h @@ -25,7 +25,9 @@ void Register_sceAtrac3plus(); void __AtracInit(); void __AtracDoState(PointerWrap &p); void __AtracShutdown(); -void __AtracLoadModule(int version, u32 crc, u32 bssAddr, int bssSize); + +void __AtracNotifyLoadModule(int version, u32 crc, u32 bssAddr, int bssSize); +void __AtracNotifyUnloadModule(); enum AtracStatus : u8 { ATRAC_STATUS_NO_DATA = 1, diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 511e969a71..e5ffc05b8b 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -277,8 +277,9 @@ public: const char *GetTypeName() override { return GetStaticTypeName(); } static const char *GetStaticTypeName() { return "Module"; } void GetQuickInfo(char *ptr, int size) override { - snprintf(ptr, size, "%sname=%s gp=%08x entry=%08x", + snprintf(ptr, size, "%s %d.%d name=%s gp=%08x entry=%08x", isFake ? "faked " : "", + nm.version[0], nm.version[1], nm.name, nm.gp_value, nm.entry_addr); @@ -480,7 +481,8 @@ public: void PSPModule::GetLongInfo(char *ptr, int bufSize) const { StringWriter w(ptr, bufSize); - w.F("%s: Version %d.%d. %d segments", nm.name, nm.version[0], nm.version[1], nm.nsegment).endl(); + w.F("%s: Version %d.%d. %d segments", nm.name, nm.version[1], nm.version[0], nm.nsegment).endl(); + w.F("Memory block: %08x (%08x/%d bytes)", memoryBlockAddr, memoryBlockSize, memoryBlockSize).endl(); for (int i = 0; i < nm.nsegment; i++) { w.F(" %08x (%08x bytes)\n", nm.segmentaddr[i], nm.segmentsize[i]); } @@ -1340,7 +1342,6 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load strncpy(module->nm.name, head->modname, ARRAY_SIZE(module->nm.name)); module->nm.entry_addr = -1; module->nm.gp_value = -1; - module->nm.bss_size = head->bss_size; // Let's still try to allocate it. It may use user memory. u32 totalSize = 0; @@ -1367,6 +1368,8 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load module->memoryBlockAddr = addr; module->memoryBlockSize = totalSize; module->nm.text_addr = addr; + module->nm.bss_size = head->bss_size; + module->nm.nsegment = head->nsegments; module->nm.version[0] = head->module_ver_hi; module->nm.version[1] = head->module_ver_lo; @@ -1389,7 +1392,7 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load __PsmfPlayerLoadModule(devkitVersion, module->crc); } if (!strcmp(head->modname, "sceATRAC3plus_Library")) { - __AtracLoadModule(ver, module->crc, module->GetBSSAddr(), head->bss_size); + __AtracNotifyLoadModule(ver, module->crc, module->GetBSSAddr(), head->bss_size); } return module; @@ -1775,7 +1778,7 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load __PsmfPlayerLoadModule(devkitVersion, module->crc); } if (!strcmp(modinfo->name, "sceATRAC3plus_Library")) { - __AtracLoadModule(modinfo->moduleVersion, module->crc, module->GetBSSAddr(), module->nm.bss_size); + __AtracNotifyLoadModule(modinfo->moduleVersion, module->crc, module->GetBSSAddr(), module->nm.bss_size); } } diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index f9d7334c7c..75c18d8340 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -87,7 +87,10 @@ static void NotifyLoadStatusAtrac(int state, u32 loadAddr, u32 totalSize) { constexpr int version = 0x103; constexpr int bssSize = 0x67C; _dbg_assert_(bssSize <= totalSize); - __AtracLoadModule(version, 0, loadAddr, bssSize); + __AtracNotifyLoadModule(version, 0, loadAddr, bssSize); + } else if (state == -1) { + // Unload. + __AtracNotifyUnloadModule(); } } @@ -508,6 +511,9 @@ bool __UtilityModuleGetMemoryRange(int moduleID, u32 *startPtr, u32 *sizePtr) { return true; } +static int LoadModuleInternal(u32 module); +static int UnloadModuleInternal(u32 module); + // Same as sceUtilityLoadModule, just limited in categories. // It seems this just loads module 0x300 + module & 0xFF.. static u32 sceUtilityLoadAvModule(u32 module) { @@ -516,30 +522,54 @@ static u32 sceUtilityLoadAvModule(u32 module) { return hleLogError(Log::sceUtility, SCE_ERROR_AV_MODULE_BAD_ID); } - if (module == 0) - JpegNotifyLoadStatus(1); - return hleDelayResult(hleLogInfo(Log::sceUtility, 0), "utility av module loaded", 25000); + int result = LoadModuleInternal(0x300 | module); + return hleDelayResult(hleLogDebugOrError(Log::sceUtility, result), "utility av module loaded", 25000); } static u32 sceUtilityUnloadAvModule(u32 module) { - if (module == 0) - JpegNotifyLoadStatus(-1); - return hleDelayResult(hleLogInfo(Log::sceUtility, 0), "utility av module unloaded", 800); + if (module > 7) { + ERROR_LOG_REPORT(Log::sceUtility, "sceUtilityLoadAvModule(%i): invalid module id", module); + return hleLogError(Log::sceUtility, SCE_ERROR_AV_MODULE_BAD_ID); + } + + int result = UnloadModuleInternal(0x300 | module); + return hleDelayResult(hleLogDebugOrError(Log::sceUtility, result), "utility av module unloaded", 800); } static u32 sceUtilityLoadModule(u32 module) { + int result = LoadModuleInternal(module); + // TODO: Each module has its own timing, technically, but this is a low-end. + if (module == 0x3FF) { + return hleDelayResult(hleLogDebugOrError(Log::sceUtility, result), "utility module loaded", 130); + } else { + return hleDelayResult(hleLogDebugOrError(Log::sceUtility, result), "utility module loaded", 25000); + } +} + +static u32 sceUtilityUnloadModule(u32 module) { + int result = UnloadModuleInternal(module); + // TODO: Each module has its own timing, technically, but this is a low-end. + if (module == 0x3FF) { + return hleDelayResult(hleLogDebugOrError(Log::sceUtility, result), "utility module unloaded", 110); + } else { + return hleDelayResult(hleLogDebugOrError(Log::sceUtility, result), "utility module unloaded", 400); + } +} + +static int LoadModuleInternal(u32 module) { const ModuleLoadInfo *info = __UtilityModuleInfo(module); if (!info) { - return hleReportError(Log::sceUtility, SCE_ERROR_MODULE_BAD_ID, "invalid module id"); + return SCE_ERROR_MODULE_BAD_ID; } + if (currentlyLoadedModules.find(module) != currentlyLoadedModules.end()) { - return hleLogError(Log::sceUtility, SCE_ERROR_MODULE_ALREADY_LOADED, "already loaded"); + return SCE_ERROR_MODULE_ALREADY_LOADED; } // Some games, like Kamen Rider Climax Heroes OOO, require an error if dependencies aren't loaded yet. for (const int *dep = info->dependencies; *dep != 0; ++dep) { if (currentlyLoadedModules.find(*dep) == currentlyLoadedModules.end()) { - return hleDelayResult(hleLogError(Log::sceUtility, SCE_KERNEL_ERROR_LIBRARY_NOTFOUND, "dependent module %04x not loaded", *dep), "utility module load attempt", 25000); + return SCE_KERNEL_ERROR_LIBRARY_NOTFOUND; } } @@ -554,36 +584,28 @@ static u32 sceUtilityLoadModule(u32 module) { if (info->notify) { info->notify(1, address, allocSize); } - - // TODO: Each module has its own timing, technically, but this is a low-end. - if (module == 0x3FF) - return hleDelayResult(hleLogInfo(Log::sceUtility, 0), "utility module loaded", 130); - else - return hleDelayResult(hleLogInfo(Log::sceUtility, 0), "utility module loaded", 25000); + return 0; } -static u32 sceUtilityUnloadModule(u32 module) { +static int UnloadModuleInternal(u32 module) { const ModuleLoadInfo *info = __UtilityModuleInfo(module); if (!info) { - return hleReportError(Log::sceUtility, SCE_ERROR_MODULE_BAD_ID, "invalid module id"); + return SCE_ERROR_MODULE_BAD_ID; } - if (currentlyLoadedModules.find(module) == currentlyLoadedModules.end()) { - return hleLogWarning(Log::sceUtility, SCE_ERROR_MODULE_NOT_LOADED, "not yet loaded"); + auto iter = currentlyLoadedModules.find(module); + if (iter == currentlyLoadedModules.end()) { + return SCE_ERROR_MODULE_NOT_LOADED; } - if (currentlyLoadedModules[module] != 0) { - userMemory.Free(currentlyLoadedModules[module]); + if (iter->second != 0) { + userMemory.Free(iter->second); } currentlyLoadedModules.erase(module); - if (info->notify) + if (info->notify) { info->notify(-1, 0, 0); - - // TODO: Each module has its own timing, technically, but this is a low-end. - if (module == 0x3FF) - return hleDelayResult(hleLogInfo(Log::sceUtility, 0), "utility module unloaded", 110); - else - return hleDelayResult(hleLogInfo(Log::sceUtility, 0), "utility module unloaded", 400); + } + return 0; } static int sceUtilityMsgDialogInitStart(u32 paramAddr) { From 11e8b0d12694822c8c13e2c0f53d4d577703df4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Mar 2025 17:40:54 +0100 Subject: [PATCH 2/4] ImDebugger: Allow browsing memory tags in the memory views --- UI/ImDebugger/ImDebugger.cpp | 43 +++++++++++++++++++++++++----------- UI/ImDebugger/ImDebugger.h | 1 + 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index a215f32927..dadf583bee 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -10,6 +10,7 @@ #include "Common/Log/LogManager.h" #include "Core/Config.h" #include "Core/System.h" +#include "Core/Debugger/MemBlockInfo.h" #include "Core/RetroAchievements.h" #include "Core/Core.h" #include "Core/Debugger/DebugInterface.h" @@ -21,7 +22,6 @@ #include "Core/FileSystems/MetaFileSystem.h" #include "Core/Debugger/SymbolMap.h" #include "Core/MemMap.h" -#include "Core/System.h" #include "Core/HLE/HLE.h" #include "Core/HLE/SocketManager.h" #include "Core/HLE/NetInetConstants.h" @@ -1852,21 +1852,38 @@ void ImMemWindow::Draw(MIPSDebugInterface *mipsDebug, ImConfig &cfg, ImControl & ImVec2 size(0, -ImGui::GetFrameHeightWithSpacing()); + auto node = [&](const char *title, uint32_t start, uint32_t len) { + if (ImGui::TreeNode(title)) { + if (ImGui::Selectable("(start)", cfg.selectedMemoryBlock == start)) { + cfg.selectedMemoryBlock = start; + GotoAddr(start); + } + const std::vector info = FindMemInfo(start, len); + for (auto &iter : info) { + ImGui::PushID(iter.start); + if (ImGui::Selectable(iter.tag.c_str(), cfg.selectedMemoryBlock == iter.start)) { + cfg.selectedMemoryBlock = iter.start; + GotoAddr(iter.start); + } + ImGui::PopID(); + } + const u32 end = start + len; + if (ImGui::Selectable("(end)", cfg.selectedMemoryBlock == end)) { + cfg.selectedMemoryBlock = end; + GotoAddr(end); + } + ImGui::TreePop(); + } + }; + // Main views - list of interesting addresses to the left, memory view to the right. if (ImGui::BeginChild("addr_list", ImVec2(200.0f, size.y), ImGuiChildFlags_ResizeX)) { - if (ImGui::Selectable("Scratch")) { - GotoAddr(0x00010000); - } - if (ImGui::Selectable("Kernel RAM")) { - GotoAddr(0x08000000); - } - if (ImGui::Selectable("User RAM")) { - GotoAddr(0x08800000); - } - if (ImGui::Selectable("VRAM")) { - GotoAddr(0x04000000); - } + node("Scratch", 0x00010000, 0x00004000); + node("Kernel RAM", 0x08000000, 0x00800000); + node("User RAM" , 0x08800000, 0x01800000); + node("VRAM", 0x04000000, 0x00200000); } + ImGui::EndChild(); ImGui::SameLine(); diff --git a/UI/ImDebugger/ImDebugger.h b/UI/ImDebugger/ImDebugger.h index 8559166441..e3bc32773e 100644 --- a/UI/ImDebugger/ImDebugger.h +++ b/UI/ImDebugger/ImDebugger.h @@ -164,6 +164,7 @@ struct ImConfig { int selectedBreakpoint = -1; int selectedMemCheck = -1; int selectedAtracCtx = 0; + u32 selectedMemoryBlock = 0; uint64_t selectedTexAddr = 0; bool realtimePixelPreview = false; From 5a8e4c1c2e451bb5ce1948cb698d29625a6b5194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Mar 2025 17:52:39 +0100 Subject: [PATCH 3/4] Assorted debugger stuff --- Core/HLE/sceKernelModule.cpp | 6 +++--- Core/HLE/sceUtility.cpp | 14 +++++++------- UI/ImDebugger/ImDebugger.cpp | 11 ++++++++--- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index e5ffc05b8b..a864f25e82 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -277,9 +277,9 @@ public: const char *GetTypeName() override { return GetStaticTypeName(); } static const char *GetStaticTypeName() { return "Module"; } void GetQuickInfo(char *ptr, int size) override { - snprintf(ptr, size, "%s %d.%d name=%s gp=%08x entry=%08x", - isFake ? "faked " : "", - nm.version[0], nm.version[1], + snprintf(ptr, size, "%d.%d %sname=%s gp=%08x entry=%08x", + nm.version[1], nm.version[0], + isFake ? "(faked) " : "", nm.name, nm.gp_value, nm.entry_addr); diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index 75c18d8340..961657886c 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -108,13 +108,13 @@ static const ModuleLoadInfo moduleLoadInfo[] = { ModuleLoadInfo(0x104, 0x00002000, "net_parse_http"), ModuleLoadInfo(0x105, 0x00028000, "net_http", httpModuleDeps), ModuleLoadInfo(0x106, 0x00044000, "net_ssl", sslModuleDeps), - ModuleLoadInfo(0x107, 0x00010000, "0x107"), + ModuleLoadInfo(0x107, 0x00010000, "unk_0x107"), ModuleLoadInfo(0x108, 0x00008000, "usb_pspcm", httpStorageModuleDeps), ModuleLoadInfo(0x200, 0x00000000, "usb_mic"), ModuleLoadInfo(0x201, 0x00000000, "usb_cam"), ModuleLoadInfo(0x202, 0x00000000, "usb_gps"), - ModuleLoadInfo(0x203, 0x00000000, "0x203"), - ModuleLoadInfo(0x2ff, 0x00000000, "0x2ff"), + ModuleLoadInfo(0x203, 0x00000000, "usb_unk_0x203"), + ModuleLoadInfo(0x2ff, 0x00000000, "unk_0x2ff"), ModuleLoadInfo(0x300, 0x00000000, "av_avcodec", &NotifyLoadStatusAvcodec), ModuleLoadInfo(0x301, 0x00000000, "av_sascore"), ModuleLoadInfo(0x302, 0x00008000, "av_atrac3plus", atrac3PlusModuleDeps, &NotifyLoadStatusAtrac), // TODO: 0x8000 is likely too large. @@ -123,16 +123,16 @@ static const ModuleLoadInfo moduleLoadInfo[] = { ModuleLoadInfo(0x305, 0x0000a300, "av_vaudio"), ModuleLoadInfo(0x306, 0x00004000, "av_aac"), ModuleLoadInfo(0x307, 0x00000000, "av_g729"), - ModuleLoadInfo(0x308, 0x0003c000, "av_", mp4ModuleDeps), + ModuleLoadInfo(0x308, 0x0003c000, "av_mp4", mp4ModuleDeps), ModuleLoadInfo(0x3fe, 0x00000000, "me_stuff"), ModuleLoadInfo(0x3ff, 0x00000000, "me_core"), // ME Core? ModuleLoadInfo(0x400, 0x0000c000, "np_common"), ModuleLoadInfo(0x401, 0x00018000, "np_service"), ModuleLoadInfo(0x402, 0x00048000, "np_matching2"), - ModuleLoadInfo(0x403, 0x0000e000, "0x403"), + ModuleLoadInfo(0x403, 0x0000e000, "np_unk_0x403"), ModuleLoadInfo(0x500, 0x00000000, "np_drm"), ModuleLoadInfo(0x600, 0x00000000, "irda"), - ModuleLoadInfo(0x601, 0x00000000, "0x601"), + ModuleLoadInfo(0x601, 0x00000000, "unk_0x601"), }; // Only a single dialog is allowed at a time. @@ -576,7 +576,7 @@ static int LoadModuleInternal(u32 module) { u32 allocSize = info->size; u32 address = 0; char name[128]; - snprintf(name, sizeof(name), "UtilityModule/%x", module); + snprintf(name, sizeof(name), "UtilityModule/%3x_%s", module, info->name); if (allocSize != 0) { address = userMemory.Alloc(allocSize, false, name); } diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index dadf583bee..bc466c5772 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -1575,6 +1575,10 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu } ImGui::EndMenu(); } + if (ImGui::BeginMenu("Core")) { + ImGui::MenuItem("Scheduler", nullptr, &cfg_.schedulerOpen); + ImGui::EndMenu(); + } if (ImGui::BeginMenu("CPU")) { ImGui::MenuItem("CPU debugger", nullptr, &cfg_.disasmOpen); ImGui::MenuItem("GPR regs", nullptr, &cfg_.gprOpen); @@ -1582,8 +1586,9 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu ImGui::MenuItem("VFPU regs", nullptr, &cfg_.vfpuOpen); ImGui::MenuItem("Callstacks", nullptr, &cfg_.callstackOpen); ImGui::MenuItem("Breakpoints", nullptr, &cfg_.breakpointsOpen); - ImGui::MenuItem("Scheduler", nullptr, &cfg_.schedulerOpen); - ImGui::Separator(); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Memory")) { for (int i = 0; i < 4; i++) { char title[64]; snprintf(title, sizeof(title), "Memory %d", i + 1); @@ -1592,7 +1597,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu ImGui::MenuItem("Memory Dumper", nullptr, &cfg_.memDumpOpen); ImGui::EndMenu(); } - if (ImGui::BeginMenu("HLE")) { + if (ImGui::BeginMenu("OS HLE")) { ImGui::MenuItem("File System Browser", nullptr, &cfg_.filesystemBrowserOpen); ImGui::MenuItem("Kernel Objects", nullptr, &cfg_.kernelObjectsOpen); ImGui::MenuItem("Threads", nullptr, &cfg_.threadsOpen); From c2a73ba2eec0c7aec92b849ec23e0f65f6bd5ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Mar 2025 17:54:53 +0100 Subject: [PATCH 4/4] sceUtilityLoadModule: Shrink the memory reservation for sceAtrac --- Core/HLE/sceUtility.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index 961657886c..42eb5fb545 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -117,7 +117,7 @@ static const ModuleLoadInfo moduleLoadInfo[] = { ModuleLoadInfo(0x2ff, 0x00000000, "unk_0x2ff"), ModuleLoadInfo(0x300, 0x00000000, "av_avcodec", &NotifyLoadStatusAvcodec), ModuleLoadInfo(0x301, 0x00000000, "av_sascore"), - ModuleLoadInfo(0x302, 0x00008000, "av_atrac3plus", atrac3PlusModuleDeps, &NotifyLoadStatusAtrac), // TODO: 0x8000 is likely too large. + ModuleLoadInfo(0x302, 0x00004000, "av_atrac3plus", atrac3PlusModuleDeps, &NotifyLoadStatusAtrac), // TODO: 0x8000 is likely too large. ModuleLoadInfo(0x303, 0x0000c000, "av_mpegbase", mpegBaseModuleDeps), ModuleLoadInfo(0x304, 0x00004000, "av_mp3"), ModuleLoadInfo(0x305, 0x0000a300, "av_vaudio"),