mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 06:21:26 +12:00
cellCrossControllerInitialize: add dialog
This commit is contained in:
parent
cdef752a9c
commit
7499f875a6
6 changed files with 154 additions and 19 deletions
|
@ -1,7 +1,11 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "Emu/System.h"
|
||||||
#include "Emu/Cell/PPUModule.h"
|
#include "Emu/Cell/PPUModule.h"
|
||||||
|
#include "Emu/IdManager.h"
|
||||||
|
#include "Emu/localized_string.h"
|
||||||
#include "cellSysutil.h"
|
#include "cellSysutil.h"
|
||||||
#include "cellCrossController.h"
|
#include "cellCrossController.h"
|
||||||
|
#include "cellMsgDialog.h"
|
||||||
|
|
||||||
|
|
||||||
LOG_CHANNEL(cellCrossController);
|
LOG_CHANNEL(cellCrossController);
|
||||||
|
@ -33,15 +37,117 @@ void fmt_class_string<CellCrossControllerError>::format(std::string& out, u64 ar
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void finish_callback(ppu_thread& ppu, s32 button_type, vm::ptr<void> userdata); // Forward declaration
|
||||||
|
|
||||||
|
struct cross_controller
|
||||||
|
{
|
||||||
|
atomic_t<s32> status{0};
|
||||||
|
std::unique_ptr<named_thread<std::function<void()>>> connection_thread;
|
||||||
|
vm::ptr<CellCrossControllerCallback> callback = vm::null;
|
||||||
|
vm::ptr<void> userdata = vm::null;
|
||||||
|
|
||||||
|
void on_connection_established(s32 status)
|
||||||
|
{
|
||||||
|
ensure(!!callback);
|
||||||
|
|
||||||
|
close_msg_dialog();
|
||||||
|
|
||||||
|
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||||
|
{
|
||||||
|
callback(ppu, CELL_CROSS_CONTROLLER_STATUS_FINALIZED, status, vm::null, userdata);
|
||||||
|
return CELL_OK;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_thread(vm::cptr<CellCrossControllerPackageInfo> pPkgInfo)
|
||||||
|
{
|
||||||
|
ensure(!!pPkgInfo);
|
||||||
|
ensure(!!callback);
|
||||||
|
|
||||||
|
const std::string msg = fmt::format("%s\n\n%s",
|
||||||
|
get_localized_string(localized_string_id::CELL_CROSS_CONTROLLER_MSG, pPkgInfo->pTitle.get_ptr()),
|
||||||
|
get_localized_string(localized_string_id::CELL_CROSS_CONTROLLER_FW_MSG));
|
||||||
|
|
||||||
|
vm::bptr<CellMsgDialogCallback> msg_dialog_callback = vm::null;
|
||||||
|
msg_dialog_callback.set(g_fxo->get<ppu_function_manager>().func_addr(FIND_FUNC(finish_callback)));
|
||||||
|
|
||||||
|
// TODO: Show icons from comboplay_plugin.rco in dialog. Maybe use a new dialog or add an optional icon to this one.
|
||||||
|
error_code res = open_msg_dialog(false, CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_OFF, vm::make_str(msg), msg_dialog_callback, userdata);
|
||||||
|
|
||||||
|
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||||
|
{
|
||||||
|
callback(ppu, CELL_CROSS_CONTROLLER_STATUS_INITIALIZED, res == CELL_OK ? CELL_OK : CELL_CROSS_CONTROLLER_ERROR_INTERNAL, vm::null, userdata);
|
||||||
|
return CELL_OK;
|
||||||
|
});
|
||||||
|
|
||||||
|
status = CELL_CROSS_CONTROLLER_STATUS_INITIALIZED;
|
||||||
|
|
||||||
|
connection_thread = std::make_unique<named_thread<std::function<void()>>>(fmt::format("Cross-Controller Thread"), [this]()
|
||||||
|
{
|
||||||
|
while (thread_ctrl::state() != thread_state::aborting)
|
||||||
|
{
|
||||||
|
if (Emu.IsPaused())
|
||||||
|
{
|
||||||
|
thread_ctrl::wait_for(10'000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: establish connection to PS Vita
|
||||||
|
if (false)
|
||||||
|
{
|
||||||
|
on_connection_established(CELL_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_ctrl::wait_for(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = CELL_CROSS_CONTROLLER_STATUS_FINALIZED;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop_thread()
|
||||||
|
{
|
||||||
|
if (connection_thread)
|
||||||
|
{
|
||||||
|
auto& thread = *connection_thread;
|
||||||
|
thread = thread_state::aborting;
|
||||||
|
thread();
|
||||||
|
connection_thread.reset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
void finish_callback(ppu_thread& ppu, s32 button_type, vm::ptr<void> userdata)
|
||||||
|
{
|
||||||
|
cross_controller& cc = g_fxo->get<cross_controller>();
|
||||||
|
|
||||||
|
// This function should only be called when the user canceled the dialog
|
||||||
|
ensure(cc.callback && button_type == CELL_MSGDIALOG_BUTTON_ESCAPE);
|
||||||
|
|
||||||
|
cc.callback(ppu, CELL_CROSS_CONTROLLER_STATUS_FINALIZED, CELL_CROSS_CONTROLLER_ERROR_CANCEL, vm::null, userdata);
|
||||||
|
cc.stop_thread();
|
||||||
|
}
|
||||||
|
|
||||||
error_code cellCrossControllerInitialize(vm::cptr<CellCrossControllerParam> pParam, vm::cptr<CellCrossControllerPackageInfo> pPkgInfo, vm::ptr<CellCrossControllerCallback> cb, vm::ptr<void> userdata) // LittleBigPlanet 2 and 3
|
error_code cellCrossControllerInitialize(vm::cptr<CellCrossControllerParam> pParam, vm::cptr<CellCrossControllerPackageInfo> pPkgInfo, vm::ptr<CellCrossControllerCallback> cb, vm::ptr<void> userdata) // LittleBigPlanet 2 and 3
|
||||||
{
|
{
|
||||||
cellCrossController.todo("cellCrossControllerInitialize(pParam=*0x%x, pPkgInfo=*0x%x, cb=*0x%x, userdata=*0x%x)", pParam, pPkgInfo, cb, userdata);
|
cellCrossController.todo("cellCrossControllerInitialize(pParam=*0x%x, pPkgInfo=*0x%x, cb=*0x%x, userdata=*0x%x)", pParam, pPkgInfo, cb, userdata);
|
||||||
|
|
||||||
// TODO
|
if (pParam)
|
||||||
//if (something)
|
{
|
||||||
//{
|
cellCrossController.notice("cellCrossControllerInitialize: pParam: pPackageFileName=%s, pSignatureFileName=%s, pIconFileName=%s", pParam->pPackageFileName, pParam->pSignatureFileName, pParam->pIconFileName);
|
||||||
// return CELL_CROSS_CONTROLLER_ERROR_INVALID_STATE;
|
}
|
||||||
//}
|
|
||||||
|
if (pPkgInfo)
|
||||||
|
{
|
||||||
|
cellCrossController.notice("cellCrossControllerInitialize: pPkgInfo: pTitle=%s, pTitleId=%s, pAppVer=%s", pPkgInfo->pTitle, pPkgInfo->pTitleId, pPkgInfo->pAppVer);
|
||||||
|
}
|
||||||
|
|
||||||
|
cross_controller& cc = g_fxo->get<cross_controller>();
|
||||||
|
|
||||||
|
if (cc.status == CELL_CROSS_CONTROLLER_STATUS_INITIALIZED) // TODO: confirm this logic
|
||||||
|
{
|
||||||
|
return CELL_CROSS_CONTROLLER_ERROR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pParam || !pPkgInfo)
|
if (!pParam || !pPkgInfo)
|
||||||
{
|
{
|
||||||
|
@ -73,13 +179,9 @@ error_code cellCrossControllerInitialize(vm::cptr<CellCrossControllerParam> pPar
|
||||||
return CELL_CROSS_CONTROLLER_ERROR_INVALID_VALUE;
|
return CELL_CROSS_CONTROLLER_ERROR_INVALID_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
cc.callback = cb;
|
||||||
{
|
cc.userdata = userdata;
|
||||||
cb(ppu, CELL_CROSS_CONTROLLER_STATUS_INITIALIZED, CELL_OK, vm::null, userdata);
|
cc.run_thread(pPkgInfo);
|
||||||
cb(ppu, CELL_CROSS_CONTROLLER_STATUS_FINALIZED, CELL_OK, vm::null, userdata);
|
|
||||||
|
|
||||||
return CELL_OK;
|
|
||||||
});
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -88,4 +190,7 @@ error_code cellCrossControllerInitialize(vm::cptr<CellCrossControllerParam> pPar
|
||||||
DECLARE(ppu_module_manager::cellCrossController)("cellCrossController", []()
|
DECLARE(ppu_module_manager::cellCrossController)("cellCrossController", []()
|
||||||
{
|
{
|
||||||
REG_FUNC(cellCrossController, cellCrossControllerInitialize);
|
REG_FUNC(cellCrossController, cellCrossControllerInitialize);
|
||||||
|
|
||||||
|
// Helper Function
|
||||||
|
REG_HIDDEN_FUNC(finish_callback);
|
||||||
});
|
});
|
||||||
|
|
|
@ -144,7 +144,7 @@ error_code cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMs
|
||||||
// wrapper to call for other hle dialogs
|
// wrapper to call for other hle dialogs
|
||||||
error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialogCallback> callback, vm::ptr<void> userData, vm::ptr<void> extParam)
|
error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialogCallback> callback, vm::ptr<void> userData, vm::ptr<void> extParam)
|
||||||
{
|
{
|
||||||
cellSysutil.warning("open_msg_dialog(is_blocking=%d, type=0x%x, msgString=%s, callback=*0x%x, userData=*0x%x, extParam=*0x%x)", is_blocking, type, msgString, callback, userData, extParam);
|
cellSysutil.notice("open_msg_dialog(is_blocking=%d, type=0x%x, msgString=%s, callback=*0x%x, userData=*0x%x, extParam=*0x%x)", is_blocking, type, msgString, callback, userData, extParam);
|
||||||
|
|
||||||
const MsgDialogType _type{ type };
|
const MsgDialogType _type{ type };
|
||||||
|
|
||||||
|
@ -263,6 +263,31 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString,
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void close_msg_dialog()
|
||||||
|
{
|
||||||
|
cellSysutil.notice("close_msg_dialog()");
|
||||||
|
|
||||||
|
if (auto manager = g_fxo->try_get<rsx::overlays::display_manager>())
|
||||||
|
{
|
||||||
|
if (auto dlg = manager->get<rsx::overlays::message_dialog>())
|
||||||
|
{
|
||||||
|
g_fxo->get<msg_dlg_thread>().wait_until = 0;
|
||||||
|
dlg->close(false, true); // this doesn't call on_close
|
||||||
|
sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto dlg = g_fxo->get<msg_info>().get())
|
||||||
|
{
|
||||||
|
dlg->state = MsgDialogState::Close;
|
||||||
|
g_fxo->get<msg_dlg_thread>().wait_until = 0;
|
||||||
|
g_fxo->get<msg_info>().remove(); // this shouldn't call on_close
|
||||||
|
input::SetIntercepted(false); // so we need to reenable the pads here
|
||||||
|
sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void exit_game(s32/* buttonType*/, vm::ptr<void>/* userData*/)
|
void exit_game(s32/* buttonType*/, vm::ptr<void>/* userData*/)
|
||||||
{
|
{
|
||||||
sysutil_send_system_cmd(CELL_SYSUTIL_REQUEST_EXITGAME, 0);
|
sysutil_send_system_cmd(CELL_SYSUTIL_REQUEST_EXITGAME, 0);
|
||||||
|
@ -270,7 +295,7 @@ void exit_game(s32/* buttonType*/, vm::ptr<void>/* userData*/)
|
||||||
|
|
||||||
error_code open_exit_dialog(const std::string& message, bool is_exit_requested)
|
error_code open_exit_dialog(const std::string& message, bool is_exit_requested)
|
||||||
{
|
{
|
||||||
cellSysutil.warning("open_exit_dialog(message=%s, is_exit_requested=%d)", message, is_exit_requested);
|
cellSysutil.notice("open_exit_dialog(message=%s, is_exit_requested=%d)", message, is_exit_requested);
|
||||||
|
|
||||||
vm::bptr<CellMsgDialogCallback> callback = vm::null;
|
vm::bptr<CellMsgDialogCallback> callback = vm::null;
|
||||||
|
|
||||||
|
@ -342,11 +367,6 @@ error_code cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMs
|
||||||
default: return CELL_MSGDIALOG_ERROR_PARAM;
|
default: return CELL_MSGDIALOG_ERROR_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_type.se_mute_on)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_type.se_normal)
|
if (_type.se_normal)
|
||||||
{
|
{
|
||||||
cellSysutil.warning("%s", msgString);
|
cellSysutil.warning("%s", msgString);
|
||||||
|
|
|
@ -91,6 +91,7 @@ enum class MsgDialogState
|
||||||
|
|
||||||
extern atomic_t<s32> g_last_user_response;
|
extern atomic_t<s32> g_last_user_response;
|
||||||
|
|
||||||
|
void close_msg_dialog();
|
||||||
error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialogCallback> callback = vm::null, vm::ptr<void> userData = vm::null, vm::ptr<void> extParam = vm::null);
|
error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialogCallback> callback = vm::null, vm::ptr<void> userData = vm::null, vm::ptr<void> extParam = vm::null);
|
||||||
error_code open_exit_dialog(const std::string& message, bool is_exit_requested);
|
error_code open_exit_dialog(const std::string& message, bool is_exit_requested);
|
||||||
|
|
||||||
|
|
|
@ -4,5 +4,9 @@
|
||||||
|
|
||||||
u64 convert_to_timebased_time(u64 time);
|
u64 convert_to_timebased_time(u64 time);
|
||||||
u64 get_timebased_time();
|
u64 get_timebased_time();
|
||||||
|
|
||||||
|
// Returns some relative time in microseconds, don't change this fact
|
||||||
u64 get_system_time();
|
u64 get_system_time();
|
||||||
|
|
||||||
|
// As get_system_time but obeys Clocks scaling setting. Microseconds.
|
||||||
u64 get_guest_system_time(u64 time = umax);
|
u64 get_guest_system_time(u64 time = umax);
|
||||||
|
|
|
@ -129,6 +129,9 @@ enum class localized_string_id
|
||||||
CELL_SAVEDATA_LOAD,
|
CELL_SAVEDATA_LOAD,
|
||||||
CELL_SAVEDATA_OVERWRITE,
|
CELL_SAVEDATA_OVERWRITE,
|
||||||
|
|
||||||
|
CELL_CROSS_CONTROLLER_MSG,
|
||||||
|
CELL_CROSS_CONTROLLER_FW_MSG,
|
||||||
|
|
||||||
RPCN_NO_ERROR,
|
RPCN_NO_ERROR,
|
||||||
RPCN_ERROR_INVALID_INPUT,
|
RPCN_ERROR_INVALID_INPUT,
|
||||||
RPCN_ERROR_WOLFSSL,
|
RPCN_ERROR_WOLFSSL,
|
||||||
|
|
|
@ -151,6 +151,8 @@ private:
|
||||||
case localized_string_id::CELL_SAVEDATA_DELETE: return tr("Delete this data?\n\n%0", "Savedata entry info").arg(std::forward<Args>(args)...);
|
case localized_string_id::CELL_SAVEDATA_DELETE: return tr("Delete this data?\n\n%0", "Savedata entry info").arg(std::forward<Args>(args)...);
|
||||||
case localized_string_id::CELL_SAVEDATA_LOAD: return tr("Load this data?\n\n%0", "Savedata entry info").arg(std::forward<Args>(args)...);
|
case localized_string_id::CELL_SAVEDATA_LOAD: return tr("Load this data?\n\n%0", "Savedata entry info").arg(std::forward<Args>(args)...);
|
||||||
case localized_string_id::CELL_SAVEDATA_OVERWRITE: return tr("Do you want to overwrite the saved data?\n\n%0", "Savedata entry info").arg(std::forward<Args>(args)...);
|
case localized_string_id::CELL_SAVEDATA_OVERWRITE: return tr("Do you want to overwrite the saved data?\n\n%0", "Savedata entry info").arg(std::forward<Args>(args)...);
|
||||||
|
case localized_string_id::CELL_CROSS_CONTROLLER_MSG: return tr("Start [%0] on the PS Vita system.\nIf you have not installed [%0], go to [Remote Play] on the PS Vita system and start [Cross-Controller] from the LiveArea™ screen.", "Cross-Controller message").arg(std::forward<Args>(args)...);
|
||||||
|
case localized_string_id::CELL_CROSS_CONTROLLER_FW_MSG: return tr("If your system software version on the PS Vita system is earlier than 1.80, you must update the system software to the latest version.", "Cross-Controller firmware message");
|
||||||
case localized_string_id::RPCN_NO_ERROR: return tr("RPCN: No Error");
|
case localized_string_id::RPCN_NO_ERROR: return tr("RPCN: No Error");
|
||||||
case localized_string_id::RPCN_ERROR_INVALID_INPUT: return tr("RPCN: Invalid Input (Wrong Host/Port)");
|
case localized_string_id::RPCN_ERROR_INVALID_INPUT: return tr("RPCN: Invalid Input (Wrong Host/Port)");
|
||||||
case localized_string_id::RPCN_ERROR_WOLFSSL: return tr("RPCN Connection Error: WolfSSL Error");
|
case localized_string_id::RPCN_ERROR_WOLFSSL: return tr("RPCN Connection Error: WolfSSL Error");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue