mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Fix a bunch of emu features for Homebrew by better identification.
This commit is contained in:
1 parent
c109f849e0
commit
939b26475d
13 files changed
+91
-32
No files matched your search
+37
-22
@@ -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("%05i", sumOfAllLetters);
|
||||
return fakeID;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -322,5 +322,16 @@ 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();
|
||||
|
||||
char title[1024];
|
||||
sprintf(title, "%s : %s", madeUpID.c_str(), homebrewName.c_str());
|
||||
INFO_LOG(LOADER, "%s", title);
|
||||
host->SetWindowTitle(title);
|
||||
|
||||
return __KernelLoadExec(finalName.c_str(), 0, error_string);
|
||||
}
|
||||
+3
-2
@@ -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();
|
||||
|
||||
@@ -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_ + "/";
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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_);
|
||||
}
|
||||
|
||||
|
||||
+14
-3
@@ -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 < 1)
|
||||
&& 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.
|
||||
@@ -444,8 +453,10 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -1331,6 +1331,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_) {
|
||||
|
||||
+1
-1
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user