mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-09 05:08:43 +00:00
Ime fixes (#3399)
* Changes -Added support for OrbisImeParamExtended (extended IME parameters) in ImeHandler, ImeState, and ImeUi -Updated all relevant constructors and logic to propagate and store the extended parameter - Now fully supports passing extended options from sceImeOpen to the IME UI and backend * Potential CUSA00434 [Debug] <Critical> assert.cpp:30 assert_fail_debug_msg: Assertion Failed! buf_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?" at C:/VS/shadPS4-ime-fixes/externals/dear_imgui/imgui_widgets.cpp:4601 fix * Attempting to resolve an assertion failure in Diablo III: - Adjusted buffer sizes - Updated the calculation of text‑length values * ime-lib another hotfix Fixed incorrect param->title validation, which caused the IME dialog to fail to appear in Stardew Valley. Need to be checked. * Clang fix * FF9 ImeDialog Hotfix * Removed the validation that disallowed null text and null placeholder, since using null values is valid in `ImeDialog`. * Added additional debug logs to aid troubleshooting. * IME Fixes - Add missing flags to `OrbisImeExtOption` - Improve debug logging - Resolve nonstop `sceImeKeyboardOpen` calls in Stardew Valley (MonoGame engine) for `userId = 254` --------- Co-authored-by: w1naenator <valdis.bogdans@hotmail.com>
This commit is contained in:
@@ -17,8 +17,10 @@ static ImeUi g_ime_ui;
|
||||
|
||||
class ImeHandler {
|
||||
public:
|
||||
ImeHandler(const OrbisImeKeyboardParam* param) {
|
||||
LOG_INFO(Lib_Ime, "Creating ImeHandler for keyboard");
|
||||
ImeHandler(const OrbisImeKeyboardParam* param,
|
||||
Libraries::UserService::OrbisUserServiceUserId userId)
|
||||
: m_user_id(userId) {
|
||||
LOG_INFO(Lib_Ime, "Creating ImeHandler for keyboard (user {})", userId);
|
||||
Init(param, false);
|
||||
}
|
||||
ImeHandler(const OrbisImeParam* param, const OrbisImeParamExtended* extended = nullptr) {
|
||||
@@ -54,8 +56,12 @@ public:
|
||||
openEvent.param.rect.x = m_param.ime.posx;
|
||||
openEvent.param.rect.y = m_param.ime.posy;
|
||||
} else {
|
||||
openEvent.param.resource_id_array.user_id = 1;
|
||||
openEvent.param.resource_id_array.resource_id[0] = 1;
|
||||
|
||||
// Report the real PS4 user ID, and mark “no physical keyboard” so games know
|
||||
openEvent.param.resource_id_array.user_id = m_user_id;
|
||||
for (auto& rid : openEvent.param.resource_id_array.resource_id)
|
||||
rid = -1;
|
||||
Execute(nullptr, &openEvent, /*use_param_handler=*/true);
|
||||
}
|
||||
|
||||
// Are we supposed to call the event handler on init with
|
||||
@@ -120,6 +126,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Libraries::UserService::OrbisUserServiceUserId m_user_id{};
|
||||
union ImeParam {
|
||||
OrbisImeKeyboardParam key;
|
||||
OrbisImeParam ime;
|
||||
@@ -308,8 +315,8 @@ Error PS4_SYSV_ABI sceImeKeyboardClose(Libraries::UserService::OrbisUserServiceU
|
||||
LOG_ERROR(Lib_Ime, "No keyboard handler is open");
|
||||
return Error::NOT_OPENED;
|
||||
}
|
||||
// TODO: Check for valid user IDs. Disabled until user manager is ready.
|
||||
if ((userId < 0 || userId > 4) && false) {
|
||||
// TODO: Check for valid user IDs.
|
||||
if (userId == Libraries::UserService::ORBIS_USER_SERVICE_USER_ID_INVALID) {
|
||||
// Maybe g_keyboard_handler should hold a user ID and I must compare it here?
|
||||
LOG_ERROR(Lib_Ime, "Invalid userId: {}", userId);
|
||||
return Error::INVALID_USER_ID;
|
||||
@@ -339,8 +346,8 @@ sceImeKeyboardGetResourceId(Libraries::UserService::OrbisUserServiceUserId userI
|
||||
return Error::INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
// TODO: Check for valid user IDs. Disabled until user manager is ready.
|
||||
if ((userId < 0 || userId > 4) && false) {
|
||||
// TODO: Check for valid user IDs.
|
||||
if (userId == Libraries::UserService::ORBIS_USER_SERVICE_USER_ID_INVALID) {
|
||||
LOG_ERROR(Lib_Ime, "Invalid userId: {}", userId);
|
||||
resourceIdArray->user_id = userId;
|
||||
for (u32& id : resourceIdArray->resource_id) {
|
||||
@@ -377,10 +384,17 @@ Error PS4_SYSV_ABI sceImeKeyboardOpen(Libraries::UserService::OrbisUserServiceUs
|
||||
LOG_ERROR(Lib_Ime, "Invalid param: NULL");
|
||||
return Error::INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if (!param->handler) {
|
||||
LOG_ERROR(Lib_Ime, "Invalid param->handler: NULL");
|
||||
return Error::INVALID_HANDLER;
|
||||
}
|
||||
|
||||
LOG_DEBUG(Lib_Ime, " userId: {}", static_cast<u32>(userId));
|
||||
LOG_DEBUG(Lib_Ime, " param->option: {:032b}", static_cast<u32>(param->option));
|
||||
LOG_DEBUG(Lib_Ime, " param->arg: {}", param->arg);
|
||||
LOG_DEBUG(Lib_Ime, " param->handler: {}", reinterpret_cast<const void*>(param->handler));
|
||||
|
||||
// seems like arg is optional, need to check if it is used in the handler
|
||||
// Todo: check if arg is used in the handler, temporarily disabled
|
||||
if (!param->arg && false) {
|
||||
@@ -396,8 +410,8 @@ Error PS4_SYSV_ABI sceImeKeyboardOpen(Libraries::UserService::OrbisUserServiceUs
|
||||
return Error::INVALID_OPTION;
|
||||
}
|
||||
|
||||
// TODO: Check for valid user IDs. Disabled until user manager is ready.
|
||||
if ((userId < 0 || userId > 4) && false) {
|
||||
// TODO: Check for valid user IDs.
|
||||
if (userId == Libraries::UserService::ORBIS_USER_SERVICE_USER_ID_INVALID) {
|
||||
LOG_ERROR(Lib_Ime, "Invalid userId: {}", userId);
|
||||
return Error::INVALID_USER_ID;
|
||||
}
|
||||
@@ -423,7 +437,7 @@ Error PS4_SYSV_ABI sceImeKeyboardOpen(Libraries::UserService::OrbisUserServiceUs
|
||||
LOG_ERROR(Lib_Ime, "Keyboard handler is already open");
|
||||
return Error::BUSY;
|
||||
}
|
||||
g_keyboard_handler = std::make_unique<ImeHandler>(param);
|
||||
g_keyboard_handler = std::make_unique<ImeHandler>(param, userId);
|
||||
if (!g_keyboard_handler) {
|
||||
LOG_ERROR(Lib_Ime, "Failed to create keyboard handler");
|
||||
return Error::INTERNAL; // or Error::NO_MEMORY;
|
||||
@@ -694,7 +708,7 @@ Error PS4_SYSV_ABI sceImeUpdate(OrbisImeEventHandler handler) {
|
||||
g_keyboard_handler->Update(handler);
|
||||
}
|
||||
|
||||
if (!g_ime_handler || !g_keyboard_handler) {
|
||||
if (!g_ime_handler && !g_keyboard_handler) {
|
||||
return Error::NOT_OPENED;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,9 @@ const u32 kValidImeOptionMask = generate_full_mask<OrbisImeOption>();
|
||||
|
||||
enum class OrbisImeExtOption : u32 {
|
||||
DEFAULT = 0x00000000,
|
||||
SET_COLOR = 0x00000001,
|
||||
SET_PRIORITY = 0x00000002,
|
||||
PRIORITY_SHIFT = 0x00000004,
|
||||
PRIORITY_FULL_WIDTH = 0x00000008,
|
||||
PRIORITY_FIXED_PANEL = 0x00000010,
|
||||
DISABLE_POINTER = 0x00000040,
|
||||
@@ -113,6 +115,7 @@ enum class OrbisImeExtOption : u32 {
|
||||
INIT_EXT_KEYBOARD_MODE = 0x00000800,
|
||||
|
||||
ENABLE_ACCESSIBILITY = 0x00001000, // ImeDialog unly
|
||||
ACCESSIBILITY_PANEL_FORCED = 0x00002000, // ImeDialog only
|
||||
ADDITIONAL_DICTIONARY_PRIORITY_MODE = 0x00004000, // ImeDialog only
|
||||
};
|
||||
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeExtOption);
|
||||
|
||||
Reference in New Issue
Block a user