* 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:
Valdis Bogdāns
2025-08-07 19:24:14 +03:00
committed by GitHub
parent f83619e313
commit f9ab6c48e3
2 changed files with 29 additions and 12 deletions

View File

@@ -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;
}

View File

@@ -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);