Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cellOskDialogAbort (Fixes OSK dialog freeze in PS-Home) #11749

Merged
merged 3 commits into from Apr 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
51 changes: 47 additions & 4 deletions rpcs3/Emu/Cell/Modules/cellGameExec.cpp
@@ -1,13 +1,23 @@
#include "stdafx.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/IdManager.h"
#include "Emu/System.h"

#include "cellGame.h"

LOG_CHANNEL(cellGameExec);

struct game_exec_data
{
atomic_t<u32> execdata = 0; // TODO: pass this to the source application after closing the current application
};

error_code cellGameSetExitParam(u32 execdata)
{
cellGameExec.todo("cellGameSetExitParam(execdata=0x%x)", execdata);

g_fxo->get<game_exec_data>().execdata = execdata;

return CELL_OK;
}

Expand All @@ -25,9 +35,17 @@ error_code cellGameGetHomeDataExportPath(vm::ptr<char> exportPath)
return CELL_GAME_ERROR_NOAPP;
}

error_code cellGameGetHomePath()
error_code cellGameGetHomePath(vm::ptr<char> homePath)
{
UNIMPLEMENTED_FUNC(cellGameExec);
cellGameExec.todo("cellGameGetHomePath(homePath=*0x%x)", homePath);

if (!homePath)
{
return CELL_GAME_ERROR_PARAM;
}

// TODO: PlayStation home is defunct.

return CELL_OK;
}

Expand Down Expand Up @@ -64,6 +82,12 @@ error_code cellGameExecGame()
return CELL_OK;
}

error_code cellGameDeleteGame()
{
UNIMPLEMENTED_FUNC(cellGameExec);
return CELL_OK;
}

error_code cellGameGetBootGameInfo(vm::ptr<u32> type, vm::ptr<char> dirName, vm::ptr<u32> execdata)
{
cellGameExec.todo("cellGameGetBootGameInfo(type=*0x%x, dirName=%s, execdata=*0x%x)", type, dirName, execdata);
Expand All @@ -73,8 +97,26 @@ error_code cellGameGetBootGameInfo(vm::ptr<u32> type, vm::ptr<char> dirName, vm:
return CELL_GAME_ERROR_PARAM;
}

// TODO: Support more boot types
*type = CELL_GAME_GAMETYPE_SYS;
const u32 source_type = Emu.GetBootSourceType();

*type = source_type;

if (execdata)
{
*execdata = g_fxo->get<game_exec_data>().execdata;
}

if (source_type == CELL_GAME_GAMETYPE_HDD)
{
const std::string dir_name = Emu.GetDir();

if (dir_name.size() >= CELL_GAME_DIRNAME_SIZE)
{
return CELL_HDDGAME_ERROR_INTERNAL; // Speculative
}

std::memcpy(dirName.get_ptr(), dir_name.c_str(), dir_name.size() + 1);
}

return CELL_OK;
}
Expand All @@ -87,5 +129,6 @@ DECLARE(ppu_module_manager::cellGameExec)("cellGameExec", []()
REG_FUNC(cellGameExec, cellGameGetHomeDataImportPath);
REG_FUNC(cellGameExec, cellGameGetHomeLaunchOptionPath);
REG_FUNC(cellGameExec, cellGameExecGame);
REG_FUNC(cellGameExec, cellGameDeleteGame);
REG_FUNC(cellGameExec, cellGameGetBootGameInfo);
});
16 changes: 7 additions & 9 deletions rpcs3/Emu/Cell/Modules/cellOskDialog.cpp
Expand Up @@ -217,7 +217,7 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia

osk->on_osk_close = [wptr = std::weak_ptr<OskDialogBase>(osk)](s32 status)
{
cellOskDialog.error("on_osk_close(status=%d)", status);
cellOskDialog.notice("on_osk_close(status=%d)", status);

const auto osk = wptr.lock();
osk->state = OskDialogState::Closed;
Expand Down Expand Up @@ -511,27 +511,25 @@ error_code cellOskDialogAbort()
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
}

const s32 result = osk->state.atomic_op([](OskDialogState& state)
const error_code result = osk->state.atomic_op([](OskDialogState& state) -> error_code
{
// Check for open dialog. In this case the dialog is "Open" if it was not unloaded before.
if (state == OskDialogState::Unloaded)
{
return static_cast<s32>(CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED);
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
}

state = OskDialogState::Abort;

return static_cast<s32>(CELL_OK);
return CELL_OK;
});

if (result != CELL_OK)
if (result == CELL_OK)
{
return result;
osk->osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_ABORT;
osk->Close(FAKE_CELL_OSKDIALOG_CLOSE_ABORT);
}

osk->osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_ABORT;
osk->Close(FAKE_CELL_OSKDIALOG_CLOSE_ABORT);

g_fxo->get<osk_info>().last_dialog_state = CELL_SYSUTIL_OSKDIALOG_FINISHED;
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0);

Expand Down
24 changes: 24 additions & 0 deletions rpcs3/Emu/System.cpp
Expand Up @@ -19,6 +19,7 @@
#include "Emu/Cell/lv2/sys_sync.h"
#include "Emu/Cell/lv2/sys_prx.h"
#include "Emu/Cell/lv2/sys_overlay.h"
#include "Emu/Cell/Modules/cellGame.h"

#include "Emu/title.h"
#include "Emu/IdManager.h"
Expand Down Expand Up @@ -560,6 +561,29 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
{
const std::string resolved_path = GetCallbacks().resolve_path(m_path);

if (m_config_mode == cfg_mode::continuous)
{
// The program is being booted from another running program
// CELL_GAME_GAMETYPE_GAMEDATA is not used as boot type

if (m_cat == "DG"sv)
{
m_boot_source_type = CELL_GAME_GAMETYPE_DISC;
}
else if (m_cat == "HM"sv)
{
m_boot_source_type = CELL_GAME_GAMETYPE_HOME;
}
else
{
m_boot_source_type = CELL_GAME_GAMETYPE_HDD;
}
}
else
{
m_boot_source_type = CELL_GAME_GAMETYPE_SYS;
}

if (!IsStopped())
{
Kill();
Expand Down
7 changes: 7 additions & 0 deletions rpcs3/Emu/System.h
Expand Up @@ -180,6 +180,13 @@ class Emulator final
std::string disc;
std::string hdd1;

u32 m_boot_source_type = 0; // CELL_GAME_GAMETYPE_SYS

const u32& GetBootSourceType() const
{
return m_boot_source_type;
}

const std::string& GetBoot() const
{
return m_path;
Expand Down