Dialog: Use a thread to init dialogs too.

This commit is contained in:
Unknown W. Brackets 2021-04-07 18:07:48 -07:00
parent 28065c1bc4
commit 429b4594d0
4 changed files with 55 additions and 3 deletions

View File

@ -75,6 +75,7 @@ void PSPDialog::ChangeStatus(DialogStatus newStatus, int delayUs) {
}
}
status = newStatus;
pendingStatus = newStatus;
pendingStatusTicks = 0;
} else {
pendingStatus = newStatus;
@ -93,6 +94,13 @@ void PSPDialog::FinishVolatile() {
}
}
int PSPDialog::FinishInit() {
if (ReadStatus() != SCE_UTILITY_STATUS_INITIALIZE)
return -1;
ChangeStatus(SCE_UTILITY_STATUS_RUNNING, 0);
return 0;
}
int PSPDialog::FinishShutdown() {
if (ReadStatus() != SCE_UTILITY_STATUS_SHUTDOWN)
return -1;
@ -101,12 +109,18 @@ int PSPDialog::FinishShutdown() {
}
void PSPDialog::ChangeStatusInit(int delayUs) {
status = SCE_UTILITY_STATUS_INITIALIZE;
ChangeStatus(SCE_UTILITY_STATUS_RUNNING, delayUs);
ChangeStatus(SCE_UTILITY_STATUS_INITIALIZE, 0);
auto params = GetCommonParam();
if (params)
UtilityDialogInitialize(DialogType(), delayUs, params->accessThread);
else
ChangeStatus(SCE_UTILITY_STATUS_RUNNING, delayUs);
}
void PSPDialog::ChangeStatusShutdown(int delayUs) {
status = SCE_UTILITY_STATUS_SHUTDOWN;
ChangeStatus(SCE_UTILITY_STATUS_SHUTDOWN, 0);
auto params = GetCommonParam();
if (params)
UtilityDialogShutdown(DialogType(), delayUs, params->accessThread);

View File

@ -86,6 +86,7 @@ public:
void EndDraw();
void FinishVolatile();
int FinishInit();
int FinishShutdown();
protected:

View File

@ -270,6 +270,30 @@ void __UtilityShutdown() {
delete gamedataInstallDialog;
}
void UtilityDialogInitialize(UtilityDialogType type, int delayUs, int priority) {
int partDelay = delayUs / 4;
const u32_le insts[] = {
// Make sure we don't discard/deadbeef 'em.
(u32_le)MIPS_MAKE_ORI(MIPS_REG_S0, MIPS_REG_A0, 0),
(u32_le)MIPS_MAKE_SYSCALL("sceUtility", "__UtilityWorkUs"),
(u32_le)MIPS_MAKE_ORI(MIPS_REG_A0, MIPS_REG_S0, 0),
(u32_le)MIPS_MAKE_SYSCALL("sceUtility", "__UtilityWorkUs"),
(u32_le)MIPS_MAKE_ORI(MIPS_REG_A0, MIPS_REG_S0, 0),
(u32_le)MIPS_MAKE_SYSCALL("sceUtility", "__UtilityWorkUs"),
(u32_le)MIPS_MAKE_ORI(MIPS_REG_A0, MIPS_REG_S0, 0),
(u32_le)MIPS_MAKE_SYSCALL("sceUtility", "__UtilityWorkUs"),
(u32_le)MIPS_MAKE_ORI(MIPS_REG_A0, MIPS_REG_ZERO, (int)type),
(u32_le)MIPS_MAKE_JR_RA(),
(u32_le)MIPS_MAKE_SYSCALL("sceUtility", "__UtilityInitDialog"),
};
CleanupDialogThreads();
_assert_(accessThread == nullptr);
accessThread = new HLEHelperThread("ScePafJob", insts, (uint32_t)ARRAY_SIZE(insts), priority, 0x200);
accessThread->Start(partDelay, 0);
}
void UtilityDialogShutdown(UtilityDialogType type, int delayUs, int priority) {
// Break it up so better-priority rescheduling happens.
// The windows aren't this regular, but close.
@ -299,11 +323,22 @@ void UtilityDialogShutdown(UtilityDialogType type, int delayUs, int priority) {
static int UtilityWorkUs(int us) {
// This blocks, but other better priority threads can get time.
// Simulate this by allowing a reschedule.
if (us > 1000) {
hleEatMicro(us - 400);
return hleDelayResult(0, "utility work", 400);
}
hleEatMicro(us);
hleReSchedule("utility work");
return 0;
}
static int UtilityInitDialog(int type) {
PSPDialog *dialog = CurrentDialog((UtilityDialogType)type);
if (dialog)
return hleLogSuccessI(SCEUTILITY, dialog->FinishInit());
return hleLogError(SCEUTILITY, 0, "invalid dialog type?");
}
static int UtilityFinishDialog(int type) {
PSPDialog *dialog = CurrentDialog((UtilityDialogType)type);
if (dialog)
@ -1046,6 +1081,7 @@ const HLEFunction sceUtility[] =
// Fake functions for PPSSPP's use.
{0xC0DE0001, &WrapI_I<UtilityFinishDialog>, "__UtilityFinishDialog", 'i', "i" },
{0xC0DE0002, &WrapI_I<UtilityWorkUs>, "__UtilityWorkUs", 'i', "i" },
{0xC0DE0003, &WrapI_I<UtilityInitDialog>, "__UtilityInitDialog", 'i', "i" },
};
void Register_sceUtility()

View File

@ -94,6 +94,7 @@ void __UtilityInit();
void __UtilityDoState(PointerWrap &p);
void __UtilityShutdown();
void UtilityDialogInitialize(UtilityDialogType type, int delayUs, int priority);
void UtilityDialogShutdown(UtilityDialogType type, int delayUs, int priority);
void Register_sceUtility();