Merge pull request #9730 from LunaMoo/HomebrewIdent
Fix a bunch of emu features for Homebrew by better identification.
This commit is contained in:
commit
901b62ae54
19 changed files with 188 additions and 94 deletions
|
@ -274,9 +274,9 @@ std::string CPUInfo::Summarize()
|
||||||
{
|
{
|
||||||
std::string sum;
|
std::string sum;
|
||||||
if (num_cores == 1)
|
if (num_cores == 1)
|
||||||
sum = StringFromFormat("%s, %i core", cpu_string, num_cores);
|
sum = StringFromFormat("%s, %d core", cpu_string, num_cores);
|
||||||
else
|
else
|
||||||
sum = StringFromFormat("%s, %i cores", cpu_string, num_cores);
|
sum = StringFromFormat("%s, %d cores", cpu_string, num_cores);
|
||||||
if (bSwp) sum += ", SWP";
|
if (bSwp) sum += ", SWP";
|
||||||
if (bHalf) sum += ", Half";
|
if (bHalf) sum += ", Half";
|
||||||
if (bThumb) sum += ", Thumb";
|
if (bThumb) sum += ", Thumb";
|
||||||
|
|
|
@ -267,10 +267,10 @@ std::string CPUInfo::Summarize()
|
||||||
{
|
{
|
||||||
std::string sum;
|
std::string sum;
|
||||||
if (num_cores == 1)
|
if (num_cores == 1)
|
||||||
sum = StringFromFormat("%s, %i core", cpu_string, num_cores);
|
sum = StringFromFormat("%s, %d core", cpu_string, num_cores);
|
||||||
else
|
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 (HTT) sum += StringFromFormat(" (%i logical threads per physical core)", logical_cpu_count);
|
||||||
}
|
}
|
||||||
if (bSSE) sum += ", SSE";
|
if (bSSE) sum += ", SSE";
|
||||||
|
|
|
@ -143,7 +143,7 @@ std::string Timer::GetTimeElapsedFormatted() const
|
||||||
// Hours
|
// Hours
|
||||||
u32 Hours = Minutes / 60;
|
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);
|
Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000);
|
||||||
return TmpStr;
|
return TmpStr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Log.h"
|
#include "Common/Log.h"
|
||||||
|
#include "Common/StringUtils.h"
|
||||||
#include "Core/ELF/ParamSFO.h"
|
#include "Core/ELF/ParamSFO.h"
|
||||||
|
#include "Core/Core.h"
|
||||||
|
|
||||||
struct Header
|
struct Header
|
||||||
{
|
{
|
||||||
|
@ -40,42 +42,36 @@ struct IndexTable
|
||||||
u32 data_table_offset; /* Offset of the param_data from start of data_table */
|
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].type = VT_INT;
|
||||||
values[key].i_value = value;
|
values[key].i_value = value;
|
||||||
values[key].max_size = max_size;
|
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].type = VT_UTF8;
|
||||||
values[key].s_value = value;
|
values[key].s_value = value;
|
||||||
values[key].max_size = max_size;
|
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].type = VT_UTF8_SPE;
|
||||||
values[key].SetData(value,size);
|
values[key].SetData(value,size);
|
||||||
values[key].max_size = max_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);
|
std::map<std::string,ValueData>::iterator it = values.find(key);
|
||||||
if(it == values.end() || it->second.type != VT_INT)
|
if(it == values.end() || it->second.type != VT_INT)
|
||||||
return 0;
|
return 0;
|
||||||
return it->second.i_value;
|
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);
|
std::map<std::string,ValueData>::iterator it = values.find(key);
|
||||||
if(it == values.end() || (it->second.type != VT_UTF8))
|
if(it == values.end() || (it->second.type != VT_UTF8))
|
||||||
return "";
|
return "";
|
||||||
return it->second.s_value;
|
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);
|
std::map<std::string,ValueData>::iterator it = values.find(key);
|
||||||
if(it == values.end() || (it->second.type != VT_UTF8_SPE))
|
if(it == values.end() || (it->second.type != VT_UTF8_SPE))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -95,8 +91,7 @@ std::vector<std::string> ParamSFOData::GetKeys() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// I'm so sorry Ced but this is highly endian unsafe :(
|
// 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))
|
if (size < sizeof(Header))
|
||||||
return false;
|
return false;
|
||||||
const Header *header = (const Header *)paramsfo;
|
const Header *header = (const Header *)paramsfo;
|
||||||
|
@ -145,8 +140,7 @@ bool ParamSFOData::ReadSFO(const u8 *paramsfo, size_t size)
|
||||||
return true;
|
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;
|
const Header *header = (const Header *)paramsfo;
|
||||||
if (header->magic != 0x46535000)
|
if (header->magic != 0x46535000)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -170,8 +164,7 @@ int ParamSFOData::GetDataOffset(const u8 *paramsfo, std::string dataName)
|
||||||
return -1;
|
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 total_size = 0;
|
||||||
size_t key_size = 0;
|
size_t key_size = 0;
|
||||||
size_t data_size = 0;
|
size_t data_size = 0;
|
||||||
|
@ -256,13 +249,11 @@ bool ParamSFOData::WriteSFO(u8 **paramsfo, size_t *size)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParamSFOData::Clear()
|
void ParamSFOData::Clear() {
|
||||||
{
|
|
||||||
values.clear();
|
values.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParamSFOData::ValueData::SetData(const u8* data, int size)
|
void ParamSFOData::ValueData::SetData(const u8* data, int size) {
|
||||||
{
|
|
||||||
if(u_value)
|
if(u_value)
|
||||||
{
|
{
|
||||||
delete[] u_value;
|
delete[] u_value;
|
||||||
|
@ -276,3 +267,27 @@ void ParamSFOData::ValueData::SetData(const u8* data, int size)
|
||||||
u_size = 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;
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ public:
|
||||||
u8* GetValueData(std::string key, unsigned int *size);
|
u8* GetValueData(std::string key, unsigned int *size);
|
||||||
|
|
||||||
std::vector<std::string> GetKeys();
|
std::vector<std::string> GetKeys();
|
||||||
|
std::string GenerateFakeID(std::string filename = "");
|
||||||
|
|
||||||
bool ReadSFO(const u8 *paramsfo, size_t size);
|
bool ReadSFO(const u8 *paramsfo, size_t size);
|
||||||
bool WriteSFO(u8 **paramsfo, size_t *size);
|
bool WriteSFO(u8 **paramsfo, size_t *size);
|
||||||
|
|
|
@ -95,14 +95,14 @@ std::vector<std::string> DisassembleArm2(const u8 *data, int size) {
|
||||||
bkpt_count++;
|
bkpt_count++;
|
||||||
} else {
|
} else {
|
||||||
if (bkpt_count) {
|
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;
|
bkpt_count = 0;
|
||||||
}
|
}
|
||||||
lines.push_back(buf);
|
lines.push_back(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bkpt_count) {
|
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;
|
return lines;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,7 @@ std::vector<std::string> DisassembleArm64(const u8 *data, int size) {
|
||||||
bkpt_count++;
|
bkpt_count++;
|
||||||
} else {
|
} else {
|
||||||
if (bkpt_count) {
|
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;
|
bkpt_count = 0;
|
||||||
}
|
}
|
||||||
if (true) {
|
if (true) {
|
||||||
|
@ -167,7 +167,7 @@ std::vector<std::string> DisassembleArm64(const u8 *data, int size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bkpt_count) {
|
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;
|
return lines;
|
||||||
}
|
}
|
||||||
|
@ -235,14 +235,14 @@ std::vector<std::string> DisassembleX86(const u8 *data, int size) {
|
||||||
int3_count++;
|
int3_count++;
|
||||||
} else {
|
} else {
|
||||||
if (int3_count) {
|
if (int3_count) {
|
||||||
lines.push_back(StringFromFormat("int3 (x%i)", int3_count));
|
lines.push_back(StringFromFormat("int3 (x%d)", int3_count));
|
||||||
int3_count = 0;
|
int3_count = 0;
|
||||||
}
|
}
|
||||||
lines.push_back(str);
|
lines.push_back(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (int3_count) {
|
if (int3_count) {
|
||||||
lines.push_back(StringFromFormat("int3 (x%i)", int3_count));
|
lines.push_back(StringFromFormat("int3 (x%d)", int3_count));
|
||||||
}
|
}
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "file/file_util.h"
|
#include "file/file_util.h"
|
||||||
#include "util/text/utf8.h"
|
#include "util/text/utf8.h"
|
||||||
|
|
||||||
|
#include "Common/FileUtil.h"
|
||||||
#include "Common/StringUtils.h"
|
#include "Common/StringUtils.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "Common/CommonWindows.h"
|
#include "Common/CommonWindows.h"
|
||||||
|
@ -187,10 +188,9 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) {
|
||||||
std::vector<u8> paramsfo;
|
std::vector<u8> paramsfo;
|
||||||
pspFileSystem.ReadEntireFile(sfoPath, paramsfo);
|
pspFileSystem.ReadEntireFile(sfoPath, paramsfo);
|
||||||
if (g_paramSFO.ReadSFO(paramsfo)) {
|
if (g_paramSFO.ReadSFO(paramsfo)) {
|
||||||
char title[1024];
|
std::string title = StringFromFormat("%s : %s", g_paramSFO.GetValueString("DISC_ID").c_str(), g_paramSFO.GetValueString("TITLE").c_str());
|
||||||
sprintf(title, "%s : %s", g_paramSFO.GetValueString("DISC_ID").c_str(), g_paramSFO.GetValueString("TITLE").c_str());
|
INFO_LOG(LOADER, "%s", title.c_str());
|
||||||
INFO_LOG(LOADER, "%s", title);
|
host->SetWindowTitle(title.c_str());
|
||||||
host->SetWindowTitle(title);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,5 +322,40 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) {
|
||||||
pspFileSystem.Mount("umd0:", fs);
|
pspFileSystem.Mount("umd0:", fs);
|
||||||
|
|
||||||
std::string finalName = ms_path + file + extension;
|
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);
|
return __KernelLoadExec(finalName.c_str(), 0, error_string);
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,33 +363,15 @@ namespace SaveState
|
||||||
std::string GenerateSaveSlotFilename(const std::string &gameFilename, int slot, const char *extension)
|
std::string GenerateSaveSlotFilename(const std::string &gameFilename, int slot, const char *extension)
|
||||||
{
|
{
|
||||||
std::string discId = g_paramSFO.GetValueString("DISC_ID");
|
std::string discId = g_paramSFO.GetValueString("DISC_ID");
|
||||||
|
std::string discVer = g_paramSFO.GetValueString("DISC_VERSION");
|
||||||
std::string fullDiscId;
|
std::string fullDiscId;
|
||||||
if (discId.size()) {
|
if (discId.empty()) {
|
||||||
fullDiscId = StringFromFormat("%s_%s",
|
discId = g_paramSFO.GenerateFakeID();
|
||||||
g_paramSFO.GetValueString("DISC_ID").c_str(),
|
discVer = "1.00";
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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;
|
std::string hostPath;
|
||||||
if (pspFileSystem.GetHostPath(temp, hostPath)) {
|
if (pspFileSystem.GetHostPath(temp, hostPath)) {
|
||||||
return hostPath;
|
return hostPath;
|
||||||
|
@ -590,6 +572,7 @@ namespace SaveState
|
||||||
bool callbackResult;
|
bool callbackResult;
|
||||||
std::string callbackMessage;
|
std::string callbackMessage;
|
||||||
std::string reason;
|
std::string reason;
|
||||||
|
std::string title;
|
||||||
|
|
||||||
I18NCategory *sc = GetI18NCategory("Screen");
|
I18NCategory *sc = GetI18NCategory("Screen");
|
||||||
const char *i18nLoadFailure = sc->T("Load savestate failed", "");
|
const char *i18nLoadFailure = sc->T("Load savestate failed", "");
|
||||||
|
@ -621,7 +604,14 @@ namespace SaveState
|
||||||
|
|
||||||
case SAVESTATE_SAVE:
|
case SAVESTATE_SAVE:
|
||||||
INFO_LOG(SAVESTATE, "Saving state to %s", op.filename.c_str());
|
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) {
|
if (result == CChunkFileReader::ERROR_NONE) {
|
||||||
callbackMessage = sc->T("Saved State");
|
callbackMessage = sc->T("Saved State");
|
||||||
callbackResult = true;
|
callbackResult = true;
|
||||||
|
|
|
@ -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
|
// 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.
|
// likely to collide with any commercial ones.
|
||||||
std::string discID = g_paramSFO.GetValueString("DISC_ID");
|
std::string discID = g_paramSFO.GetValueString("DISC_ID");
|
||||||
if (!discID.empty()) {
|
if (discID.empty()) {
|
||||||
coreParameter.compat.Load(discID);
|
discID = g_paramSFO.GenerateFakeID();
|
||||||
}
|
}
|
||||||
|
coreParameter.compat.Load(discID);
|
||||||
|
|
||||||
Memory::Init();
|
Memory::Init();
|
||||||
mipsr4k.Reset();
|
mipsr4k.Reset();
|
||||||
|
|
|
@ -48,8 +48,11 @@ void TextureReplacer::Init() {
|
||||||
|
|
||||||
void TextureReplacer::NotifyConfigChanged() {
|
void TextureReplacer::NotifyConfigChanged() {
|
||||||
gameID_ = g_paramSFO.GetValueString("DISC_ID");
|
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_) {
|
if (enabled_) {
|
||||||
basePath_ = GetSysDirectory(DIRECTORY_TEXTURES) + gameID_ + "/";
|
basePath_ = GetSysDirectory(DIRECTORY_TEXTURES) + gameID_ + "/";
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,10 @@ FramebufferManagerCommon::~FramebufferManagerCommon() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManagerCommon::Init() {
|
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();
|
BeginFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,9 +169,12 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
||||||
|
|
||||||
// Load shader cache.
|
// Load shader cache.
|
||||||
std::string discID = g_paramSFO.GetValueString("DISC_ID");
|
std::string discID = g_paramSFO.GetValueString("DISC_ID");
|
||||||
|
if (discID.empty()) {
|
||||||
|
discID = g_paramSFO.GenerateFakeID();
|
||||||
|
}
|
||||||
if (discID.size()) {
|
if (discID.size()) {
|
||||||
File::CreateFullPath(GetSysDirectory(DIRECTORY_APP_CACHE));
|
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_);
|
shaderManagerGL_->LoadAndPrecompile(shaderCachePath_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,19 +53,11 @@ void CwCheatScreen::CreateCodeList() {
|
||||||
if (info && info->paramSFOLoaded) {
|
if (info && info->paramSFOLoaded) {
|
||||||
gameTitle = info->paramSFO.GetValueString("DISC_ID");
|
gameTitle = info->paramSFO.GetValueString("DISC_ID");
|
||||||
}
|
}
|
||||||
std::size_t lslash = gamePath_.find_last_of("/");
|
if ((info->id.empty() || !info->disc_total)
|
||||||
std::size_t lastdot = gamePath_.find_last_of(".");
|
&& gamePath_.find("/PSP/GAME/") != std::string::npos) {
|
||||||
std::string extension = gamePath_.substr(lastdot + 1);
|
gameTitle = g_paramSFO.GenerateFakeID(gamePath_);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cheatEngine2 = new CWCheatEngine();
|
cheatEngine2 = new CWCheatEngine();
|
||||||
cheatEngine2->CreateCheatFile();
|
cheatEngine2->CreateCheatFile();
|
||||||
cheatList = cheatEngine2->GetCodesList();
|
cheatList = cheatEngine2->GetCodesList();
|
||||||
|
|
|
@ -262,7 +262,7 @@ bool GameInfo::DeleteAllSaveData() {
|
||||||
void GameInfo::ParseParamSFO() {
|
void GameInfo::ParseParamSFO() {
|
||||||
title = paramSFO.GetValueString("TITLE");
|
title = paramSFO.GetValueString("TITLE");
|
||||||
id = paramSFO.GetValueString("DISC_ID");
|
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_total = paramSFO.GetValueInt("DISC_TOTAL");
|
||||||
disc_number = paramSFO.GetValueInt("DISC_NUMBER");
|
disc_number = paramSFO.GetValueInt("DISC_NUMBER");
|
||||||
// region = paramSFO.GetValueInt("REGION"); // Always seems to be 32768?
|
// region = paramSFO.GetValueInt("REGION"); // Always seems to be 32768?
|
||||||
|
@ -405,6 +405,15 @@ public:
|
||||||
std::lock_guard<std::mutex> lock(info_->lock);
|
std::lock_guard<std::mutex> lock(info_->lock);
|
||||||
info_->paramSFO.ReadSFO(sfoData);
|
info_->paramSFO.ReadSFO(sfoData);
|
||||||
info_->ParseParamSFO();
|
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.
|
// Then, ICON0.PNG.
|
||||||
|
@ -412,6 +421,14 @@ public:
|
||||||
std::lock_guard<std::mutex> lock(info_->lock);
|
std::lock_guard<std::mutex> lock(info_->lock);
|
||||||
pbp.GetSubFileAsString(PBP_ICON0_PNG, &info_->icon.data);
|
pbp.GetSubFileAsString(PBP_ICON0_PNG, &info_->icon.data);
|
||||||
} else {
|
} else {
|
||||||
|
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
|
// Read standard icon
|
||||||
ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock);
|
ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock);
|
||||||
}
|
}
|
||||||
|
@ -444,15 +461,27 @@ handleELF:
|
||||||
// An elf on its own has no usable information, no icons, no nothing.
|
// An elf on its own has no usable information, no icons, no nothing.
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(info_->lock);
|
std::lock_guard<std::mutex> lock(info_->lock);
|
||||||
info_->id = "ELF000000";
|
info_->id = g_paramSFO.GenerateFakeID(gamePath_);
|
||||||
info_->id_version = "ELF000000_1.00";
|
info_->id_version = info_->id + "_1.00";
|
||||||
|
info_->region = GAMEREGION_MAX + 1; // Homebrew
|
||||||
|
|
||||||
info_->paramSFOLoaded = true;
|
info_->paramSFOLoaded = 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
|
// Read standard icon
|
||||||
DEBUG_LOG(LOADER, "Loading unknown.png because there was an ELF");
|
DEBUG_LOG(LOADER, "Loading unknown.png because there was an ELF");
|
||||||
ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock);
|
ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock);
|
||||||
|
}
|
||||||
info_->icon.dataLoaded = true;
|
info_->icon.dataLoaded = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IdentifiedFileType::PSP_SAVEDATA_DIRECTORY:
|
case IdentifiedFileType::PSP_SAVEDATA_DIRECTORY:
|
||||||
|
@ -559,9 +588,18 @@ handleELF:
|
||||||
|
|
||||||
// Fall back to unknown icon if ISO is broken/is a homebrew ISO, override is allowed though
|
// 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)) {
|
if (!ReadFileToString(&umd, "/PSP_GAME/ICON0.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");
|
DEBUG_LOG(LOADER, "Loading unknown.png because no icon was found");
|
||||||
ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock);
|
ReadVFSToString("unknown.png", &info_->icon.data, &info_->lock);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
info_->icon.dataLoaded = true;
|
info_->icon.dataLoaded = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// 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
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -236,6 +236,8 @@ void GameScreen::update() {
|
||||||
"Asia"
|
"Asia"
|
||||||
};
|
};
|
||||||
tvRegion_->SetText(ga->T(regionNames[info->region]));
|
tvRegion_->SetText(ga->T(regionNames[info->region]));
|
||||||
|
} else if (info->region > GAMEREGION_MAX){
|
||||||
|
tvRegion_->SetText(ga->T("Homebrew"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info->id.empty()) {
|
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);
|
std::shared_ptr<GameInfo> info = g_gameInfoCache->GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||||
if (info && info->paramSFOLoaded) {
|
if (info && info->paramSFOLoaded) {
|
||||||
std::string discID = info->paramSFO.GetValueString("DISC_ID");
|
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));
|
screenManager()->push(new GameSettingsScreen(gamePath_, discID, true));
|
||||||
}
|
}
|
||||||
return UI::EVENT_DONE;
|
return UI::EVENT_DONE;
|
||||||
|
|
|
@ -1336,6 +1336,9 @@ UI::EventReturn DeveloperToolsScreen::OnLoadLanguageIni(UI::EventParams &e) {
|
||||||
|
|
||||||
UI::EventReturn DeveloperToolsScreen::OnOpenTexturesIniFile(UI::EventParams &e) {
|
UI::EventReturn DeveloperToolsScreen::OnOpenTexturesIniFile(UI::EventParams &e) {
|
||||||
std::string gameID = g_paramSFO.GetValueString("DISC_ID");
|
std::string gameID = g_paramSFO.GetValueString("DISC_ID");
|
||||||
|
if (gameID.empty()) {
|
||||||
|
gameID = g_paramSFO.GenerateFakeID();
|
||||||
|
}
|
||||||
std::string texturesDirectory = GetSysDirectory(DIRECTORY_TEXTURES) + gameID + "/";
|
std::string texturesDirectory = GetSysDirectory(DIRECTORY_TEXTURES) + gameID + "/";
|
||||||
bool enabled_ = !gameID.empty();
|
bool enabled_ = !gameID.empty();
|
||||||
if (enabled_) {
|
if (enabled_) {
|
||||||
|
|
|
@ -715,7 +715,7 @@ void TakeScreenshot() {
|
||||||
|
|
||||||
std::string gameId = g_paramSFO.GetValueString("DISC_ID");
|
std::string gameId = g_paramSFO.GetValueString("DISC_ID");
|
||||||
if (gameId.empty()) {
|
if (gameId.empty()) {
|
||||||
gameId = "MENU";
|
gameId = g_paramSFO.GenerateFakeID();
|
||||||
}
|
}
|
||||||
|
|
||||||
char filename[2048];
|
char filename[2048];
|
||||||
|
|
|
@ -188,7 +188,7 @@ SaveSlotView::SaveSlotView(const std::string &gameFilename, int slot, UI::Layout
|
||||||
Add(new Spacer(5));
|
Add(new Spacer(5));
|
||||||
|
|
||||||
AsyncImageFileView *fv = Add(new AsyncImageFileView(screenshotFilename_, IS_DEFAULT, wq, new UI::LayoutParams(82 * 2, 47 * 2)));
|
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");
|
I18NCategory *pa = GetI18NCategory("Pause");
|
||||||
|
|
||||||
|
@ -321,6 +321,9 @@ void GamePauseScreen::CreateViews() {
|
||||||
continueChoice->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
continueChoice->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||||
|
|
||||||
std::string gameId = g_paramSFO.GetValueString("DISC_ID");
|
std::string gameId = g_paramSFO.GetValueString("DISC_ID");
|
||||||
|
if (gameId.empty()) {
|
||||||
|
gameId = g_paramSFO.GenerateFakeID();
|
||||||
|
}
|
||||||
if (g_Config.hasGameConfig(gameId)) {
|
if (g_Config.hasGameConfig(gameId)) {
|
||||||
rightColumnItems->Add(new Choice(pa->T("Game Settings")))->OnClick.Handle(this, &GamePauseScreen::OnGameSettings);
|
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);
|
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)
|
UI::EventReturn GamePauseScreen::OnCreateConfig(UI::EventParams &e)
|
||||||
{
|
{
|
||||||
std::string gameId = g_paramSFO.GetValueString("DISC_ID");
|
std::string gameId = g_paramSFO.GetValueString("DISC_ID");
|
||||||
|
if (gameId.empty()) {
|
||||||
|
gameId = g_paramSFO.GenerateFakeID();
|
||||||
|
}
|
||||||
g_Config.createGameConfig(gameId);
|
g_Config.createGameConfig(gameId);
|
||||||
g_Config.changeGameSpecific(gameId);
|
g_Config.changeGameSpecific(gameId);
|
||||||
g_Config.saveGameConfig(gameId);
|
g_Config.saveGameConfig(gameId);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue