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/.
|
|
|
|
|
2018-03-23 02:18:13 +00:00
|
|
|
#ifdef __MINGW32__
|
2021-02-14 17:49:14 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
|
2018-03-23 02:18:13 +00:00
|
|
|
#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
|
|
|
|
#endif
|
2021-02-14 17:49:14 +00:00
|
|
|
#endif
|
2018-03-23 02:18:13 +00:00
|
|
|
|
2023-01-08 22:10:16 +00:00
|
|
|
#include <algorithm>
|
2021-02-14 17:25:20 +00:00
|
|
|
#include <ctime>
|
2017-02-27 19:51:36 +00:00
|
|
|
#include <thread>
|
|
|
|
|
2021-03-29 07:21:26 +00:00
|
|
|
#include "Common/Data/Encoding/Utf8.h"
|
2021-05-08 16:42:52 +00:00
|
|
|
#include "Common/Data/Text/I18n.h"
|
2020-10-04 18:48:47 +00:00
|
|
|
#include "Common/File/FileUtil.h"
|
2020-08-10 07:12:51 +00:00
|
|
|
#include "Common/Serialize/Serializer.h"
|
|
|
|
#include "Common/Serialize/SerializeFuncs.h"
|
2020-09-29 10:19:22 +00:00
|
|
|
#include "Common/StringUtils.h"
|
2021-05-08 16:42:52 +00:00
|
|
|
#include "Common/Thread/ThreadUtil.h"
|
|
|
|
#include "Core/Dialog/PSPSaveDialog.h"
|
2013-12-29 22:28:31 +00:00
|
|
|
#include "Core/FileSystems/MetaFileSystem.h"
|
|
|
|
#include "Core/Util/PPGeDraw.h"
|
|
|
|
#include "Core/HLE/sceCtrl.h"
|
2020-07-15 01:59:23 +00:00
|
|
|
#include "Core/HLE/sceUtility.h"
|
2021-05-08 16:42:52 +00:00
|
|
|
#include "Core/HW/MemoryStick.h"
|
2015-04-06 01:03:50 +00:00
|
|
|
#include "Core/MemMapHelpers.h"
|
2013-12-29 22:28:31 +00:00
|
|
|
#include "Core/Config.h"
|
2013-03-04 07:50:39 +00:00
|
|
|
#include "Core/Reporting.h"
|
2021-05-08 16:42:52 +00:00
|
|
|
#include "Core/SaveState.h"
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2014-02-08 17:39:50 +00:00
|
|
|
const static float FONT_SCALE = 0.55f;
|
|
|
|
|
2014-02-11 20:45:08 +00:00
|
|
|
// These are rough, it seems to take at least 100ms or so to init, and shutdown depends on threads.
|
|
|
|
// Some games seem to required slightly longer delays to work, so we try 200ms as a compromise.
|
|
|
|
const static int SAVEDATA_INIT_DELAY_US = 200000;
|
2014-02-08 17:39:50 +00:00
|
|
|
const static int SAVEDATA_SHUTDOWN_DELAY_US = 2000;
|
|
|
|
|
2014-03-24 06:14:12 +00:00
|
|
|
// These are the only sizes which are allowed.
|
|
|
|
// TODO: We should test what the different behavior is for each.
|
|
|
|
const static int SAVEDATA_DIALOG_SIZE_V1 = 1480;
|
|
|
|
const static int SAVEDATA_DIALOG_SIZE_V2 = 1500;
|
|
|
|
const static int SAVEDATA_DIALOG_SIZE_V3 = 1536;
|
|
|
|
|
2022-10-09 17:36:19 +00:00
|
|
|
static bool IsNotVisibleAction(SceUtilitySavedataType type) {
|
|
|
|
switch (type) {
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_SIZES:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_LIST:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_FILES:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_READDATA:
|
2022-10-16 15:14:48 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_ERASESECURE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_ERASE:
|
2022-10-09 17:36:19 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-06-10 05:48:35 +00:00
|
|
|
|
2021-02-27 21:43:12 +00:00
|
|
|
PSPSaveDialog::PSPSaveDialog(UtilityDialogType type) : PSPDialog(type) {
|
2012-12-10 12:08:54 +00:00
|
|
|
param.SetPspParam(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
PSPSaveDialog::~PSPSaveDialog() {
|
2021-04-07 04:59:40 +00:00
|
|
|
JoinIOThread();
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
2012-12-25 02:37:28 +00:00
|
|
|
int PSPSaveDialog::Init(int paramAddr)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
2012-12-19 00:05:45 +00:00
|
|
|
// Ignore if already running
|
2014-02-08 17:58:31 +00:00
|
|
|
if (GetStatus() != SCE_UTILITY_STATUS_NONE) {
|
2024-07-14 12:42:59 +00:00
|
|
|
ERROR_LOG_REPORT(Log::sceUtility, "A save request is already running, not starting a new one");
|
2013-03-18 02:01:58 +00:00
|
|
|
return SCE_ERROR_UTILITY_INVALID_STATUS;
|
2012-12-19 00:05:45 +00:00
|
|
|
}
|
2014-06-30 00:29:02 +00:00
|
|
|
|
|
|
|
JoinIOThread();
|
|
|
|
ioThreadStatus = SAVEIO_NONE;
|
|
|
|
|
2012-12-24 00:22:28 +00:00
|
|
|
requestAddr = paramAddr;
|
2013-06-24 14:57:52 +00:00
|
|
|
int size = Memory::Read_U32(requestAddr);
|
|
|
|
memset(&request, 0, sizeof(request));
|
|
|
|
// Only copy the right size to support different save request format
|
2014-03-24 06:14:12 +00:00
|
|
|
if (size != SAVEDATA_DIALOG_SIZE_V1 && size != SAVEDATA_DIALOG_SIZE_V2 && size != SAVEDATA_DIALOG_SIZE_V3) {
|
2024-07-14 12:42:59 +00:00
|
|
|
ERROR_LOG_REPORT(Log::sceUtility, "sceUtilitySavedataInitStart: invalid size %d", size);
|
2014-03-24 06:14:12 +00:00
|
|
|
return SCE_ERROR_UTILITY_INVALID_PARAM_SIZE;
|
|
|
|
}
|
2013-06-24 14:57:52 +00:00
|
|
|
Memory::Memcpy(&request, requestAddr, size);
|
|
|
|
Memory::Memcpy(&originalRequest, requestAddr, size);
|
2012-12-24 00:22:28 +00:00
|
|
|
|
2022-10-09 17:36:19 +00:00
|
|
|
param.SetIgnoreTextures(IsNotVisibleAction((SceUtilitySavedataType)(u32)request.mode));
|
2024-07-16 15:07:11 +00:00
|
|
|
param.ClearSFOCache();
|
2014-02-08 17:39:50 +00:00
|
|
|
int retval = param.SetPspParam(&request);
|
2012-12-24 00:22:28 +00:00
|
|
|
|
2014-03-16 00:20:34 +00:00
|
|
|
const u32 mode = (u32)param.GetPspParam()->mode;
|
|
|
|
const char *modeName = mode < ARRAY_SIZE(utilitySavedataTypeNames) ? utilitySavedataTypeNames[mode] : "UNKNOWN";
|
2024-07-14 12:42:59 +00:00
|
|
|
INFO_LOG(Log::sceUtility,"sceUtilitySavedataInitStart(%08x) - %s (%d)", paramAddr, modeName, mode);
|
|
|
|
INFO_LOG(Log::sceUtility,"sceUtilitySavedataInitStart(%08x) : Game key (hex): %s", paramAddr, param.GetKey(param.GetPspParam()).c_str());
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2013-05-19 13:03:45 +00:00
|
|
|
yesnoChoice = 1;
|
2013-07-29 03:28:32 +00:00
|
|
|
switch ((SceUtilitySavedataFocus)(u32)param.GetPspParam()->focus)
|
2013-05-20 11:03:58 +00:00
|
|
|
{
|
|
|
|
case SCE_UTILITY_SAVEDATA_FOCUS_NAME:
|
2013-11-12 09:10:56 +00:00
|
|
|
currentSelectedSave = param.GetSaveNameIndex(param.GetPspParam());
|
2013-05-20 11:03:58 +00:00
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_FOCUS_FIRSTLIST:
|
|
|
|
currentSelectedSave = param.GetFirstListSave();
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_FOCUS_LASTLIST:
|
|
|
|
currentSelectedSave = param.GetLastListSave();
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_FOCUS_LATEST:
|
|
|
|
currentSelectedSave = param.GetLatestSave();
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_FOCUS_OLDEST:
|
|
|
|
currentSelectedSave = param.GetOldestSave();
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_FOCUS_FIRSTDATA:
|
|
|
|
currentSelectedSave = param.GetFirstDataSave();
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_FOCUS_LASTDATA:
|
|
|
|
currentSelectedSave = param.GetLastDataSave();
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_FOCUS_FIRSTEMPTY:
|
|
|
|
currentSelectedSave = param.GetFirstEmptySave();
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_FOCUS_LASTEMPTY:
|
|
|
|
currentSelectedSave = param.GetLastEmptySave();
|
|
|
|
break;
|
|
|
|
default:
|
2024-07-14 12:42:59 +00:00
|
|
|
WARN_LOG(Log::sceUtility, "Unknown save list focus option: %d", param.GetPspParam()->focus);
|
2013-05-20 11:03:58 +00:00
|
|
|
currentSelectedSave = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-12-11 05:02:44 +00:00
|
|
|
if (!param.WouldHaveMultiSaveName(param.GetPspParam()))
|
2020-09-15 13:48:55 +00:00
|
|
|
currentSelectedSave = 0;
|
|
|
|
|
2013-07-29 03:28:32 +00:00
|
|
|
switch ((SceUtilitySavedataType)(u32)param.GetPspParam()->mode)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_LOAD:
|
2024-07-14 12:42:59 +00:00
|
|
|
DEBUG_LOG(Log::sceUtility, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetSaveName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
|
2020-10-01 07:41:27 +00:00
|
|
|
if (param.GetFileInfo(0).size != 0) {
|
|
|
|
if (param.GetFileInfo(0).broken) {
|
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN;
|
|
|
|
display = DS_LOAD_FAILED;
|
|
|
|
} else {
|
|
|
|
display = DS_LOAD_CONFIRM;
|
|
|
|
}
|
|
|
|
} else
|
2013-05-12 02:10:01 +00:00
|
|
|
display = DS_LOAD_NODATA;
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD:
|
2024-07-14 12:42:59 +00:00
|
|
|
DEBUG_LOG(Log::sceUtility, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetSaveName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
|
2012-12-10 12:08:54 +00:00
|
|
|
display = DS_NONE;
|
2013-05-19 13:11:54 +00:00
|
|
|
// Is this necessary?
|
|
|
|
// currentSelectedSave = param.GetSelectedSave();
|
2012-12-10 12:08:54 +00:00
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD:
|
2024-07-14 12:42:59 +00:00
|
|
|
DEBUG_LOG(Log::sceUtility, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
|
2012-12-10 12:08:54 +00:00
|
|
|
if(param.GetFilenameCount() == 0)
|
|
|
|
display = DS_LOAD_NODATA;
|
|
|
|
else
|
|
|
|
display = DS_LOAD_LIST_CHOICE;
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_SAVE:
|
2024-07-14 12:42:59 +00:00
|
|
|
DEBUG_LOG(Log::sceUtility, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
|
2013-05-12 02:10:01 +00:00
|
|
|
if (param.GetFileInfo(0).size != 0)
|
2013-05-19 13:03:45 +00:00
|
|
|
{
|
|
|
|
yesnoChoice = 0;
|
2013-05-12 02:10:01 +00:00
|
|
|
display = DS_SAVE_CONFIRM_OVERWRITE;
|
2013-05-19 13:03:45 +00:00
|
|
|
}
|
2013-05-12 02:10:01 +00:00
|
|
|
else
|
|
|
|
display = DS_SAVE_CONFIRM;
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE:
|
2024-07-14 12:42:59 +00:00
|
|
|
DEBUG_LOG(Log::sceUtility, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
|
2012-12-10 12:08:54 +00:00
|
|
|
display = DS_NONE;
|
2013-05-19 13:11:54 +00:00
|
|
|
// Is this necessary?
|
|
|
|
// currentSelectedSave = param.GetSelectedSave();
|
2012-12-10 12:08:54 +00:00
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE:
|
2024-07-14 12:42:59 +00:00
|
|
|
DEBUG_LOG(Log::sceUtility, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
|
2012-12-10 12:08:54 +00:00
|
|
|
display = DS_SAVE_LIST_CHOICE;
|
|
|
|
break;
|
2020-09-30 16:39:14 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE:
|
2024-07-14 12:42:59 +00:00
|
|
|
DEBUG_LOG(Log::sceUtility, "Delete. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
|
2012-12-10 12:08:54 +00:00
|
|
|
if(param.GetFilenameCount() == 0)
|
|
|
|
display = DS_DELETE_NODATA;
|
|
|
|
else
|
|
|
|
display = DS_DELETE_LIST_CHOICE;
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_SIZES:
|
2012-12-11 02:09:52 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_LIST:
|
2012-12-31 18:08:46 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_FILES:
|
2013-01-10 06:33:05 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE:
|
2012-12-31 18:08:46 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE:
|
2013-04-21 21:18:12 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA:
|
2012-12-31 18:08:46 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE:
|
2013-04-21 21:18:12 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA:
|
2012-12-31 18:08:46 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE:
|
2013-04-21 21:18:12 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_READDATA:
|
2022-10-16 15:14:48 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_ERASESECURE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_ERASE:
|
2013-05-17 05:33:10 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA:
|
2012-12-11 02:09:52 +00:00
|
|
|
display = DS_NONE;
|
|
|
|
break;
|
2013-05-12 03:27:54 +00:00
|
|
|
|
2020-09-30 16:39:14 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_DELETE:
|
2024-07-14 12:42:59 +00:00
|
|
|
DEBUG_LOG(Log::sceUtility, "Delete. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
|
2020-09-30 16:39:14 +00:00
|
|
|
if (param.GetFileInfo(0).size != 0) {
|
|
|
|
yesnoChoice = 0;
|
|
|
|
display = DS_DELETE_CONFIRM;
|
|
|
|
} else
|
|
|
|
display = DS_DELETE_NODATA;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE:
|
2024-07-14 12:42:59 +00:00
|
|
|
DEBUG_LOG(Log::sceUtility, "Delete. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
|
2020-09-30 16:39:14 +00:00
|
|
|
display = DS_NONE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE:
|
2024-07-14 12:42:59 +00:00
|
|
|
DEBUG_LOG(Log::sceUtility, "Delete. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
|
2020-09-30 16:39:14 +00:00
|
|
|
if (param.GetFilenameCount() == 0)
|
|
|
|
display = DS_DELETE_NODATA;
|
|
|
|
else
|
|
|
|
display = DS_DELETE_LIST_CHOICE;
|
2013-01-06 12:41:49 +00:00
|
|
|
break;
|
2012-12-10 12:08:54 +00:00
|
|
|
default:
|
|
|
|
{
|
2024-07-14 12:42:59 +00:00
|
|
|
ERROR_LOG_REPORT(Log::sceUtility, "Load/Save function %d not coded. Title: %s Save: %s File: %s", (SceUtilitySavedataType)(u32)param.GetPspParam()->mode, param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
|
2013-06-10 08:52:26 +00:00
|
|
|
param.GetPspParam()->common.result = 0;
|
2014-02-08 17:39:50 +00:00
|
|
|
ChangeStatusInit(SAVEDATA_INIT_DELAY_US);
|
2012-12-10 12:08:54 +00:00
|
|
|
display = DS_NONE;
|
2012-12-19 20:23:52 +00:00
|
|
|
return 0; // Return 0 should allow the game to continue, but missing function must be implemented and returning the right value or the game can block.
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-02-08 17:39:50 +00:00
|
|
|
if (retval < 0) {
|
|
|
|
ChangeStatusShutdown(SAVEDATA_SHUTDOWN_DELAY_US);
|
|
|
|
} else {
|
|
|
|
ChangeStatusInit(SAVEDATA_INIT_DELAY_US);
|
|
|
|
}
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2024-07-16 15:07:11 +00:00
|
|
|
param.ClearSFOCache();
|
2023-02-09 03:02:37 +00:00
|
|
|
InitCommon();
|
2014-02-02 23:47:25 +00:00
|
|
|
UpdateButtons();
|
2013-01-18 23:45:00 +00:00
|
|
|
StartFade(true);
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2024-07-14 12:42:59 +00:00
|
|
|
/*INFO_LOG(Log::sceUtility,"Dump Param :");
|
|
|
|
INFO_LOG(Log::sceUtility,"size : %d",param.GetPspParam()->common.size);
|
|
|
|
INFO_LOG(Log::sceUtility,"language : %d",param.GetPspParam()->common.language);
|
|
|
|
INFO_LOG(Log::sceUtility,"buttonSwap : %d",param.GetPspParam()->common.buttonSwap);
|
|
|
|
INFO_LOG(Log::sceUtility,"result : %d",param.GetPspParam()->common.result);
|
|
|
|
INFO_LOG(Log::sceUtility,"mode : %d",param.GetPspParam()->mode);
|
|
|
|
INFO_LOG(Log::sceUtility,"bind : %d",param.GetPspParam()->bind);
|
|
|
|
INFO_LOG(Log::sceUtility,"overwriteMode : %d",param.GetPspParam()->overwriteMode);
|
|
|
|
INFO_LOG(Log::sceUtility,"gameName : %s",param.GetGameName(param.GetPspParam()).c_str());
|
|
|
|
INFO_LOG(Log::sceUtility,"saveName : %s",param.GetPspParam()->saveName);
|
|
|
|
INFO_LOG(Log::sceUtility,"saveNameList : %08x",*((unsigned int*)¶m.GetPspParam()->saveNameList));
|
|
|
|
INFO_LOG(Log::sceUtility,"fileName : %s",param.GetPspParam()->fileName);
|
|
|
|
INFO_LOG(Log::sceUtility,"dataBuf : %08x",*((unsigned int*)¶m.GetPspParam()->dataBuf));
|
|
|
|
INFO_LOG(Log::sceUtility,"dataBufSize : %u",param.GetPspParam()->dataBufSize);
|
|
|
|
INFO_LOG(Log::sceUtility,"dataSize : %u",param.GetPspParam()->dataSize);
|
|
|
|
|
|
|
|
INFO_LOG(Log::sceUtility,"sfo title : %s",param.GetPspParam()->sfoParam.title);
|
|
|
|
INFO_LOG(Log::sceUtility,"sfo savedataTitle : %s",param.GetPspParam()->sfoParam.savedataTitle);
|
|
|
|
INFO_LOG(Log::sceUtility,"sfo detail : %s",param.GetPspParam()->sfoParam.detail);
|
|
|
|
|
|
|
|
INFO_LOG(Log::sceUtility,"icon0 data : %08x",*((unsigned int*)¶m.GetPspParam()->icon0FileData.buf));
|
|
|
|
INFO_LOG(Log::sceUtility,"icon0 size : %u",param.GetPspParam()->icon0FileData.bufSize);
|
|
|
|
|
|
|
|
INFO_LOG(Log::sceUtility,"icon1 data : %08x",*((unsigned int*)¶m.GetPspParam()->icon1FileData.buf));
|
|
|
|
INFO_LOG(Log::sceUtility,"icon1 size : %u",param.GetPspParam()->icon1FileData.bufSize);
|
|
|
|
|
|
|
|
INFO_LOG(Log::sceUtility,"pic1 data : %08x",*((unsigned int*)¶m.GetPspParam()->pic1FileData.buf));
|
|
|
|
INFO_LOG(Log::sceUtility,"pic1 size : %u",param.GetPspParam()->pic1FileData.bufSize);
|
|
|
|
|
|
|
|
INFO_LOG(Log::sceUtility,"snd0 data : %08x",*((unsigned int*)¶m.GetPspParam()->snd0FileData.buf));
|
|
|
|
INFO_LOG(Log::sceUtility,"snd0 size : %u",param.GetPspParam()->snd0FileData.bufSize);*/
|
2024-07-15 13:28:44 +00:00
|
|
|
INFO_LOG(Log::sceUtility, "Return value: %d", retval);
|
2012-12-19 20:23:52 +00:00
|
|
|
return retval;
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
2024-04-02 15:37:00 +00:00
|
|
|
std::string PSPSaveDialog::GetSelectedSaveDirName() const
|
2013-05-12 03:27:54 +00:00
|
|
|
{
|
2013-07-29 03:28:32 +00:00
|
|
|
switch ((SceUtilitySavedataType)(u32)param.GetPspParam()->mode)
|
2013-05-12 03:27:54 +00:00
|
|
|
{
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_LOAD:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_SAVE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE:
|
2020-09-30 16:39:14 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_DELETE:
|
2013-06-23 18:06:12 +00:00
|
|
|
return param.GetSaveDirName(param.GetPspParam());
|
2013-05-12 03:27:54 +00:00
|
|
|
|
2013-05-31 05:58:48 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_READDATA:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_ERASESECURE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_ERASE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA:
|
2013-06-23 18:06:12 +00:00
|
|
|
return param.GetSaveDirName(param.GetPspParam());
|
2013-05-31 05:58:48 +00:00
|
|
|
|
2014-01-24 09:21:13 +00:00
|
|
|
// SIZES ignores saveName it seems.
|
2013-06-23 18:31:46 +00:00
|
|
|
|
2013-05-12 03:27:54 +00:00
|
|
|
default:
|
|
|
|
return param.GetSaveDirName(param.GetPspParam(), currentSelectedSave);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-10 05:48:35 +00:00
|
|
|
void PSPSaveDialog::DisplayBanner(int which)
|
|
|
|
{
|
2023-04-05 22:34:50 +00:00
|
|
|
auto di = GetI18NCategory(I18NCat::DIALOG);
|
2013-06-10 05:48:35 +00:00
|
|
|
PPGeDrawRect(0, 0, 480, 23, CalcFadedColor(0x65636358));
|
2020-05-24 04:21:16 +00:00
|
|
|
|
|
|
|
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_VCENTER, 0.6f);
|
|
|
|
textStyle.hasShadow = false;
|
|
|
|
|
2024-01-19 12:44:49 +00:00
|
|
|
std::string_view title;
|
|
|
|
switch (which) {
|
2013-06-10 05:48:35 +00:00
|
|
|
case DB_SAVE:
|
2015-07-01 21:26:55 +00:00
|
|
|
title = di->T("Save");
|
2013-06-10 05:48:35 +00:00
|
|
|
break;
|
|
|
|
case DB_LOAD:
|
2015-07-01 21:26:55 +00:00
|
|
|
title = di->T("Load");
|
2013-06-10 05:48:35 +00:00
|
|
|
break;
|
|
|
|
case DB_DELETE:
|
2015-07-01 21:26:55 +00:00
|
|
|
title = di->T("Delete");
|
2013-06-10 05:48:35 +00:00
|
|
|
break;
|
|
|
|
default:
|
2013-06-11 08:37:50 +00:00
|
|
|
title = "";
|
2013-06-10 05:48:35 +00:00
|
|
|
break;
|
|
|
|
}
|
2013-06-11 08:37:50 +00:00
|
|
|
// TODO: Draw a hexagon icon
|
2021-01-03 22:42:29 +00:00
|
|
|
PPGeDrawImage(10, 6, 12.0f, 12.0f, 1, 10, 1, 10, 10, 10, FadedImageStyle());
|
2020-05-24 04:21:16 +00:00
|
|
|
PPGeDrawText(title, 30, 11, textStyle);
|
2013-06-10 05:48:35 +00:00
|
|
|
}
|
|
|
|
|
2017-02-27 20:57:46 +00:00
|
|
|
void PSPSaveDialog::DisplaySaveList(bool canMove) {
|
|
|
|
std::lock_guard<std::mutex> guard(paramLock);
|
2013-12-09 01:15:35 +00:00
|
|
|
static int upFramesHeld = 0;
|
|
|
|
static int downFramesHeld = 0;
|
|
|
|
|
2021-01-03 22:42:29 +00:00
|
|
|
for (int displayCount = 0; displayCount < param.GetFilenameCount(); displayCount++) {
|
|
|
|
PPGeImageStyle imageStyle = FadedImageStyle();
|
2013-12-17 16:07:30 +00:00
|
|
|
auto fileInfo = param.GetFileInfo(displayCount);
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2022-10-09 17:36:19 +00:00
|
|
|
if (fileInfo.size == 0 && fileInfo.texture && fileInfo.texture->IsValid())
|
2021-01-03 22:42:29 +00:00
|
|
|
imageStyle.color = CalcFadedColor(0xFF777777);
|
2012-12-10 12:08:54 +00:00
|
|
|
|
|
|
|
// Calc save image position on screen
|
2021-02-08 07:39:12 +00:00
|
|
|
float w, h, x;
|
2013-07-01 12:42:10 +00:00
|
|
|
float y = 97;
|
2013-06-10 12:37:30 +00:00
|
|
|
if (displayCount != currentSelectedSave) {
|
|
|
|
w = 81;
|
|
|
|
h = 45;
|
|
|
|
x = 58.5f;
|
2013-07-01 12:42:10 +00:00
|
|
|
} else {
|
|
|
|
w = 144;
|
|
|
|
h = 80;
|
|
|
|
x = 27;
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
2013-06-10 12:37:30 +00:00
|
|
|
if (displayCount < currentSelectedSave)
|
|
|
|
y -= 13 + 45 * (currentSelectedSave - displayCount);
|
|
|
|
else if (displayCount > currentSelectedSave)
|
|
|
|
y += 48 + 45 * (displayCount - currentSelectedSave);
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2013-12-17 16:07:30 +00:00
|
|
|
// Skip if it's well outside the screen.
|
|
|
|
if (y > 472.0f || y < -200.0f)
|
|
|
|
continue;
|
|
|
|
|
2021-02-08 07:39:12 +00:00
|
|
|
int pad = 0;
|
2022-10-09 17:36:19 +00:00
|
|
|
if (fileInfo.texture != nullptr && fileInfo.texture->IsValid()) {
|
2013-12-08 19:06:18 +00:00
|
|
|
fileInfo.texture->SetTexture();
|
2021-02-08 07:39:12 +00:00
|
|
|
int tw = fileInfo.texture->Width();
|
|
|
|
int th = fileInfo.texture->Height();
|
|
|
|
float scale = (float)h / (float)th;
|
|
|
|
int scaledW = (int)(tw * scale);
|
|
|
|
pad = (w - scaledW) / 2;
|
|
|
|
w = scaledW;
|
|
|
|
|
|
|
|
PPGeDrawImage(x + pad, y, w, h, 0, 0, 1, 1, tw, th, imageStyle);
|
2021-02-08 07:18:39 +00:00
|
|
|
} else {
|
|
|
|
PPGeDrawRect(x, y, x + w, y + h, 0x88666666);
|
2013-12-08 19:06:18 +00:00
|
|
|
}
|
2021-02-08 07:39:12 +00:00
|
|
|
if (displayCount == currentSelectedSave) {
|
|
|
|
float b = 1.2f;
|
|
|
|
uint32_t bc = CalcFadedColor(0xD0FFFFFF);
|
|
|
|
PPGeDrawRect(x + pad - b, y - b, x + pad + w + b, y, bc); // top border
|
|
|
|
PPGeDrawRect(x + pad - b, y, x + pad, y + h, bc); // left border
|
|
|
|
PPGeDrawRect(x + pad - b, y + h, x + pad + w + b, y + h + b, bc); //bottom border
|
|
|
|
PPGeDrawRect(x + pad + w, y, x + pad + w + b, y + h, bc); //right border
|
2013-12-08 19:06:18 +00:00
|
|
|
}
|
2012-12-14 00:04:45 +00:00
|
|
|
PPGeSetDefaultTexture();
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
2013-06-10 12:37:30 +00:00
|
|
|
if (canMove) {
|
2013-12-09 01:15:35 +00:00
|
|
|
if ( (IsButtonPressed(CTRL_UP) || IsButtonHeld(CTRL_UP, upFramesHeld)) && currentSelectedSave > 0)
|
2012-12-10 12:08:54 +00:00
|
|
|
currentSelectedSave--;
|
2013-12-09 01:15:35 +00:00
|
|
|
|
|
|
|
else if ( (IsButtonPressed(CTRL_DOWN) || IsButtonHeld(CTRL_DOWN, downFramesHeld)) && currentSelectedSave < (param.GetFilenameCount() - 1))
|
2012-12-10 12:08:54 +00:00
|
|
|
currentSelectedSave++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-01 21:40:44 +00:00
|
|
|
void PSPSaveDialog::DisplaySaveIcon(bool checkExists)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
2017-02-27 20:57:46 +00:00
|
|
|
std::lock_guard<std::mutex> guard(paramLock);
|
2021-01-03 22:42:29 +00:00
|
|
|
PPGeImageStyle imageStyle = FadedImageStyle();
|
2013-12-08 19:06:18 +00:00
|
|
|
auto curSave = param.GetFileInfo(currentSelectedSave);
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2018-09-01 21:40:44 +00:00
|
|
|
if (curSave.size == 0 && checkExists)
|
2021-01-03 22:42:29 +00:00
|
|
|
imageStyle.color = CalcFadedColor(0xFF777777);
|
2012-12-10 12:08:54 +00:00
|
|
|
|
|
|
|
// Calc save image position on screen
|
2013-06-10 12:37:30 +00:00
|
|
|
float w = 144;
|
2012-12-19 20:23:52 +00:00
|
|
|
float h = 80;
|
2013-06-10 12:37:30 +00:00
|
|
|
float x = 27;
|
2013-06-10 05:48:35 +00:00
|
|
|
float y = 97;
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2012-12-13 21:06:45 +00:00
|
|
|
int tw = 256;
|
|
|
|
int th = 256;
|
2022-10-09 17:36:19 +00:00
|
|
|
if (curSave.texture != nullptr && curSave.texture->IsValid()) {
|
2013-12-08 19:06:18 +00:00
|
|
|
curSave.texture->SetTexture();
|
|
|
|
tw = curSave.texture->Width();
|
|
|
|
th = curSave.texture->Height();
|
2021-02-08 07:39:12 +00:00
|
|
|
float scale = (float)h / (float)th;
|
|
|
|
int scaledW = (int)(tw * scale);
|
|
|
|
x += (w - scaledW) / 2;
|
|
|
|
w = scaledW;
|
2013-12-08 19:06:18 +00:00
|
|
|
} else {
|
2012-12-13 21:06:45 +00:00
|
|
|
PPGeDisableTexture();
|
2013-12-08 19:06:18 +00:00
|
|
|
}
|
2021-01-03 22:42:29 +00:00
|
|
|
PPGeDrawImage(x, y, w, h, 0, 0, 1, 1, tw, th, imageStyle);
|
2017-04-24 08:07:00 +00:00
|
|
|
PPGeSetDefaultTexture();
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
2020-07-15 01:59:23 +00:00
|
|
|
static void FormatSaveHourMin(char *hour_time, size_t sz, const tm &t) {
|
|
|
|
const char *am_pm = "AM";
|
|
|
|
int hour = t.tm_hour;
|
|
|
|
switch (g_Config.iTimeFormat) {
|
|
|
|
case 1:
|
|
|
|
if (hour == 12) {
|
|
|
|
am_pm = "PM";
|
|
|
|
} else if (hour > 12) {
|
|
|
|
am_pm = "PM";
|
|
|
|
hour -= 12;
|
|
|
|
} else if (hour == 0) {
|
|
|
|
hour = 12;
|
|
|
|
}
|
|
|
|
snprintf(hour_time, sz, "%02d:%02d %s", hour, t.tm_min, am_pm);
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
default:
|
|
|
|
snprintf(hour_time, sz, "%02d:%02d", hour, t.tm_min);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void FormatSaveDate(char *date, size_t sz, const tm &t) {
|
|
|
|
int year = t.tm_year + 1900;
|
|
|
|
int month = t.tm_mon + 1;
|
|
|
|
switch (g_Config.iDateFormat) {
|
|
|
|
case 1:
|
|
|
|
snprintf(date, sz, "%02d/%02d/%04d", month, t.tm_mday, year);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
snprintf(date, sz, "%02d/%02d/%04d", t.tm_mday, month, year);
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
default:
|
|
|
|
snprintf(date, sz, "%04d/%02d/%02d", year, month, t.tm_mday);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PSPSaveDialog::DisplaySaveDataInfo1() {
|
2017-02-27 20:57:46 +00:00
|
|
|
std::lock_guard<std::mutex> guard(paramLock);
|
2020-07-15 01:59:23 +00:00
|
|
|
const SaveFileInfo &saveInfo = param.GetFileInfo(currentSelectedSave);
|
2021-02-08 07:18:39 +00:00
|
|
|
PPGeStyle saveTitleStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.55f);
|
2020-07-15 01:59:23 +00:00
|
|
|
|
2020-10-01 07:41:27 +00:00
|
|
|
if (saveInfo.broken) {
|
2023-04-05 22:34:50 +00:00
|
|
|
auto di = GetI18NCategory(I18NCat::DIALOG);
|
2020-10-01 07:41:27 +00:00
|
|
|
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_VCENTER, 0.6f);
|
|
|
|
PPGeDrawText(di->T("Corrupted Data"), 180, 136, textStyle);
|
2021-02-08 07:18:39 +00:00
|
|
|
PPGeDrawText(saveInfo.title, 175, 159, saveTitleStyle);
|
2020-10-01 07:41:27 +00:00
|
|
|
} else if (saveInfo.size == 0) {
|
2023-04-05 22:34:50 +00:00
|
|
|
auto di = GetI18NCategory(I18NCat::DIALOG);
|
2020-05-24 04:21:16 +00:00
|
|
|
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_VCENTER, 0.6f);
|
|
|
|
PPGeDrawText(di->T("NEW DATA"), 180, 136, textStyle);
|
2013-05-18 22:07:00 +00:00
|
|
|
} else {
|
2019-02-27 09:05:15 +00:00
|
|
|
char hour_time[32];
|
2020-07-15 01:59:23 +00:00
|
|
|
FormatSaveHourMin(hour_time, sizeof(hour_time), saveInfo.modif_time);
|
2013-01-19 15:41:35 +00:00
|
|
|
|
2020-07-15 01:59:23 +00:00
|
|
|
char date_year[32];
|
|
|
|
FormatSaveDate(date_year, sizeof(date_year), saveInfo.modif_time);
|
|
|
|
|
|
|
|
s64 sizeK = saveInfo.size / 1024;
|
2018-01-31 13:41:47 +00:00
|
|
|
|
2013-12-15 16:54:01 +00:00
|
|
|
PPGeDrawRect(180, 136, 480, 137, CalcFadedColor(0xFFFFFFFF));
|
2020-07-15 01:59:23 +00:00
|
|
|
std::string titleTxt = saveInfo.title;
|
|
|
|
std::string timeTxt = StringFromFormat("%s %s %lld KB", date_year, hour_time, sizeK);
|
|
|
|
std::string saveTitleTxt = saveInfo.saveTitle;
|
|
|
|
std::string saveDetailTxt = saveInfo.saveDetail;
|
2013-04-16 12:55:27 +00:00
|
|
|
|
2020-05-24 04:21:16 +00:00
|
|
|
PPGeStyle titleStyle = FadedStyle(PPGeAlign::BOX_BOTTOM, 0.6f);
|
|
|
|
titleStyle.color = CalcFadedColor(0xFFC0C0C0);
|
|
|
|
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f);
|
|
|
|
|
2024-10-17 20:21:07 +00:00
|
|
|
PPGeDrawText(titleTxt, 180, 136, titleStyle);
|
|
|
|
PPGeDrawText(timeTxt, 180, 137, textStyle);
|
|
|
|
PPGeDrawText(saveTitleTxt, 175, 159, saveTitleStyle);
|
|
|
|
PPGeDrawTextWrapped(saveDetailTxt, 175, 181, 480 - 175, 250 - 181, textStyle);
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-02 16:17:50 +00:00
|
|
|
void PSPSaveDialog::DisplaySaveDataInfo2(bool showNewData) {
|
2017-02-27 20:57:46 +00:00
|
|
|
std::lock_guard<std::mutex> guard(paramLock);
|
2017-12-02 16:17:50 +00:00
|
|
|
|
|
|
|
tm modif_time;
|
|
|
|
const char *save_title;
|
|
|
|
u32 data_size;
|
|
|
|
|
|
|
|
if (showNewData || param.GetFileInfo(currentSelectedSave).size == 0) {
|
|
|
|
time_t t;
|
|
|
|
time(&t);
|
|
|
|
localtime_r(&t, &modif_time);
|
|
|
|
save_title = param.GetPspParam()->sfoParam.savedataTitle;
|
|
|
|
// TODO: Account for icon, etc., etc.
|
|
|
|
data_size = param.GetPspParam()->dataSize;
|
2013-05-18 22:07:00 +00:00
|
|
|
} else {
|
2017-12-02 16:17:50 +00:00
|
|
|
modif_time = param.GetFileInfo(currentSelectedSave).modif_time;
|
|
|
|
save_title = param.GetFileInfo(currentSelectedSave).saveTitle;
|
|
|
|
data_size = param.GetFileInfo(currentSelectedSave).size;
|
|
|
|
}
|
2013-01-21 13:35:31 +00:00
|
|
|
|
2019-02-27 09:05:15 +00:00
|
|
|
char hour_time[32];
|
2020-07-15 01:59:23 +00:00
|
|
|
FormatSaveHourMin(hour_time, sizeof(hour_time), modif_time);
|
|
|
|
|
|
|
|
char date_year[32];
|
|
|
|
FormatSaveDate(date_year, sizeof(date_year), modif_time);
|
2017-12-02 16:17:50 +00:00
|
|
|
|
|
|
|
s64 sizeK = data_size / 1024;
|
|
|
|
|
2020-05-24 04:21:16 +00:00
|
|
|
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f);
|
2021-03-29 07:21:26 +00:00
|
|
|
std::string title = SanitizeUTF8(std::string(save_title, strnlen(save_title, 128)));
|
|
|
|
std::string saveinfoTxt = StringFromFormat("%s\n%s %s\n%lld KB", title.c_str(), date_year, hour_time, sizeK);
|
2020-05-24 04:21:16 +00:00
|
|
|
PPGeDrawText(saveinfoTxt.c_str(), 8, 200, textStyle);
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
2024-01-19 12:44:49 +00:00
|
|
|
void PSPSaveDialog::DisplayMessage(std::string_view text, bool hasYesNo)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
2020-05-24 04:21:16 +00:00
|
|
|
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_CENTER, FONT_SCALE);
|
|
|
|
|
2013-06-10 12:37:30 +00:00
|
|
|
const float WRAP_WIDTH = 254.0f;
|
|
|
|
float y = 136.0f, h;
|
2024-01-19 12:44:49 +00:00
|
|
|
PPGeMeasureText(nullptr, &h, text, FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH);
|
2020-03-24 01:23:35 +00:00
|
|
|
float h2 = h / 2.0f;
|
2013-06-10 12:37:30 +00:00
|
|
|
if (hasYesNo)
|
|
|
|
{
|
2023-04-05 22:34:50 +00:00
|
|
|
auto di = GetI18NCategory(I18NCat::DIALOG);
|
2024-01-19 12:44:49 +00:00
|
|
|
std::string_view choiceText;
|
2013-06-10 12:37:30 +00:00
|
|
|
float x, w;
|
|
|
|
if (yesnoChoice == 1) {
|
2015-07-01 21:26:55 +00:00
|
|
|
choiceText = di->T("Yes");
|
2013-06-10 12:37:30 +00:00
|
|
|
x = 302.0f;
|
|
|
|
}
|
|
|
|
else {
|
2015-07-01 21:26:55 +00:00
|
|
|
choiceText = di->T("No");
|
2013-06-10 12:37:30 +00:00
|
|
|
x = 366.0f;
|
|
|
|
}
|
2020-03-24 01:23:35 +00:00
|
|
|
PPGeMeasureText(&w, &h, choiceText, FONT_SCALE);
|
2013-06-10 12:37:30 +00:00
|
|
|
w = w / 2.0f + 5.5f;
|
|
|
|
h /= 2.0f;
|
|
|
|
float y2 = y + h2 + 4.0f;
|
|
|
|
h2 += h + 4.0f;
|
|
|
|
y = 132.0f - h;
|
2013-07-13 14:56:46 +00:00
|
|
|
PPGeDrawRect(x - w, y2 - h, x + w, y2 + h, CalcFadedColor(0x40C0C0C0));
|
2020-05-24 04:21:16 +00:00
|
|
|
PPGeDrawText(di->T("Yes"), 302.0f, y2, textStyle);
|
|
|
|
PPGeDrawText(di->T("No"), 366.0f, y2, textStyle);
|
2013-06-10 12:37:30 +00:00
|
|
|
if (IsButtonPressed(CTRL_LEFT) && yesnoChoice == 0) {
|
|
|
|
yesnoChoice = 1;
|
|
|
|
}
|
|
|
|
else if (IsButtonPressed(CTRL_RIGHT) && yesnoChoice == 1) {
|
|
|
|
yesnoChoice = 0;
|
|
|
|
}
|
2013-06-10 05:48:35 +00:00
|
|
|
}
|
2024-01-19 12:44:49 +00:00
|
|
|
PPGeDrawTextWrapped(text, 334.0f, y, WRAP_WIDTH, 0, textStyle);
|
2013-06-10 12:37:30 +00:00
|
|
|
float sy = 122.0f - h2, ey = 150.0f + h2;
|
|
|
|
PPGeDrawRect(202.0f, sy, 466.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF));
|
|
|
|
PPGeDrawRect(202.0f, ey, 466.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF));
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
2013-05-18 22:07:00 +00:00
|
|
|
|
2013-10-16 16:54:17 +00:00
|
|
|
int PSPSaveDialog::Update(int animSpeed)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
2014-02-08 17:58:31 +00:00
|
|
|
if (GetStatus() != SCE_UTILITY_STATUS_RUNNING)
|
2013-03-18 04:39:06 +00:00
|
|
|
return SCE_ERROR_UTILITY_INVALID_STATUS;
|
2012-12-10 12:08:54 +00:00
|
|
|
|
|
|
|
if (!param.GetPspParam()) {
|
2014-02-08 17:39:50 +00:00
|
|
|
ChangeStatusShutdown(SAVEDATA_SHUTDOWN_DELAY_US);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pendingStatus != SCE_UTILITY_STATUS_RUNNING) {
|
|
|
|
// We're actually done, we're just waiting to tell the game that.
|
2012-12-25 02:37:28 +00:00
|
|
|
return 0;
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
2013-06-24 05:30:23 +00:00
|
|
|
// The struct may have been updated by the game. This happens in "Where Is My Heart?"
|
|
|
|
// Check if it has changed, reload it.
|
|
|
|
// TODO: Cut down on preloading? This rebuilds the list from scratch.
|
2023-01-08 22:10:16 +00:00
|
|
|
int size = std::min((u32)sizeof(originalRequest), Memory::Read_U32(requestAddr));
|
|
|
|
const u8 *updatedRequest = Memory::GetPointerRange(requestAddr, size);
|
|
|
|
if (updatedRequest && memcmp(updatedRequest, &originalRequest, size) != 0) {
|
2013-06-24 05:30:23 +00:00
|
|
|
memset(&request, 0, sizeof(request));
|
|
|
|
Memory::Memcpy(&request, requestAddr, size);
|
2013-06-24 15:35:09 +00:00
|
|
|
Memory::Memcpy(&originalRequest, requestAddr, size);
|
2017-02-27 20:57:46 +00:00
|
|
|
std::lock_guard<std::mutex> guard(paramLock);
|
2013-06-24 05:30:23 +00:00
|
|
|
param.SetPspParam(&request);
|
|
|
|
}
|
|
|
|
|
2024-07-16 15:07:11 +00:00
|
|
|
param.ClearSFOCache();
|
2014-02-02 23:47:25 +00:00
|
|
|
UpdateButtons();
|
2013-10-16 16:54:17 +00:00
|
|
|
UpdateFade(animSpeed);
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2023-02-09 03:02:37 +00:00
|
|
|
UpdateCommon();
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2023-04-05 22:34:50 +00:00
|
|
|
auto di = GetI18NCategory(I18NCat::DIALOG);
|
2013-04-20 19:36:50 +00:00
|
|
|
|
2013-05-19 13:03:45 +00:00
|
|
|
switch (display)
|
2012-12-10 12:08:54 +00:00
|
|
|
{
|
|
|
|
case DS_SAVE_LIST_CHOICE:
|
|
|
|
StartDraw();
|
2013-06-10 05:48:35 +00:00
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
DisplaySaveList();
|
|
|
|
DisplaySaveDataInfo1();
|
|
|
|
|
2013-06-10 08:52:26 +00:00
|
|
|
DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_SAVE);
|
2013-05-12 02:10:01 +00:00
|
|
|
|
2013-05-18 22:07:00 +00:00
|
|
|
if (IsButtonPressed(cancelButtonFlag)) {
|
2013-06-10 08:52:26 +00:00
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
|
2013-01-18 23:45:00 +00:00
|
|
|
StartFade(false);
|
2013-05-18 22:07:00 +00:00
|
|
|
} else if (IsButtonPressed(okButtonFlag)) {
|
2012-12-10 12:08:54 +00:00
|
|
|
// Save exist, ask user confirm
|
2013-05-19 13:03:45 +00:00
|
|
|
if (param.GetFileInfo(currentSelectedSave).size > 0) {
|
2012-12-10 12:08:54 +00:00
|
|
|
yesnoChoice = 0;
|
|
|
|
display = DS_SAVE_CONFIRM_OVERWRITE;
|
2013-05-18 22:07:00 +00:00
|
|
|
} else {
|
2012-12-10 12:08:54 +00:00
|
|
|
display = DS_SAVE_SAVING;
|
2014-06-30 00:29:02 +00:00
|
|
|
StartIOThread();
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
EndDraw();
|
|
|
|
break;
|
2013-05-12 02:10:01 +00:00
|
|
|
case DS_SAVE_CONFIRM:
|
|
|
|
StartDraw();
|
|
|
|
|
2018-09-01 21:40:44 +00:00
|
|
|
DisplaySaveIcon(false);
|
2017-12-02 16:17:50 +00:00
|
|
|
DisplaySaveDataInfo2(true);
|
2013-05-12 02:10:01 +00:00
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("Confirm Save", "Do you want to save this data?"), true);
|
2013-05-12 02:10:01 +00:00
|
|
|
|
2013-06-10 08:52:26 +00:00
|
|
|
DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_SAVE);
|
|
|
|
|
2013-05-18 22:07:00 +00:00
|
|
|
if (IsButtonPressed(cancelButtonFlag) || (IsButtonPressed(okButtonFlag) && yesnoChoice == 0)) {
|
2013-06-10 08:52:26 +00:00
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
|
2013-05-12 02:10:01 +00:00
|
|
|
StartFade(false);
|
2013-05-18 22:07:00 +00:00
|
|
|
} else if (IsButtonPressed(okButtonFlag)) {
|
2013-05-12 02:10:01 +00:00
|
|
|
display = DS_SAVE_SAVING;
|
2014-06-30 00:29:02 +00:00
|
|
|
StartIOThread();
|
2013-05-12 02:10:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
2012-12-10 12:08:54 +00:00
|
|
|
case DS_SAVE_CONFIRM_OVERWRITE:
|
|
|
|
StartDraw();
|
|
|
|
|
2018-09-01 21:40:44 +00:00
|
|
|
DisplaySaveIcon(true);
|
2012-12-10 12:08:54 +00:00
|
|
|
DisplaySaveDataInfo2();
|
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("Confirm Overwrite","Do you want to overwrite the data?"), true);
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2013-06-10 08:52:26 +00:00
|
|
|
DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_SAVE);
|
|
|
|
|
2013-05-18 22:07:00 +00:00
|
|
|
if (IsButtonPressed(cancelButtonFlag) || (IsButtonPressed(okButtonFlag) && yesnoChoice == 0)) {
|
2013-05-12 02:10:01 +00:00
|
|
|
if (param.GetPspParam()->mode != SCE_UTILITY_SAVEDATA_TYPE_SAVE)
|
|
|
|
display = DS_SAVE_LIST_CHOICE;
|
2013-05-18 22:07:00 +00:00
|
|
|
else {
|
2013-06-10 08:52:26 +00:00
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
|
2013-05-12 02:10:01 +00:00
|
|
|
StartFade(false);
|
|
|
|
}
|
2013-05-18 22:07:00 +00:00
|
|
|
} else if (IsButtonPressed(okButtonFlag)) {
|
2013-05-12 02:10:01 +00:00
|
|
|
display = DS_SAVE_SAVING;
|
2014-06-30 00:29:02 +00:00
|
|
|
StartIOThread();
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
|
|
|
case DS_SAVE_SAVING:
|
2014-06-30 00:29:02 +00:00
|
|
|
if (ioThreadStatus != SAVEIO_PENDING) {
|
|
|
|
JoinIOThread();
|
|
|
|
}
|
2014-06-30 00:07:04 +00:00
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
StartDraw();
|
|
|
|
|
2018-09-01 21:40:44 +00:00
|
|
|
DisplaySaveIcon(true);
|
2017-12-02 16:17:50 +00:00
|
|
|
DisplaySaveDataInfo2(true);
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("Saving","Saving\nPlease Wait..."));
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_SAVE);
|
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
EndDraw();
|
|
|
|
break;
|
2014-06-30 00:42:20 +00:00
|
|
|
case DS_SAVE_FAILED:
|
|
|
|
JoinIOThread();
|
|
|
|
StartDraw();
|
|
|
|
|
2018-09-01 21:40:44 +00:00
|
|
|
DisplaySaveIcon(true);
|
2017-12-02 16:17:50 +00:00
|
|
|
DisplaySaveDataInfo2(true);
|
2014-06-30 00:42:20 +00:00
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("SavingFailed", "Unable to save data."));
|
2014-06-30 00:42:20 +00:00
|
|
|
|
|
|
|
DisplayButtons(DS_BUTTON_CANCEL);
|
|
|
|
DisplayBanner(DB_SAVE);
|
|
|
|
|
|
|
|
if (IsButtonPressed(cancelButtonFlag)) {
|
|
|
|
// Go back to the list so they can try again.
|
|
|
|
if (param.GetPspParam()->mode != SCE_UTILITY_SAVEDATA_TYPE_SAVE) {
|
|
|
|
display = DS_SAVE_LIST_CHOICE;
|
|
|
|
} else {
|
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
|
|
|
|
StartFade(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
2012-12-10 12:08:54 +00:00
|
|
|
case DS_SAVE_DONE:
|
2014-07-02 05:52:51 +00:00
|
|
|
if (ioThread) {
|
|
|
|
JoinIOThread();
|
|
|
|
param.SetPspParam(param.GetPspParam());
|
|
|
|
}
|
2012-12-10 12:08:54 +00:00
|
|
|
StartDraw();
|
|
|
|
|
2018-09-01 21:40:44 +00:00
|
|
|
DisplaySaveIcon(true);
|
2020-12-13 16:37:57 +00:00
|
|
|
DisplaySaveDataInfo2();
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("Save completed"));
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2013-06-10 08:52:26 +00:00
|
|
|
DisplayButtons(DS_BUTTON_CANCEL);
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_SAVE);
|
|
|
|
|
2013-05-18 22:07:00 +00:00
|
|
|
if (IsButtonPressed(cancelButtonFlag)) {
|
2013-06-10 08:52:26 +00:00
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_SUCCESS;
|
2012-12-10 12:08:54 +00:00
|
|
|
// Set the save to use for autosave and autoload
|
|
|
|
param.SetSelectedSave(param.GetFileInfo(currentSelectedSave).idx);
|
2013-01-18 23:45:00 +00:00
|
|
|
StartFade(false);
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DS_LOAD_LIST_CHOICE:
|
|
|
|
StartDraw();
|
2013-01-16 00:39:31 +00:00
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
DisplaySaveList();
|
|
|
|
DisplaySaveDataInfo1();
|
|
|
|
|
2013-06-10 08:52:26 +00:00
|
|
|
DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_LOAD);
|
|
|
|
|
2013-05-18 22:07:00 +00:00
|
|
|
if (IsButtonPressed(cancelButtonFlag)) {
|
2013-06-10 08:52:26 +00:00
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
|
2013-01-18 23:45:00 +00:00
|
|
|
StartFade(false);
|
2013-05-18 22:07:00 +00:00
|
|
|
} else if (IsButtonPressed(okButtonFlag)) {
|
2012-12-10 12:08:54 +00:00
|
|
|
display = DS_LOAD_LOADING;
|
2014-06-30 00:29:02 +00:00
|
|
|
StartIOThread();
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
2013-05-12 02:10:01 +00:00
|
|
|
case DS_LOAD_CONFIRM:
|
|
|
|
StartDraw();
|
|
|
|
|
2018-09-01 21:40:44 +00:00
|
|
|
DisplaySaveIcon(true);
|
2013-05-12 02:10:01 +00:00
|
|
|
DisplaySaveDataInfo2();
|
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("ConfirmLoad", "Load this data?"), true);
|
2013-05-12 02:10:01 +00:00
|
|
|
|
2013-06-10 08:52:26 +00:00
|
|
|
DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_LOAD);
|
|
|
|
|
2013-05-18 22:07:00 +00:00
|
|
|
if (IsButtonPressed(cancelButtonFlag) || (IsButtonPressed(okButtonFlag) && yesnoChoice == 0)) {
|
2013-06-10 08:52:26 +00:00
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
|
2013-05-12 02:10:01 +00:00
|
|
|
StartFade(false);
|
2013-05-18 22:07:00 +00:00
|
|
|
} else if (IsButtonPressed(okButtonFlag)) {
|
2013-05-12 02:10:01 +00:00
|
|
|
display = DS_LOAD_LOADING;
|
2014-06-30 00:29:02 +00:00
|
|
|
StartIOThread();
|
2013-05-12 02:10:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
2012-12-10 12:08:54 +00:00
|
|
|
case DS_LOAD_LOADING:
|
2014-06-30 00:29:02 +00:00
|
|
|
if (ioThreadStatus != SAVEIO_PENDING) {
|
|
|
|
JoinIOThread();
|
|
|
|
}
|
2014-06-30 00:07:04 +00:00
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
StartDraw();
|
|
|
|
|
2018-09-01 21:40:44 +00:00
|
|
|
DisplaySaveIcon(true);
|
2012-12-10 12:08:54 +00:00
|
|
|
DisplaySaveDataInfo2();
|
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("Loading","Loading\nPlease Wait..."));
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_LOAD);
|
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
EndDraw();
|
|
|
|
break;
|
2014-06-30 00:42:20 +00:00
|
|
|
case DS_LOAD_FAILED:
|
|
|
|
JoinIOThread();
|
|
|
|
StartDraw();
|
|
|
|
|
2018-09-01 21:40:44 +00:00
|
|
|
DisplaySaveIcon(true);
|
2014-06-30 00:42:20 +00:00
|
|
|
DisplaySaveDataInfo2();
|
|
|
|
|
2020-10-01 07:41:27 +00:00
|
|
|
DisplayMessage(di->T("LoadingFailed", "Load failed\nThe data is corrupted."));
|
2014-06-30 00:42:20 +00:00
|
|
|
|
|
|
|
DisplayButtons(DS_BUTTON_CANCEL);
|
|
|
|
DisplayBanner(DB_LOAD);
|
|
|
|
|
|
|
|
if (IsButtonPressed(cancelButtonFlag)) {
|
|
|
|
// Go back to the list so they can try again.
|
|
|
|
if (param.GetPspParam()->mode != SCE_UTILITY_SAVEDATA_TYPE_LOAD) {
|
|
|
|
display = DS_LOAD_LIST_CHOICE;
|
|
|
|
} else {
|
|
|
|
StartFade(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
2012-12-10 12:08:54 +00:00
|
|
|
case DS_LOAD_DONE:
|
2014-06-30 00:29:02 +00:00
|
|
|
JoinIOThread();
|
2012-12-10 12:08:54 +00:00
|
|
|
StartDraw();
|
2013-01-16 00:39:31 +00:00
|
|
|
|
2018-09-01 21:40:44 +00:00
|
|
|
DisplaySaveIcon(true);
|
2012-12-10 12:08:54 +00:00
|
|
|
DisplaySaveDataInfo2();
|
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("Load completed"));
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2013-06-10 08:52:26 +00:00
|
|
|
DisplayButtons(DS_BUTTON_CANCEL);
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_LOAD);
|
|
|
|
|
2014-02-03 00:00:01 +00:00
|
|
|
// Allow OK to be pressed as well to confirm the save.
|
|
|
|
// The PSP only allows cancel, but that's generally not great UX.
|
|
|
|
// Allowing this here makes it quicker for most users to get into the actual game.
|
|
|
|
if (IsButtonPressed(cancelButtonFlag) || IsButtonPressed(okButtonFlag)) {
|
2013-06-10 08:52:26 +00:00
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_SUCCESS;
|
2012-12-10 12:08:54 +00:00
|
|
|
// Set the save to use for autosave and autoload
|
|
|
|
param.SetSelectedSave(param.GetFileInfo(currentSelectedSave).idx);
|
2013-01-18 23:45:00 +00:00
|
|
|
StartFade(false);
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
|
|
|
case DS_LOAD_NODATA:
|
|
|
|
StartDraw();
|
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("There is no data"));
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2013-06-10 08:52:26 +00:00
|
|
|
DisplayButtons(DS_BUTTON_CANCEL);
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_LOAD);
|
|
|
|
|
2013-05-18 22:07:00 +00:00
|
|
|
if (IsButtonPressed(cancelButtonFlag)) {
|
2013-06-10 08:52:26 +00:00
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA;
|
2013-01-18 23:45:00 +00:00
|
|
|
StartFade(false);
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DS_DELETE_LIST_CHOICE:
|
|
|
|
StartDraw();
|
2013-01-16 00:39:31 +00:00
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
DisplaySaveList();
|
|
|
|
DisplaySaveDataInfo1();
|
|
|
|
|
2013-06-10 08:52:26 +00:00
|
|
|
DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_DELETE);
|
|
|
|
|
2013-05-18 22:07:00 +00:00
|
|
|
if (IsButtonPressed(cancelButtonFlag)) {
|
2013-06-10 08:52:26 +00:00
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
|
2013-01-18 23:45:00 +00:00
|
|
|
StartFade(false);
|
2013-05-18 22:07:00 +00:00
|
|
|
} else if (IsButtonPressed(okButtonFlag)) {
|
2012-12-10 12:08:54 +00:00
|
|
|
yesnoChoice = 0;
|
|
|
|
display = DS_DELETE_CONFIRM;
|
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
|
|
|
case DS_DELETE_CONFIRM:
|
|
|
|
StartDraw();
|
|
|
|
|
2018-09-01 21:40:44 +00:00
|
|
|
DisplaySaveIcon(true);
|
2012-12-10 12:08:54 +00:00
|
|
|
DisplaySaveDataInfo2();
|
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("DeleteConfirm",
|
2013-06-10 12:37:30 +00:00
|
|
|
"This save data will be deleted.\nAre you sure you want to continue?"),
|
|
|
|
true);
|
2013-01-19 14:14:19 +00:00
|
|
|
|
2013-06-10 08:52:26 +00:00
|
|
|
DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL);
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_DELETE);
|
|
|
|
|
2020-09-30 16:39:14 +00:00
|
|
|
if (IsButtonPressed(cancelButtonFlag) || (IsButtonPressed(okButtonFlag) && yesnoChoice == 0)) {
|
|
|
|
if(param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE || param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE)
|
2012-12-10 12:08:54 +00:00
|
|
|
display = DS_DELETE_LIST_CHOICE;
|
2013-05-18 22:07:00 +00:00
|
|
|
else {
|
2020-09-30 16:39:14 +00:00
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL;
|
|
|
|
StartFade(false);
|
|
|
|
}
|
|
|
|
} else if (IsButtonPressed(okButtonFlag)) {
|
2012-12-10 12:08:54 +00:00
|
|
|
display = DS_DELETE_DELETING;
|
2014-06-30 00:29:02 +00:00
|
|
|
StartIOThread();
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
|
|
|
case DS_DELETE_DELETING:
|
2014-06-30 00:29:02 +00:00
|
|
|
if (ioThreadStatus != SAVEIO_PENDING) {
|
|
|
|
JoinIOThread();
|
|
|
|
}
|
2014-06-30 00:07:04 +00:00
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
StartDraw();
|
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("Deleting","Deleting\nPlease Wait..."));
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_DELETE);
|
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
EndDraw();
|
|
|
|
break;
|
2014-06-30 00:42:20 +00:00
|
|
|
case DS_DELETE_FAILED:
|
|
|
|
JoinIOThread();
|
|
|
|
StartDraw();
|
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("DeleteFailed", "Unable to delete data."));
|
2014-06-30 00:42:20 +00:00
|
|
|
|
|
|
|
DisplayButtons(DS_BUTTON_CANCEL);
|
|
|
|
DisplayBanner(DB_DELETE);
|
|
|
|
|
|
|
|
if (IsButtonPressed(cancelButtonFlag)) {
|
2020-10-01 07:41:27 +00:00
|
|
|
if (param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE || param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE)
|
|
|
|
display = DS_DELETE_LIST_CHOICE;
|
|
|
|
else
|
|
|
|
StartFade(false);
|
2014-06-30 00:42:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
2012-12-10 12:08:54 +00:00
|
|
|
case DS_DELETE_DONE:
|
2014-07-02 05:52:51 +00:00
|
|
|
if (ioThread) {
|
|
|
|
JoinIOThread();
|
|
|
|
param.SetPspParam(param.GetPspParam());
|
|
|
|
}
|
2012-12-10 12:08:54 +00:00
|
|
|
StartDraw();
|
2013-01-16 00:39:31 +00:00
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("Delete completed"));
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2013-06-10 08:52:26 +00:00
|
|
|
DisplayButtons(DS_BUTTON_CANCEL);
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_DELETE);
|
|
|
|
|
2013-05-18 22:07:00 +00:00
|
|
|
if (IsButtonPressed(cancelButtonFlag)) {
|
2013-05-19 13:03:45 +00:00
|
|
|
if (param.GetFilenameCount() == 0)
|
2012-12-10 12:08:54 +00:00
|
|
|
display = DS_DELETE_NODATA;
|
2020-09-30 16:39:14 +00:00
|
|
|
else if (param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE || param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE) {
|
2020-10-04 16:00:28 +00:00
|
|
|
if (currentSelectedSave > param.GetFilenameCount() - 1)
|
|
|
|
currentSelectedSave = param.GetFilenameCount() - 1;
|
2012-12-10 12:08:54 +00:00
|
|
|
display = DS_DELETE_LIST_CHOICE;
|
2020-09-30 16:39:14 +00:00
|
|
|
} else {
|
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_SUCCESS;
|
|
|
|
StartFade(false);
|
|
|
|
}
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
|
|
|
case DS_DELETE_NODATA:
|
|
|
|
StartDraw();
|
2013-01-16 00:39:31 +00:00
|
|
|
|
2015-07-01 21:26:55 +00:00
|
|
|
DisplayMessage(di->T("There is no data"));
|
2012-12-10 12:08:54 +00:00
|
|
|
|
2013-06-10 08:52:26 +00:00
|
|
|
DisplayButtons(DS_BUTTON_CANCEL);
|
2013-06-10 05:48:35 +00:00
|
|
|
DisplayBanner(DB_DELETE);
|
|
|
|
|
2013-05-18 22:07:00 +00:00
|
|
|
if (IsButtonPressed(cancelButtonFlag)) {
|
2013-06-10 08:52:26 +00:00
|
|
|
param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA;
|
2013-01-18 23:45:00 +00:00
|
|
|
StartFade(false);
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EndDraw();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DS_NONE: // For action which display nothing
|
2014-06-30 00:29:02 +00:00
|
|
|
switch (ioThreadStatus) {
|
|
|
|
case SAVEIO_NONE:
|
|
|
|
StartIOThread();
|
|
|
|
break;
|
|
|
|
case SAVEIO_PENDING:
|
|
|
|
case SAVEIO_DONE:
|
|
|
|
// To make sure there aren't any timing variations, we sync the next frame.
|
2021-09-12 14:05:51 +00:00
|
|
|
if (g_Config.iIOTimingMethod == IOTIMING_HOST && ioThreadStatus == SAVEIO_PENDING) {
|
|
|
|
// ... except in Host IO timing, where we wait as long as needed.
|
|
|
|
break;
|
|
|
|
}
|
2014-06-30 00:29:02 +00:00
|
|
|
JoinIOThread();
|
|
|
|
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
|
|
|
|
break;
|
|
|
|
}
|
2012-12-10 12:08:54 +00:00
|
|
|
break;
|
2014-06-30 00:07:04 +00:00
|
|
|
|
2012-12-10 12:08:54 +00:00
|
|
|
default:
|
2014-02-08 17:39:50 +00:00
|
|
|
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
|
2012-12-10 12:08:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-01-18 18:46:57 +00:00
|
|
|
if (ReadStatus() == SCE_UTILITY_STATUS_FINISHED || pendingStatus == SCE_UTILITY_STATUS_FINISHED)
|
2021-02-03 08:09:21 +00:00
|
|
|
Memory::Memcpy(requestAddr, &request, request.common.size, "SaveDialogParam");
|
2024-07-16 15:07:11 +00:00
|
|
|
param.ClearSFOCache();
|
2012-12-24 00:22:28 +00:00
|
|
|
|
2012-12-25 02:37:28 +00:00
|
|
|
return 0;
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
2014-06-30 00:07:04 +00:00
|
|
|
void PSPSaveDialog::ExecuteIOAction() {
|
2024-07-16 15:07:11 +00:00
|
|
|
param.ClearSFOCache();
|
2020-10-01 07:41:27 +00:00
|
|
|
auto &result = param.GetPspParam()->common.result;
|
2017-02-27 20:57:46 +00:00
|
|
|
std::lock_guard<std::mutex> guard(paramLock);
|
2014-06-30 00:07:04 +00:00
|
|
|
switch (display) {
|
|
|
|
case DS_LOAD_LOADING:
|
2020-10-01 07:41:27 +00:00
|
|
|
result = param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave);
|
|
|
|
if (result == 0) {
|
2014-06-30 00:07:04 +00:00
|
|
|
display = DS_LOAD_DONE;
|
|
|
|
} else {
|
2014-06-30 00:42:20 +00:00
|
|
|
display = DS_LOAD_FAILED;
|
2014-06-30 00:07:04 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DS_SAVE_SAVING:
|
2021-05-08 16:42:52 +00:00
|
|
|
SaveState::NotifySaveData();
|
2018-06-24 20:28:57 +00:00
|
|
|
if (param.Save(param.GetPspParam(), GetSelectedSaveDirName()) == 0) {
|
2014-06-30 00:07:04 +00:00
|
|
|
display = DS_SAVE_DONE;
|
|
|
|
} else {
|
2014-06-30 00:42:20 +00:00
|
|
|
display = DS_SAVE_FAILED;
|
2014-06-30 00:07:04 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DS_DELETE_DELETING:
|
2020-10-04 16:00:28 +00:00
|
|
|
if (param.Delete(param.GetPspParam(), currentSelectedSave)) {
|
2020-10-01 07:41:27 +00:00
|
|
|
result = 0;
|
2014-06-30 00:07:04 +00:00
|
|
|
display = DS_DELETE_DONE;
|
|
|
|
} else {
|
2020-10-01 07:41:27 +00:00
|
|
|
//result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA;// What the result should be?
|
2014-06-30 00:42:20 +00:00
|
|
|
display = DS_DELETE_FAILED;
|
2014-06-30 00:07:04 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DS_NONE:
|
|
|
|
ExecuteNotVisibleIOAction();
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
// Nothing to do here.
|
|
|
|
break;
|
|
|
|
}
|
2014-06-30 00:29:02 +00:00
|
|
|
|
|
|
|
ioThreadStatus = SAVEIO_DONE;
|
2024-07-16 15:07:11 +00:00
|
|
|
param.ClearSFOCache();
|
2014-06-30 00:07:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void PSPSaveDialog::ExecuteNotVisibleIOAction() {
|
2024-07-16 15:07:11 +00:00
|
|
|
param.ClearSFOCache();
|
2018-06-24 20:28:57 +00:00
|
|
|
auto &result = param.GetPspParam()->common.result;
|
|
|
|
|
2024-09-10 17:06:22 +00:00
|
|
|
SceUtilitySavedataType utilityMode = (SceUtilitySavedataType)(u32)param.GetPspParam()->mode;
|
|
|
|
switch (utilityMode) {
|
2014-06-30 00:07:04 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_LOAD: // Only load and exit
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD:
|
2018-06-24 20:28:57 +00:00
|
|
|
result = param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave);
|
2014-06-30 00:07:04 +00:00
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_SAVE: // Only save and exit
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE:
|
2021-05-08 16:42:52 +00:00
|
|
|
SaveState::NotifySaveData();
|
2018-06-24 20:28:57 +00:00
|
|
|
result = param.Save(param.GetPspParam(), GetSelectedSaveDirName());
|
2014-06-30 00:07:04 +00:00
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_SIZES:
|
2018-06-24 20:28:57 +00:00
|
|
|
result = param.GetSizes(param.GetPspParam());
|
2014-06-30 00:07:04 +00:00
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_LIST:
|
|
|
|
param.GetList(param.GetPspParam());
|
2018-06-24 20:28:57 +00:00
|
|
|
result = 0;
|
2014-06-30 00:07:04 +00:00
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_FILES:
|
2022-01-26 08:31:30 +00:00
|
|
|
result = param.GetFilesList(param.GetPspParam(), requestAddr);
|
2014-06-30 00:07:04 +00:00
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE:
|
|
|
|
{
|
2018-06-24 20:28:57 +00:00
|
|
|
bool sizeResult = param.GetSize(param.GetPspParam());
|
2014-06-30 00:07:04 +00:00
|
|
|
// TODO: According to JPCSP, should test/verify this part but seems edge casey.
|
2016-09-11 02:41:39 +00:00
|
|
|
if (MemoryStick_State() != PSP_MEMORYSTICK_STATE_INSERTED) {
|
2018-06-24 20:28:57 +00:00
|
|
|
result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_MEMSTICK;
|
|
|
|
} else if (sizeResult) {
|
|
|
|
result = 0;
|
2014-06-30 00:07:04 +00:00
|
|
|
} else {
|
2018-06-24 20:28:57 +00:00
|
|
|
result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
|
2014-06-30 00:07:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA:
|
2024-07-14 12:42:59 +00:00
|
|
|
DEBUG_LOG(Log::sceUtility, "sceUtilitySavedata DELETEDATA: %s", param.GetPspParam()->saveName);
|
2020-09-30 16:39:14 +00:00
|
|
|
if (param.Delete(param.GetPspParam(), param.GetSelectedSave())) {
|
|
|
|
result = 0;
|
|
|
|
} else {
|
|
|
|
result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
|
|
|
|
}
|
2014-06-30 00:07:04 +00:00
|
|
|
break;
|
2020-09-30 16:39:14 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_DELETE:
|
2014-06-30 00:07:04 +00:00
|
|
|
if (param.Delete(param.GetPspParam(), param.GetSelectedSave())) {
|
2018-06-24 20:28:57 +00:00
|
|
|
result = 0;
|
2014-06-30 00:07:04 +00:00
|
|
|
} else {
|
2018-06-24 20:28:57 +00:00
|
|
|
result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA;
|
2014-06-30 00:07:04 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
// TODO: Should reset the directory's other files.
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE:
|
2021-05-08 16:42:52 +00:00
|
|
|
SaveState::NotifySaveData();
|
2018-08-11 23:35:58 +00:00
|
|
|
result = param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE);
|
|
|
|
if (result == SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE) {
|
2018-06-24 20:28:57 +00:00
|
|
|
result = SCE_UTILITY_SAVEDATA_ERROR_RW_MEMSTICK_FULL;
|
2014-06-30 00:07:04 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE:
|
2021-05-08 16:42:52 +00:00
|
|
|
SaveState::NotifySaveData();
|
2018-08-11 23:35:58 +00:00
|
|
|
result = param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE);
|
2014-06-30 00:07:04 +00:00
|
|
|
break;
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_READDATA:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE:
|
2020-10-01 07:41:27 +00:00
|
|
|
result = param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave, param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE);
|
2022-09-13 07:10:27 +00:00
|
|
|
if (result == SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN)
|
|
|
|
result = SCE_UTILITY_SAVEDATA_ERROR_RW_DATA_BROKEN;
|
|
|
|
if (result == SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA)
|
2018-06-24 20:28:57 +00:00
|
|
|
result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
|
2014-06-30 00:07:04 +00:00
|
|
|
break;
|
2020-09-30 16:39:14 +00:00
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_ERASE:
|
|
|
|
case SCE_UTILITY_SAVEDATA_TYPE_ERASESECURE:
|
|
|
|
result = param.DeleteData(param.GetPspParam());
|
2014-06-30 00:07:04 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2022-10-09 18:25:39 +00:00
|
|
|
|
2024-07-16 15:07:11 +00:00
|
|
|
param.ClearSFOCache();
|
2014-06-30 00:07:04 +00:00
|
|
|
}
|
|
|
|
|
2014-06-30 00:29:02 +00:00
|
|
|
void PSPSaveDialog::JoinIOThread() {
|
|
|
|
if (ioThread) {
|
|
|
|
ioThread->join();
|
|
|
|
delete ioThread;
|
|
|
|
ioThread = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DoExecuteIOAction(PSPSaveDialog *dialog) {
|
2020-11-30 23:46:26 +00:00
|
|
|
SetCurrentThreadName("SaveIO");
|
2023-01-04 12:48:40 +00:00
|
|
|
|
|
|
|
AndroidJNIThreadContext jniContext;
|
2014-06-30 00:29:02 +00:00
|
|
|
dialog->ExecuteIOAction();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PSPSaveDialog::StartIOThread() {
|
|
|
|
if (ioThread) {
|
2024-07-14 12:42:59 +00:00
|
|
|
WARN_LOG_REPORT(Log::sceUtility, "Starting a save io thread when one already pending, uh oh.");
|
2014-06-30 00:29:02 +00:00
|
|
|
JoinIOThread();
|
|
|
|
}
|
|
|
|
|
|
|
|
ioThreadStatus = SAVEIO_PENDING;
|
|
|
|
ioThread = new std::thread(&DoExecuteIOAction, this);
|
|
|
|
}
|
|
|
|
|
2014-06-30 00:07:04 +00:00
|
|
|
int PSPSaveDialog::Shutdown(bool force) {
|
2014-02-08 17:58:31 +00:00
|
|
|
if (GetStatus() != SCE_UTILITY_STATUS_FINISHED && !force)
|
2013-03-18 04:39:06 +00:00
|
|
|
return SCE_ERROR_UTILITY_INVALID_STATUS;
|
|
|
|
|
2014-06-30 00:29:02 +00:00
|
|
|
JoinIOThread();
|
|
|
|
ioThreadStatus = SAVEIO_NONE;
|
|
|
|
|
2014-02-09 00:48:40 +00:00
|
|
|
PSPDialog::Shutdown(force);
|
|
|
|
if (!force) {
|
|
|
|
ChangeStatusShutdown(SAVEDATA_SHUTDOWN_DELAY_US);
|
|
|
|
}
|
2012-12-10 12:08:54 +00:00
|
|
|
param.SetPspParam(0);
|
2024-07-16 15:07:11 +00:00
|
|
|
param.ClearSFOCache();
|
2012-12-25 02:37:28 +00:00
|
|
|
|
|
|
|
return 0;
|
2012-12-10 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
2014-06-30 00:29:02 +00:00
|
|
|
void PSPSaveDialog::DoState(PointerWrap &p) {
|
|
|
|
JoinIOThread();
|
2012-12-29 10:56:27 +00:00
|
|
|
PSPDialog::DoState(p);
|
2013-09-15 03:23:03 +00:00
|
|
|
|
2014-06-30 00:29:02 +00:00
|
|
|
auto s = p.Section("PSPSaveDialog", 1, 2);
|
|
|
|
if (!s) {
|
2013-09-15 03:23:03 +00:00
|
|
|
return;
|
2014-06-30 00:29:02 +00:00
|
|
|
}
|
2013-09-15 03:23:03 +00:00
|
|
|
|
2020-08-10 04:20:42 +00:00
|
|
|
Do(p, display);
|
2012-12-28 21:36:37 +00:00
|
|
|
param.DoState(p);
|
2020-08-10 04:20:42 +00:00
|
|
|
Do(p, request);
|
2012-12-28 21:36:37 +00:00
|
|
|
// Just reset it.
|
2012-12-29 10:56:27 +00:00
|
|
|
bool hasParam = param.GetPspParam() != NULL;
|
2020-08-10 04:20:42 +00:00
|
|
|
Do(p, hasParam);
|
2022-12-02 12:45:17 +00:00
|
|
|
if (hasParam && p.mode == p.MODE_READ) {
|
2012-12-29 10:56:27 +00:00
|
|
|
param.SetPspParam(&request);
|
2014-06-30 00:29:02 +00:00
|
|
|
}
|
2020-08-10 04:20:42 +00:00
|
|
|
Do(p, requestAddr);
|
|
|
|
Do(p, currentSelectedSave);
|
|
|
|
Do(p, yesnoChoice);
|
2014-06-30 00:29:02 +00:00
|
|
|
if (s > 2) {
|
2020-08-10 04:20:42 +00:00
|
|
|
Do(p, ioThreadStatus);
|
2014-06-30 00:29:02 +00:00
|
|
|
} else {
|
|
|
|
ioThreadStatus = SAVEIO_NONE;
|
|
|
|
}
|
2012-12-28 21:36:37 +00:00
|
|
|
}
|
2013-06-10 08:52:26 +00:00
|
|
|
|
2014-06-30 00:29:02 +00:00
|
|
|
pspUtilityDialogCommon *PSPSaveDialog::GetCommonParam() {
|
2013-06-10 08:52:26 +00:00
|
|
|
return ¶m.GetPspParam()->common;
|
|
|
|
}
|