From 22107275a37e078e1caa7073bba1accc18f89cbe Mon Sep 17 00:00:00 2001 From: Nicholaos Mouzourakis Date: Mon, 8 Jul 2024 23:16:30 -0400 Subject: [PATCH] Adding code comments from github comments as per suggestion. --- arm9/source/common/swkbd.h | 2 ++ arm9/source/utils/scripting.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/arm9/source/common/swkbd.h b/arm9/source/common/swkbd.h index 41ffa264..551f27da 100644 --- a/arm9/source/common/swkbd.h +++ b/arm9/source/common/swkbd.h @@ -108,5 +108,7 @@ enum { #define ShowKeyboardOrPrompt (TouchIsCalibrated() ? ShowKeyboard : ShowStringPrompt) bool PRINTF_ARGS(3) ShowKeyboard(char* inputstr, u32 max_size, const char *format, ...); + +// Exposing this to prevent rebuilds between keypresses in the ShowMultiLineKeyboard calling functions. bool BuildKeyboard(TouchBox* swkbd, const char* keys, const u8* layout, bool multi_line); char ShowMultiLineKeyboard(const char* instructions, TouchBox* swkbd_alphabet, TouchBox* swkbd_special, TouchBox* swkbd_numpad, TouchBox** swkbd, TouchBox** swkbd_prev, u32* uppercase); diff --git a/arm9/source/utils/scripting.c b/arm9/source/utils/scripting.c index dfe58c46..10b0ea18 100644 --- a/arm9/source/utils/scripting.c +++ b/arm9/source/utils/scripting.c @@ -265,6 +265,8 @@ static inline u32 hexntostr(const u8* hex, char* str, u32 len) { return len; } +// we determine the line endings of a text file by simple majority; +// correcting mixed line endings is outside the scope of this program. static inline bool is_crlf(const char* str) { u32 crlf = 0, lf = 0; do if (str[0] == '\n') ++lf; else if (str[0] == '\r' && str[1] == '\n') ++crlf, ++str; @@ -276,6 +278,7 @@ static inline bool is_newline(const char* chr) { return chr[0] == '\n' || (chr[0] == '\r' && chr[1] == '\n'); } +// to ease calculations related to supporting mutlibyte UTF-8 characters static inline u32 bytes_in_chars_u32(const char* str, u32 nchars) { u32 bytes = 0; for (u32 i = 0; str[bytes] && i < nchars; bytes += GetCharSize(str + bytes), ++i); @@ -1682,6 +1685,7 @@ void MemTextView(const char* text, u32 len, const char* line0, int off_disp_char u32 nln = lno; bool last_empty_line_drawn = false; for (u32 y = TV_VPAD; y < SCREEN_HEIGHT; y += FONT_HEIGHT_EXT + (2*TV_VPAD)) { + // account for multibyte chacters and word wrap when drawing lines int off_disp_bytes = bytes_in_chars_int(ptr, off_disp_chars); const char* ptr_next = line_seek_chars(text, len, ww, ptr, 1); u32 llen_chars = line_len_chars(text, len, ww, ptr, NULL); @@ -1745,7 +1749,7 @@ void MemTextView(const char* text, u32 len, const char* line0, int off_disp_char DrawPixel(TOP_SCREEN, x_txt, y + FONT_HEIGHT_EXT, COLOR_STD_BG); DrawPixel(TOP_SCREEN, x_txt_end - 1, y + FONT_HEIGHT_EXT, COLOR_STD_BG); - // draw cursor / selection + // draw selection if (cursor_end) { int x_hline_start = -1, x_hline_end = -1; @@ -1763,10 +1767,12 @@ void MemTextView(const char* text, u32 len, const char* line0, int off_disp_char && (!ww || cursor_end_prev != ptr + off_disp_bytes + ncpy_bytes || is_newline(cursor_end_prev)); if (draw_cursor_end) { x_hline_end = x_txt + (cursor_end_line_offset_chars + 1) * FONT_WIDTH_EXT; + // account for selections drawn at the end of the screen; they should be one pixel thinner so that they are drawn over by text on the next screen redraw DrawRectangle(TOP_SCREEN, x_hline_end - ((cursor_end_line_offset_chars == TV_LLEN_DISP - 1) ? 1 : 0), y, 1, FONT_HEIGHT_EXT, COLOR_YELLOW); cursor_end = NULL; // prevent cursor from being drawn multiple times at the end of the screen } else if (cursor_end_prev >= ptr + off_disp_bytes + ncpy_bytes) x_hline_end = x_txt_end; + // edge cases related to drawing multi-line selections if (draw_cursor && draw_cursor_end) { DrawRectangle(TOP_SCREEN, x_hline_start, y, x_hline_end - x_hline_start, 1, COLOR_YELLOW); DrawRectangle(TOP_SCREEN, x_hline_start, y + FONT_HEIGHT_EXT - 1, x_hline_end - x_hline_start, 1, COLOR_YELLOW); @@ -1826,11 +1832,12 @@ void MemTextView(const char* text, u32 len, const char* line0, int off_disp_char } if (!cursor_end) cursor = NULL; - } else if (cursor) { + } else if (cursor) { // draw cursor u32 cursor_line_offset_chars = chars_between_pointers(ptr + off_disp_bytes, cursor); if (cursor >= ptr + off_disp_bytes && cursor <= ptr + off_disp_bytes + ncpy_bytes && cursor_line_offset_chars < TV_LLEN_DISP && (cursor != ptr + off_disp_bytes + ncpy_bytes || is_newline(cursor) || cursor == text + len)) { DrawRectangle(TOP_SCREEN, x_txt + cursor_line_offset_chars * FONT_WIDTH_EXT, y, FONT_WIDTH_EXT, 1, COLOR_RED); + // account for cursors drawn at the end of the screen; they should be one pixel thinner so that they are drawn over by text on the next screen redraw DrawRectangle(TOP_SCREEN, x_txt + (cursor_line_offset_chars + 1) * FONT_WIDTH_EXT - ((cursor_line_offset_chars == TV_LLEN_DISP - 1) ? 1 : 0), y, 1, FONT_HEIGHT_EXT, COLOR_RED); DrawRectangle(TOP_SCREEN, x_txt + cursor_line_offset_chars * FONT_WIDTH_EXT, y, 1, FONT_HEIGHT_EXT, COLOR_RED); DrawRectangle(TOP_SCREEN, x_txt + cursor_line_offset_chars * FONT_WIDTH_EXT, y + FONT_HEIGHT_EXT - 1, FONT_WIDTH_EXT, 1, COLOR_RED);