ime-changes (#3348)

* 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

---------

Co-authored-by: w1naenator <valdis.bogdans@hotmail.com>
This commit is contained in:
Valdis Bogdāns 2025-07-31 12:24:36 +03:00 committed by GitHub
parent 1b195c9613
commit 1e7c4bb69c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 34 additions and 15 deletions

View File

@ -21,8 +21,12 @@ public:
LOG_INFO(Lib_Ime, "Creating ImeHandler for keyboard");
Init(param, false);
}
ImeHandler(const OrbisImeParam* param) {
ImeHandler(const OrbisImeParam* param, const OrbisImeParamExtended* extended = nullptr) {
LOG_INFO(Lib_Ime, "Creating ImeHandler for IME");
if (extended) {
m_extended = *extended;
m_has_extended = true;
}
Init(param, true);
}
~ImeHandler() = default;
@ -61,8 +65,8 @@ public:
}*/
if (ime_mode) {
g_ime_state = ImeState(&m_param.ime);
g_ime_ui = ImeUi(&g_ime_state, &m_param.ime);
g_ime_state = ImeState(&m_param.ime, m_has_extended ? &m_extended : nullptr);
g_ime_ui = ImeUi(&g_ime_state, &m_param.ime, m_has_extended ? &m_extended : nullptr);
}
}
@ -121,6 +125,9 @@ private:
OrbisImeParam ime;
} m_param{};
bool m_ime_mode = false;
OrbisImeParamExtended m_extended{};
bool m_has_extended = false;
};
static std::unique_ptr<ImeHandler> g_ime_handler;
@ -616,7 +623,7 @@ Error PS4_SYSV_ABI sceImeOpen(const OrbisImeParam* param, const OrbisImeParamExt
return Error::BUSY;
}
g_ime_handler = std::make_unique<ImeHandler>(param);
g_ime_handler = std::make_unique<ImeHandler>(param, extended);
if (!g_ime_handler) {
LOG_ERROR(Lib_Ime, "Failed to create IME handler");
return Error::NO_MEMORY; // or Error::INTERNAL

View File

@ -324,8 +324,8 @@ void ImeDialogUi::DrawInputText() {
}
const char* placeholder = state->placeholder.empty() ? nullptr : state->placeholder.data();
if (InputTextEx("##ImeDialogInput", placeholder, state->current_text.begin(),
state->max_text_length + 1, input_size, ImGuiInputTextFlags_CallbackCharFilter,
InputTextCallback, this)) {
state->max_text_length * 4 + 1, input_size,
ImGuiInputTextFlags_CallbackCharFilter, InputTextCallback, this)) {
state->input_changed = true;
}
}
@ -340,7 +340,7 @@ void ImeDialogUi::DrawMultiLineInputText() {
}
const char* placeholder = state->placeholder.empty() ? nullptr : state->placeholder.data();
if (InputTextEx("##ImeDialogInput", placeholder, state->current_text.begin(),
state->max_text_length + 1, input_size, flags, InputTextCallback, this)) {
state->max_text_length * 4 + 1, input_size, flags, InputTextCallback, this)) {
state->input_changed = true;
}
}

View File

@ -33,7 +33,7 @@ class ImeDialogState final {
std::vector<char> placeholder;
// A character can hold up to 4 bytes in UTF-8
Common::CString<ORBIS_IME_DIALOG_MAX_TEXT_LENGTH * 4> current_text;
Common::CString<ORBIS_IME_DIALOG_MAX_TEXT_LENGTH * 4 + 1> current_text;
public:
/*

View File

@ -10,7 +10,7 @@ using namespace ImGui;
static constexpr ImVec2 BUTTON_SIZE{100.0f, 30.0f};
ImeState::ImeState(const OrbisImeParam* param) {
ImeState::ImeState(const OrbisImeParam* param, const OrbisImeParamExtended* extended) {
if (!param) {
return;
}
@ -18,6 +18,11 @@ ImeState::ImeState(const OrbisImeParam* param) {
work_buffer = param->work;
text_buffer = param->inputTextBuffer;
if (extended) {
extended_param = *extended;
has_extended = true;
}
std::size_t text_len = std::char_traits<char16_t>::length(text_buffer);
if (!ConvertOrbisToUTF8(text_buffer, text_len, current_text.begin(),
ORBIS_IME_MAX_TEXT_LENGTH * 4)) {
@ -82,7 +87,8 @@ bool ImeState::ConvertUTF8ToOrbis(const char* utf8_text, std::size_t utf8_text_l
return true;
}
ImeUi::ImeUi(ImeState* state, const OrbisImeParam* param) : state(state), ime_param(param) {
ImeUi::ImeUi(ImeState* state, const OrbisImeParam* param, const OrbisImeParamExtended* extended)
: state(state), ime_param(param), extended_param(extended) {
if (param) {
AddLayer(this);
}
@ -182,8 +188,9 @@ void ImeUi::DrawInputText() {
if (first_render) {
SetKeyboardFocusHere();
}
if (InputTextEx("##ImeInput", nullptr, state->current_text.begin(), ime_param->maxTextLength,
input_size, ImGuiInputTextFlags_CallbackAlways, InputTextCallback, this)) {
if (InputTextEx("##ImeInput", nullptr, state->current_text.begin(),
ime_param->maxTextLength * 4 + 1, input_size,
ImGuiInputTextFlags_CallbackAlways, InputTextCallback, this)) {
}
}

View File

@ -25,14 +25,17 @@ class ImeState {
void* work_buffer{};
char16_t* text_buffer{};
OrbisImeParamExtended extended_param{};
bool has_extended = false;
// A character can hold up to 4 bytes in UTF-8
Common::CString<ORBIS_IME_MAX_TEXT_LENGTH * 4> current_text;
Common::CString<ORBIS_IME_MAX_TEXT_LENGTH * 4 + 1> current_text;
std::queue<OrbisImeEvent> event_queue;
std::mutex queue_mutex;
public:
ImeState(const OrbisImeParam* param = nullptr);
ImeState(const OrbisImeParam* param = nullptr, const OrbisImeParamExtended* extended = nullptr);
ImeState(ImeState&& other) noexcept;
ImeState& operator=(ImeState&& other) noexcept;
@ -53,12 +56,14 @@ private:
class ImeUi : public ImGui::Layer {
ImeState* state{};
const OrbisImeParam* ime_param{};
const OrbisImeParamExtended* extended_param{};
bool first_render = true;
std::mutex draw_mutex;
public:
explicit ImeUi(ImeState* state = nullptr, const OrbisImeParam* param = nullptr);
explicit ImeUi(ImeState* state = nullptr, const OrbisImeParam* param = nullptr,
const OrbisImeParamExtended* extended = nullptr);
~ImeUi() override;
ImeUi(const ImeUi& other) = delete;
ImeUi& operator=(ImeUi&& other);