mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
cellOsk: partially implement continuous mode
This commit is contained in:
parent
e3ec71c683
commit
a7cb513a89
3 changed files with 74 additions and 39 deletions
|
@ -33,6 +33,23 @@ void fmt_class_string<CellOskDialogError>::format(std::string& out, u64 arg)
|
|||
});
|
||||
}
|
||||
|
||||
template<>
|
||||
void fmt_class_string<CellOskDialogContinuousMode>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](auto mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
STR_CASE(CELL_OSKDIALOG_CONTINUOUS_MODE_NONE);
|
||||
STR_CASE(CELL_OSKDIALOG_CONTINUOUS_MODE_REMAIN_OPEN);
|
||||
STR_CASE(CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE);
|
||||
STR_CASE(CELL_OSKDIALOG_CONTINUOUS_MODE_SHOW);
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
OskDialogBase::~OskDialogBase()
|
||||
{
|
||||
}
|
||||
|
@ -154,7 +171,7 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
|
|||
auto osk = _get_osk_dialog(true);
|
||||
|
||||
// Can't open another dialog if this one is already open.
|
||||
if (!osk || osk->state.load() == OskDialogState::Open)
|
||||
if (!osk || osk->state.load() != OskDialogState::Unloaded)
|
||||
{
|
||||
return CELL_SYSUTIL_ERROR_BUSY;
|
||||
}
|
||||
|
@ -200,21 +217,10 @@ 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);
|
||||
|
||||
const auto osk = wptr.lock();
|
||||
|
||||
if (osk->state.atomic_op([&](OskDialogState& state)
|
||||
{
|
||||
if (state == OskDialogState::Abort)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
state = OskDialogState::Close;
|
||||
return false;
|
||||
}))
|
||||
{
|
||||
cellOskDialog.notice("Called on_osk_close after abort");
|
||||
}
|
||||
osk->state = OskDialogState::Closed;
|
||||
|
||||
auto& info = g_fxo->get<osk_info>();
|
||||
|
||||
|
@ -275,11 +281,16 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
|
|||
osk->osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_CANCELED;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case FAKE_CELL_OSKDIALOG_CLOSE_ABORT:
|
||||
{
|
||||
osk->osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_ABORT;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
cellOskDialog.fatal("on_osk_close: Unknown status (%d)", status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Send OSK status
|
||||
|
@ -299,15 +310,24 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
|
|||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED, 0);
|
||||
break;
|
||||
}
|
||||
case FAKE_CELL_OSKDIALOG_CLOSE_ABORT:
|
||||
{
|
||||
// Handled in cellOskDialogAbort
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
info.last_dialog_state = CELL_SYSUTIL_OSKDIALOG_FINISHED;
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0);
|
||||
cellOskDialog.fatal("on_osk_close: Unknown status (%d)", status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (info.osk_continuous_mode.load() == CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE)
|
||||
{
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_DISPLAY_CHANGED, CELL_OSKDIALOG_DISPLAY_STATUS_HIDE);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (status != FAKE_CELL_OSKDIALOG_CLOSE_ABORT) // Handled in cellOskDialogAbort
|
||||
{
|
||||
info.last_dialog_state = CELL_SYSUTIL_OSKDIALOG_FINISHED;
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0);
|
||||
|
@ -316,6 +336,13 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
|
|||
input::SetIntercepted(false);
|
||||
};
|
||||
|
||||
if (auto& info = g_fxo->get<osk_info>(); info.osk_continuous_mode == CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE)
|
||||
{
|
||||
info.last_dialog_state = CELL_SYSUTIL_OSKDIALOG_LOADED;
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_LOADED, 0);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
input::SetIntercepted(true);
|
||||
|
||||
Emu.CallAfter([=, &result]()
|
||||
|
@ -323,12 +350,14 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
|
|||
osk->Create(get_localized_string(localized_string_id::CELL_OSK_DIALOG_TITLE), message, osk->osk_text, maxLength, prohibitFlgs, allowOskPanelFlg, firstViewPanel);
|
||||
result = true;
|
||||
result.notify_one();
|
||||
|
||||
if (g_fxo->get<osk_info>().osk_continuous_mode.load() == CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE)
|
||||
{
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_DISPLAY_CHANGED, CELL_OSKDIALOG_DISPLAY_STATUS_SHOW);
|
||||
}
|
||||
});
|
||||
|
||||
{
|
||||
auto& info = g_fxo->get<osk_info>();
|
||||
info.last_dialog_state = CELL_SYSUTIL_OSKDIALOG_LOADED;
|
||||
}
|
||||
g_fxo->get<osk_info>().last_dialog_state = CELL_SYSUTIL_OSKDIALOG_LOADED;
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_LOADED, 0);
|
||||
|
||||
while (!result && !Emu.IsStopped())
|
||||
|
@ -420,6 +449,7 @@ error_code getText(vm::ptr<CellOskDialogCallbackReturnParam> OutputInfo, bool is
|
|||
info.reset();
|
||||
}
|
||||
|
||||
osk->state = OskDialogState::Unloaded;
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_UNLOADED, 0);
|
||||
}
|
||||
else if (keep_seperate_window_open)
|
||||
|
@ -483,18 +513,12 @@ error_code cellOskDialogAbort()
|
|||
|
||||
const s32 result = osk->state.atomic_op([](OskDialogState& state)
|
||||
{
|
||||
// Check for open dialog. In this case the dialog is only "Open" if it was not aborted before.
|
||||
if (state == OskDialogState::Abort)
|
||||
// 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);
|
||||
}
|
||||
|
||||
// If the dialog has the Open state then it is in use. Only dialogs with the Close state can be aborted.
|
||||
if (state == OskDialogState::Open)
|
||||
{
|
||||
return static_cast<s32>(CELL_SYSUTIL_ERROR_BUSY);
|
||||
}
|
||||
|
||||
state = OskDialogState::Abort;
|
||||
|
||||
return static_cast<s32>(CELL_OK);
|
||||
|
@ -506,7 +530,10 @@ error_code cellOskDialogAbort()
|
|||
}
|
||||
|
||||
osk->osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_ABORT;
|
||||
osk->Close(-1);
|
||||
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);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -536,7 +563,9 @@ error_code cellOskDialogSetSeparateWindowOption(vm::ptr<CellOskDialogSeparateWin
|
|||
auto& osk = g_fxo->get<osk_info>();
|
||||
osk.use_separate_windows = true;
|
||||
osk.osk_continuous_mode = static_cast<CellOskDialogContinuousMode>(+windowOption->continuousMode);
|
||||
// TODO: rest
|
||||
// TODO: handle rest of windowOption
|
||||
|
||||
cellOskDialog.warning("cellOskDialogSetSeparateWindowOption: continuousMode=%s)", osk.osk_continuous_mode.load());
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -702,8 +731,8 @@ error_code cellOskDialogExtSendFinishMessage(u32 /*CellOskDialogFinishReason*/ f
|
|||
|
||||
const auto osk = _get_osk_dialog();
|
||||
|
||||
// Check for open dialog.
|
||||
if (!osk || osk->state.load() != OskDialogState::Open)
|
||||
// Check for "Open" dialog.
|
||||
if (!osk || osk->state.load() == OskDialogState::Unloaded)
|
||||
{
|
||||
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
|
||||
}
|
||||
|
|
|
@ -83,6 +83,11 @@ enum CellOskDialogFinishReason
|
|||
CELL_OSKDIALOG_CLOSE_CANCEL = 1,
|
||||
};
|
||||
|
||||
enum CellOskDialogFinishReasonFake // Helper. Must be negative values.
|
||||
{
|
||||
FAKE_CELL_OSKDIALOG_CLOSE_ABORT = -1,
|
||||
};
|
||||
|
||||
enum CellOskDialogType
|
||||
{
|
||||
CELL_OSKDIALOG_TYPE_SINGLELINE_OSK = 0,
|
||||
|
@ -239,9 +244,10 @@ using cellOskDialogForceFinishCallback = class b8();
|
|||
|
||||
enum class OskDialogState
|
||||
{
|
||||
Unloaded,
|
||||
Open,
|
||||
Abort,
|
||||
Close,
|
||||
Closed
|
||||
};
|
||||
|
||||
class OskDialogBase
|
||||
|
@ -258,7 +264,7 @@ public:
|
|||
std::function<void(s32 status)> on_osk_close;
|
||||
std::function<void()> on_osk_input_entered;
|
||||
|
||||
atomic_t<OskDialogState> state{ OskDialogState::Close };
|
||||
atomic_t<OskDialogState> state{ OskDialogState::Unloaded };
|
||||
|
||||
atomic_t<CellOskDialogInputFieldResult> osk_input_result{ CellOskDialogInputFieldResult::CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK };
|
||||
char16_t osk_text[CELL_OSKDIALOG_STRING_SIZE]{};
|
||||
|
|
|
@ -170,7 +170,7 @@ void osk_dialog_frame::Create(const std::string& title, const std::u16string& me
|
|||
on_osk_close(CELL_OSKDIALOG_CLOSE_CANCEL);
|
||||
break;
|
||||
default:
|
||||
on_osk_close(-1);
|
||||
on_osk_close(result);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
@ -198,7 +198,7 @@ void osk_dialog_frame::Close(s32 status)
|
|||
m_dialog->done(QDialog::Rejected);
|
||||
break;
|
||||
default:
|
||||
m_dialog->done(-1);
|
||||
m_dialog->done(status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue