diff --git a/include/background_engine.h b/include/background_engine.h index e6224ed..b782175 100644 --- a/include/background_engine.h +++ b/include/background_engine.h @@ -13,7 +13,24 @@ #define BG_TEXT REG_BG3CNT void background_frame(int global_frame_count); + +/** + * @brief This function draws the textbox (=copies the tiles) for a specific text table and text key. + * Each text table entry could have a different type of textbox associated with it. + * This function will look up the textbox type for the given text table and text key, and then draw the textbox accordingly. + */ void create_textbox(int text_section, int text_key, bool eraseMainBox); + +/** + * @brief Given the textbox type, this function draws it (=copies the tiles). + */ +void create_textbox(u8 textbox_type, bool eraseMainBox); + +/** + * @brief This function draws a textbox at the specified tile coordinates, with the specified text space dimensions. + * This is the most low-level version of the create_textbox function, and it doesn't do any lookup for textbox types. + * It just draws a textbox with the given parameters. + */ void create_textbox(int startTileX, int startTileY, int text_space_width, int text_space_height, bool eraseMainBox); void show_textbox(); void hide_textbox(); diff --git a/source/Gen3CartridgeSaveReader.cpp b/source/Gen3CartridgeSaveReader.cpp index 5cbe640..75f3b77 100644 --- a/source/Gen3CartridgeSaveReader.cpp +++ b/source/Gen3CartridgeSaveReader.cpp @@ -11,6 +11,7 @@ Gen3CartridgeSaveReader::Gen3CartridgeSaveReader(u8 *sector_buffer) , cur_(sector_buffer) , dirty_(false) { + seek(0); } Gen3CartridgeSaveReader::~Gen3CartridgeSaveReader() @@ -32,14 +33,24 @@ void Gen3CartridgeSaveReader::readUint8(u8& outByte) void Gen3CartridgeSaveReader::readUint16(u16& outWord, Endianness fieldEndianness) { // Right now we only support little endian (no need for big endian thus far) - outWord = *((u16*)cur_); + (void)fieldEndianness; + // The read is implemented this way to avoid any issues with unaligned reads. + // see writeUint16 for more details. + outWord = static_cast(cur_[0]) | + (static_cast(cur_[1]) << 8); cur_ += sizeof(u16); } void Gen3CartridgeSaveReader::readUint32(u32& outDWord, Endianness fieldEndianness) { // Right now we only support little endian (no need for big endian thus far) - outDWord = *((u32*)cur_); + (void)fieldEndianness; + // The read is implemented this way to avoid any issues with unaligned reads. + // see writeUint16 for more details. + outDWord = static_cast(cur_[0]) | + (static_cast(cur_[1]) << 8) | + (static_cast(cur_[2]) << 16) | + (static_cast(cur_[3]) << 24); cur_ += sizeof(u32); } @@ -61,7 +72,14 @@ void Gen3CartridgeSaveReader::writeUint8(u8 value) void Gen3CartridgeSaveReader::writeUint16(u16 value, Endianness fieldEndianness) { // Right now we only support little endian (no need for big endian thus far) - *((u16*)cur_) = value; + (void)fieldEndianness; + // The write is implemented this way to avoid any issues with unaligned writes. + // I tried + // *((u16*)cur_) = value; + // earlier, but when cur_ was set to 0x0019, this caused undefined behaviour. + // (specifically the word was written 1 byte earlier than it should've been) + cur_[0] = static_cast(value & 0xFF); + cur_[1] = static_cast(value >> 8); cur_ += sizeof(u16); dirty_ = true; } @@ -69,14 +87,21 @@ void Gen3CartridgeSaveReader::writeUint16(u16 value, Endianness fieldEndianness) void Gen3CartridgeSaveReader::writeUint32(u32 value, Endianness fieldEndianness) { // Right now we only support little endian (no need for big endian thus far) - *((u32*)cur_) = value; + (void)fieldEndianness; + // The write is implemented this way to avoid any issues with unaligned writes. + // see writeUint16 for more details. + cur_[0] = static_cast(value & 0xFF); + cur_[1] = static_cast((value >> 8) & 0xFF); + cur_[2] = static_cast((value >> 16) & 0xFF); + cur_[3] = static_cast((value >> 24) & 0xFF); cur_ += sizeof(u32); dirty_ = true; } void Gen3CartridgeSaveReader::seek(u32 offset) { - const uintptr_t sector_start = offset / SECTOR_SIZE; + const u32 sector_offset = offset % SECTOR_SIZE; + const uintptr_t sector_start = offset - sector_offset; if(sector_start != sector_start_) { // write any pending changes. @@ -85,7 +110,7 @@ void Gen3CartridgeSaveReader::seek(u32 offset) copy_save_to_ram(sector_start, sector_buffer_, SECTOR_SIZE); } - cur_ = sector_buffer_ + (offset - sector_start); + cur_ = sector_buffer_ + (offset % SECTOR_SIZE); } void Gen3CartridgeSaveReader::advance(u32 numBytes) @@ -117,8 +142,7 @@ void Gen3CartridgeSaveReader::flush() return; } - const uintptr_t sector_offset = sector_start_ * SECTOR_SIZE; update_memory_buffer_checksum(sector_buffer_, (sector_start_ == HALL_OF_FAME)); - copy_ram_to_save(sector_buffer_, sector_offset, SECTOR_SIZE); + copy_ram_to_save(sector_buffer_, sector_start_, SECTOR_SIZE); dirty_ = false; } \ No newline at end of file diff --git a/source/background_engine.cpp b/source/background_engine.cpp index 99e653f..64c8d27 100644 --- a/source/background_engine.cpp +++ b/source/background_engine.cpp @@ -22,11 +22,16 @@ void background_frame(int global_frame_count) // This could honestly be an object... might want to do that in the future, depending on how complex using this gets void create_textbox(int text_section, int text_key, bool eraseMainBox) { - int box_type = text_box_type_tables[text_section][text_key]; - int startTileX = box_type_info[box_type][BOX_TYPE_VAL_START_TILE_X]; - int startTileY = box_type_info[box_type][BOX_TYPE_VAL_START_TILE_Y]; - int text_space_width = box_type_info[box_type][BOX_TYPE_VAL_PIXELS_PER_LINE]; - int text_space_height = box_type_info[box_type][BOX_TYPE_VAL_NUM_OF_LINES] * 16; + const u8 box_type = text_box_type_tables[text_section][text_key]; + create_textbox(box_type, eraseMainBox); +} + +void create_textbox(u8 textbox_type, bool eraseMainBox) +{ + const int startTileX = box_type_info[textbox_type][BOX_TYPE_VAL_START_TILE_X]; + const int startTileY = box_type_info[textbox_type][BOX_TYPE_VAL_START_TILE_Y]; + const int text_space_width = box_type_info[textbox_type][BOX_TYPE_VAL_PIXELS_PER_LINE]; + const int text_space_height = box_type_info[textbox_type][BOX_TYPE_VAL_NUM_OF_LINES] * 16; create_textbox(startTileX, startTileY, text_space_width, text_space_height, eraseMainBox); } diff --git a/source/dbg/debug_menu_functions.cpp b/source/dbg/debug_menu_functions.cpp index a030f4a..b0d5850 100644 --- a/source/dbg/debug_menu_functions.cpp +++ b/source/dbg/debug_menu_functions.cpp @@ -14,6 +14,12 @@ #include "Gen3SaveManager.h" #include "Gen3Pokemon.h" #include "pokemon_data.h" +#include "translated_text.h" + +#define LEFT 8 +#define RIGHT (H_MAX - LEFT) +#define TOP 120 +#define BOTTOM V_MAX extern rom_data curr_GBA_rom; @@ -145,6 +151,9 @@ void show_debug_info_screen(void *context, unsigned user_param) case EMERALD_ID: game_code = "-E-"; break; + default: + game_code = "-UNK-"; + break; } n2hexstr(flags_hex_str, pkmn_flags); @@ -222,9 +231,13 @@ void dbg_inject_pkmn(void *context, unsigned user_param) do { ret = save_manager.addPokemonToBox(boxIndex, celebi); + if(ret != UINT32_MAX) + { + break; + } ++boxIndex; - } while (ret == UINT32_MAX && boxIndex < 14); + } while (boxIndex < 14); if(ret == UINT32_MAX) { @@ -236,8 +249,8 @@ void dbg_inject_pkmn(void *context, unsigned user_param) reader.flush(); save_manager.readTrainerName(encoded_OT, ret); - reset_textbox(); - show_text_box(); + create_textbox(BOX_TYPE_DIALOUGEBOX, true); + show_textbox(); convert_OT_to_utf8(encoded_OT, decoded_OT_utf8, tables.gen3_charset); @@ -251,8 +264,7 @@ void dbg_inject_pkmn(void *context, unsigned user_param) { if (key_hit(KEY_A)) { - hide_text_box(); - reset_textbox(); + hide_textbox(); break; } global_next_frame(); diff --git a/source/dbg/ptgb_mgba_print.cpp b/source/dbg/ptgb_mgba_print.cpp index b22cca2..acaaed4 100644 --- a/source/dbg/ptgb_mgba_print.cpp +++ b/source/dbg/ptgb_mgba_print.cpp @@ -23,7 +23,7 @@ void ptgb_mgba_print(int level, const char *format_str, ...) { va_list args; va_start(args, format_str); - mgba_printf(level, format_str, args); + mgba_vprintf(level, format_str, args); va_end(args); }