2012-12-10 12:08:54 +00:00
|
|
|
// Copyright (c) 2012- 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
|
|
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
// Official git repository and contact information can be found at
|
|
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
|
|
|
|
#include "SavedataParam.h"
|
2012-12-13 21:06:45 +00:00
|
|
|
#include "image/png_load.h"
|
|
|
|
#include "../HLE/sceKernelMemory.h"
|
2012-12-14 19:55:57 +00:00
|
|
|
#include "../ELF/ParamSFO.h"
|
2012-12-19 15:57:22 +00:00
|
|
|
#include "Core/HW/MemoryStick.h"
|
2012-12-19 20:23:52 +00:00
|
|
|
#include "PSPSaveDialog.h"
|
2012-12-10 12:08:54 +00:00
|
|
|
|
|
|
|
std::string icon0Name = "ICON0.PNG";
|
2012-12-14 20:36:54 +00:00
|
|
|
std::string icon1Name = "ICON1.PMF";
|
2012-12-10 12:08:54 +00:00
|
|
|
std::string pic1Name = "PIC1.PNG";
|
2012-12-14 20:36:54 +00:00
|
|
|
std::string snd0Name = "SND0.AT3";
|
2012-12-10 12:08:54 +00:00
|
|
|
std::string sfoName = "PARAM.SFO";
|
|
|
|
|
2012-12-11 07:30:48 +00:00
|
|
|
std::string savePath = "ms0:/PSP/SAVEDATA/";
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2012-12-19 15:57:22 +00:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
int getSizeNormalized(int size)
|
|
|
|
{
|
2012-12-25 01:05:54 +00:00
|
|
|
int sizeCluster = (int)MemoryStick_SectorSize();
|
2012-12-19 17:15:02 +00:00
|
|
|
return ((int)((size + sizeCluster - 1) / sizeCluster)) * sizeCluster;
|
2012-12-19 15:57:22 +00:00
|
|
|
}
|
2012-12-25 01:18:59 +00:00
|
|
|
|
|
|
|
void SetStringFromSFO(ParamSFOData &sfoFile, const char *name, char *str, int strLength)
|
|
|
|
{
|
|
|
|
std::string value = sfoFile.GetValueString(name);
|
|
|
|
strncpy(str, value.c_str(), strLength - 1);
|
|
|
|
str[strLength - 1] = 0;
|
|
|
|
}
|
2012-12-19 15:57:22 +00:00
|
|
|
}
|
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
SavedataParam::SavedataParam()
|
|
|
|
: pspParam(0)
|
|
|
|
, selectedSave(0)
|
|
|
|
, saveNameListData(0)
|
|
|
|
, saveDataList(0)
|
|
|
|
, saveNameListDataCount(0)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void SavedataParam::Init()
|
|
|
|
{
|
2012-12-19 20:23:52 +00:00
|
|
|
if (!pspFileSystem.GetFileInfo(savePath).exists)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
pspFileSystem.MkDir(savePath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-14 19:55:57 +00:00
|
|
|
std::string SavedataParam::GetSaveDir(SceUtilitySavedataParam* param, int saveId)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
if (!param) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2012-12-11 02:09:52 +00:00
|
|
|
std::string dirPath = GetGameName(param)+GetSaveName(param);
|
2012-12-19 20:23:52 +00:00
|
|
|
if (saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it
|
2012-12-11 02:09:52 +00:00
|
|
|
dirPath = std::string(GetGameName(param))+GetFilename(saveId);
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2012-12-14 19:55:57 +00:00
|
|
|
return dirPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string SavedataParam::GetSaveFilePath(SceUtilitySavedataParam* param, int saveId)
|
|
|
|
{
|
|
|
|
if (!param) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
return savePath + GetSaveDir(param,saveId);
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
2012-12-11 02:09:52 +00:00
|
|
|
std::string SavedataParam::GetGameName(SceUtilitySavedataParam* param)
|
|
|
|
{
|
|
|
|
char gameName[14];
|
|
|
|
memcpy(gameName,param->gameName,13);
|
|
|
|
gameName[13] = 0;
|
|
|
|
return gameName;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string SavedataParam::GetSaveName(SceUtilitySavedataParam* param)
|
|
|
|
{
|
|
|
|
char saveName[21];
|
|
|
|
memcpy(saveName,param->saveName,20);
|
|
|
|
saveName[20] = 0;
|
|
|
|
return saveName;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string SavedataParam::GetFileName(SceUtilitySavedataParam* param)
|
|
|
|
{
|
|
|
|
char fileName[14];
|
|
|
|
memcpy(fileName,param->fileName,13);
|
|
|
|
fileName[13] = 0;
|
|
|
|
return fileName;
|
|
|
|
}
|
2012-12-10 12:08:54 +00:00
|
|
|
|
|
|
|
bool SavedataParam::Delete(SceUtilitySavedataParam* param, int saveId)
|
|
|
|
{
|
|
|
|
if (!param)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string dirPath = GetSaveFilePath(param,saveId);
|
2012-12-19 20:23:52 +00:00
|
|
|
if (saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
2012-12-19 20:23:52 +00:00
|
|
|
if (saveDataList[saveId].size == 0) // don't delete no existing file
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pspFileSystem.RmDir(dirPath);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SavedataParam::Save(SceUtilitySavedataParam* param, int saveId)
|
|
|
|
{
|
|
|
|
if (!param) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-12-19 20:23:52 +00:00
|
|
|
u8 *data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->dataBuf));
|
2012-12-10 12:08:54 +00:00
|
|
|
|
|
|
|
std::string dirPath = GetSaveFilePath(param, saveId);
|
|
|
|
|
2012-12-19 20:23:52 +00:00
|
|
|
if (!pspFileSystem.GetFileInfo(dirPath).exists)
|
2012-12-10 12:08:54 +00:00
|
|
|
pspFileSystem.MkDir(dirPath);
|
|
|
|
|
2012-12-11 02:09:52 +00:00
|
|
|
std::string filePath = dirPath+"/"+GetFileName(param);
|
2012-12-10 12:08:54 +00:00
|
|
|
INFO_LOG(HLE,"Saving file with size %u in %s",param->dataBufSize,filePath.c_str());
|
|
|
|
unsigned int handle = pspFileSystem.OpenFile(filePath,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE));
|
2012-12-19 20:23:52 +00:00
|
|
|
if (handle == 0)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
ERROR_LOG(HLE,"Error opening file %s",filePath.c_str());
|
|
|
|
return false;
|
|
|
|
}
|
2012-12-19 20:23:52 +00:00
|
|
|
if (!pspFileSystem.WriteFile(handle, data_, param->dataBufSize))
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
pspFileSystem.CloseFile(handle);
|
|
|
|
ERROR_LOG(HLE,"Error writing file %s",filePath.c_str());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pspFileSystem.CloseFile(handle);
|
|
|
|
|
2012-12-14 19:55:57 +00:00
|
|
|
// SAVE PARAM.SFO
|
|
|
|
ParamSFOData sfoFile;
|
|
|
|
sfoFile.SetValue("TITLE",param->sfoParam.title,128);
|
|
|
|
sfoFile.SetValue("SAVEDATA_TITLE",param->sfoParam.savedataTitle,128);
|
2012-12-14 22:08:56 +00:00
|
|
|
sfoFile.SetValue("SAVEDATA_DETAIL",param->sfoParam.detail,1024);
|
2012-12-14 19:55:57 +00:00
|
|
|
sfoFile.SetValue("PARENTAL_LEVEL",param->sfoParam.parentalLevel,4);
|
|
|
|
sfoFile.SetValue("CATEGORY","MS",4);
|
|
|
|
sfoFile.SetValue("SAVEDATA_DIRECTORY",GetSaveDir(param,saveId),64);
|
2012-12-14 20:36:54 +00:00
|
|
|
sfoFile.SetValue("SAVEDATA_FILE_LIST","",3168); // This need to be filed with the save filename and a hash
|
|
|
|
sfoFile.SetValue("SAVEDATA_PARAMS","",128); // This need to be filled with a hash of the save file encrypted.
|
2012-12-19 20:23:52 +00:00
|
|
|
u8 *sfoData;
|
2012-12-14 19:55:57 +00:00
|
|
|
size_t sfoSize;
|
|
|
|
sfoFile.WriteSFO(&sfoData,&sfoSize);
|
|
|
|
std::string sfopath = dirPath+"/"+sfoName;
|
|
|
|
handle = pspFileSystem.OpenFile(sfopath,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE));
|
2012-12-19 20:23:52 +00:00
|
|
|
if (handle)
|
2012-12-14 19:55:57 +00:00
|
|
|
{
|
|
|
|
pspFileSystem.WriteFile(handle, sfoData, sfoSize);
|
|
|
|
pspFileSystem.CloseFile(handle);
|
|
|
|
}
|
|
|
|
delete[] sfoData;
|
2012-12-10 12:08:54 +00:00
|
|
|
|
|
|
|
// SAVE ICON0
|
2012-12-19 20:23:52 +00:00
|
|
|
if (param->icon0FileData.buf)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->icon0FileData.buf));
|
|
|
|
std::string icon0path = dirPath+"/"+icon0Name;
|
|
|
|
handle = pspFileSystem.OpenFile(icon0path,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE));
|
2012-12-19 20:23:52 +00:00
|
|
|
if (handle)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
pspFileSystem.WriteFile(handle, data_, param->icon0FileData.bufSize);
|
|
|
|
pspFileSystem.CloseFile(handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// SAVE ICON1
|
2012-12-19 20:23:52 +00:00
|
|
|
if (param->icon1FileData.buf)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->icon1FileData.buf));
|
|
|
|
std::string icon1path = dirPath+"/"+icon1Name;
|
|
|
|
handle = pspFileSystem.OpenFile(icon1path,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE));
|
2012-12-19 20:23:52 +00:00
|
|
|
if (handle)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
pspFileSystem.WriteFile(handle, data_, param->icon1FileData.bufSize);
|
|
|
|
pspFileSystem.CloseFile(handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// SAVE PIC1
|
2012-12-19 20:23:52 +00:00
|
|
|
if (param->pic1FileData.buf)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->pic1FileData.buf));
|
|
|
|
std::string pic1path = dirPath+"/"+pic1Name;
|
|
|
|
handle = pspFileSystem.OpenFile(pic1path,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE));
|
2012-12-19 20:23:52 +00:00
|
|
|
if (handle)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
pspFileSystem.WriteFile(handle, data_, param->pic1FileData.bufSize);
|
|
|
|
pspFileSystem.CloseFile(handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-14 20:36:54 +00:00
|
|
|
// Save SND
|
2012-12-19 20:23:52 +00:00
|
|
|
if (param->snd0FileData.buf)
|
2012-12-14 20:36:54 +00:00
|
|
|
{
|
|
|
|
data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->snd0FileData.buf));
|
|
|
|
std::string snd0path = dirPath+"/"+snd0Name;
|
|
|
|
handle = pspFileSystem.OpenFile(snd0path,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE));
|
2012-12-19 20:23:52 +00:00
|
|
|
if (handle)
|
2012-12-14 20:36:54 +00:00
|
|
|
{
|
|
|
|
pspFileSystem.WriteFile(handle, data_, param->snd0FileData.bufSize);
|
|
|
|
pspFileSystem.CloseFile(handle);
|
|
|
|
}
|
|
|
|
}
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-12-19 20:23:52 +00:00
|
|
|
bool SavedataParam::Load(SceUtilitySavedataParam *param, int saveId)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
if (!param) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-12-19 20:23:52 +00:00
|
|
|
u8 *data_ = (u8*)Memory::GetPointer(*((unsigned int*)¶m->dataBuf));
|
2012-12-10 12:08:54 +00:00
|
|
|
|
|
|
|
std::string dirPath = GetSaveFilePath(param, saveId);
|
2012-12-19 20:23:52 +00:00
|
|
|
if (saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
2012-12-19 20:23:52 +00:00
|
|
|
if (saveDataList[saveId].size == 0) // don't read no existing file
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-11 02:09:52 +00:00
|
|
|
std::string filePath = dirPath+"/"+GetFileName(param);
|
2012-12-10 12:08:54 +00:00
|
|
|
INFO_LOG(HLE,"Loading file with size %u in %s",param->dataBufSize,filePath.c_str());
|
|
|
|
u32 handle = pspFileSystem.OpenFile(filePath,FILEACCESS_READ);
|
2012-12-19 20:23:52 +00:00
|
|
|
if (!handle)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
ERROR_LOG(HLE,"Error opening file %s",filePath.c_str());
|
|
|
|
return false;
|
|
|
|
}
|
2012-12-19 20:23:52 +00:00
|
|
|
if (!pspFileSystem.ReadFile(handle, data_, param->dataBufSize))
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
2012-12-11 16:40:26 +00:00
|
|
|
pspFileSystem.CloseFile(handle);
|
2012-12-10 12:08:54 +00:00
|
|
|
ERROR_LOG(HLE,"Error reading file %s",filePath.c_str());
|
|
|
|
return false;
|
|
|
|
}
|
2012-12-11 16:40:26 +00:00
|
|
|
pspFileSystem.CloseFile(handle);
|
2012-12-10 12:08:54 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-12-19 15:57:22 +00:00
|
|
|
std::string SavedataParam::GetSpaceText(int size)
|
|
|
|
{
|
2012-12-19 17:15:02 +00:00
|
|
|
char text[50];
|
|
|
|
|
2012-12-19 15:57:22 +00:00
|
|
|
if(size < 1024)
|
2012-12-19 17:15:02 +00:00
|
|
|
{
|
|
|
|
sprintf(text,"%d B",size);
|
|
|
|
return std::string(text);
|
|
|
|
}
|
2012-12-19 15:57:22 +00:00
|
|
|
|
|
|
|
size /= 1024;
|
|
|
|
|
|
|
|
if(size < 1024)
|
2012-12-19 17:15:02 +00:00
|
|
|
{
|
|
|
|
sprintf(text,"%d KB",size);
|
|
|
|
return std::string(text);
|
|
|
|
}
|
2012-12-19 15:57:22 +00:00
|
|
|
|
|
|
|
size /= 1024;
|
|
|
|
|
|
|
|
if(size < 1024)
|
2012-12-19 17:15:02 +00:00
|
|
|
{
|
|
|
|
sprintf(text,"%d MB",size);
|
|
|
|
return std::string(text);
|
|
|
|
}
|
2012-12-19 15:57:22 +00:00
|
|
|
|
2012-12-19 17:15:02 +00:00
|
|
|
size /= 1024;
|
|
|
|
sprintf(text,"%d GB",size);
|
|
|
|
return std::string(text);
|
2012-12-19 15:57:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// From my test, PSP only answer with data for save of size 1500 (sdk < 2)
|
2012-12-19 17:15:02 +00:00
|
|
|
// Perhaps changed to use mode 22 id SDK >= 2
|
|
|
|
// For now we always return results
|
2012-12-19 20:23:52 +00:00
|
|
|
bool SavedataParam::GetSizes(SceUtilitySavedataParam *param)
|
2012-12-11 02:09:52 +00:00
|
|
|
{
|
|
|
|
if (!param) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-12-19 20:23:52 +00:00
|
|
|
if (Memory::IsValidAddress(param->msFree))
|
2012-12-11 02:09:52 +00:00
|
|
|
{
|
2012-12-19 15:57:22 +00:00
|
|
|
Memory::Write_U32((u32)MemoryStick_SectorSize(),param->msFree); // cluster Size
|
|
|
|
Memory::Write_U32((u32)(MemoryStick_FreeSpace() / MemoryStick_SectorSize()),param->msFree+4); // Free cluster
|
|
|
|
Memory::Write_U32((u32)(MemoryStick_FreeSpace() / 0x400),param->msFree+8); // Free space (in KB)
|
2012-12-25 01:05:54 +00:00
|
|
|
std::string spaceTxt = SavedataParam::GetSpaceText((int)MemoryStick_FreeSpace());
|
2012-12-19 15:57:22 +00:00
|
|
|
Memory::Memset(param->msFree+12,0,spaceTxt.size()+1);
|
|
|
|
Memory::Memcpy(param->msFree+12,spaceTxt.c_str(),spaceTxt.size()); // Text representing free space
|
2012-12-11 02:09:52 +00:00
|
|
|
}
|
2012-12-19 20:23:52 +00:00
|
|
|
if (Memory::IsValidAddress(param->msData))
|
2012-12-11 02:09:52 +00:00
|
|
|
{
|
2012-12-19 15:57:22 +00:00
|
|
|
std::string path = GetSaveFilePath(param,0);
|
|
|
|
PSPFileInfo finfo = pspFileSystem.GetFileInfo(path);
|
|
|
|
if(finfo.exists)
|
|
|
|
{
|
2012-12-19 17:15:02 +00:00
|
|
|
// TODO : fill correctly with the total save size
|
2012-12-19 15:57:22 +00:00
|
|
|
Memory::Write_U32(1,param->msData+36); //1
|
|
|
|
Memory::Write_U32(0x20,param->msData+40); // 0x20
|
|
|
|
Memory::Write_U8(0,param->msData+44); // "32 KB" // 8 u8
|
|
|
|
Memory::Write_U32(0x20,param->msData+52); // 0x20
|
|
|
|
Memory::Write_U8(0,param->msData+56); // "32 KB" // 8 u8
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Memory::Write_U32(1,param->msData+36);
|
|
|
|
Memory::Write_U32(0x20,param->msData+40);
|
|
|
|
Memory::Write_U8(0,param->msData+44);
|
|
|
|
Memory::Write_U32(0x20,param->msData+52);
|
|
|
|
Memory::Write_U8(0,param->msData+56);
|
|
|
|
//return false;
|
|
|
|
}
|
2012-12-11 02:09:52 +00:00
|
|
|
}
|
2012-12-19 20:23:52 +00:00
|
|
|
if (Memory::IsValidAddress(param->utilityData))
|
2012-12-11 02:09:52 +00:00
|
|
|
{
|
2012-12-19 15:57:22 +00:00
|
|
|
int total_size = 0;
|
|
|
|
total_size += getSizeNormalized(1); // SFO;
|
|
|
|
total_size += getSizeNormalized(param->dataSize); // Save Data
|
|
|
|
total_size += getSizeNormalized(param->icon0FileData.size);
|
|
|
|
total_size += getSizeNormalized(param->icon1FileData.size);
|
|
|
|
total_size += getSizeNormalized(param->pic1FileData.size);
|
|
|
|
total_size += getSizeNormalized(param->snd0FileData.size);
|
|
|
|
|
2012-12-25 01:05:54 +00:00
|
|
|
Memory::Write_U32(total_size / (u32)MemoryStick_SectorSize(),param->utilityData); // num cluster
|
2012-12-19 15:57:22 +00:00
|
|
|
Memory::Write_U32(total_size / 0x400,param->utilityData+4); // save size in KB
|
|
|
|
std::string spaceTxt = SavedataParam::GetSpaceText(total_size);
|
|
|
|
Memory::Memset(param->utilityData+8,0,spaceTxt.size()+1);
|
|
|
|
Memory::Memcpy(param->utilityData+8,spaceTxt.c_str(),spaceTxt.size()); // save size in text
|
|
|
|
Memory::Write_U32(total_size / 0x400,param->utilityData+16); // save size in KB
|
|
|
|
spaceTxt = SavedataParam::GetSpaceText(total_size);
|
|
|
|
Memory::Memset(param->utilityData+20,0,spaceTxt.size()+1);
|
|
|
|
Memory::Memcpy(param->utilityData+20,spaceTxt.c_str(),spaceTxt.size()); // save size in text
|
2012-12-11 02:09:52 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-12-19 20:23:52 +00:00
|
|
|
bool SavedataParam::GetList(SceUtilitySavedataParam *param)
|
2012-12-11 02:09:52 +00:00
|
|
|
{
|
|
|
|
if (!param) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-12-19 20:23:52 +00:00
|
|
|
if (Memory::IsValidAddress(param->idListAddr))
|
2012-12-11 02:09:52 +00:00
|
|
|
{
|
|
|
|
Memory::Write_U32(0,param->idListAddr+4);
|
|
|
|
}
|
2012-12-11 09:54:13 +00:00
|
|
|
return true;
|
2012-12-11 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2012-12-13 21:06:45 +00:00
|
|
|
void SavedataParam::Clear()
|
|
|
|
{
|
2012-12-19 20:23:52 +00:00
|
|
|
if (saveDataList)
|
2012-12-13 21:06:45 +00:00
|
|
|
{
|
2012-12-19 20:23:52 +00:00
|
|
|
for (int i = 0; i < saveNameListDataCount; i++)
|
2012-12-13 21:06:45 +00:00
|
|
|
{
|
2012-12-19 20:23:52 +00:00
|
|
|
if (saveDataList[i].textureData != 0)
|
2012-12-13 21:06:45 +00:00
|
|
|
kernelMemory.Free(saveDataList[i].textureData);
|
|
|
|
saveDataList[i].textureData = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete[] saveDataList;
|
|
|
|
saveDataList = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-19 20:23:52 +00:00
|
|
|
u32 SavedataParam::SetPspParam(SceUtilitySavedataParam *param)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
pspParam = param;
|
2012-12-19 20:23:52 +00:00
|
|
|
if (!pspParam)
|
2012-12-13 21:06:45 +00:00
|
|
|
{
|
|
|
|
Clear();
|
2012-12-19 20:23:52 +00:00
|
|
|
return 0;
|
2012-12-13 21:06:45 +00:00
|
|
|
}
|
2012-12-10 12:08:54 +00:00
|
|
|
|
|
|
|
bool listEmptyFile = true;
|
2012-12-19 20:23:52 +00:00
|
|
|
if (param->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD ||
|
2012-12-10 12:08:54 +00:00
|
|
|
param->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE)
|
|
|
|
{
|
|
|
|
listEmptyFile = false;
|
|
|
|
}
|
|
|
|
|
2012-12-19 20:23:52 +00:00
|
|
|
if (param->saveNameList != 0)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
saveNameListData = (char(*)[20])Memory::GetPointer(param->saveNameList);
|
|
|
|
|
|
|
|
// Get number of fileName in array
|
|
|
|
int count = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
count++;
|
|
|
|
} while(saveNameListData[count][0] != 0);
|
|
|
|
|
2012-12-13 21:06:45 +00:00
|
|
|
Clear();
|
2012-12-10 12:08:54 +00:00
|
|
|
saveDataList = new SaveFileInfo[count];
|
|
|
|
|
|
|
|
// get and stock file info for each file
|
|
|
|
int realCount = 0;
|
2012-12-19 20:23:52 +00:00
|
|
|
for (int i = 0; i < count; i++)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
DEBUG_LOG(HLE,"Name : %s",saveNameListData[i]);
|
|
|
|
|
2012-12-11 09:54:13 +00:00
|
|
|
std::string fileDataPath = savePath+GetGameName(param)+saveNameListData[i]+"/"+param->fileName;
|
2012-12-10 12:08:54 +00:00
|
|
|
PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataPath);
|
2012-12-19 20:23:52 +00:00
|
|
|
if (info.exists)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
2012-12-25 01:07:00 +00:00
|
|
|
SetFileInfo(realCount, info);
|
2012-12-14 22:08:56 +00:00
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
DEBUG_LOG(HLE,"%s Exist",fileDataPath.c_str());
|
|
|
|
realCount++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-12-19 20:23:52 +00:00
|
|
|
if (listEmptyFile)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
saveDataList[realCount].size = 0;
|
|
|
|
saveDataList[realCount].saveName = saveNameListData[i];
|
|
|
|
saveDataList[realCount].idx = i;
|
2012-12-13 21:06:45 +00:00
|
|
|
saveDataList[realCount].textureData = 0;
|
2012-12-10 12:08:54 +00:00
|
|
|
DEBUG_LOG(HLE,"Don't Exist");
|
|
|
|
realCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
saveNameListDataCount = realCount;
|
|
|
|
}
|
2012-12-16 11:51:02 +00:00
|
|
|
else // Load info on only save
|
|
|
|
{
|
2012-12-18 21:27:59 +00:00
|
|
|
saveNameListData = 0;
|
2012-12-16 11:51:02 +00:00
|
|
|
|
|
|
|
Clear();
|
|
|
|
saveDataList = new SaveFileInfo[1];
|
|
|
|
|
|
|
|
// get and stock file info for each file
|
|
|
|
DEBUG_LOG(HLE,"Name : %s",GetSaveName(param).c_str());
|
|
|
|
|
|
|
|
std::string fileDataPath = savePath+GetGameName(param)+GetSaveName(param)+"/"+param->fileName;
|
|
|
|
PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataPath);
|
2012-12-19 20:23:52 +00:00
|
|
|
if (info.exists)
|
2012-12-16 11:51:02 +00:00
|
|
|
{
|
2012-12-25 01:07:00 +00:00
|
|
|
SetFileInfo(0, info);
|
2012-12-16 11:51:02 +00:00
|
|
|
|
|
|
|
DEBUG_LOG(HLE,"%s Exist",fileDataPath.c_str());
|
|
|
|
saveNameListDataCount = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-12-19 20:23:52 +00:00
|
|
|
if (listEmptyFile)
|
2012-12-16 11:51:02 +00:00
|
|
|
{
|
|
|
|
saveDataList[0].size = 0;
|
|
|
|
saveDataList[0].saveName = GetSaveName(param);
|
|
|
|
saveDataList[0].idx = 0;
|
|
|
|
saveDataList[0].textureData = 0;
|
|
|
|
DEBUG_LOG(HLE,"Don't Exist");
|
|
|
|
}
|
|
|
|
saveNameListDataCount = 0;
|
2012-12-19 20:23:52 +00:00
|
|
|
return 0;
|
2012-12-16 11:51:02 +00:00
|
|
|
}
|
|
|
|
}
|
2012-12-19 20:23:52 +00:00
|
|
|
return 0;
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
2012-12-25 01:07:00 +00:00
|
|
|
void SavedataParam::SetFileInfo(int idx, PSPFileInfo &info)
|
2012-12-25 01:00:05 +00:00
|
|
|
{
|
|
|
|
saveDataList[idx].size = info.size;
|
|
|
|
saveDataList[idx].saveName = GetSaveName(pspParam);
|
|
|
|
saveDataList[idx].idx = 0;
|
|
|
|
saveDataList[idx].modif_time = info.mtime;
|
|
|
|
|
|
|
|
// Search save image icon0
|
|
|
|
// TODO : If icon0 don't exist, need to use icon1 which is a moving icon. Also play sound
|
|
|
|
std::string fileDataPath2 = savePath+GetGameName(pspParam)+GetSaveName(pspParam)+"/"+icon0Name;
|
|
|
|
PSPFileInfo info2 = pspFileSystem.GetFileInfo(fileDataPath2);
|
|
|
|
if (info2.exists)
|
|
|
|
{
|
|
|
|
u8 *textureDataPNG = new u8[(size_t)info2.size];
|
|
|
|
int handle = pspFileSystem.OpenFile(fileDataPath2,FILEACCESS_READ);
|
|
|
|
pspFileSystem.ReadFile(handle,textureDataPNG,info2.size);
|
|
|
|
pspFileSystem.CloseFile(handle);
|
|
|
|
unsigned char *textureData;
|
|
|
|
int w,h;
|
2012-12-25 01:04:49 +00:00
|
|
|
|
|
|
|
int success = pngLoadPtr(textureDataPNG, (int)info2.size, &w, &h, &textureData, false);
|
2012-12-25 01:00:05 +00:00
|
|
|
delete[] textureDataPNG;
|
2012-12-25 01:04:49 +00:00
|
|
|
|
2012-12-25 01:07:00 +00:00
|
|
|
u32 texSize = w*h*4;
|
|
|
|
u32 atlasPtr;
|
2012-12-25 01:04:49 +00:00
|
|
|
if (success)
|
2012-12-25 01:07:00 +00:00
|
|
|
atlasPtr = kernelMemory.Alloc(texSize, true, "SaveData Icon");
|
|
|
|
if (success && atlasPtr > 0)
|
2012-12-25 01:04:49 +00:00
|
|
|
{
|
|
|
|
saveDataList[idx].textureData = atlasPtr;
|
|
|
|
Memory::Memcpy(atlasPtr, textureData, texSize);
|
|
|
|
free(textureData);
|
|
|
|
saveDataList[idx].textureWidth = w;
|
|
|
|
saveDataList[idx].textureHeight = h;
|
|
|
|
}
|
|
|
|
else
|
2012-12-25 01:07:00 +00:00
|
|
|
{
|
|
|
|
WARN_LOG(HLE, "Unable to load PNG data for savedata.");
|
2012-12-25 01:04:49 +00:00
|
|
|
saveDataList[idx].textureData = 0;
|
2012-12-25 01:07:00 +00:00
|
|
|
}
|
2012-12-25 01:00:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
saveDataList[idx].textureData = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load info in PARAM.SFO
|
|
|
|
fileDataPath2 = savePath+GetGameName(pspParam)+GetSaveName(pspParam)+"/"+sfoName;
|
|
|
|
info2 = pspFileSystem.GetFileInfo(fileDataPath2);
|
|
|
|
if (info2.exists)
|
|
|
|
{
|
|
|
|
u8 *sfoParam = new u8[(size_t)info2.size];
|
|
|
|
int handle = pspFileSystem.OpenFile(fileDataPath2,FILEACCESS_READ);
|
|
|
|
pspFileSystem.ReadFile(handle,sfoParam,info2.size);
|
|
|
|
pspFileSystem.CloseFile(handle);
|
|
|
|
ParamSFOData sfoFile;
|
|
|
|
if (sfoFile.ReadSFO(sfoParam,(size_t)info2.size))
|
|
|
|
{
|
2012-12-25 01:18:59 +00:00
|
|
|
SetStringFromSFO(sfoFile, "TITLE", saveDataList[idx].title, sizeof(saveDataList[idx].title));
|
|
|
|
SetStringFromSFO(sfoFile, "SAVEDATA_TITLE", saveDataList[idx].saveTitle, sizeof(saveDataList[idx].saveTitle));
|
|
|
|
SetStringFromSFO(sfoFile, "SAVEDATA_DETAIL", saveDataList[idx].saveDetail, sizeof(saveDataList[idx].saveDetail));
|
2012-12-25 01:00:05 +00:00
|
|
|
}
|
|
|
|
delete [] sfoParam;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
SceUtilitySavedataParam* SavedataParam::GetPspParam()
|
|
|
|
{
|
|
|
|
return pspParam;
|
|
|
|
}
|
|
|
|
|
|
|
|
int SavedataParam::GetFilenameCount()
|
|
|
|
{
|
|
|
|
return saveNameListDataCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
const SaveFileInfo& SavedataParam::GetFileInfo(int idx)
|
|
|
|
{
|
|
|
|
return saveDataList[idx];
|
|
|
|
}
|
2012-12-11 02:09:52 +00:00
|
|
|
std::string SavedataParam::GetFilename(int idx)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
2012-12-16 11:51:02 +00:00
|
|
|
return saveDataList[idx].saveName;
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int SavedataParam::GetSelectedSave()
|
|
|
|
{
|
|
|
|
return selectedSave;
|
|
|
|
}
|
2012-12-19 20:23:52 +00:00
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
void SavedataParam::SetSelectedSave(int idx)
|
|
|
|
{
|
|
|
|
selectedSave = idx;
|
|
|
|
}
|