Merge pull request #9730 from LunaMoo/HomebrewIdent

Fix a bunch of emu features for Homebrew by better identification.
This commit is contained in:
Henrik Rydgård 2017-05-30 14:57:31 +02:00 committed by GitHub
commit 901b62ae54
19 changed files with 188 additions and 94 deletions

View file

@ -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";

View file

@ -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";

View file

@ -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;
}

View file

@ -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<std::string,ValueData>::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<std::string,ValueData>::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<std::string,ValueData>::iterator it = values.find(key);
if(it == values.end() || (it->second.type != VT_UTF8_SPE))
return 0;
@ -95,8 +91,7 @@ std::vector<std::string> 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;
}

View file

@ -35,6 +35,7 @@ public:
u8* GetValueData(std::string key, unsigned int *size);
std::vector<std::string> GetKeys();
std::string GenerateFakeID(std::string filename = "");
bool ReadSFO(const u8 *paramsfo, size_t size);
bool WriteSFO(u8 **paramsfo, size_t *size);

View file

@ -95,14 +95,14 @@ std::vector<std::string> 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<std::string> 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<std::string> 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<std::string> 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;
}

View file

@ -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<u8> 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);
}

View file

@ -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;

View file

@ -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();

View file

@ -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_ + "/";

View file

@ -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();
}

View file

@ -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_);
}

View file

@ -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();

View file

@ -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<std::mutex> 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<std::mutex> 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<std::mutex> 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;

View file

@ -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

View file

@ -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<GameInfo> 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;

View file

@ -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_) {

View file

@ -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];

View file

@ -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<UIScreen>(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);