diff --git a/Core/ELF/ParamSFO.cpp b/Core/ELF/ParamSFO.cpp index 4c2b65fa9b93..7d9387a97d49 100644 --- a/Core/ELF/ParamSFO.cpp +++ b/Core/ELF/ParamSFO.cpp @@ -86,6 +86,14 @@ u8* ParamSFOData::GetValueData(std::string key, unsigned int *size) return it->second.u_value; } +std::vector ParamSFOData::GetKeys() { + std::vector result; + for (const auto &pair : values) { + result.push_back(pair.first); + } + return result; +} + // I'm so sorry Ced but this is highly endian unsafe :( bool ParamSFOData::ReadSFO(const u8 *paramsfo, size_t size) { diff --git a/Core/ELF/ParamSFO.h b/Core/ELF/ParamSFO.h index e58f28d81708..956ebbab14b0 100644 --- a/Core/ELF/ParamSFO.h +++ b/Core/ELF/ParamSFO.h @@ -34,6 +34,8 @@ class ParamSFOData std::string GetValueString(std::string key); u8* GetValueData(std::string key, unsigned int *size); + std::vector GetKeys(); + bool ReadSFO(const u8 *paramsfo, size_t size); bool WriteSFO(u8 **paramsfo, size_t *size); diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 9a90c2b8a82d..e07fc65bb832 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -340,7 +340,7 @@ void Init() void DoState(PointerWrap &p) { - auto s = p.Section("Memory", 1, 2); + auto s = p.Section("Memory", 1, 3); if (!s) return; @@ -348,7 +348,8 @@ void DoState(PointerWrap &p) if (!g_RemasterMode) g_MemorySize = RAM_NORMAL_SIZE; g_PSPModel = PSP_MODEL_FAT; - } else { + } else if (s == 2) { + // In version 2, we determine memory size based on PSP model. u32 oldMemorySize = g_MemorySize; p.Do(g_PSPModel); p.DoMarker("PSPModel"); @@ -359,6 +360,17 @@ void DoState(PointerWrap &p) Init(); } } + } else { + // In version 3, we started just saving the memory size directly. + // It's no longer based strictly on the PSP model. + u32 oldMemorySize = g_MemorySize; + p.Do(g_PSPModel); + p.DoMarker("PSPModel"); + p.Do(g_MemorySize); + if (oldMemorySize != g_MemorySize) { + Shutdown(); + Init(); + } } p.DoArray(GetPointer(PSP_GetKernelMemoryBase()), g_MemorySize); diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 82a8f3806855..7b1c8130a89d 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -102,20 +102,53 @@ void InitMemoryForGameISO(FileLoader *fileLoader) { { std::vector paramsfo; pspFileSystem.ReadEntireFile(sfoPath, paramsfo); - if (g_paramSFO.ReadSFO(paramsfo)) - { + if (g_paramSFO.ReadSFO(paramsfo)) { + // TODO: Check the SFO for other parameters that might be useful for identifying? gameID = g_paramSFO.GetValueString("DISC_ID"); for (size_t i = 0; i < ARRAY_SIZE(g_HDRemasters); i++) { - if(g_HDRemasters[i].gameID == gameID) { + if (g_HDRemasters[i].gameID == gameID) { g_RemasterMode = true; Memory::g_MemorySize = g_HDRemasters[i].MemorySize; - if(g_HDRemasters[i].DoubleTextureCoordinates) + if (g_HDRemasters[i].DoubleTextureCoordinates) g_DoubleTextureCoordinates = true; break; } } - DEBUG_LOG(LOADER, "HDRemaster mode is %s", g_RemasterMode? "true": "false"); + if (g_RemasterMode) { + INFO_LOG(LOADER, "HDRemaster found, using increased memory"); + } + } + } +} + +void InitMemoryForGamePBP(FileLoader *fileLoader) { + bool useLargeMem = false; + + // TODO: Change PBPReader to read FileLoader objects? + std::string filename = fileLoader->Path(); + PBPReader pbp(filename.c_str()); + if (pbp.IsValid() && !pbp.IsELF()) { + size_t sfoSize; + u8 *sfoData = pbp.GetSubFile(PBP_PARAM_SFO, &sfoSize); + if (sfoData) { + ParamSFOData paramSFO; + paramSFO.ReadSFO(sfoData, sfoSize); + + // This is the parameter CFW uses to determine homebrew wants the full 64MB. + int memsize = paramSFO.GetValueInt("MEMSIZE"); + useLargeMem = memsize == 1; + + delete [] sfoData; + } + } + + if (useLargeMem) { + if (Memory::g_PSPModel != PSP_MODEL_FAT) { + INFO_LOG(LOADER, "Homebrew requested full PSP-2000 memory access"); + Memory::g_MemorySize = Memory::RAM_DOUBLE_SIZE; + } else { + WARN_LOG(LOADER, "Homebrew requested full PSP-2000 memory access, ignoring in PSP-1000 mode"); } } } diff --git a/Core/PSPLoaders.h b/Core/PSPLoaders.h index 3dce913c0815..400df80d6576 100644 --- a/Core/PSPLoaders.h +++ b/Core/PSPLoaders.h @@ -24,3 +24,4 @@ class FileLoader; bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string); bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string); void InitMemoryForGameISO(FileLoader *fileLoader); +void InitMemoryForGamePBP(FileLoader *fileLoader); diff --git a/Core/System.cpp b/Core/System.cpp index 95e3eb6ca101..5d726ba2ad85 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -177,10 +177,7 @@ void CPU_Init() { // Default memory settings // Seems to be the safest place currently.. - if (g_Config.iPSPModel == PSP_MODEL_FAT) - Memory::g_MemorySize = Memory::RAM_NORMAL_SIZE; // 32 MB of ram by default - else - Memory::g_MemorySize = Memory::RAM_DOUBLE_SIZE; + Memory::g_MemorySize = Memory::RAM_NORMAL_SIZE; // 32 MB of ram by default g_RemasterMode = false; g_DoubleTextureCoordinates = false; @@ -209,6 +206,17 @@ void CPU_Init() { case FILETYPE_PSP_DISC_DIRECTORY: InitMemoryForGameISO(loadedFile); break; + case FILETYPE_PSP_PBP_DIRECTORY: { + // TODO: Can we get this lower into LoadFile? + std::string ebootFilename = loadedFile->Path() + "/EBOOT.PBP"; + FileLoader *tempLoader = ConstructFileLoader(ebootFilename); + InitMemoryForGamePBP(tempLoader); + delete tempLoader; + break; + } + case FILETYPE_PSP_PBP: + InitMemoryForGamePBP(loadedFile); + break; default: break; }