diff --git a/Common/ArmCPUDetect.cpp b/Common/ArmCPUDetect.cpp index 8aa3fd3a5..a7b333fe8 100644 --- a/Common/ArmCPUDetect.cpp +++ b/Common/ArmCPUDetect.cpp @@ -274,9 +274,9 @@ std::string CPUInfo::Summarize() { std::string sum; if (num_cores == 1) - sum = StringFromFormat("%s, %i core", cpu_string, num_cores); + sum = StringFromFormat("%s, %d core", cpu_string, num_cores); else - sum = StringFromFormat("%s, %i cores", cpu_string, num_cores); + sum = StringFromFormat("%s, %d cores", cpu_string, num_cores); if (bSwp) sum += ", SWP"; if (bHalf) sum += ", Half"; if (bThumb) sum += ", Thumb"; diff --git a/Common/CPUDetect.cpp b/Common/CPUDetect.cpp index 4f4304320..cb50ce807 100644 --- a/Common/CPUDetect.cpp +++ b/Common/CPUDetect.cpp @@ -267,10 +267,10 @@ std::string CPUInfo::Summarize() { std::string sum; if (num_cores == 1) - sum = StringFromFormat("%s, %i core", cpu_string, num_cores); + sum = StringFromFormat("%s, %d core", cpu_string, num_cores); else { - sum = StringFromFormat("%s, %i cores", cpu_string, num_cores); + sum = StringFromFormat("%s, %d cores", cpu_string, num_cores); if (HTT) sum += StringFromFormat(" (%i logical threads per physical core)", logical_cpu_count); } if (bSSE) sum += ", SSE"; diff --git a/Common/Timer.cpp b/Common/Timer.cpp index 4c8969c1d..9c34ee151 100644 --- a/Common/Timer.cpp +++ b/Common/Timer.cpp @@ -143,7 +143,7 @@ std::string Timer::GetTimeElapsedFormatted() const // Hours u32 Hours = Minutes / 60; - std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i", + std::string TmpStr = StringFromFormat("%02d:%02d:%02d:%03d", Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000); return TmpStr; } diff --git a/Core/ELF/ParamSFO.cpp b/Core/ELF/ParamSFO.cpp index 7d9387a97..6c164db35 100644 --- a/Core/ELF/ParamSFO.cpp +++ b/Core/ELF/ParamSFO.cpp @@ -20,7 +20,9 @@ #include "Common/CommonTypes.h" #include "Common/Log.h" +#include "Common/StringUtils.h" #include "Core/ELF/ParamSFO.h" +#include "Core/Core.h" struct Header { @@ -40,42 +42,36 @@ struct IndexTable u32 data_table_offset; /* Offset of the param_data from start of data_table */ }; -void ParamSFOData::SetValue(std::string key, unsigned int value, int max_size) -{ +void ParamSFOData::SetValue(std::string key, unsigned int value, int max_size) { values[key].type = VT_INT; values[key].i_value = value; values[key].max_size = max_size; } -void ParamSFOData::SetValue(std::string key, std::string value, int max_size) -{ +void ParamSFOData::SetValue(std::string key, std::string value, int max_size) { values[key].type = VT_UTF8; values[key].s_value = value; values[key].max_size = max_size; } -void ParamSFOData::SetValue(std::string key, const u8* value, unsigned int size, int max_size) -{ +void ParamSFOData::SetValue(std::string key, const u8* value, unsigned int size, int max_size) { values[key].type = VT_UTF8_SPE; values[key].SetData(value,size); values[key].max_size = max_size; } -int ParamSFOData::GetValueInt(std::string key) -{ +int ParamSFOData::GetValueInt(std::string key) { std::map::iterator it = values.find(key); if(it == values.end() || it->second.type != VT_INT) return 0; return it->second.i_value; } -std::string ParamSFOData::GetValueString(std::string key) -{ +std::string ParamSFOData::GetValueString(std::string key) { std::map::iterator it = values.find(key); if(it == values.end() || (it->second.type != VT_UTF8)) return ""; return it->second.s_value; } -u8* ParamSFOData::GetValueData(std::string key, unsigned int *size) -{ +u8* ParamSFOData::GetValueData(std::string key, unsigned int *size) { std::map::iterator it = values.find(key); if(it == values.end() || (it->second.type != VT_UTF8_SPE)) return 0; @@ -95,8 +91,7 @@ std::vector ParamSFOData::GetKeys() { } // I'm so sorry Ced but this is highly endian unsafe :( -bool ParamSFOData::ReadSFO(const u8 *paramsfo, size_t size) -{ +bool ParamSFOData::ReadSFO(const u8 *paramsfo, size_t size) { if (size < sizeof(Header)) return false; const Header *header = (const Header *)paramsfo; @@ -145,8 +140,7 @@ bool ParamSFOData::ReadSFO(const u8 *paramsfo, size_t size) return true; } -int ParamSFOData::GetDataOffset(const u8 *paramsfo, std::string dataName) -{ +int ParamSFOData::GetDataOffset(const u8 *paramsfo, std::string dataName) { const Header *header = (const Header *)paramsfo; if (header->magic != 0x46535000) return -1; @@ -170,8 +164,7 @@ int ParamSFOData::GetDataOffset(const u8 *paramsfo, std::string dataName) return -1; } -bool ParamSFOData::WriteSFO(u8 **paramsfo, size_t *size) -{ +bool ParamSFOData::WriteSFO(u8 **paramsfo, size_t *size) { size_t total_size = 0; size_t key_size = 0; size_t data_size = 0; @@ -256,13 +249,11 @@ bool ParamSFOData::WriteSFO(u8 **paramsfo, size_t *size) return true; } -void ParamSFOData::Clear() -{ +void ParamSFOData::Clear() { values.clear(); } -void ParamSFOData::ValueData::SetData(const u8* data, int size) -{ +void ParamSFOData::ValueData::SetData(const u8* data, int size) { if(u_value) { delete[] u_value; @@ -276,3 +267,27 @@ void ParamSFOData::ValueData::SetData(const u8* data, int size) u_size = size; } +std::string ParamSFOData::GenerateFakeID(std::string filename) { + // Generates fake gameID for homebrew based on it's folder name. + // Should probably not be a part of ParamSFO, but it'll be called in same places. + std::string file = PSP_CoreParameter().fileToStart; + if (filename != "") + file = filename; + + std::size_t lslash = file.find_last_of("/"); + file = file.substr(lslash + 1); + + int sumOfAllLetters = 0; + for (char &c : file) { + sumOfAllLetters += c; + c = toupper(c); + } + + if (file.size() < 4) { + file += "HOME"; + } + file = file.substr(0, 4); + + std::string fakeID = file + StringFromFormat("%05d", sumOfAllLetters); + return fakeID; +} diff --git a/Core/ELF/ParamSFO.h b/Core/ELF/ParamSFO.h index 956ebbab1..ead49feff 100644 --- a/Core/ELF/ParamSFO.h +++ b/Core/ELF/ParamSFO.h @@ -35,6 +35,7 @@ public: u8* GetValueData(std::string key, unsigned int *size); std::vector GetKeys(); + std::string GenerateFakeID(std::string filename = ""); bool ReadSFO(const u8 *paramsfo, size_t size); bool WriteSFO(u8 **paramsfo, size_t *size); diff --git a/Core/MIPS/JitCommon/JitCommon.cpp b/Core/MIPS/JitCommon/JitCommon.cpp index c3764fce5..7c0289f07 100644 --- a/Core/MIPS/JitCommon/JitCommon.cpp +++ b/Core/MIPS/JitCommon/JitCommon.cpp @@ -95,14 +95,14 @@ std::vector DisassembleArm2(const u8 *data, int size) { bkpt_count++; } else { if (bkpt_count) { - lines.push_back(StringFromFormat("BKPT 1 (x%i)", bkpt_count)); + lines.push_back(StringFromFormat("BKPT 1 (x%d)", bkpt_count)); bkpt_count = 0; } lines.push_back(buf); } } if (bkpt_count) { - lines.push_back(StringFromFormat("BKPT 1 (x%i)", bkpt_count)); + lines.push_back(StringFromFormat("BKPT 1 (x%d)", bkpt_count)); } return lines; } @@ -157,7 +157,7 @@ std::vector DisassembleArm64(const u8 *data, int size) { bkpt_count++; } else { if (bkpt_count) { - lines.push_back(StringFromFormat("BKPT 1 (x%i)", bkpt_count)); + lines.push_back(StringFromFormat("BKPT 1 (x%d)", bkpt_count)); bkpt_count = 0; } if (true) { @@ -167,7 +167,7 @@ std::vector DisassembleArm64(const u8 *data, int size) { } } if (bkpt_count) { - lines.push_back(StringFromFormat("BKPT 1 (x%i)", bkpt_count)); + lines.push_back(StringFromFormat("BKPT 1 (x%d)", bkpt_count)); } return lines; } @@ -235,14 +235,14 @@ std::vector DisassembleX86(const u8 *data, int size) { int3_count++; } else { if (int3_count) { - lines.push_back(StringFromFormat("int3 (x%i)", int3_count)); + lines.push_back(StringFromFormat("int3 (x%d)", int3_count)); int3_count = 0; } lines.push_back(str); } } if (int3_count) { - lines.push_back(StringFromFormat("int3 (x%i)", int3_count)); + lines.push_back(StringFromFormat("int3 (x%d)", int3_count)); } return lines; } diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 0a7fd9b16..f87ea7f64 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -18,6 +18,7 @@ #include "file/file_util.h" #include "util/text/utf8.h" +#include "Common/FileUtil.h" #include "Common/StringUtils.h" #ifdef _WIN32 #include "Common/CommonWindows.h" @@ -187,10 +188,9 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) { std::vector paramsfo; pspFileSystem.ReadEntireFile(sfoPath, paramsfo); if (g_paramSFO.ReadSFO(paramsfo)) { - char title[1024]; - sprintf(title, "%s : %s", g_paramSFO.GetValueString("DISC_ID").c_str(), g_paramSFO.GetValueString("TITLE").c_str()); - INFO_LOG(LOADER, "%s", title); - host->SetWindowTitle(title); + std::string title = StringFromFormat("%s : %s", g_paramSFO.GetValueString("DISC_ID").c_str(), g_paramSFO.GetValueString("TITLE").c_str()); + INFO_LOG(LOADER, "%s", title.c_str()); + host->SetWindowTitle(title.c_str()); } } @@ -322,5 +322,40 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) { pspFileSystem.Mount("umd0:", fs); std::string finalName = ms_path + file + extension; + + std::string homebrewName = PSP_CoreParameter().fileToStart; + std::size_t lslash = homebrewName.find_last_of("/"); + homebrewName = homebrewName.substr(lslash + 1); + std::string madeUpID = g_paramSFO.GenerateFakeID(); + + std::string title = StringFromFormat("%s : %s", madeUpID.c_str(), homebrewName.c_str()); + INFO_LOG(LOADER, "%s", title.c_str()); + host->SetWindowTitle(title.c_str()); + + // Temporary code + // TODO: Remove this after ~ 1.6 + // It checks for old filenames for homebrew savestates(folder name) and rename them to new fakeID format + std::string savestateDir = GetSysDirectory(DIRECTORY_SAVESTATE); + savestateDir = ReplaceAll(savestateDir, "\\", "/"); +#ifdef _WIN32 + // Turn the slashes back to the Windows way. + savestateDir = ReplaceAll(savestateDir, "/", "\\"); +#endif + for (int i = 0; i < 5; i += 1) { + std::string oldName = StringFromFormat("%s%s_%d.ppst", savestateDir.c_str(), homebrewName.c_str(), i); + if (File::Exists(oldName)) { + std::string newName = StringFromFormat("%s%s_1.00_%d.ppst", savestateDir.c_str(), madeUpID.c_str(), i); + File::Rename(oldName, newName); + } + } + for (int i = 0; i < 5; i += 1) { + std::string oldName = StringFromFormat("%s%s_%d.jpg", savestateDir.c_str(), homebrewName.c_str(), i); + if (File::Exists(oldName)) { + std::string newName = StringFromFormat("%s%s_1.00_%d.jpg", savestateDir.c_str(), madeUpID.c_str(), i); + File::Rename(oldName, newName); + } + } + // End of temporary code + return __KernelLoadExec(finalName.c_str(), 0, error_string); } diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index dbda741aa..4b5a4a542 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -363,33 +363,15 @@ namespace SaveState std::string GenerateSaveSlotFilename(const std::string &gameFilename, int slot, const char *extension) { std::string discId = g_paramSFO.GetValueString("DISC_ID"); + std::string discVer = g_paramSFO.GetValueString("DISC_VERSION"); std::string fullDiscId; - if (discId.size()) { - fullDiscId = StringFromFormat("%s_%s", - g_paramSFO.GetValueString("DISC_ID").c_str(), - g_paramSFO.GetValueString("DISC_VERSION").c_str()); - } else { - // Okay, no discId. Probably homebrew, let's use the last part of the path name. - if (File::IsDirectory(gameFilename)) { - // EBOOT.PBP directory, most likely. - std::string path = gameFilename; - size_t slash = path.rfind('/'); // Always '/', not '\\', as we're in a virtual directory - if (slash != std::string::npos && slash < path.size() - 1) - path = path.substr(slash + 1); - fullDiscId = path; - } else { - // Probably a loose elf. - std::string fn = File::GetFilename(gameFilename); - size_t dot = fn.rfind('.'); - if (dot != std::string::npos) { - fullDiscId = fn.substr(0, dot); - } else { - fullDiscId = "elf"; // Fallback - } - } + if (discId.empty()) { + discId = g_paramSFO.GenerateFakeID(); + discVer = "1.00"; } + fullDiscId = StringFromFormat("%s_%s", discId.c_str(), discVer.c_str()); - std::string temp = StringFromFormat("ms0:/PSP/PPSSPP_STATE/%s_%i.%s", fullDiscId.c_str(), slot, extension); + std::string temp = StringFromFormat("ms0:/PSP/PPSSPP_STATE/%s_%d.%s", fullDiscId.c_str(), slot, extension); std::string hostPath; if (pspFileSystem.GetHostPath(temp, hostPath)) { return hostPath; @@ -590,6 +572,7 @@ namespace SaveState bool callbackResult; std::string callbackMessage; std::string reason; + std::string title; I18NCategory *sc = GetI18NCategory("Screen"); const char *i18nLoadFailure = sc->T("Load savestate failed", ""); @@ -621,7 +604,14 @@ namespace SaveState case SAVESTATE_SAVE: INFO_LOG(SAVESTATE, "Saving state to %s", op.filename.c_str()); - result = CChunkFileReader::Save(op.filename, g_paramSFO.GetValueString("TITLE"), PPSSPP_GIT_VERSION, state); + title = g_paramSFO.GetValueString("TITLE"); + if (title.empty()) { + // Homebrew title + title = PSP_CoreParameter().fileToStart; + std::size_t lslash = title.find_last_of("/"); + title = title.substr(lslash + 1); + } + result = CChunkFileReader::Save(op.filename, title, PPSSPP_GIT_VERSION, state); if (result == CChunkFileReader::ERROR_NONE) { callbackMessage = sc->T("Saved State"); callbackResult = true; diff --git a/Core/System.cpp b/Core/System.cpp index bca2a58ea..89a5151ed 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -243,9 +243,10 @@ void CPU_Init() { // Homebrew usually has an empty discID, and even if they do have a disc id, it's not // likely to collide with any commercial ones. std::string discID = g_paramSFO.GetValueString("DISC_ID"); - if (!discID.empty()) { - coreParameter.compat.Load(discID); + if (discID.empty()) { + discID = g_paramSFO.GenerateFakeID(); } + coreParameter.compat.Load(discID); Memory::Init(); mipsr4k.Reset(); diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index ed9b2c10f..2889d9b9d 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -48,8 +48,11 @@ void TextureReplacer::Init() { void TextureReplacer::NotifyConfigChanged() { gameID_ = g_paramSFO.GetValueString("DISC_ID"); + if (gameID_.empty()) { + gameID_ = g_paramSFO.GenerateFakeID(); + } - enabled_ = !gameID_.empty() && (g_Config.bReplaceTextures || g_Config.bSaveNewTextures); + enabled_ = g_Config.bReplaceTextures || g_Config.bSaveNewTextures; if (enabled_) { basePath_ = GetSysDirectory(DIRECTORY_TEXTURES) + gameID_ + "/"; diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 70b3e7ab0..91e1675ee 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -133,7 +133,10 @@ FramebufferManagerCommon::~FramebufferManagerCommon() { } void FramebufferManagerCommon::Init() { - const std::string gameId = g_paramSFO.GetValueString("DISC_ID"); + std::string gameId = g_paramSFO.GetValueString("DISC_ID"); + if (gameId.empty()) { + gameId = g_paramSFO.GenerateFakeID(); + } BeginFrame(); } diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index b56c3789c..1f40a0299 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -169,9 +169,12 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw) // Load shader cache. std::string discID = g_paramSFO.GetValueString("DISC_ID"); + if (discID.empty()) { + discID = g_paramSFO.GenerateFakeID(); + } if (discID.size()) { File::CreateFullPath(GetSysDirectory(DIRECTORY_APP_CACHE)); - shaderCachePath_ = GetSysDirectory(DIRECTORY_APP_CACHE) + "/" + g_paramSFO.GetValueString("DISC_ID") + ".glshadercache"; + shaderCachePath_ = GetSysDirectory(DIRECTORY_APP_CACHE) + "/" + discID + ".glshadercache"; shaderManagerGL_->LoadAndPrecompile(shaderCachePath_); } diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index edbcdfe92..8eebd778a 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -53,19 +53,11 @@ void CwCheatScreen::CreateCodeList() { if (info && info->paramSFOLoaded) { gameTitle = info->paramSFO.GetValueString("DISC_ID"); } - std::size_t lslash = gamePath_.find_last_of("/"); - std::size_t lastdot = gamePath_.find_last_of("."); - std::string extension = gamePath_.substr(lastdot + 1); - for (size_t i = 0; i < extension.size(); i++) { - extension[i] = tolower(extension[i]); - } - if ((extension != "iso" && extension != "cso" && extension != "pbp") || gameTitle == "") { - if (extension == "elf") { - gameTitle = "ELF000000"; - } else { - gameTitle = gamePath_.substr(lslash + 1); - } + if ((info->id.empty() || !info->disc_total) + && gamePath_.find("/PSP/GAME/") != std::string::npos) { + gameTitle = g_paramSFO.GenerateFakeID(gamePath_); } + cheatEngine2 = new CWCheatEngine(); cheatEngine2->CreateCheatFile(); cheatList = cheatEngine2->GetCodesList(); diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index af3672a3a..37f962c87 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -262,7 +262,7 @@ bool GameInfo::DeleteAllSaveData() { void GameInfo::ParseParamSFO() { title = paramSFO.GetValueString("TITLE"); id = paramSFO.GetValueString("DISC_ID"); - id_version = paramSFO.GetValueString("DISC_ID") + "_" + paramSFO.GetValueString("DISC_VERSION"); + id_version = id + "_" + paramSFO.GetValueString("DISC_VERSION"); disc_total = paramSFO.GetValueInt("DISC_TOTAL"); disc_number = paramSFO.GetValueInt("DISC_NUMBER"); // region = paramSFO.GetValueInt("REGION"); // Always seems to be 32768? @@ -405,6 +405,15 @@ public: std::lock_guard lock(info_->lock); info_->paramSFO.ReadSFO(sfoData); info_->ParseParamSFO(); + + // Assuming PSP_PBP_DIRECTORY without ID or with disc_total < 1 in GAME dir must be homebrew + if ((info_->id.empty() || !info_->disc_total) + && gamePath_.find("/PSP/GAME/") != std::string::npos + && info_->fileType == IdentifiedFileType::PSP_PBP_DIRECTORY) { + info_->id = g_paramSFO.GenerateFakeID(gamePath_); + info_->id_version = info_->id + "_1.00"; + info_->region = GAMEREGION_MAX + 1; // Homebrew + } } // Then, ICON0.PNG. @@ -412,8 +421,16 @@ public: std::lock_guard lock(info_->lock); pbp.GetSubFileAsString(PBP_ICON0_PNG, &info_->icon.data); } else { - // Read standard icon - ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock); + std::string screenshot_jpg = GetSysDirectory(DIRECTORY_SCREENSHOT) + info_->id + "_00000.jpg"; + std::string screenshot_png = GetSysDirectory(DIRECTORY_SCREENSHOT) + info_->id + "_00000.png"; + // Try using png/jpg screenshots first + if (File::Exists(screenshot_png)) + readFileToString(false, screenshot_png.c_str(), info_->icon.data); + else if (File::Exists(screenshot_jpg)) + readFileToString(false, screenshot_jpg.c_str(), info_->icon.data); + else + // Read standard icon + ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock); } info_->icon.dataLoaded = true; @@ -444,15 +461,27 @@ handleELF: // An elf on its own has no usable information, no icons, no nothing. { std::lock_guard lock(info_->lock); - info_->id = "ELF000000"; - info_->id_version = "ELF000000_1.00"; + info_->id = g_paramSFO.GenerateFakeID(gamePath_); + info_->id_version = info_->id + "_1.00"; + info_->region = GAMEREGION_MAX + 1; // Homebrew + info_->paramSFOLoaded = true; } - - // Read standard icon - DEBUG_LOG(LOADER, "Loading unknown.png because there was an ELF"); - ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock); - info_->icon.dataLoaded = true; + { + std::string screenshot_jpg = GetSysDirectory(DIRECTORY_SCREENSHOT) + info_->id + "_00000.jpg"; + std::string screenshot_png = GetSysDirectory(DIRECTORY_SCREENSHOT) + info_->id + "_00000.png"; + // Try using png/jpg screenshots first + if (File::Exists(screenshot_png)) + readFileToString(false, screenshot_png.c_str(), info_->icon.data); + else if (File::Exists(screenshot_jpg)) + readFileToString(false, screenshot_jpg.c_str(), info_->icon.data); + else { + // Read standard icon + DEBUG_LOG(LOADER, "Loading unknown.png because there was an ELF"); + ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock); + } + info_->icon.dataLoaded = true; + } break; case IdentifiedFileType::PSP_SAVEDATA_DIRECTORY: @@ -559,8 +588,17 @@ handleELF: // Fall back to unknown icon if ISO is broken/is a homebrew ISO, override is allowed though if (!ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &info_->icon.data, &info_->lock)) { - DEBUG_LOG(LOADER, "Loading unknown.png because no icon was found"); - ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock); + std::string screenshot_jpg = GetSysDirectory(DIRECTORY_SCREENSHOT) + info_->id + "_00000.jpg"; + std::string screenshot_png = GetSysDirectory(DIRECTORY_SCREENSHOT) + info_->id + "_00000.png"; + // Try using png/jpg screenshots first + if (File::Exists(screenshot_png)) + readFileToString(false, screenshot_png.c_str(), info_->icon.data); + else if (File::Exists(screenshot_jpg)) + readFileToString(false, screenshot_jpg.c_str(), info_->icon.data); + else { + DEBUG_LOG(LOADER, "Loading unknown.png because no icon was found"); + ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock); + } } info_->icon.dataLoaded = true; break; diff --git a/UI/GameInfoCache.h b/UI/GameInfoCache.h index 14e290a04..f664a1d62 100644 --- a/UI/GameInfoCache.h +++ b/UI/GameInfoCache.h @@ -1,4 +1,4 @@ -// Copyright (c) 2013- PPSSPP Project. +// Copyright (c) 2013- PPSSPP Project. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index 37729c24e..05ae58a51 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -236,6 +236,8 @@ void GameScreen::update() { "Asia" }; tvRegion_->SetText(ga->T(regionNames[info->region])); + } else if (info->region > GAMEREGION_MAX){ + tvRegion_->SetText(ga->T("Homebrew")); } if (!info->id.empty()) { @@ -285,6 +287,8 @@ UI::EventReturn GameScreen::OnGameSettings(UI::EventParams &e) { std::shared_ptr info = g_gameInfoCache->GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE); if (info && info->paramSFOLoaded) { std::string discID = info->paramSFO.GetValueString("DISC_ID"); + if ((discID.empty() || !info->disc_total) && gamePath_.find("/PSP/GAME/") != std::string::npos) + discID = g_paramSFO.GenerateFakeID(gamePath_); screenManager()->push(new GameSettingsScreen(gamePath_, discID, true)); } return UI::EVENT_DONE; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 155810c9c..d364a9463 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -1336,6 +1336,9 @@ UI::EventReturn DeveloperToolsScreen::OnLoadLanguageIni(UI::EventParams &e) { UI::EventReturn DeveloperToolsScreen::OnOpenTexturesIniFile(UI::EventParams &e) { std::string gameID = g_paramSFO.GetValueString("DISC_ID"); + if (gameID.empty()) { + gameID = g_paramSFO.GenerateFakeID(); + } std::string texturesDirectory = GetSysDirectory(DIRECTORY_TEXTURES) + gameID + "/"; bool enabled_ = !gameID.empty(); if (enabled_) { diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 6eaee626b..429ee2cd3 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -715,7 +715,7 @@ void TakeScreenshot() { std::string gameId = g_paramSFO.GetValueString("DISC_ID"); if (gameId.empty()) { - gameId = "MENU"; + gameId = g_paramSFO.GenerateFakeID(); } char filename[2048]; diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index f0630fb3d..60b7f5a94 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -188,7 +188,7 @@ SaveSlotView::SaveSlotView(const std::string &gameFilename, int slot, UI::Layout Add(new Spacer(5)); AsyncImageFileView *fv = Add(new AsyncImageFileView(screenshotFilename_, IS_DEFAULT, wq, new UI::LayoutParams(82 * 2, 47 * 2))); - fv->SetOverlayText(StringFromFormat("%i", slot_ + 1)); + fv->SetOverlayText(StringFromFormat("%d", slot_ + 1)); I18NCategory *pa = GetI18NCategory("Pause"); @@ -321,6 +321,9 @@ void GamePauseScreen::CreateViews() { continueChoice->OnClick.Handle(this, &UIScreen::OnBack); std::string gameId = g_paramSFO.GetValueString("DISC_ID"); + if (gameId.empty()) { + gameId = g_paramSFO.GenerateFakeID(); + } if (g_Config.hasGameConfig(gameId)) { rightColumnItems->Add(new Choice(pa->T("Game Settings")))->OnClick.Handle(this, &GamePauseScreen::OnGameSettings); rightColumnItems->Add(new Choice(pa->T("Delete Game Config")))->OnClick.Handle(this, &GamePauseScreen::OnDeleteConfig); @@ -422,6 +425,9 @@ void GamePauseScreen::CallbackDeleteConfig(bool yes) UI::EventReturn GamePauseScreen::OnCreateConfig(UI::EventParams &e) { std::string gameId = g_paramSFO.GetValueString("DISC_ID"); + if (gameId.empty()) { + gameId = g_paramSFO.GenerateFakeID(); + } g_Config.createGameConfig(gameId); g_Config.changeGameSpecific(gameId); g_Config.saveGameConfig(gameId);