Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Savedata management screen #7808

Merged
merged 9 commits into from
Jun 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,7 @@ set(NativeAppSource
UI/OnScreenDisplay.cpp
UI/ControlMappingScreen.cpp
UI/ReportScreen.cpp
UI/SavedataScreen.cpp
UI/Store.cpp
UI/CwCheatScreen.cpp
UI/InstallZipScreen.cpp
Expand Down
2 changes: 0 additions & 2 deletions Core/HLE/sceIo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,6 @@ static void __IoFreeFd(int fd, u32 &error) {
// TODO: We don't do any of that yet.
// For now, let's at least delay the callback notification.
static void __IoAsyncNotify(u64 userdata, int cyclesLate) {
PROFILE_THIS_SCOPE("io_rw");

int fd = (int) userdata;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, why? The goal is to capture time in __IoCompleteAsyncIO essentially.

-[Unknown]

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to remove it because our profiler can't handle entering the same scope recursively.

However shouldn't have done it in this branch, and should probably rather have fixed the profiler :)


u32 error;
Expand Down
32 changes: 25 additions & 7 deletions Core/Loaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader)
}

std::string extension = fileLoader->Extension();
if (!strcasecmp(extension.c_str(),".iso"))
if (!strcasecmp(extension.c_str(), ".iso"))
{
// may be a psx iso, they have 2352 byte sectors. You never know what some people try to open
if ((fileLoader->FileSize() % 2352) == 0)
Expand All @@ -780,26 +780,36 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader)
{
return FILETYPE_PSP_ISO;
}

else if (!strcasecmp(extension.c_str(),".ppst"))
{
return FILETYPE_PPSSPP_SAVESTATE;
}

// First, check if it's a directory with an EBOOT.PBP in it.
if (fileLoader->IsDirectory()) {
std::string filename = fileLoader->Path();
if (filename.size() > 4) {
FileInfo ebootInfo;
FileInfo fileInfo;
// Check for existence of EBOOT.PBP, as required for "Directory games".
if (getFileInfo((filename + "/EBOOT.PBP").c_str(), &ebootInfo)) {
if (ebootInfo.exists) {
if (getFileInfo((filename + "/EBOOT.PBP").c_str(), &fileInfo)) {
if (fileInfo.exists) {
return FILETYPE_PSP_PBP_DIRECTORY;
}
}

// check if it's a disc directory
if (getFileInfo((filename + "/PSP_GAME").c_str(), &ebootInfo)) {
if (ebootInfo.exists) {
if (getFileInfo((filename + "/PSP_GAME").c_str(), &fileInfo)) {
if (fileInfo.exists) {
return FILETYPE_PSP_DISC_DIRECTORY;
}
}

// Not that, okay, let's guess it's a savedata directory if it has a param.sfo...
if (getFileInfo((filename + "/PARAM.SFO").c_str(), &fileInfo)) {
if (fileInfo.exists) {
return FILETYPE_PSP_SAVEDATA_DIRECTORY;
}
}
}

return FILETYPE_NORMAL_DIRECTORY;
Expand Down Expand Up @@ -990,6 +1000,14 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) {
*error_string = "Just a directory.";
break;

case FILETYPE_PPSSPP_SAVESTATE:
*error_string = "This is a saved state, not a game."; // Actually, we could make it load it...
break;

case FILETYPE_PSP_SAVEDATA_DIRECTORY:
*error_string = "This is save data, not a game."; // Actually, we could make it load it...
break;

case FILETYPE_UNKNOWN_BIN:
case FILETYPE_UNKNOWN_ELF:
case FILETYPE_UNKNOWN:
Expand Down
3 changes: 3 additions & 0 deletions Core/Loaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ enum IdentifiedFileType {

FILETYPE_NORMAL_DIRECTORY,

FILETYPE_PSP_SAVEDATA_DIRECTORY,
FILETYPE_PPSSPP_SAVESTATE,

FILETYPE_UNKNOWN
};

Expand Down
2 changes: 2 additions & 0 deletions Core/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,8 @@ std::string GetSysDirectory(PSPDirectories directoryType) {
return g_Config.memStickDirectory + "PAUTH/";
case DIRECTORY_DUMP:
return g_Config.memStickDirectory + "PSP/SYSTEM/DUMP/";
case DIRECTORY_SAVESTATE:
return g_Config.memStickDirectory + "PSP/PPSSPP_STATE/";
// Just return the memory stick root if we run into some sort of problem.
default:
ERROR_LOG(FILESYS, "Unknown directory type.");
Expand Down
1 change: 1 addition & 0 deletions Core/System.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ enum PSPDirectories {
DIRECTORY_SAVEDATA,
DIRECTORY_PAUTH,
DIRECTORY_DUMP,
DIRECTORY_SAVESTATE,
};


Expand Down
2 changes: 1 addition & 1 deletion GPU/Software/SoftGpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
}

if (!(gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME)) {
TransformUnit::SubmitSpline(control_points, indices, sp_ucount, sp_vcount, sp_utype, sp_vtype, gstate.getPatchPrimitiveType(), gstate.vertType);
//TransformUnit::SubmitSpline(control_points, indices, sp_ucount, sp_vcount, sp_utype, sp_vtype, gstate.getPatchPrimitiveType(), gstate.vertType);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, not sure if this belonged in this branch either?

-[Unknown]

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It crashes, but yeah, you're right, it should have been separate.

}
framebufferDirty_ = true;
DEBUG_LOG(G3D,"DL DRAW SPLINE: %i x %i, %i x %i", sp_ucount, sp_vcount, sp_utype, sp_vtype);
Expand Down
7 changes: 3 additions & 4 deletions UI/DevScreens.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ class DevMenu : public PopupScreen {
public:
DevMenu() : PopupScreen("Dev Tools") {}

virtual void CreatePopupContents(UI::ViewGroup *parent);

virtual void dialogFinished(const Screen *dialog, DialogResult result);
void CreatePopupContents(UI::ViewGroup *parent) override;
void dialogFinished(const Screen *dialog, DialogResult result) override;

protected:
UI::EventReturn OnLogView(UI::EventParams &e);
Expand All @@ -48,7 +47,7 @@ class DevMenu : public PopupScreen {
class LogConfigScreen : public UIDialogScreenWithBackground {
public:
LogConfigScreen() {}
virtual void CreateViews();
virtual void CreateViews() override;

private:
UI::EventReturn OnToggleAll(UI::EventParams &e);
Expand Down
97 changes: 78 additions & 19 deletions UI/GameInfoCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ GameInfo::~GameInfo() {
delete fileLoader;
}

bool GameInfo::DeleteGame() {
bool GameInfo::Delete() {
switch (fileType) {
case FILETYPE_PSP_ISO:
case FILETYPE_PSP_ISO_NP:
Expand All @@ -63,9 +63,9 @@ bool GameInfo::DeleteGame() {
return true;
}
case FILETYPE_PSP_PBP_DIRECTORY:
case FILETYPE_PSP_SAVEDATA_DIRECTORY:
{
// TODO: This could be handled by Core/Util/GameManager too somehow.

const char *directoryToRemove = filePath_.c_str();
INFO_LOG(HLE, "Deleting %s", directoryToRemove);
if (!File::DeleteDirRecursively(directoryToRemove)) {
Expand All @@ -76,6 +76,12 @@ bool GameInfo::DeleteGame() {
return true;
}
case FILETYPE_PSP_ELF:
case FILETYPE_PPSSPP_SAVESTATE:
case FILETYPE_UNKNOWN_BIN:
case FILETYPE_UNKNOWN_ELF:
case FILETYPE_ARCHIVE_RAR:
case FILETYPE_ARCHIVE_ZIP:
case FILETYPE_ARCHIVE_7Z:
{
const char *fileToRemove = filePath_.c_str();
deleteFile(fileToRemove);
Expand All @@ -87,16 +93,35 @@ bool GameInfo::DeleteGame() {
}
}

static int64_t GetDirectoryRecursiveSize(std::string path) {
std::vector<FileInfo> fileInfo;
getFilesInDir(path.c_str(), &fileInfo);
int64_t sizeSum = 0;
// Note: getFileInDir does not fill in fileSize properly.
for (size_t i = 0; i < fileInfo.size(); i++) {
FileInfo finfo;
getFileInfo(fileInfo[i].fullName.c_str(), &finfo);
if (!finfo.isDirectory)
sizeSum += finfo.size;
else
sizeSum += GetDirectoryRecursiveSize(finfo.fullName);
}
return sizeSum;
}

u64 GameInfo::GetGameSizeInBytes() {
switch (fileType) {
case FILETYPE_PSP_PBP_DIRECTORY:
// TODO: Need to recurse here.
return 0;
case FILETYPE_PSP_SAVEDATA_DIRECTORY:
{
return GetDirectoryRecursiveSize(filePath_);
}
default:
return GetFileLoader()->FileSize();
}
}

// Not too meaningful if the object itself is a savedata directory...
std::vector<std::string> GameInfo::GetSaveDataDirectories() {
std::string memc = GetSysDirectory(DIRECTORY_SAVEDATA);

Expand All @@ -117,6 +142,9 @@ std::vector<std::string> GameInfo::GetSaveDataDirectories() {
}

u64 GameInfo::GetSaveDataSizeInBytes() {
if (fileType == FILETYPE_PSP_SAVEDATA_DIRECTORY || fileType == FILETYPE_PPSSPP_SAVESTATE) {
return 0;
}
std::vector<std::string> saveDataDir = GetSaveDataDirectories();

u64 totalSize = 0;
Expand All @@ -132,7 +160,7 @@ u64 GameInfo::GetSaveDataSizeInBytes() {
filesSizeInDir += finfo.size;
}
if (filesSizeInDir < 0xA00000) {
//Generally the savedata size in a dir shouldn't be more than 10MB.
// HACK: Generally the savedata size in a dir shouldn't be more than 10MB.
totalSize += filesSizeInDir;
}
filesSizeInDir = 0;
Expand All @@ -141,6 +169,9 @@ u64 GameInfo::GetSaveDataSizeInBytes() {
}

u64 GameInfo::GetInstallDataSizeInBytes() {
if (fileType == FILETYPE_PSP_SAVEDATA_DIRECTORY || fileType == FILETYPE_PPSSPP_SAVESTATE) {
return 0;
}
std::vector<std::string> saveDataDir = GetSaveDataDirectories();

u64 totalSize = 0;
Expand All @@ -156,7 +187,7 @@ u64 GameInfo::GetInstallDataSizeInBytes() {
filesSizeInDir += finfo.size;
}
if (filesSizeInDir >= 0xA00000) {
// Generally the savedata size in a dir shouldn't be more than 10MB.
// HACK: Generally the savedata size in a dir shouldn't be more than 10MB.
// This is probably GameInstall data.
totalSize += filesSizeInDir;
}
Expand Down Expand Up @@ -371,6 +402,33 @@ class GameInfoWorkItem : public PrioritizedWorkQueueItem {
}
break;

case FILETYPE_PSP_SAVEDATA_DIRECTORY:
{
SequentialHandleAllocator handles;
VirtualDiscFileSystem umd(&handles, gamePath_.c_str());

// Alright, let's fetch the PARAM.SFO.
std::string paramSFOcontents;
if (ReadFileToString(&umd, "/PARAM.SFO", &paramSFOcontents, 0)) {
lock_guard lock(info_->lock);
info_->paramSFO.ReadSFO((const u8 *)paramSFOcontents.data(), paramSFOcontents.size());
info_->ParseParamSFO();
}

ReadFileToString(&umd, "/ICON0.PNG", &info_->iconTextureData, &info_->lock);
info_->iconDataLoaded = true;
if (info_->wantFlags & GAMEINFO_WANTBG) {
ReadFileToString(&umd, "/PIC1.PNG", &info_->pic1TextureData, &info_->lock);
info_->pic1DataLoaded = true;
}
break;
}

case FILETYPE_PPSSPP_SAVESTATE:
{
break;
}

case FILETYPE_PSP_DISC_DIRECTORY:
{
info_->fileType = FILETYPE_PSP_ISO;
Expand Down Expand Up @@ -399,6 +457,7 @@ class GameInfoWorkItem : public PrioritizedWorkQueueItem {
}
break;
}

case FILETYPE_PSP_ISO:
case FILETYPE_PSP_ISO_NP:
{
Expand Down Expand Up @@ -517,7 +576,6 @@ class GameInfoWorkItem : public PrioritizedWorkQueueItem {
};



GameInfoCache::~GameInfoCache() {
Clear();
}
Expand All @@ -531,18 +589,6 @@ void GameInfoCache::Shutdown() {
StopProcessingWorkQueue(gameInfoWQ_);
}

void GameInfoCache::Save() {
// TODO
}

void GameInfoCache::Load() {
// TODO
}

void GameInfoCache::Decimate() {
// TODO
}

void GameInfoCache::Clear() {
if (gameInfoWQ_)
gameInfoWQ_->Flush();
Expand Down Expand Up @@ -610,6 +656,19 @@ void GameInfoCache::FlushBGs() {
}
}

void GameInfoCache::PurgeType(IdentifiedFileType fileType) {
if (gameInfoWQ_)
gameInfoWQ_->Flush();
restart:
for (auto iter = info_.begin(); iter != info_.end(); iter++) {
if (iter->second->fileType == fileType) {
info_.erase(iter);
goto restart;
}
}
}


// Runs on the main thread.
GameInfo *GameInfoCache::GetInfo(Thin3DContext *thin3d, const std::string &gamePath, int wantFlags) {
GameInfo *info = 0;
Expand Down
15 changes: 7 additions & 8 deletions UI/GameInfoCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class Thin3DTexture;
// does on the PSP, namely checking for and deleting savedata, and similar things.
// Only cares about games that are installed on the current device.

// A GameInfo object can also represent a piece of savedata.

// Guessed from GameID, not necessarily accurate
enum GameRegion {
GAMEREGION_JAPAN,
Expand Down Expand Up @@ -94,14 +96,15 @@ class GameInfo {
public:
GameInfo()
: disc_total(0), disc_number(0), region(-1), fileType(FILETYPE_UNKNOWN), paramSFOLoaded(false),
iconTexture(NULL), pic0Texture(NULL), pic1Texture(NULL), wantFlags(0),
timeIconWasLoaded(0.0), timePic0WasLoaded(0.0), timePic1WasLoaded(0.0),
iconTexture(nullptr), pic0Texture(nullptr), pic1Texture(nullptr), wantFlags(0),
lastAccessedTime(0.0), timeIconWasLoaded(0.0), timePic0WasLoaded(0.0), timePic1WasLoaded(0.0),
gameSize(0), saveDataSize(0), installDataSize(0), fileLoader(nullptr) {}
~GameInfo();

bool DeleteGame(); // Better be sure what you're doing when calling this.
bool Delete(); // Better be sure what you're doing when calling this.
bool DeleteAllSaveData();
bool LoadFromPath(const std::string &gamePath);

FileLoader *GetFileLoader();
void DisposeFileLoader();

Expand Down Expand Up @@ -174,19 +177,15 @@ class GameInfoCache {
void Init();
void Shutdown();
void Clear();
void PurgeType(IdentifiedFileType fileType);

// All data in GameInfo including iconTexture may be zero the first time you call this
// but filled in later asynchronously in the background. So keep calling this,
// redrawing the UI often. Only set flags to GAMEINFO_WANTBG or WANTSND if you really want them
// because they're big. bgTextures and sound may be discarded over time as well.
GameInfo *GetInfo(Thin3DContext *thin3d, const std::string &gamePath, int wantFlags);
void Decimate(); // Deletes old info.
void FlushBGs(); // Gets rid of all BG textures. Also gets rid of bg sounds.

// TODO - save cache between sessions
void Save();
void Load();

PrioritizedWorkQueue *WorkQueue() { return gameInfoWQ_; }

private:
Expand Down
2 changes: 1 addition & 1 deletion UI/GameScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ UI::EventReturn GameScreen::OnDeleteGame(UI::EventParams &e) {
void GameScreen::CallbackDeleteGame(bool yes) {
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
if (yes) {
info->DeleteGame();
info->Delete();
g_gameInfoCache.Clear();
screenManager()->switchScreen(new MainScreen());
}
Expand Down
Loading