Update mode 8

Add mode 12, 13, 17, 22
This commit is contained in:
Xele02 2012-12-31 19:08:46 +01:00
parent ca4c767d38
commit cd8ba8495d
3 changed files with 231 additions and 94 deletions

View File

@ -81,9 +81,12 @@ int PSPSaveDialog::Init(int paramAddr)
display = DS_DELETE_LIST_CHOICE; display = DS_DELETE_LIST_CHOICE;
break; break;
case SCE_UTILITY_SAVEDATA_TYPE_SIZES: case SCE_UTILITY_SAVEDATA_TYPE_SIZES:
display = DS_NONE;
break;
case SCE_UTILITY_SAVEDATA_TYPE_LIST: case SCE_UTILITY_SAVEDATA_TYPE_LIST:
case SCE_UTILITY_SAVEDATA_TYPE_FILES:
case SCE_UTILITY_SAVEDATA_TYPE_SIZES22:
case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE:
case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE:
case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE:
display = DS_NONE; display = DS_NONE;
break; break;
case SCE_UTILITY_SAVEDATA_TYPE_DELETE: // This run on PSP display a list of all save on the PSP. Weird. (Not really, it's to let you free up space) case SCE_UTILITY_SAVEDATA_TYPE_DELETE: // This run on PSP display a list of all save on the PSP. Weird. (Not really, it's to let you free up space)
@ -242,7 +245,7 @@ void PSPSaveDialog::DisplaySaveDataInfo1()
char txt[2048]; char txt[2048];
_dbg_assert_msg_(HLE, sizeof(txt) > sizeof(SaveFileInfo), "Local buffer is too small."); _dbg_assert_msg_(HLE, sizeof(txt) > sizeof(SaveFileInfo), "Local buffer is too small.");
sprintf(txt,"%s\n%02d/%02d/%d %02d:%02d %lld KB\n%s\n%s" snprintf(txt,2048,"%s\n%02d/%02d/%d %02d:%02d %lld KB\n%s\n%s"
, param.GetFileInfo(currentSelectedSave).title , param.GetFileInfo(currentSelectedSave).title
, param.GetFileInfo(currentSelectedSave).modif_time.tm_mday , param.GetFileInfo(currentSelectedSave).modif_time.tm_mday
, param.GetFileInfo(currentSelectedSave).modif_time.tm_mon + 1 , param.GetFileInfo(currentSelectedSave).modif_time.tm_mon + 1
@ -266,7 +269,7 @@ void PSPSaveDialog::DisplaySaveDataInfo2()
else else
{ {
char txt[1024]; char txt[1024];
sprintf(txt,"%s\n%02d/%02d/%d %02d:%02d\n%lld KB" snprintf(txt,1024,"%s\n%02d/%02d/%d %02d:%02d\n%lld KB"
, param.GetFileInfo(currentSelectedSave).saveTitle , param.GetFileInfo(currentSelectedSave).saveTitle
, param.GetFileInfo(currentSelectedSave).modif_time.tm_mday , param.GetFileInfo(currentSelectedSave).modif_time.tm_mday
, param.GetFileInfo(currentSelectedSave).modif_time.tm_mon + 1 , param.GetFileInfo(currentSelectedSave).modif_time.tm_mon + 1
@ -671,10 +674,41 @@ int PSPSaveDialog::Update()
param.GetPspParam()->result = 0; param.GetPspParam()->result = 0;
status = SCE_UTILITY_STATUS_FINISHED; status = SCE_UTILITY_STATUS_FINISHED;
break; break;
// TODO: Don't know the name? case SCE_UTILITY_SAVEDATA_TYPE_FILES:
case 12: if(param.GetFilesList(param.GetPspParam()))
// Pretend we have nothing, always. {
param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; param.GetPspParam()->result = 0;
}
else
{
param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
}
status = SCE_UTILITY_STATUS_FINISHED;
break;
case SCE_UTILITY_SAVEDATA_TYPE_SIZES22:
if(param.GetSizes22(param.GetPspParam()))
{
param.GetPspParam()->result = 0;
}
else
{
param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
}
status = SCE_UTILITY_STATUS_FINISHED;
break;
case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE:
case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE:
if(param.Save(param.GetPspParam(),param.GetSelectedSave()))
param.GetPspParam()->result = 0;
else
param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
status = SCE_UTILITY_STATUS_FINISHED;
break;
case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE:
if(param.Load(param.GetPspParam(),param.GetSelectedSave()))
param.GetPspParam()->result = 0;
else
param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; // not sure if correct code
status = SCE_UTILITY_STATUS_FINISHED; status = SCE_UTILITY_STATUS_FINISHED;
break; break;
default: default:

View File

@ -163,6 +163,8 @@ std::string SavedataParam::GetSaveName(SceUtilitySavedataParam* param)
char saveName[21]; char saveName[21];
memcpy(saveName,param->saveName,20); memcpy(saveName,param->saveName,20);
saveName[20] = 0; saveName[20] = 0;
if(strcmp(saveName,"<>") == 0)
return "";
return saveName; return saveName;
} }
@ -200,95 +202,129 @@ bool SavedataParam::Save(SceUtilitySavedataParam* param, int saveId)
return false; return false;
} }
u8 *data_ = (u8*)Memory::GetPointer(*((unsigned int*)&param->dataBuf));
std::string dirPath = GetSaveFilePath(param, saveId); std::string dirPath = GetSaveFilePath(param, saveId);
if (!pspFileSystem.GetFileInfo(dirPath).exists) if (!pspFileSystem.GetFileInfo(dirPath).exists)
pspFileSystem.MkDir(dirPath); pspFileSystem.MkDir(dirPath);
std::string filePath = dirPath+"/"+GetFileName(param); if(param->dataBuf != 0) // Can launch save without save data in mode 13
INFO_LOG(HLE,"Saving file with size %u in %s",param->dataBufSize,filePath.c_str());
if (!WritePSPFile(filePath, data_, param->dataBufSize))
{ {
ERROR_LOG(HLE,"Error writing file %s",filePath.c_str()); std::string filePath = dirPath+"/"+GetFileName(param);
return false; INFO_LOG(HLE,"Saving file with size %u in %s",param->dataBufSize,filePath.c_str());
u8 *data_ = (u8*)Memory::GetPointer(param->dataBuf);
if (!WritePSPFile(filePath, data_, param->dataBufSize))
{
ERROR_LOG(HLE,"Error writing file %s",filePath.c_str());
return false;
}
} }
else
// SAVE PARAM.SFO
ParamSFOData sfoFile;
std::string sfopath = dirPath+"/"+sfoName;
PSPFileInfo sfoInfo = pspFileSystem.GetFileInfo(sfopath);
if(sfoInfo.exists) // Read old sfo if exist
{ {
// SAVE PARAM.SFO u8 *sfoData = new u8[sfoInfo.size];
ParamSFOData sfoFile; size_t sfoSize = sfoInfo.size;
sfoFile.SetValue("TITLE",param->sfoParam.title,128); if(ReadPSPFile(sfopath,sfoData,sfoSize))
sfoFile.SetValue("SAVEDATA_TITLE",param->sfoParam.savedataTitle,128); {
sfoFile.SetValue("SAVEDATA_DETAIL",param->sfoParam.detail,1024); sfoFile.ReadSFO(sfoData,sfoSize);
sfoFile.SetValue("PARENTAL_LEVEL",param->sfoParam.parentalLevel,4); delete[] sfoData;
sfoFile.SetValue("CATEGORY","MS",4); }
sfoFile.SetValue("SAVEDATA_DIRECTORY",GetSaveDir(param,saveId),64); }
// For each file, 32 bytes for filename, 32 bytes for file hash (0 in PPSSPP) // Update values
u8* tmpData = new u8[3168]; sfoFile.SetValue("TITLE",param->sfoParam.title,128);
sfoFile.SetValue("SAVEDATA_TITLE",param->sfoParam.savedataTitle,128);
sfoFile.SetValue("SAVEDATA_DETAIL",param->sfoParam.detail,1024);
sfoFile.SetValue("PARENTAL_LEVEL",param->sfoParam.parentalLevel,4);
sfoFile.SetValue("CATEGORY","MS",4);
sfoFile.SetValue("SAVEDATA_DIRECTORY",GetSaveDir(param,saveId),64);
// For each file, 13 bytes for filename, 16 bytes for file hash (0 in PPSSPP), 3 byte for padding
u8* tmpData = sfoFile.GetValueData("SAVEDATA_FILE_LIST", 0);
u8* tmpData2 = 0;
if(tmpData == 0)
{
tmpData2 = new u8[3168]; // 99 filename max
tmpData = tmpData2;
memset(tmpData, 0, 3168); memset(tmpData, 0, 3168);
sprintf((char*)tmpData,"%s",GetFileName(param).c_str()); }
sfoFile.SetValue("SAVEDATA_FILE_LIST", tmpData, 3168, 3168); if(param->dataBuf != 0)
delete[] tmpData; {
char* fName = (char*)tmpData;
// No crypted save, so fill with 0 for(int i = 0; i < 99; i++)
tmpData = new u8[128];
memset(tmpData, 0, 128);
sfoFile.SetValue("SAVEDATA_PARAMS", tmpData, 128, 128);
delete[] tmpData;
u8 *sfoData;
size_t sfoSize;
sfoFile.WriteSFO(&sfoData,&sfoSize);
std::string sfopath = dirPath+"/"+sfoName;
WritePSPFile(sfopath, sfoData, sfoSize);
delete[] sfoData;
// SAVE ICON0
if (param->icon0FileData.buf)
{ {
data_ = (u8*)Memory::GetPointer(*((unsigned int*)&param->icon0FileData.buf)); if(fName[0] == 0)
std::string icon0path = dirPath+"/"+icon0Name; break; // End of list
WritePSPFile(icon0path, data_, param->icon0FileData.bufSize); if(strncmp(fName,GetFileName(param).c_str(),20) == 0)
} break; // File already in SFO
// SAVE ICON1
if (param->icon1FileData.buf)
{
data_ = (u8*)Memory::GetPointer(*((unsigned int*)&param->icon1FileData.buf));
std::string icon1path = dirPath+"/"+icon1Name;
WritePSPFile(icon1path, data_, param->icon1FileData.bufSize);
}
// SAVE PIC1
if (param->pic1FileData.buf)
{
data_ = (u8*)Memory::GetPointer(*((unsigned int*)&param->pic1FileData.buf));
std::string pic1path = dirPath+"/"+pic1Name;
WritePSPFile(pic1path, data_, param->pic1FileData.bufSize);
}
// Save SND fName += 32;
if (param->snd0FileData.buf)
{
data_ = (u8*)Memory::GetPointer(*((unsigned int*)&param->snd0FileData.buf));
std::string snd0path = dirPath+"/"+snd0Name;
WritePSPFile(snd0path, data_, param->snd0FileData.bufSize);
} }
snprintf(fName, 20,"%s",GetFileName(param).c_str());
}
sfoFile.SetValue("SAVEDATA_FILE_LIST", tmpData, 3168, 3168);
if(tmpData2)
delete[] tmpData2;
// Save Encryption Data // No crypted save, so fill with 0
{ tmpData = new u8[128];
EncryptFileInfo encryptInfo; memset(tmpData, 0, 128);
int dataSize = sizeof(encryptInfo); // version + key + sdkVersion sfoFile.SetValue("SAVEDATA_PARAMS", tmpData, 128, 128);
memset(&encryptInfo,0,dataSize); delete[] tmpData;
encryptInfo.fileVersion = 1; u8 *sfoData;
encryptInfo.sdkVersion = sceKernelGetCompiledSdkVersion(); size_t sfoSize;
if(param->size > 1500) sfoFile.WriteSFO(&sfoData,&sfoSize);
memcpy(encryptInfo.key,param->key,16); WritePSPFile(sfopath, sfoData, sfoSize);
delete[] sfoData;
std::string encryptInfoPath = dirPath+"/"+"ENCRYPT_INFO.BIN"; // SAVE ICON0
WritePSPFile(encryptInfoPath, (u8*)&encryptInfo, dataSize); if (param->icon0FileData.buf)
} {
u8* data_ = (u8*)Memory::GetPointer(param->icon0FileData.buf);
std::string icon0path = dirPath+"/"+icon0Name;
WritePSPFile(icon0path, data_, param->icon0FileData.bufSize);
}
// SAVE ICON1
if (param->icon1FileData.buf)
{
u8* data_ = (u8*)Memory::GetPointer(param->icon1FileData.buf);
std::string icon1path = dirPath+"/"+icon1Name;
WritePSPFile(icon1path, data_, param->icon1FileData.bufSize);
}
// SAVE PIC1
if (param->pic1FileData.buf)
{
u8* data_ = (u8*)Memory::GetPointer(param->pic1FileData.buf);
std::string pic1path = dirPath+"/"+pic1Name;
WritePSPFile(pic1path, data_, param->pic1FileData.bufSize);
}
// Save SND
if (param->snd0FileData.buf)
{
u8* data_ = (u8*)Memory::GetPointer(param->snd0FileData.buf);
std::string snd0path = dirPath+"/"+snd0Name;
WritePSPFile(snd0path, data_, param->snd0FileData.bufSize);
}
// Save Encryption Data
{
EncryptFileInfo encryptInfo;
int dataSize = sizeof(encryptInfo); // version + key + sdkVersion
memset(&encryptInfo,0,dataSize);
encryptInfo.fileVersion = 1;
encryptInfo.sdkVersion = sceKernelGetCompiledSdkVersion();
if(param->size > 1500)
memcpy(encryptInfo.key,param->key,16);
std::string encryptInfoPath = dirPath+"/"+"ENCRYPT_INFO.BIN";
WritePSPFile(encryptInfoPath, (u8*)&encryptInfo, dataSize);
} }
return true; return true;
} }
@ -299,7 +335,7 @@ bool SavedataParam::Load(SceUtilitySavedataParam *param, int saveId)
return false; return false;
} }
u8 *data_ = (u8*)Memory::GetPointer(*((unsigned int*)&param->dataBuf)); u8 *data_ = (u8*)Memory::GetPointer(param->dataBuf);
std::string dirPath = GetSaveFilePath(param, saveId); std::string dirPath = GetSaveFilePath(param, saveId);
if (saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it if (saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it
@ -317,6 +353,7 @@ bool SavedataParam::Load(SceUtilitySavedataParam *param, int saveId)
ERROR_LOG(HLE,"Error reading file %s",filePath.c_str()); ERROR_LOG(HLE,"Error reading file %s",filePath.c_str());
return false; return false;
} }
param->dataSize = param->dataBufSize;
return true; return true;
} }
@ -351,9 +388,6 @@ std::string SavedataParam::GetSpaceText(int size)
return std::string(text); return std::string(text);
} }
// From my test, PSP only answer with data for save of size 1500 (sdk < 2)
// Perhaps changed to use mode 22 id SDK >= 2
// For now we always return results
bool SavedataParam::GetSizes(SceUtilitySavedataParam *param) bool SavedataParam::GetSizes(SceUtilitySavedataParam *param)
{ {
if (!param) { if (!param) {
@ -449,9 +483,12 @@ bool SavedataParam::GetList(SceUtilitySavedataParam *param)
{ {
u32 baseAddr = outputBuffer + (i*72); u32 baseAddr = outputBuffer + (i*72);
Memory::Write_U32(0x11FF,baseAddr + 0); // mode Memory::Write_U32(0x11FF,baseAddr + 0); // mode
Memory::Write_U64(0,baseAddr + 4); // TODO ctime << this seems to not work, write 0 only on 32bits Memory::Write_U64(0,baseAddr + 4); // TODO ctime
Memory::Write_U64(0,baseAddr + 12); // TODO unknow
Memory::Write_U64(0,baseAddr + 20); // TODO atime Memory::Write_U64(0,baseAddr + 20); // TODO atime
Memory::Write_U64(0,baseAddr + 28); // TODO unknow
Memory::Write_U64(0,baseAddr + 36); // TODO mtime Memory::Write_U64(0,baseAddr + 36); // TODO mtime
Memory::Write_U64(0,baseAddr + 44); // TODO unknow
// folder name without gamename (max 20 u8) // folder name without gamename (max 20 u8)
std::string outName = validDir[i].name.substr(GetGameName(param).size()); std::string outName = validDir[i].name.substr(GetGameName(param).size());
Memory::Memset(baseAddr + 52,0,20); Memory::Memset(baseAddr + 52,0,20);
@ -464,6 +501,65 @@ bool SavedataParam::GetList(SceUtilitySavedataParam *param)
return true; return true;
} }
bool SavedataParam::GetFilesList(SceUtilitySavedataParam *param)
{
if (!param)
{
return false;
}
u32 dataAddr = param->fileListAddr;
if(!Memory::IsValidAddress(dataAddr))
return false;
// TODO : Need to be checked against more game
u32 fileInfosAddr = Memory::Read_U32(dataAddr + 24);
//for Valkyria2, dataAddr+0 and dataAddr+12 has "5" for 5 files
int numFiles = Memory::Read_U32(dataAddr+12);
int foundFiles = 0;
for(int i = 0; i < numFiles; i++)
{
// for each file (80 bytes):
// u32 mode, u32 ??, u64 size, u64 ctime, u64 ??, u64 atime, u64 ???, u64 mtime, u64 ???
// u8[16] filename (or 13 + padding?)
u32 curFileInfoAddr = fileInfosAddr + i*80;
char fileName[16];
strncpy(fileName, Memory::GetCharPointer(curFileInfoAddr + 64),16);
std::string filePath = savePath + GetGameName(param) + GetSaveName(param) + "/" + fileName;
PSPFileInfo info = pspFileSystem.GetFileInfo(filePath);
if(info.exists)
{
Memory::Write_U32(0x21FF, curFileInfoAddr+0);
Memory::Write_U64(info.size, curFileInfoAddr+8);
Memory::Write_U64(0,curFileInfoAddr + 16); // TODO ctime
Memory::Write_U64(0,curFileInfoAddr + 24); // TODO unknow
Memory::Write_U64(0,curFileInfoAddr + 32); // TODO atime
Memory::Write_U64(0,curFileInfoAddr + 40); // TODO unknow
Memory::Write_U64(0,curFileInfoAddr + 48); // TODO mtime
Memory::Write_U64(0,curFileInfoAddr + 56); // TODO unknow
foundFiles++;
}
}
// TODO : verify if return true if at least 1 file found or only if all found
return foundFiles > 0;
}
bool SavedataParam::GetSizes22(SceUtilitySavedataParam *param)
{
if (!param)
{
return false;
}
// TODO code this
return false;
}
void SavedataParam::Clear() void SavedataParam::Clear()
{ {
if (saveDataList) if (saveDataList)

View File

@ -31,7 +31,12 @@ enum SceUtilitySavedataType
SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE = 6, SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE = 6,
SCE_UTILITY_SAVEDATA_TYPE_DELETE = 7, SCE_UTILITY_SAVEDATA_TYPE_DELETE = 7,
SCE_UTILITY_SAVEDATA_TYPE_SIZES = 8, SCE_UTILITY_SAVEDATA_TYPE_SIZES = 8,
SCE_UTILITY_SAVEDATA_TYPE_LIST = 11 SCE_UTILITY_SAVEDATA_TYPE_LIST = 11,
SCE_UTILITY_SAVEDATA_TYPE_FILES = 12,
SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE = 13,
SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE = 15,
SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE = 17,
SCE_UTILITY_SAVEDATA_TYPE_SIZES22 = 22
} ; } ;
// title, savedataTitle, detail: parts of the unencrypted SFO // title, savedataTitle, detail: parts of the unencrypted SFO
@ -81,7 +86,7 @@ struct SceUtilitySavedataParam
char unused2[3]; char unused2[3];
/** pointer to a buffer that will contain data file unencrypted data */ /** pointer to a buffer that will contain data file unencrypted data */
int dataBuf; // Initially void*, but void* in 64bit system take 8 bytes. u32 dataBuf; // Initially void*, but void* in 64bit system take 8 bytes.
/** size of allocated space to dataBuf */ /** size of allocated space to dataBuf */
SceSize dataBufSize; SceSize dataBufSize;
SceSize dataSize; // Size of the actual save data SceSize dataSize; // Size of the actual save data
@ -98,9 +103,9 @@ struct SceUtilitySavedataParam
int abortStatus; int abortStatus;
// Function SCE_UTILITY_SAVEDATA_TYPE_SIZES // Function SCE_UTILITY_SAVEDATA_TYPE_SIZES
int msFree; u32 msFree;
int msData; u32 msData;
int utilityData; u32 utilityData;
char key[16]; char key[16];
@ -108,13 +113,13 @@ struct SceUtilitySavedataParam
int multiStatus; int multiStatus;
// Function 11 LIST // Function 11 LIST
int idListAddr; u32 idListAddr;
// Function 12 FILES // Function 12 FILES
int fileListAddr; u32 fileListAddr;
// Function 22 GETSIZES // Function 22 GETSIZES
int sizeAddr; u32 sizeAddr;
}; };
@ -147,6 +152,8 @@ public:
bool Load(SceUtilitySavedataParam* param, int saveId = -1); bool Load(SceUtilitySavedataParam* param, int saveId = -1);
bool GetSizes(SceUtilitySavedataParam* param); bool GetSizes(SceUtilitySavedataParam* param);
bool GetList(SceUtilitySavedataParam* param); bool GetList(SceUtilitySavedataParam* param);
bool GetFilesList(SceUtilitySavedataParam* param);
bool GetSizes22(SceUtilitySavedataParam* param);
std::string GetGameName(SceUtilitySavedataParam* param); std::string GetGameName(SceUtilitySavedataParam* param);
std::string GetSaveName(SceUtilitySavedataParam* param); std::string GetSaveName(SceUtilitySavedataParam* param);