mirror of
https://github.com/GearsProgress/Poke_Transporter_GB.git
synced 2026-07-15 07:44:11 -05:00
text_data_table was very similar in concept to FileContainerReader. But FileContainerReader is generally more flexible, as it allows you to split up your table into several chunks. This takes away the worry of these files getting too big to compress. However, we now have a maintenance duty for the text_tables file, which maps a table index to the list of chunks. We also need to be careful about every use of FileContainerReader::getPointerToFileInDecompressionBuffer(). Using it is fine when you're dealing with a single chunk or if you're sure the file doesn't span multiple chunks. But the moment you seek to a different chunk, any pointer obtained from getPointerToFileInDecompressionBuffer() becomes stale as the decompression buffer gets overwritten. Still, this function is necessary for high memory pressure situations, such as mystery_gift_builder, because we can't maintain multiple lineBuffers there.
176 lines
5.6 KiB
C++
176 lines
5.6 KiB
C++
#include "dbg/debug_menu.h"
|
|
#include "dbg/debug_menu_functions.h"
|
|
#include "dbg/debug_menu_entries.h"
|
|
#include "sprite_data.h"
|
|
#include "background_engine.h"
|
|
#include "vertical_menu_cursor_handler.h"
|
|
#include "libraries/nanoprintf/nanoprintf.h"
|
|
|
|
#include <tonc.h>
|
|
#include <cstdlib>
|
|
|
|
static on_execute_callback delayed_execute_callback = nullptr;
|
|
static void *delayed_execute_context = nullptr;
|
|
static unsigned delayed_execute_user_param = 0;
|
|
|
|
void show_debug_menu()
|
|
{
|
|
u16 charset[256];
|
|
const s16 cursor_offset_x = 3;
|
|
const s16 cursor_offset_y = 6;
|
|
|
|
load_localized_charset(charset, 3, ENGLISH);
|
|
tte_erase_rect(0, 0, H_MAX, V_MAX);
|
|
erase_textbox_tiles();
|
|
show_textbox();
|
|
tte_set_ink(INK_DARK_GREY);
|
|
|
|
obj_unhide(toggle_arrow_left, 0);
|
|
|
|
const vertical_menu_settings menu_settings = {
|
|
.x = 20,
|
|
.y = 0,
|
|
.width = 208,
|
|
.height = 155,
|
|
.margin_top = 8,
|
|
.margin_bottom = 8,
|
|
.initial_focus_index = 0,
|
|
.item_height = 10,
|
|
.text_table_index = INT32_MAX,
|
|
.allow_cancel = true,
|
|
.should_delete_item_widgets_on_destruct = true,
|
|
.should_hide_state_changed_handler_on_not_focused = true
|
|
};
|
|
|
|
vertical_menu_cursor_handler cursor_handler(cursor_offset_x, cursor_offset_y);
|
|
vertical_menu debug_menu(menu_settings);
|
|
|
|
debug_menu.set_state_changed_handler(&cursor_handler);
|
|
fill_debug_menu_with_entries(debug_menu, charset);
|
|
|
|
debug_menu.show();
|
|
debug_menu.run();
|
|
debug_menu.hide();
|
|
|
|
obj_hide(toggle_arrow_left);
|
|
obj_hide(toggle_arrow_right);
|
|
hide_textbox();
|
|
tte_erase_rect(0, 0, H_MAX, V_MAX);
|
|
|
|
// execute any callback that was delayed by pressing the A button on an executable row.
|
|
// This is done to make sure the debug menu is fully hidden before executing the callback,
|
|
// to avoid rendering issues.
|
|
if(delayed_execute_callback)
|
|
{
|
|
delayed_execute_callback(delayed_execute_context, delayed_execute_user_param);
|
|
delayed_execute_callback = nullptr;
|
|
delayed_execute_context = nullptr;
|
|
delayed_execute_user_param = 0;
|
|
}
|
|
}
|
|
|
|
debug_menu_row_widget::debug_menu_row_widget(const debug_menu_row_data &data)
|
|
: data_(data)
|
|
{
|
|
}
|
|
|
|
debug_menu_row_widget::~debug_menu_row_widget()
|
|
{
|
|
if(data_.option_section.should_free_on_destruct)
|
|
{
|
|
free(const_cast<option_data*>(data_.option_section.options));
|
|
data_.option_section.options = nullptr;
|
|
}
|
|
}
|
|
|
|
void debug_menu_row_widget::render_item(FileContainerReader &text_table, unsigned x, unsigned y, bool is_focused)
|
|
{
|
|
const int label_margin_left = 12;
|
|
const int margin_top = 2;
|
|
const int option_margin_left = 120;
|
|
const int toggle_arrow_left_offset_x = -10;
|
|
const int toggle_arrow_right_offset_x = 35;
|
|
const int toggle_arrows_offset_y = 4;
|
|
|
|
tte_set_pos(x + label_margin_left, y + margin_top);
|
|
ptgb_write_debug(data_.charset, data_.labelText, true);
|
|
|
|
if(data_.option_section.num_options > 0)
|
|
{
|
|
const u8 selected_option_index = data_.option_section.selected_option_index;
|
|
|
|
tte_set_pos(x + option_margin_left, y + margin_top);
|
|
if(data_.option_section.options[selected_option_index].text)
|
|
{
|
|
ptgb_write_debug(data_.charset, data_.option_section.options[selected_option_index].text, true);
|
|
}
|
|
else
|
|
{
|
|
char buf[32];
|
|
npf_snprintf(buf, sizeof(buf), "%u", data_.option_section.options[selected_option_index].value);
|
|
ptgb_write_debug(data_.charset, buf, true);
|
|
}
|
|
}
|
|
|
|
if(is_focused)
|
|
{
|
|
if(data_.option_section.num_options > 0)
|
|
{
|
|
const int toggle_arrow_left_x = static_cast<int>(x) + option_margin_left + toggle_arrow_left_offset_x;
|
|
const int toggle_arrow_right_x = static_cast<int>(x) + option_margin_left + toggle_arrow_right_offset_x;
|
|
const int toggle_arrows_y = static_cast<int>(y) + margin_top + toggle_arrows_offset_y;
|
|
|
|
obj_set_pos(toggle_arrow_left, toggle_arrow_left_x, toggle_arrows_y);
|
|
obj_set_pos(toggle_arrow_right, toggle_arrow_right_x, toggle_arrows_y);
|
|
obj_unhide(toggle_arrow_left, 0);
|
|
obj_unhide(toggle_arrow_right, 0);
|
|
}
|
|
else
|
|
{
|
|
obj_hide(toggle_arrow_left);
|
|
obj_hide(toggle_arrow_right);
|
|
}
|
|
}
|
|
}
|
|
|
|
MenuInputHandleState debug_menu_row_widget::handle_input()
|
|
{
|
|
if(data_.option_section.num_options > 0)
|
|
{
|
|
bool handled = false;
|
|
if(key_hit(KEY_RIGHT))
|
|
{
|
|
data_.option_section.selected_option_index = (data_.option_section.selected_option_index + 1) % data_.option_section.num_options;
|
|
handled = true;
|
|
}
|
|
if(key_hit(KEY_LEFT))
|
|
{
|
|
--data_.option_section.selected_option_index;
|
|
if(data_.option_section.selected_option_index >= data_.option_section.num_options)
|
|
{
|
|
data_.option_section.selected_option_index = data_.option_section.num_options - 1;
|
|
}
|
|
handled = true;
|
|
}
|
|
|
|
if(handled && data_.option_section.on_option_activate)
|
|
{
|
|
data_.option_section.on_option_activate(data_.context, data_.option_section.options[data_.option_section.selected_option_index].value);
|
|
}
|
|
|
|
if(handled)
|
|
{
|
|
return MenuInputHandleState::HANDLED_UPDATE_VIEWPORT;
|
|
}
|
|
}
|
|
|
|
if(key_hit(KEY_A) && data_.on_execute)
|
|
{
|
|
delayed_execute_callback = data_.on_execute;
|
|
delayed_execute_context = data_.context;
|
|
delayed_execute_user_param = data_.user_param;
|
|
return MenuInputHandleState::CHOICE_MADE;
|
|
}
|
|
|
|
return MenuInputHandleState::NOT_HANDLED;
|
|
} |