From bfb071786886b319dd7c3e72088fb96a81c156a6 Mon Sep 17 00:00:00 2001 From: aestellic Date: Wed, 29 Apr 2026 01:30:38 -0400 Subject: [PATCH 1/2] add indicator for finished dialogue --- include/text_engine.h | 3 +- source/dbg/debug_menu_functions.cpp | 2 +- source/text_engine.cpp | 66 ++++++++++++++++++++--------- 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/include/text_engine.h b/include/text_engine.h index 21e339f..8bfaa0a 100644 --- a/include/text_engine.h +++ b/include/text_engine.h @@ -19,11 +19,12 @@ void init_text_engine(); int text_loop(int script); int text_next_obj_id(script_obj current_line); void set_text_exit(); +int* initialize_box_type(int box_type); int ptgb_write_textbox(const byte *text, bool instant, bool waitForUser, int text_section, int text_key, bool eraseMainBox); int ptgb_write_simple(const byte *text, bool instant); int ptgb_write(const byte *text, bool instant, int length, int box_type); int ptgb_write_debug(const u16* charset, const char *text, bool instant); -void wait_for_user_to_continue(); +void wait_for_user_to_continue(int right, int bottom); void scroll_text(bool instant, TTC *tc, int left, int top, int right, int bottom); #endif \ No newline at end of file diff --git a/source/dbg/debug_menu_functions.cpp b/source/dbg/debug_menu_functions.cpp index f52c582..84f520d 100644 --- a/source/dbg/debug_menu_functions.cpp +++ b/source/dbg/debug_menu_functions.cpp @@ -278,7 +278,7 @@ void dbg_inject_pkmn(void *context, unsigned user_param) npf_snprintf(text_buffer, sizeof(text_buffer), "%s received a Celebi!\n Celebi was sent to box %d!", decoded_OT_utf8, boxIndex); ptgb_write_debug(tables.gen3_charset, text_buffer, false); - wait_for_user_to_continue(); + wait_for_user_to_continue(H_MAX, V_MAX); if(!g_debug_options.ignore_game_pak && !g_debug_options.ignore_game_pak_sprites) { diff --git a/source/text_engine.cpp b/source/text_engine.cpp index 8334c80..00abfea 100644 --- a/source/text_engine.cpp +++ b/source/text_engine.cpp @@ -266,6 +266,28 @@ void set_text_exit() key_poll(); // This removes the "A Hit" when exiting the text } +int* initialize_box_type(int box_type) +{ + static int coords[4]; + + if (box_type == -1) + { + coords[0] = 0; // left + coords[1] = 0; // top + coords[2] = H_MAX; // right + coords[3] = V_MAX; // bottom + } + else + { + coords[0] = 8 * (box_type_info[box_type][BOX_TYPE_VAL_START_TILE_X] + 1); + coords[1] = 8 * (box_type_info[box_type][BOX_TYPE_VAL_START_TILE_Y] + 1); + coords[2] = coords[0] + box_type_info[box_type][BOX_TYPE_VAL_PIXELS_PER_LINE]; + coords[3] = coords[1] + box_type_info[box_type][BOX_TYPE_VAL_NUM_OF_LINES] * 16; + } + + return coords; +} + // Implement a version that creates the textbox as well int ptgb_write_textbox(const byte *text, bool instant, bool waitForUser, int text_section, int text_key, bool eraseMainBox) @@ -281,7 +303,9 @@ int ptgb_write_textbox(const byte *text, bool instant, bool waitForUser, int out = ptgb_write(text, instant, 9999, text_box_type_tables[text_section][text_key]); // This is kinda silly but it'll work. if (waitForUser) { - wait_for_user_to_continue(); + int right = H_MAX - 5; + int bottom = V_MAX - 5; + wait_for_user_to_continue(right, bottom); } if (eraseMainBox) { @@ -301,26 +325,16 @@ int ptgb_write_simple(const byte *text, bool instant) // Re-implementing TTE's "tte_write" to use the gen 3 character encoding chart int ptgb_write(const byte *text, bool instant, int length, int box_type) { - int left, top, right, bottom; - instant = instant || g_debug_options.instant_text_speed; if (text == NULL) return 0; - if (box_type == -1) - { - left = 0; - top = 0; - right = H_MAX; - bottom = V_MAX; - } - else - { - left = 8 * (box_type_info[box_type][BOX_TYPE_VAL_START_TILE_X] + 1); - top = 8 * (box_type_info[box_type][BOX_TYPE_VAL_START_TILE_Y] + 1); - right = left + box_type_info[box_type][BOX_TYPE_VAL_PIXELS_PER_LINE]; - bottom = top + box_type_info[box_type][BOX_TYPE_VAL_NUM_OF_LINES] * 16; - } + int* coords = initialize_box_type(box_type); + + int left = coords[0]; + int top = coords[1]; + int right = coords[2]; + int bottom = coords[3]; uint ch, gid; char *str = (char *)text; @@ -340,7 +354,7 @@ int ptgb_write(const byte *text, bool instant, int length, int box_type) { tc->drawgProc(0x79); } - wait_for_user_to_continue(); + wait_for_user_to_continue(right, bottom); scroll_text(instant, tc, left, top, right, bottom); break; case 0xFB: @@ -348,7 +362,7 @@ int ptgb_write(const byte *text, bool instant, int length, int box_type) { tc->drawgProc(0xB9); } - wait_for_user_to_continue(); + wait_for_user_to_continue(right, bottom); tte_erase_rect(left, top, right, bottom); tte_set_pos(left, top); break; @@ -437,7 +451,7 @@ int ptgb_write_debug(const u16 *charset, const char *text, bool instant) return ptgb_write_simple(temp_holding, instant); } -void wait_for_user_to_continue() +void wait_for_user_to_continue(int right, int bottom) { if (get_curr_flex_background() == FLEXBG_FENNEL) { @@ -451,11 +465,23 @@ void wait_for_user_to_continue() fennel_speak(0); } } + + obj_set_pos(point_arrow, right-7, bottom-12); + obj_unhide(point_arrow, 0); + key_poll(); while (!(key_hit(KEY_A) || key_hit(KEY_B))) { + int frameCount = get_frame_count(); + if (frameCount % 60 == 0) { + obj_unhide(point_arrow, 0); + } + else if (frameCount % 30 == 0) { + obj_hide(point_arrow); + } global_next_frame(); } + obj_hide(point_arrow); } void scroll_text(bool instant, TTC *tc, int left, int top, int right, int bottom) From 92758f44ec98068065131fc8d09e4064010fbce0 Mon Sep 17 00:00:00 2001 From: aestellic Date: Fri, 1 May 2026 00:55:15 -0400 Subject: [PATCH 2/2] add wrap around for menus + left/right jumps for dream dex --- include/text_engine.h | 1 - include/vertical_menu.h | 2 +- source/main.cpp | 7 ++++- source/pokedex.cpp | 29 ++++++++++++++++++ source/text_engine.cpp | 66 ++++++++++++++++++++-------------------- source/vertical_menu.cpp | 23 ++++++++++---- 6 files changed, 86 insertions(+), 42 deletions(-) diff --git a/include/text_engine.h b/include/text_engine.h index 8bfaa0a..489e183 100644 --- a/include/text_engine.h +++ b/include/text_engine.h @@ -19,7 +19,6 @@ void init_text_engine(); int text_loop(int script); int text_next_obj_id(script_obj current_line); void set_text_exit(); -int* initialize_box_type(int box_type); int ptgb_write_textbox(const byte *text, bool instant, bool waitForUser, int text_section, int text_key, bool eraseMainBox); int ptgb_write_simple(const byte *text, bool instant); int ptgb_write(const byte *text, bool instant, int length, int box_type); diff --git a/include/vertical_menu.h b/include/vertical_menu.h index bb1841d..99dd8ff 100644 --- a/include/vertical_menu.h +++ b/include/vertical_menu.h @@ -235,7 +235,7 @@ private: vertical_menu_settings settings_; i_vertical_menu_state_changed_handler *state_changed_handler_; i_run_cycle_handler *run_cycle_handler_; - unsigned focused_index_; + int focused_index_; unsigned viewport_start_index_; ptgb::vector items_; bool is_focused_; diff --git a/source/main.cpp b/source/main.cpp index ee0c9fe..3f588ff 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -250,7 +250,12 @@ int main_menu_loop() } else if (key_hit(KEY_UP)) { - curr_selection = ((curr_selection + (NUM_MENU_OPTIONS - 1)) % NUM_MENU_OPTIONS); + if (curr_selection == 0) { + curr_selection = NUM_MENU_OPTIONS - 1; + } + else { + curr_selection = ((curr_selection + (NUM_MENU_OPTIONS - 1)) % NUM_MENU_OPTIONS); + } } else if (key_hit(KEY_A)) { diff --git a/source/pokedex.cpp b/source/pokedex.cpp index 51abeee..4211d4c 100644 --- a/source/pokedex.cpp +++ b/source/pokedex.cpp @@ -173,6 +173,35 @@ int pokedex_loop() delay++; } } + else if (key_hit(KEY_LEFT) || key_hit(KEY_RIGHT)) + { + dex_shift += key_tri_horz() * 7; + update = true; + } + else if (key_held(KEY_LEFT) || key_held(KEY_RIGHT)) + { + if (delay > SPEED_DELAY) + { + if ((get_frame_count() % speed == 0)) + { + if (count > 3 && speed >= 5) + { + speed = speed / 2; + count = 0; + } + else + { + count++; + } + dex_shift += key_tri_horz() * 7; + update = true; + } + } + else + { + delay++; + } + } else { speed = 20; diff --git a/source/text_engine.cpp b/source/text_engine.cpp index 00abfea..d4c2af3 100644 --- a/source/text_engine.cpp +++ b/source/text_engine.cpp @@ -183,7 +183,12 @@ int text_loop(int script) } else if (key_hit(KEY_UP)) { - text_section = (text_section + 1) % NUM_TEXT_SECTIONS; + if (text_section == 0) { + text_section = NUM_TEXT_SECTIONS - 1; + } + else { + text_section = ((text_section + (NUM_TEXT_SECTIONS - 1)) % NUM_TEXT_SECTIONS); + } update_text = true; } else if (key_hit(KEY_DOWN)) @@ -266,28 +271,6 @@ void set_text_exit() key_poll(); // This removes the "A Hit" when exiting the text } -int* initialize_box_type(int box_type) -{ - static int coords[4]; - - if (box_type == -1) - { - coords[0] = 0; // left - coords[1] = 0; // top - coords[2] = H_MAX; // right - coords[3] = V_MAX; // bottom - } - else - { - coords[0] = 8 * (box_type_info[box_type][BOX_TYPE_VAL_START_TILE_X] + 1); - coords[1] = 8 * (box_type_info[box_type][BOX_TYPE_VAL_START_TILE_Y] + 1); - coords[2] = coords[0] + box_type_info[box_type][BOX_TYPE_VAL_PIXELS_PER_LINE]; - coords[3] = coords[1] + box_type_info[box_type][BOX_TYPE_VAL_NUM_OF_LINES] * 16; - } - - return coords; -} - // Implement a version that creates the textbox as well int ptgb_write_textbox(const byte *text, bool instant, bool waitForUser, int text_section, int text_key, bool eraseMainBox) @@ -303,6 +286,7 @@ int ptgb_write_textbox(const byte *text, bool instant, bool waitForUser, int out = ptgb_write(text, instant, 9999, text_box_type_tables[text_section][text_key]); // This is kinda silly but it'll work. if (waitForUser) { + int right = H_MAX - 5; int bottom = V_MAX - 5; wait_for_user_to_continue(right, bottom); @@ -329,12 +313,22 @@ int ptgb_write(const byte *text, bool instant, int length, int box_type) if (text == NULL) return 0; - int* coords = initialize_box_type(box_type); + int left, top, right, bottom; - int left = coords[0]; - int top = coords[1]; - int right = coords[2]; - int bottom = coords[3]; + if (box_type == -1) + { + left = 0; + top = 0; + right = H_MAX; + bottom = V_MAX; + } + else + { + left = 8 * (box_type_info[box_type][BOX_TYPE_VAL_START_TILE_X] + 1); + top = 8 * (box_type_info[box_type][BOX_TYPE_VAL_START_TILE_Y] + 1); + right = left + box_type_info[box_type][BOX_TYPE_VAL_PIXELS_PER_LINE]; + bottom = top + box_type_info[box_type][BOX_TYPE_VAL_NUM_OF_LINES] * 16; + } uint ch, gid; char *str = (char *)text; @@ -466,22 +460,28 @@ void wait_for_user_to_continue(int right, int bottom) } } - obj_set_pos(point_arrow, right-7, bottom-12); - obj_unhide(point_arrow, 0); + //obj_set_pos(scroll_indicator_red, right-16, bottom-11); + //obj_set_pos(scroll_indicator_gray, right-16, bottom-10); + //obj_unhide(scroll_indicator_red, 0); key_poll(); while (!(key_hit(KEY_A) || key_hit(KEY_B))) { + /* int frameCount = get_frame_count(); if (frameCount % 60 == 0) { - obj_unhide(point_arrow, 0); + obj_unhide(scroll_indicator_red, 0); + obj_hide(scroll_indicator_gray); } else if (frameCount % 30 == 0) { - obj_hide(point_arrow); + obj_hide(scroll_indicator_red); + obj_unhide(scroll_indicator_gray, 0); } + */ global_next_frame(); } - obj_hide(point_arrow); + //obj_hide(scroll_indicator_red); + //obj_hide(scroll_indicator_gray); } void scroll_text(bool instant, TTC *tc, int left, int top, int right, int bottom) diff --git a/source/vertical_menu.cpp b/source/vertical_menu.cpp index 4903c3d..98b8bd8 100644 --- a/source/vertical_menu.cpp +++ b/source/vertical_menu.cpp @@ -175,23 +175,34 @@ MenuInputHandleState vertical_menu::handle_input() return MenuInputHandleState::CANCELLED; } - if(key_hit(KEY_DOWN) && focused_index_ < (items_.size() - 1u)) + if(key_hit(KEY_DOWN)) { - const unsigned current_viewport_end_index = get_viewport_end_index(viewport_start_index_, get_num_visible_items(settings_.height, settings_.margin_top, settings_.margin_bottom, settings_.item_height), items_.size()); + const unsigned num_visible_items = get_num_visible_items(settings_.height, settings_.margin_top, settings_.margin_bottom, settings_.item_height); + const unsigned current_viewport_end_index = get_viewport_end_index(viewport_start_index_, num_visible_items, items_.size()); ++focused_index_; - if(focused_index_ >= current_viewport_end_index) + if(focused_index_ == current_viewport_end_index) { ++viewport_start_index_; viewport_changed = true; } + if (focused_index_ > items_.size() - 1) { + viewport_start_index_ = 0; + focused_index_ = 0; + viewport_changed = true; + } did_navigate = true; } - else if(key_hit(KEY_UP) && focused_index_ > 0) + else if(key_hit(KEY_UP)) { --focused_index_; - if(focused_index_ < viewport_start_index_) + if(focused_index_ < 0) { - --viewport_start_index_; + const unsigned num_visible_items = get_num_visible_items(settings_.height, settings_.margin_top, settings_.margin_bottom, settings_.item_height); + const unsigned current_viewport_end_index = get_viewport_end_index(viewport_start_index_, num_visible_items, items_.size()); + const unsigned max_index = items_.size() - 1; + + viewport_start_index_ = (max_index - num_visible_items) + 1; + focused_index_ = max_index; viewport_changed = true; } did_navigate = true;