mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Save unencrypted PARAM.SFO
This commit is contained in:
parent
1ea6fe7e4d
commit
ab71c3d1d0
@ -19,6 +19,7 @@
|
||||
#include "../System.h"
|
||||
#include "image/png_load.h"
|
||||
#include "../HLE/sceKernelMemory.h"
|
||||
#include "../ELF/ParamSFO.h"
|
||||
|
||||
std::string icon0Name = "ICON0.PNG";
|
||||
std::string icon1Name = "ICON1.PNG";
|
||||
@ -45,8 +46,7 @@ void SavedataParam::Init()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string SavedataParam::GetSaveFilePath(SceUtilitySavedataParam* param, int saveId)
|
||||
std::string SavedataParam::GetSaveDir(SceUtilitySavedataParam* param, int saveId)
|
||||
{
|
||||
if (!param) {
|
||||
return "";
|
||||
@ -56,7 +56,16 @@ std::string SavedataParam::GetSaveFilePath(SceUtilitySavedataParam* param, int s
|
||||
if(saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it
|
||||
dirPath = std::string(GetGameName(param))+GetFilename(saveId);
|
||||
|
||||
return savePath + dirPath;
|
||||
return dirPath;
|
||||
}
|
||||
|
||||
std::string SavedataParam::GetSaveFilePath(SceUtilitySavedataParam* param, int saveId)
|
||||
{
|
||||
if (!param) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return savePath + GetSaveDir(param,saveId);
|
||||
}
|
||||
|
||||
std::string SavedataParam::GetGameName(SceUtilitySavedataParam* param)
|
||||
@ -134,9 +143,27 @@ bool SavedataParam::Save(SceUtilitySavedataParam* param, int saveId)
|
||||
{
|
||||
pspFileSystem.CloseFile(handle);
|
||||
|
||||
// TODO SAVE PARAM.SFO
|
||||
/*data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->dataBuf));
|
||||
writeDataToFile(false, );*/
|
||||
// SAVE PARAM.SFO
|
||||
ParamSFOData sfoFile;
|
||||
sfoFile.SetValue("TITLE",param->sfoParam.title,128);
|
||||
sfoFile.SetValue("SAVEDATA_TITLE",param->sfoParam.savedataTitle,128);
|
||||
sfoFile.SetValue("SAVEDATA_DETAIL",param->sfoParam.savedataTitle,1024);
|
||||
sfoFile.SetValue("PARENTAL_LEVEL",param->sfoParam.parentalLevel,4);
|
||||
sfoFile.SetValue("CATEGORY","MS",4);
|
||||
sfoFile.SetValue("SAVEDATA_DIRECTORY",GetSaveDir(param,saveId),64);
|
||||
sfoFile.SetValue("SAVEDATA_FILE_LIST","",3168);
|
||||
sfoFile.SetValue("SAVEDATA_PARAMS","",128);
|
||||
u8* sfoData;
|
||||
size_t sfoSize;
|
||||
sfoFile.WriteSFO(&sfoData,&sfoSize);
|
||||
std::string sfopath = dirPath+"/"+sfoName;
|
||||
handle = pspFileSystem.OpenFile(sfopath,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE));
|
||||
if(handle)
|
||||
{
|
||||
pspFileSystem.WriteFile(handle, sfoData, sfoSize);
|
||||
pspFileSystem.CloseFile(handle);
|
||||
}
|
||||
delete[] sfoData;
|
||||
|
||||
// SAVE ICON0
|
||||
if(param->icon0FileData.buf)
|
||||
|
@ -134,6 +134,7 @@ class SavedataParam
|
||||
public:
|
||||
static void Init();
|
||||
std::string GetSaveFilePath(SceUtilitySavedataParam* param, int saveId = -1);
|
||||
std::string GetSaveDir(SceUtilitySavedataParam* param, int saveId = -1);
|
||||
bool Delete(SceUtilitySavedataParam* param, int saveId = -1);
|
||||
bool Save(SceUtilitySavedataParam* param, int saveId = -1);
|
||||
bool Load(SceUtilitySavedataParam* param, int saveId = -1);
|
||||
|
@ -38,22 +38,48 @@ struct IndexTable
|
||||
u32 data_table_offset; /* Offset of the param_data from start of data_table */
|
||||
};
|
||||
|
||||
void ParseDataString(const char *key, const char *utfdata, ParamSFOData *sfodata, int maxlen = 0)
|
||||
void ParamSFOData::SetValue(std::string key, unsigned int value, int max_size)
|
||||
{
|
||||
std::string data;
|
||||
if (maxlen)
|
||||
data = std::string(utfdata, maxlen);
|
||||
else
|
||||
data = std::string(utfdata);
|
||||
if (!strcmp(key, "DISC_ID")) {
|
||||
sfodata->discID = data;
|
||||
} else if (!strcmp(key, "TITLE")) {
|
||||
sfodata->title = data;
|
||||
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)
|
||||
{
|
||||
if(key == "ACCOUNT_ID" ||
|
||||
key == "PADDING" ||
|
||||
key == "PARAMS" ||
|
||||
key == "PARAMS2" ||
|
||||
key == "SAVEDATA_FILE_LIST" ||
|
||||
key == "SAVEDATA_PARAMS")
|
||||
{
|
||||
values[key].type = VT_UTF8_SPE;
|
||||
}
|
||||
else
|
||||
{
|
||||
values[key].type = VT_UTF8;
|
||||
}
|
||||
values[key].s_value = value;
|
||||
values[key].max_size = max_size;
|
||||
}
|
||||
|
||||
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::map<std::string,ValueData>::iterator it = values.find(key);
|
||||
if(it == values.end() || (it->second.type != VT_UTF8 && it->second.type != VT_UTF8_SPE))
|
||||
return "";
|
||||
return it->second.s_value;
|
||||
}
|
||||
|
||||
// I'm so sorry Ced but this is highly endian unsafe :(
|
||||
bool ParseParamSFO(const u8 *paramsfo, size_t size, ParamSFOData *data)
|
||||
bool ParamSFOData::ReadSFO(const u8 *paramsfo, size_t size)
|
||||
{
|
||||
const Header *header = (const Header *)paramsfo;
|
||||
if (header->magic != 0x46535000)
|
||||
@ -75,6 +101,7 @@ bool ParseParamSFO(const u8 *paramsfo, size_t size, ParamSFOData *data)
|
||||
{
|
||||
// Unsigned int
|
||||
const u32 *data = (const u32 *)(data_start + indexTables[i].data_table_offset);
|
||||
SetValue(key,*data,indexTables[i].param_max_len);
|
||||
DEBUG_LOG(LOADER, "%s %08x", key, *data);
|
||||
}
|
||||
break;
|
||||
@ -83,7 +110,7 @@ bool ParseParamSFO(const u8 *paramsfo, size_t size, ParamSFOData *data)
|
||||
{
|
||||
const char *utfdata = (const char *)(data_start + indexTables[i].data_table_offset);
|
||||
DEBUG_LOG(LOADER, "%s %s", key, utfdata);
|
||||
ParseDataString(key, utfdata, data, indexTables[i].param_len);
|
||||
SetValue(key,std::string(utfdata,indexTables[i].param_len),indexTables[i].param_max_len);
|
||||
}
|
||||
break;
|
||||
case 0x0204:
|
||||
@ -91,7 +118,7 @@ bool ParseParamSFO(const u8 *paramsfo, size_t size, ParamSFOData *data)
|
||||
{
|
||||
const char *utfdata = (const char *)(data_start + indexTables[i].data_table_offset);
|
||||
DEBUG_LOG(LOADER, "%s %s", key, utfdata);
|
||||
ParseDataString(key, utfdata, data, indexTables[i].param_len);
|
||||
SetValue(key,std::string(utfdata,indexTables[i].param_len),indexTables[i].param_max_len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -99,3 +126,92 @@ bool ParseParamSFO(const u8 *paramsfo, size_t size, ParamSFOData *data)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParamSFOData::WriteSFO(u8 **paramsfo, size_t *size)
|
||||
{
|
||||
size_t total_size = 0;
|
||||
size_t key_size = 0;
|
||||
size_t data_size = 0;
|
||||
|
||||
Header header;
|
||||
header.magic = 0x46535000;
|
||||
header.version = 0x00000101;
|
||||
header.index_table_entries = 0;
|
||||
|
||||
total_size += sizeof(Header);
|
||||
|
||||
// Get size info
|
||||
for(std::map<std::string,ValueData>::iterator it = values.begin(); it != values.end(); it++)
|
||||
{
|
||||
key_size += it->first.size()+1;
|
||||
data_size += it->second.max_size;
|
||||
|
||||
header.index_table_entries++;
|
||||
}
|
||||
|
||||
// Padding
|
||||
while((key_size%4)) key_size++;
|
||||
|
||||
header.key_table_start = sizeof(Header) + header.index_table_entries * sizeof(IndexTable);
|
||||
header.data_table_start = header.key_table_start + key_size;
|
||||
|
||||
total_size += sizeof(IndexTable) * header.index_table_entries;
|
||||
total_size += key_size;
|
||||
total_size += data_size;
|
||||
*size = total_size;
|
||||
|
||||
u8* data = new u8[total_size];
|
||||
*paramsfo = data;
|
||||
memset(data,0,total_size);
|
||||
memcpy(data,&header,sizeof(Header));
|
||||
|
||||
// Now fill
|
||||
IndexTable *index_ptr = (IndexTable*)(data + sizeof(Header));
|
||||
u8* key_ptr = data + header.key_table_start;
|
||||
u8* data_ptr = data + header.data_table_start;
|
||||
|
||||
for(std::map<std::string,ValueData>::iterator it = values.begin(); it != values.end(); it++)
|
||||
{
|
||||
u16 offset = (u16)(key_ptr - (data+header.key_table_start));
|
||||
index_ptr->key_table_offset = offset;
|
||||
offset = (u16)(data_ptr - (data+header.data_table_start));
|
||||
index_ptr->data_table_offset = offset;
|
||||
index_ptr->param_max_len = it->second.max_size;
|
||||
if(it->second.type == VT_INT)
|
||||
{
|
||||
index_ptr->param_fmt = 0x0404;
|
||||
index_ptr->param_len = 4;
|
||||
|
||||
*(int*)data_ptr = it->second.i_value;
|
||||
}
|
||||
else if(it->second.type == VT_UTF8_SPE)
|
||||
{
|
||||
index_ptr->param_fmt = 0x0004;
|
||||
index_ptr->param_len = it->second.s_value.size()+1;
|
||||
|
||||
memcpy(data_ptr,it->second.s_value.c_str(),index_ptr->param_len);
|
||||
data_ptr[index_ptr->param_len] = 0;
|
||||
}
|
||||
else if(it->second.type == VT_UTF8)
|
||||
{
|
||||
index_ptr->param_fmt = 0x0204;
|
||||
index_ptr->param_len = it->second.s_value.size()+1;
|
||||
|
||||
memcpy(data_ptr,it->second.s_value.c_str(),index_ptr->param_len);
|
||||
data_ptr[index_ptr->param_len] = 0;
|
||||
}
|
||||
|
||||
memcpy(key_ptr,it->first.c_str(),it->first.size());
|
||||
key_ptr[it->first.size()] = 0;
|
||||
|
||||
data_ptr += index_ptr->param_max_len;
|
||||
key_ptr += it->first.size()+1;
|
||||
index_ptr++;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -18,11 +18,35 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
struct ParamSFOData
|
||||
class ParamSFOData
|
||||
{
|
||||
std::string discID;
|
||||
std::string title; // utf-8
|
||||
public:
|
||||
void SetValue(std::string key, unsigned int value, int max_size);
|
||||
void SetValue(std::string key, std::string value, int max_size);
|
||||
|
||||
int GetValueInt(std::string key);
|
||||
std::string GetValueString(std::string key);
|
||||
|
||||
bool ReadSFO(const u8 *paramsfo, size_t size);
|
||||
bool WriteSFO(u8 **paramsfo, size_t *size);
|
||||
private:
|
||||
|
||||
enum ValueType
|
||||
{
|
||||
VT_INT,
|
||||
VT_UTF8,
|
||||
VT_UTF8_SPE
|
||||
};
|
||||
struct ValueData
|
||||
{
|
||||
ValueType type;
|
||||
int max_size;
|
||||
std::string s_value;
|
||||
int i_value;
|
||||
};
|
||||
|
||||
std::map<std::string,ValueData> values;
|
||||
};
|
||||
|
||||
bool ParseParamSFO(const u8 *paramsfo, size_t size, ParamSFOData *data);
|
@ -78,10 +78,10 @@ bool Load_PSP_ISO(const char *filename, std::string *error_string)
|
||||
pspFileSystem.ReadFile(fd, paramsfo, fileInfo.size);
|
||||
pspFileSystem.CloseFile(fd);
|
||||
ParamSFOData data;
|
||||
if (ParseParamSFO(paramsfo, (size_t)fileInfo.size, &data))
|
||||
if (data.ReadSFO(paramsfo, (size_t)fileInfo.size))
|
||||
{
|
||||
char title[1024];
|
||||
sprintf(title, "%s : %s", data.discID.c_str(), data.title.c_str());
|
||||
sprintf(title, "%s : %s", data.GetValueString("DISC_ID").c_str(), data.GetValueString("TITLE").c_str());
|
||||
INFO_LOG(LOADER, "%s", title);
|
||||
host->SetWindowTitle(title);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user