mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
- The Yugioh savedata workaround force-stopped the other dialog without releasing the volatile memory it held, so the savedata helper then waited for it forever. - Screenshot's ShutdownStart and Update succeeded when no screenshot was running, putting it back into SHUTDOWN. - Savestates: Netconf didn't keep its request address, and a DNS json download going on was gone after a load, so it could wait for it forever; it now fetches the json again (it's cached). NpSignin didn't keep its request address either. Both restart their timeouts instead of timing out at once. With states from before, they keep the current address as they used to. - Loading a state from before NpSignin, GameSharing or HtmlViewer were saved resets them rather than keeping this session's state (including the HtmlViewer's memory block), and without Shutdown's side effects, which would write to the loaded memory and release its volatile lock. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
141 lines
4.4 KiB
C++
141 lines
4.4 KiB
C++
// Copyright (c) 2012- PPSSPP Project.
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
// Official git repository and contact information can be found at
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
#include "Common/Serialize/Serializer.h"
|
|
#include "Common/Serialize/SerializeFuncs.h"
|
|
#include "Core/Dialog/PSPDialog.h"
|
|
#include "Core/Dialog/PSPScreenshotDialog.h"
|
|
#include "Core/HLE/sceKernel.h"
|
|
#include "Core/HLE/ErrorCodes.h"
|
|
#include "Core/MemMap.h"
|
|
#include "Core/Reporting.h"
|
|
|
|
enum SceUtilityScreenshotType {
|
|
SCE_UTILITY_SCREENSHOT_TYPE_GUI = 0,
|
|
SCE_UTILITY_SCREENSHOT_TYPE_AUTO = 1,
|
|
SCE_UTILITY_SCREENSHOT_TYPE_SAVE = 2,
|
|
SCE_UTILITY_SCREENSHOT_TYPE_VIEW = 3,
|
|
|
|
// Names are just guesses based on status value behavior.
|
|
SCE_UTILITY_SCREENSHOT_TYPE_CONT_START = 100,
|
|
SCE_UTILITY_SCREENSHOT_TYPE_CONT_FINISH = 101,
|
|
SCE_UTILITY_SCREENSHOT_TYPE_CONT_STOP = 102,
|
|
};
|
|
|
|
static const int SCE_UTILITY_SCREENSHOTDIALOG_SIZE_V1 = 436;
|
|
static const int SCE_UTILITY_SCREENSHOTDIALOG_SIZE_V2 = 928;
|
|
static const int SCE_UTILITY_SCREENSHOTDIALOG_SIZE_V3 = 932;
|
|
|
|
#if COMMON_LITTLE_ENDIAN
|
|
typedef SceUtilityScreenshotType SceUtilityScreenshotType_le;
|
|
#else
|
|
typedef swap_struct_t<SceUtilityScreenshotType, swap_32_t<SceUtilityScreenshotType> > SceUtilityScreenshotType_le;
|
|
#endif
|
|
|
|
struct SceUtilityScreenshotParams {
|
|
pspUtilityDialogCommon base;
|
|
SceUtilityScreenshotType_le mode;
|
|
|
|
// TODO
|
|
};
|
|
|
|
PSPScreenshotDialog::PSPScreenshotDialog(UtilityDialogType type) : PSPDialog(type) {
|
|
}
|
|
|
|
PSPScreenshotDialog::~PSPScreenshotDialog() {
|
|
}
|
|
|
|
int PSPScreenshotDialog::Init(u32 paramAddr) {
|
|
// Already running
|
|
if (ReadStatus() != SCE_UTILITY_STATUS_NONE && ReadStatus() != SCE_UTILITY_STATUS_SHUTDOWN) {
|
|
ERROR_LOG_REPORT(Log::HLE, "sceUtilityScreenshotInitStart(%08x): invalid status", paramAddr);
|
|
return SCE_ERROR_UTILITY_INVALID_STATUS;
|
|
}
|
|
|
|
const int check = CheckRequest(paramAddr, { SCE_UTILITY_SCREENSHOTDIALOG_SIZE_V1, SCE_UTILITY_SCREENSHOTDIALOG_SIZE_V2, SCE_UTILITY_SCREENSHOTDIALOG_SIZE_V3 });
|
|
if (check < 0) {
|
|
ERROR_LOG(Log::HLE, "sceUtilityScreenshotInitStart(%08x): bad request: %08x", paramAddr, check);
|
|
return check;
|
|
}
|
|
params_ = PSPPointer<SceUtilityScreenshotParams>::Create(paramAddr);
|
|
|
|
mode = params_->mode;
|
|
ChangeStatus(SCE_UTILITY_STATUS_INITIALIZE, 0);
|
|
InitCommon();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int PSPScreenshotDialog::Update(int animSpeed) {
|
|
if (ReadStatus() == SCE_UTILITY_STATUS_NONE) {
|
|
return SCE_ERROR_UTILITY_INVALID_STATUS;
|
|
}
|
|
UpdateCommon();
|
|
if (UseAutoStatus()) {
|
|
if (ReadStatus() == SCE_UTILITY_STATUS_INITIALIZE) {
|
|
ChangeStatus(SCE_UTILITY_STATUS_RUNNING, 0);
|
|
} else if (ReadStatus() == SCE_UTILITY_STATUS_RUNNING) {
|
|
if (mode == SCE_UTILITY_SCREENSHOT_TYPE_CONT_START) {
|
|
ChangeStatus(SCE_UTILITY_STATUS_SCREENSHOT_UNKNOWN, 0);
|
|
} else {
|
|
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
|
|
}
|
|
} else if (ReadStatus() == SCE_UTILITY_STATUS_FINISHED) {
|
|
ChangeStatus(SCE_UTILITY_STATUS_SHUTDOWN, 0);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int PSPScreenshotDialog::Shutdown(bool force) {
|
|
// TODO: Only from FINISHED, like the other dialogs? Update moves on to SHUTDOWN by itself here.
|
|
if (!force && ReadStatus() == SCE_UTILITY_STATUS_NONE) {
|
|
return SCE_ERROR_UTILITY_INVALID_STATUS;
|
|
}
|
|
return PSPDialog::Shutdown(force);
|
|
}
|
|
|
|
int PSPScreenshotDialog::ContStart() {
|
|
// Based on JPCSP http://code.google.com/p/jpcsp/source/detail?r=3381
|
|
if (ReadStatus() != SCE_UTILITY_STATUS_SCREENSHOT_UNKNOWN)
|
|
return SCE_ERROR_UTILITY_INVALID_STATUS;
|
|
|
|
// Check with JPCSPTrace log of Dream Club Portable
|
|
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void PSPScreenshotDialog::DoState(PointerWrap &p) {
|
|
PSPDialog::DoState(p);
|
|
|
|
auto s = p.Section("PSPScreenshotDialog", 0, 2);
|
|
if (!s)
|
|
return;
|
|
|
|
Do(p, mode);
|
|
if (s >= 2) {
|
|
Do(p, params_);
|
|
}
|
|
}
|
|
|
|
pspUtilityDialogCommon *PSPScreenshotDialog::GetCommonParam() {
|
|
if (params_.IsValid())
|
|
return ¶ms_->base;
|
|
return nullptr;
|
|
}
|