From 16f833a516f9fe7e5184a538a321e55c3a2602ca Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 20 Jan 2024 16:30:19 +0100 Subject: [PATCH] cellImeJp: add cursor --- rpcs3/Emu/Cell/Modules/cellImeJp.cpp | 60 ++++++++++++++++++---------- rpcs3/Emu/Cell/Modules/cellImeJp.h | 3 ++ 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellImeJp.cpp b/rpcs3/Emu/Cell/Modules/cellImeJp.cpp index c5b3917084..4439fbd73c 100644 --- a/rpcs3/Emu/Cell/Modules/cellImeJp.cpp +++ b/rpcs3/Emu/Cell/Modules/cellImeJp.cpp @@ -40,7 +40,7 @@ ime_jp_manager::ime_jp_manager() bool ime_jp_manager::addChar(u16 c) { - if (!c || focus_begin >= (CELL_IMEJP_STRING_MAXLENGTH - 1ULL) || focus_begin > input_string.length()) + if (!c || cursor >= (CELL_IMEJP_STRING_MAXLENGTH - 1ULL) || cursor > input_string.length()) return false; std::u16string tmp; @@ -49,12 +49,28 @@ bool ime_jp_manager::addChar(u16 c) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wrestrict" #endif - input_string.insert(focus_begin, tmp); + input_string.insert(cursor, tmp); #if defined(__GNUG__) && !defined(__clang__) #pragma GCC diagnostic pop #endif - move_focus(1); // TODO: The split into normal cursor and focus cursor + const usz cursor_old = cursor; + const bool cursor_was_in_focus = cursor >= focus_begin && cursor <= (focus_begin + focus_length); + + move_cursor(1); + + if (cursor_was_in_focus) + { + // Add this char to the focus + move_focus_end(1, false); + } + else + { + // Let's just move the focus to the cursor, so that it contains the new char. + focus_begin = cursor_old; + focus_length = 1; + move_focus(0); // Sanitize focus + } input_state = CELL_IMEJP_BEFORE_CONVERT; return true; @@ -108,6 +124,20 @@ bool ime_jp_manager::deleteWord() return true; } +void ime_jp_manager::clear_input() +{ + cursor = 0; + focus_begin = 0; + focus_length = 0; + input_string.clear(); + converted_string.clear(); +} + +void ime_jp_manager::move_cursor(s8 amount) +{ + cursor = std::max(0, std::min(static_cast(cursor) + amount, ::narrow(input_string.length()))); +} + void ime_jp_manager::move_focus(s8 amount) { focus_begin = std::max(0, std::min(static_cast(focus_begin) + amount, ::narrow(input_string.length()))); @@ -268,11 +298,8 @@ static error_code cellImeJpClose(CellImeJpHandle hImeJpHandle) } manager.input_state = CELL_IMEJP_BEFORE_INPUT; - manager.input_string.clear(); - manager.converted_string.clear(); + manager.clear_input(); manager.confirmed_string.clear(); - manager.focus_begin = 0; - manager.focus_length = 0; manager.is_initialized = false; return CELL_OK; @@ -369,11 +396,8 @@ static error_code cellImeJpReset(CellImeJpHandle hImeJpHandle) } manager.input_state = CELL_IMEJP_BEFORE_INPUT; - manager.input_string.clear(); - manager.converted_string.clear(); + manager.clear_input(); manager.confirmed_string.clear(); - manager.focus_begin = 0; - manager.focus_length = 0; return CELL_OK; } @@ -487,7 +511,7 @@ static error_code cellImeJpModeCaretRight(CellImeJpHandle hImeJpHandle) return CELL_IMEJP_ERROR_ERR; } - manager.move_focus(1); + manager.move_cursor(1); return CELL_OK; } @@ -509,7 +533,7 @@ static error_code cellImeJpModeCaretLeft(CellImeJpHandle hImeJpHandle) return CELL_IMEJP_ERROR_ERR; } - manager.move_focus(-1); + manager.move_cursor(-1); return CELL_OK; } @@ -575,10 +599,7 @@ static error_code cellImeJpAllDeleteConvertString(CellImeJpHandle hImeJpHandle) return CELL_IMEJP_ERROR_ERR; } - manager.focus_begin = 0; - manager.focus_length = 0; - manager.input_string.clear(); - manager.converted_string.clear(); + manager.clear_input(); manager.input_state = CELL_IMEJP_BEFORE_INPUT; return CELL_OK; @@ -667,10 +688,7 @@ static error_code cellImeJpAllConfirm(CellImeJpHandle hImeJpHandle) // Use input_string for now manager.confirmed_string = manager.input_string; - manager.focus_begin = 0; - manager.focus_length = 0; - manager.input_string.clear(); - manager.converted_string.clear(); + manager.clear_input(); manager.input_state = CELL_IMEJP_BEFORE_INPUT; return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/cellImeJp.h b/rpcs3/Emu/Cell/Modules/cellImeJp.h index 990b5e2ba6..9efa7d3abe 100644 --- a/rpcs3/Emu/Cell/Modules/cellImeJp.h +++ b/rpcs3/Emu/Cell/Modules/cellImeJp.h @@ -118,6 +118,7 @@ struct ime_jp_manager std::u16string confirmed_string; // Confirmed part of the string (first part of the entire string) std::u16string converted_string; // Converted part of the unconfirmed input string std::u16string input_string; // Unconfirmed part of the string (second part of the entire string) + usz cursor = 0; // The cursor. Can move across the entire input string. usz focus_begin = 0; // Begin of the focus string usz focus_length = 0; // Length of the focus string s16 fix_input_mode = CELL_IMEJP_FIXINMODE_OFF; @@ -131,6 +132,8 @@ struct ime_jp_manager bool addString(vm::cptr str); bool backspaceWord(); bool deleteWord(); + void clear_input(); + void move_cursor(s8 amount); // s8 because CELL_IMEJP_STRING_MAXLENGTH is 128 void move_focus(s8 amount); // s8 because CELL_IMEJP_STRING_MAXLENGTH is 128 void move_focus_end(s8 amount, bool wrap_around); // s8 because CELL_IMEJP_STRING_MAXLENGTH is 128 };