Dialog: Simulate volatile memory lock behavior.

Also simply clear to zero, which isn't exactly correct but should be
fairly close.  See #8288 (NBA Live 08 hang.)
This commit is contained in:
Unknown W. Brackets 2021-01-18 11:07:21 -08:00
parent 8bd32b6009
commit e42dac2fb4
3 changed files with 54 additions and 9 deletions

View file

@ -21,9 +21,11 @@
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/StringUtils.h"
#include "Core/CoreTiming.h"
#include "Core/HLE/sceCtrl.h"
#include "Core/Util/PPGeDraw.h"
#include "Core/Dialog/PSPDialog.h"
#include "Core/HLE/sceCtrl.h"
#include "Core/HLE/scePower.h"
#include "Core/MemMapHelpers.h"
#include "Core/Util/PPGeDraw.h"
#define FADE_TIME 1.0
const float FONT_SCALE = 0.55f;
@ -34,11 +36,24 @@ PSPDialog::PSPDialog() {
PSPDialog::~PSPDialog() {
}
PSPDialog::DialogStatus PSPDialog::GetStatus()
{
PSPDialog::DialogStatus PSPDialog::GetStatus() {
if (pendingStatusTicks != 0 && CoreTiming::GetTicks() >= pendingStatusTicks) {
status = pendingStatus;
pendingStatusTicks = 0;
bool changeAllowed = true;
if (pendingStatus == SCE_UTILITY_STATUS_NONE && status == SCE_UTILITY_STATUS_SHUTDOWN) {
if (volatileLocked_) {
KernelVolatileMemUnlock(0);
volatileLocked_ = false;
}
} else if (pendingStatus == SCE_UTILITY_STATUS_RUNNING && status == SCE_UTILITY_STATUS_INITIALIZE) {
if (!volatileLocked_) {
volatileLocked_ = KernelVolatileMemLock(0, 0, 0) == 0;
changeAllowed = volatileLocked_;
}
}
if (changeAllowed) {
status = pendingStatus;
pendingStatusTicks = 0;
}
}
PSPDialog::DialogStatus retval = status;
@ -53,6 +68,17 @@ PSPDialog::DialogStatus PSPDialog::GetStatus()
void PSPDialog::ChangeStatus(DialogStatus newStatus, int delayUs) {
if (delayUs <= 0) {
if (newStatus == SCE_UTILITY_STATUS_NONE && status == SCE_UTILITY_STATUS_SHUTDOWN) {
if (volatileLocked_) {
KernelVolatileMemUnlock(0);
volatileLocked_ = false;
}
} else if (newStatus == SCE_UTILITY_STATUS_RUNNING && status == SCE_UTILITY_STATUS_INITIALIZE) {
if (!volatileLocked_) {
// TODO: Should probably make the status pending instead?
volatileLocked_ = KernelVolatileMemLock(0, 0, 0) == 0;
}
}
status = newStatus;
pendingStatusTicks = 0;
} else {
@ -61,6 +87,14 @@ void PSPDialog::ChangeStatus(DialogStatus newStatus, int delayUs) {
}
}
void PSPDialog::FinishVolatile() {
if (KernelVolatileMemUnlock(0) == 0) {
volatileLocked_ = false;
// Simulate modifications to volatile memory.
Memory::Memset(PSP_GetVolatileMemoryStart(), 0, PSP_GetVolatileMemoryEnd() - PSP_GetVolatileMemoryStart());
}
}
void PSPDialog::ChangeStatusInit(int delayUs) {
status = SCE_UTILITY_STATUS_INITIALIZE;
ChangeStatus(SCE_UTILITY_STATUS_RUNNING, delayUs);
@ -128,9 +162,8 @@ u32 PSPDialog::CalcFadedColor(u32 inColor)
return (inColor & 0x00FFFFFF) | (alpha << 24);
}
void PSPDialog::DoState(PointerWrap &p)
{
auto s = p.Section("PSPDialog", 1, 2);
void PSPDialog::DoState(PointerWrap &p) {
auto s = p.Section("PSPDialog", 1, 3);
if (!s)
return;
@ -157,6 +190,12 @@ void PSPDialog::DoState(PointerWrap &p)
} else {
pendingStatusTicks = 0;
}
if (s >= 3) {
Do(p, volatileLocked_);
} else {
volatileLocked_ = false;
}
}
pspUtilityDialogCommon *PSPDialog::GetCommonParam()

View file

@ -123,5 +123,8 @@ protected:
int cancelButtonFlag;
private:
void FinishVolatile();
DialogStatus status = SCE_UTILITY_STATUS_NONE;
bool volatileLocked_ = false;
};

View file

@ -465,8 +465,11 @@ inline u32 PSP_GetScratchpadMemoryEnd() { return 0x00014000;}
inline u32 PSP_GetKernelMemoryBase() { return 0x08000000;}
inline u32 PSP_GetUserMemoryEnd() { return PSP_GetKernelMemoryBase() + Memory::g_MemorySize;}
inline u32 PSP_GetKernelMemoryEnd() { return 0x08400000;}
// "Volatile" RAM is between 0x08400000 and 0x08800000, can be requested by the
// game through sceKernelVolatileMemTryLock.
inline u32 PSP_GetVolatileMemoryStart() { return 0x08400000; }
inline u32 PSP_GetVolatileMemoryEnd() { return 0x08800000; }
inline u32 PSP_GetUserMemoryBase() { return 0x08800000;}
inline u32 PSP_GetDefaultLoadAddress() { return 0;}