Implemented sceUtilityGamedataInstallUpdate.

This commit is contained in:
shenweip 2013-09-27 22:52:25 +08:00
parent 89c562d327
commit 7bb798edb6
3 changed files with 131 additions and 11 deletions

View File

@ -19,6 +19,23 @@
#include "ChunkFile.h" #include "ChunkFile.h"
#include "../Core/MemMap.h" #include "../Core/MemMap.h"
std::string saveBasePath = "ms0:/PSP/SAVEDATA/";
namespace
{
std::vector<std::string> GetPSPFileList (std::string dirpath) {
std::vector<std::string> FileList;
auto Fileinfos = pspFileSystem.GetDirListing(dirpath);
std::string info;
for (auto it = Fileinfos.begin(); it != Fileinfos.end(); ++it) {
std::string info = (*it).name;
FileList.push_back(info);
}
return FileList;
}
}
PSPGamedataInstallDialog::PSPGamedataInstallDialog() { PSPGamedataInstallDialog::PSPGamedataInstallDialog() {
} }
@ -26,6 +43,18 @@ PSPGamedataInstallDialog::~PSPGamedataInstallDialog() {
} }
int PSPGamedataInstallDialog::Init(u32 paramAddr) { int PSPGamedataInstallDialog::Init(u32 paramAddr) {
///////////////////////////////////////////////////////
this->paramAddr = paramAddr;
inFileNames = GetPSPFileList ("disc0:/PSP_GAME/INSDIR");
numFiles = inFileNames.size();
readFiles = 0;
progressValue = 0;
allFilesSize = 0;
allReadSize = 0;
for (auto it = inFileNames.begin(); it != inFileNames.end(); ++it) {
allFilesSize += pspFileSystem.GetFileInfo("disc0:/PSP_GAME/INSDIR/" + (*it)).size;
}
//////////////////////////////////////////////////////
// Already running // Already running
if (status != SCE_UTILITY_STATUS_NONE && status != SCE_UTILITY_STATUS_SHUTDOWN) if (status != SCE_UTILITY_STATUS_NONE && status != SCE_UTILITY_STATUS_SHUTDOWN)
return SCE_ERROR_UTILITY_INVALID_STATUS; return SCE_ERROR_UTILITY_INVALID_STATUS;
@ -39,6 +68,61 @@ int PSPGamedataInstallDialog::Init(u32 paramAddr) {
return 0; return 0;
} }
int PSPGamedataInstallDialog::Update() {
if (status == SCE_UTILITY_STATUS_INITIALIZE){
status = SCE_UTILITY_STATUS_RUNNING;
} else if (status == SCE_UTILITY_STATUS_RUNNING) {
std::string fullinFileName;
std::string outFileName;
u64 totalLength;
u64 restLength;
u32 bytesToRead = 4096;
u8 *temp = new u8[4096];
u32 inhandle;
u32 outhandle;
size_t readSize;
if (readFiles < numFiles) {
fullinFileName = "disc0:/PSP_GAME/INSDIR/" + inFileNames[readFiles];
outFileName = GetGameDataInstallFileName(&request, inFileNames[readFiles]);
totalLength = pspFileSystem.GetFileInfo(fullinFileName).size;
restLength = totalLength;
inhandle = pspFileSystem.OpenFile(fullinFileName, FILEACCESS_READ);
if (inhandle != 0) {
outhandle = pspFileSystem.OpenFile(outFileName, (FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE));
if (outhandle != 0) {
while (restLength > 0) {
if (restLength < bytesToRead)
bytesToRead = (u32)restLength;
readSize = pspFileSystem.ReadFile(inhandle, temp, bytesToRead);
if(readSize > 0) {
pspFileSystem.WriteFile(outhandle, temp, readSize);
restLength -= readSize;
allReadSize += readSize;
} else
break;
}
pspFileSystem.CloseFile(outhandle);
}
++readFiles;
pspFileSystem.CloseFile(inhandle);
}
updateProgress();
delete temp;
} else {
//What is this?
request.unknownResult1 = readFiles;
request.unknownResult2 = readFiles;
Memory::WriteStruct(paramAddr,&request);
status = SCE_UTILITY_STATUS_FINISHED;
}
} else if (status == SCE_UTILITY_STATUS_FINISHED) {
status = SCE_UTILITY_STATUS_SHUTDOWN;
}
return 0;
}
int PSPGamedataInstallDialog::Abort() { int PSPGamedataInstallDialog::Abort() {
return PSPDialog::Shutdown(); return PSPDialog::Shutdown();
} }
@ -50,6 +134,25 @@ int PSPGamedataInstallDialog::Shutdown(bool force) {
return PSPDialog::Shutdown(); return PSPDialog::Shutdown();
} }
std::string PSPGamedataInstallDialog::GetGameDataInstallFileName(SceUtilityGamedataInstallParam *param, std::string filename){
if (!param)
return "";
std::string GameDataInstallPath = saveBasePath + param->gameName + param->dataName + "/";
if (!pspFileSystem.GetFileInfo(GameDataInstallPath).exists)
pspFileSystem.MkDir(GameDataInstallPath);
return GameDataInstallPath + filename;
}
void PSPGamedataInstallDialog::updateProgress() {
// Update progress bar(if there is).
// progress value is progress[3] << 24 | progress[2] << 16 | progress[1] << 8 | progress[0].
// We only should update progress[0] here as the max progress value is 100.
progressValue = (int)(allReadSize / allFilesSize) * 100;
request.progress[0] = progressValue;
Memory::WriteStruct(paramAddr,&request);
}
void PSPGamedataInstallDialog::DoState(PointerWrap &p) { void PSPGamedataInstallDialog::DoState(PointerWrap &p) {
auto s = p.Section("PSPGamedataInstallDialog", 0, 1); auto s = p.Section("PSPGamedataInstallDialog", 0, 1);
if (!s) if (!s)
@ -57,4 +160,4 @@ void PSPGamedataInstallDialog::DoState(PointerWrap &p) {
PSPDialog::DoState(p); PSPDialog::DoState(p);
p.Do(request); p.Do(request);
} }

View File

@ -18,6 +18,7 @@
#pragma once #pragma once
#include "Core/Dialog/PSPDialog.h" #include "Core/Dialog/PSPDialog.h"
#include "Core/System.h"
struct SceUtilityGamedataInstallParam { struct SceUtilityGamedataInstallParam {
pspUtilityDialogCommon common; pspUtilityDialogCommon common;
@ -29,10 +30,11 @@ struct SceUtilityGamedataInstallParam {
char gamedataParamsDataTitle[128]; char gamedataParamsDataTitle[128];
char gamedataParamsData[1024]; char gamedataParamsData[1024];
u8 unknown2; u8 unknown2;
char ignore2[7]; char ignore2[3];
char progress[4]; // This is progress value,should be updated.
u32 unknownResult1; u32 unknownResult1;
u32 unknownResult2; u32 unknownResult2;
char ignore[48]; char ignore3[48];
}; };
class PSPGamedataInstallDialog: public PSPDialog { class PSPGamedataInstallDialog: public PSPDialog {
@ -41,12 +43,22 @@ public:
virtual ~PSPGamedataInstallDialog(); virtual ~PSPGamedataInstallDialog();
virtual int Init(u32 paramAddr); virtual int Init(u32 paramAddr);
//virtual int Update(); virtual int Update();
virtual int Shutdown(bool force = false); virtual int Shutdown(bool force = false);
virtual void DoState(PointerWrap &p); virtual void DoState(PointerWrap &p);
int Abort(); int Abort();
std::string GetGameDataInstallFileName(SceUtilityGamedataInstallParam *param, std::string filename);
private: private:
SceUtilityGamedataInstallParam request; SceUtilityGamedataInstallParam request;
u32 paramAddr;
std::vector<std::string> inFileNames;
int numFiles;
int readFiles;
u64 allFilesSize;
u64 allReadSize;
int progressValue;
void updateProgress();
}; };

View File

@ -454,9 +454,10 @@ int sceUtilityGamedataInstallInitStart(u32 paramsAddr)
WARN_LOG(SCEUTILITY, "sceUtilityGamedataInstallInitStart(%08x): wrong dialog type", paramsAddr); WARN_LOG(SCEUTILITY, "sceUtilityGamedataInstallInitStart(%08x): wrong dialog type", paramsAddr);
return SCE_ERROR_UTILITY_WRONG_TYPE; return SCE_ERROR_UTILITY_WRONG_TYPE;
} }
DEBUG_LOG(SCEUTILITY, "sceUtilityGamedataInstallInitStart(%08x)", paramsAddr);
currentDialogType = UTILITY_DIALOG_GAMEDATAINSTALL; currentDialogType = UTILITY_DIALOG_GAMEDATAINSTALL;
currentDialogActive = true; currentDialogActive = true;
DEBUG_LOG(SCEUTILITY, "sceUtilityGamedataInstallInitStart(%08x)", paramsAddr);
return gamedataInstallDialog.Init(paramsAddr); return gamedataInstallDialog.Init(paramsAddr);
} }
@ -472,11 +473,15 @@ int sceUtilityGamedataInstallShutdownStart() {
return gamedataInstallDialog.Shutdown(); return gamedataInstallDialog.Shutdown();
} }
int sceUtilityGamedataInstallUpdate(int speed) { int sceUtilityGamedataInstallUpdate(int Speed) {
ERROR_LOG(SCEUTILITY, "UNIMPL sceUtilityGamedataInstallUpdate(%08x)", speed); if (currentDialogType != UTILITY_DIALOG_GAMEDATAINSTALL)
currentDialogActive = false; {
gamedataInstallDialog.Abort(); WARN_LOG(SCEUTILITY, "sceUtilityGamedataInstallUpdate(): wrong dialog type");
return 0; return SCE_ERROR_UTILITY_WRONG_TYPE;
}
DEBUG_LOG(SCEUTILITY, "sceUtilityGamedataInstallUpdate(%i)", Speed);
return gamedataInstallDialog.Update();
} }
int sceUtilityGamedataInstallGetStatus() int sceUtilityGamedataInstallGetStatus()