mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-11 05:26:24 +02:00
Make sceUtilityLoadAvModule work correctly
This commit is contained in:
1 parent
143641b1cf
commit
17d7dcdd6c
4 files changed
+73
-37
No files matched your search
+11
-2
@@ -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)
|
||||
|
||||
+3
-1
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+51
-29
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user