diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index 7edd337ee4..72468c6547 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -1000,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: diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 693660d525..878122f1bd 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -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); } framebufferDirty_ = true; DEBUG_LOG(G3D,"DL DRAW SPLINE: %i x %i, %i x %i", sp_ucount, sp_vcount, sp_utype, sp_vtype); diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 0cb78a9502..dac13d1a6e 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -651,6 +651,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; diff --git a/UI/GameInfoCache.h b/UI/GameInfoCache.h index 90f66ffb1a..2a26d22b5a 100644 --- a/UI/GameInfoCache.h +++ b/UI/GameInfoCache.h @@ -104,6 +104,7 @@ public: bool Delete(); // Better be sure what you're doing when calling this. bool DeleteAllSaveData(); bool LoadFromPath(const std::string &gamePath); + FileLoader *GetFileLoader(); void DisposeFileLoader(); @@ -176,6 +177,7 @@ public: 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, diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 1052b6ab34..6e9c7d9623 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -971,6 +971,12 @@ UI::EventReturn MainScreen::OnGameSelected(UI::EventParams &e) { #else std::string path = e.s; #endif + GameInfo *ginfo = 0; + ginfo = g_gameInfoCache.GetInfo(nullptr, path, GAMEINFO_WANTBG); + if (ginfo && ginfo->fileType == FILETYPE_PSP_SAVEDATA_DIRECTORY) { + return UI::EVENT_DONE; + } + SetBackgroundAudioGame(path); lockBackgroundAudio_ = true; screenManager()->push(new GameScreen(path)); diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index f1857429a0..999284a65f 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -40,6 +40,17 @@ class SavedataButton; +std::string GetFileDateAsString(std::string filename) { + tm time; + if (File::GetModifTime(filename, time)) { + char buf[256]; + // TODO: Use local time format? Americans and some others might not like ISO standard :) + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &time); + return std::string(buf); + } + return "never"; +} + class SavedataPopupScreen : public PopupScreen { public: SavedataPopupScreen(std::string savePath, std::string title) : PopupScreen(title), savePath_(savePath) { @@ -63,8 +74,10 @@ public: toprow->Add(new Thin3DTextureView(ginfo->iconTexture, IS_FIXED, new LinearLayoutParams(Margins(10, 5)))); } LinearLayout *topright = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0)); + topright->SetSpacing(1.0f); topright->Add(new TextView(savedata_title, 0, false)); topright->Add(new TextView(StringFromFormat("%d kB", ginfo->gameSize / 1024), 0, true)); + topright->Add(new TextView(GetFileDateAsString(savePath_ + "/PARAM.SFO"), 0, true)); toprow->Add(topright); root->Add(new Spacer(3.0)); root->Add(new TextView(savedata_detail, 0, true, new LinearLayoutParams(Margins(10, 0)))); @@ -75,14 +88,15 @@ public: PrioritizedWorkQueue *wq = g_gameInfoCache.WorkQueue(); toprow->Add(new AsyncImageFileView(image_path, IS_DEFAULT, wq, new UI::LayoutParams(500, 500/16*9))); } else { - toprow->Add(new TextView("no screenshot")); + toprow->Add(new TextView("no screenshot", new LinearLayoutParams(Margins(10, 5)))); } + root->Add(new TextView(GetFileDateAsString(savePath_), 0, true, new LinearLayoutParams(Margins(10, 5)))); } I18NCategory *di = GetI18NCategory("Dialog"); LinearLayout *buttons = new LinearLayout(ORIENT_HORIZONTAL); - buttons->Add(new Button(di->T("Delete"), new LinearLayoutParams(1.0)))->OnClick.Handle(this, &SavedataPopupScreen::OnDeleteButtonClick); buttons->Add(new Button(di->T("Back"), new LinearLayoutParams(1.0)))->OnClick.Handle(this, &UIScreen::OnBack); + buttons->Add(new Button(di->T("Delete"), new LinearLayoutParams(1.0)))->OnClick.Handle(this, &SavedataPopupScreen::OnDeleteButtonClick); root->Add(buttons); } @@ -212,8 +226,10 @@ void SavedataButton::Draw(UIContext &dc) { dc.PushScissor(bounds_); if (title_.empty() && !ginfo->title.empty()) { - std::string savedata_title = ginfo->paramSFO.GetValueString("SAVEDATA_TITLE"); title_ = CleanSaveString(ginfo->title); + } + if (subtitle_.empty() && ginfo->gameSize > 0) { + std::string savedata_title = ginfo->paramSFO.GetValueString("SAVEDATA_TITLE"); subtitle_ = CleanSaveString(savedata_title) + StringFromFormat(" (%d kB)", ginfo->gameSize / 1024); } @@ -249,6 +265,11 @@ SavedataBrowser::SavedataBrowser(std::string path, UI::LayoutParams *layoutParam Refresh(); } +SavedataBrowser::~SavedataBrowser() { + g_gameInfoCache.PurgeType(FILETYPE_PPSSPP_SAVESTATE); + g_gameInfoCache.PurgeType(FILETYPE_PSP_SAVEDATA_DIRECTORY); +} + void SavedataBrowser::Refresh() { using namespace UI; @@ -299,7 +320,7 @@ UI::EventReturn SavedataBrowser::SavedataButtonClick(UI::EventParams &e) { return UI::EVENT_DONE; } -SavedataScreen::SavedataScreen(std::string gamePath) : UIScreenWithGameBackground(gamePath) { +SavedataScreen::SavedataScreen(std::string gamePath) : UIDialogScreenWithGameBackground(gamePath) { } void SavedataScreen::CreateViews() { diff --git a/UI/SavedataScreen.h b/UI/SavedataScreen.h index dfd5eddc09..44cb0a1c80 100644 --- a/UI/SavedataScreen.h +++ b/UI/SavedataScreen.h @@ -29,6 +29,7 @@ class SavedataBrowser : public UI::LinearLayout { public: SavedataBrowser(std::string path, UI::LayoutParams *layoutParams = 0); + ~SavedataBrowser(); UI::Event OnChoice; @@ -40,7 +41,7 @@ private: UI::ViewGroup *gameList_; }; -class SavedataScreen : public UIScreenWithGameBackground { +class SavedataScreen : public UIDialogScreenWithGameBackground { public: // gamePath can be empty, in that case this screen will show all savedata in the save directory. SavedataScreen(std::string gamePath);