diff --git a/PCCS b/PCCS index dab21f5..c60e391 160000 --- a/PCCS +++ b/PCCS @@ -1 +1 @@ -Subproject commit dab21f5ea99e066733e309647397ee1a2087c6de +Subproject commit c60e3916521e17afb20d84c5bbf023296b59969c diff --git a/container/GB_Payloads.containerdef b/container/GB_Payloads.containerdef index 62cc30c..53d77d2 100644 --- a/container/GB_Payloads.containerdef +++ b/container/GB_Payloads.containerdef @@ -40,6 +40,8 @@ tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_sp_s.bi tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_kor_s.bin tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_jp_c.bin tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_en_c.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_en_c11.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_en_cAU.bin tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_fr_c.bin tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_it_c.bin tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_de_c.bin diff --git a/graphics/boxBG.grit b/graphics/boxBG_Blue.grit similarity index 66% rename from graphics/boxBG.grit rename to graphics/boxBG_Blue.grit index 2a3d2d2..05abfd6 100644 --- a/graphics/boxBG.grit +++ b/graphics/boxBG_Blue.grit @@ -2,5 +2,5 @@ # Text Box (Background) : 64x64t, 4bpp, SBB-layout, LZ77 compressed. # Pallet bank 2, copy from 32 to 48. # --gt -gB4 -gzl -mR4 -mLs -mp2 -ma64 -mzl -ps0 -pe16 +-gt -gB4 -gzl -mR4 -mLs -mp2 -ma64 -mzl -ps0 -pe16 -pT15 diff --git a/graphics/boxBG_Blue.png b/graphics/boxBG_Blue.png new file mode 100644 index 0000000..642cf84 Binary files /dev/null and b/graphics/boxBG_Blue.png differ diff --git a/graphics/boxBG_Crystal.grit b/graphics/boxBG_Crystal.grit new file mode 100644 index 0000000..05abfd6 --- /dev/null +++ b/graphics/boxBG_Crystal.grit @@ -0,0 +1,6 @@ +# +# Text Box (Background) : 64x64t, 4bpp, SBB-layout, LZ77 compressed. +# Pallet bank 2, copy from 32 to 48. +# +-gt -gB4 -gzl -mR4 -mLs -mp2 -ma64 -mzl -ps0 -pe16 -pT15 + diff --git a/graphics/boxBG_Crystal.png b/graphics/boxBG_Crystal.png new file mode 100644 index 0000000..60799de Binary files /dev/null and b/graphics/boxBG_Crystal.png differ diff --git a/graphics/boxBG_Gold.grit b/graphics/boxBG_Gold.grit new file mode 100644 index 0000000..05abfd6 --- /dev/null +++ b/graphics/boxBG_Gold.grit @@ -0,0 +1,6 @@ +# +# Text Box (Background) : 64x64t, 4bpp, SBB-layout, LZ77 compressed. +# Pallet bank 2, copy from 32 to 48. +# +-gt -gB4 -gzl -mR4 -mLs -mp2 -ma64 -mzl -ps0 -pe16 -pT15 + diff --git a/graphics/boxBG_Gold.png b/graphics/boxBG_Gold.png new file mode 100644 index 0000000..ae1434f Binary files /dev/null and b/graphics/boxBG_Gold.png differ diff --git a/graphics/boxBG_Green.grit b/graphics/boxBG_Green.grit new file mode 100644 index 0000000..05abfd6 --- /dev/null +++ b/graphics/boxBG_Green.grit @@ -0,0 +1,6 @@ +# +# Text Box (Background) : 64x64t, 4bpp, SBB-layout, LZ77 compressed. +# Pallet bank 2, copy from 32 to 48. +# +-gt -gB4 -gzl -mR4 -mLs -mp2 -ma64 -mzl -ps0 -pe16 -pT15 + diff --git a/graphics/boxBG_Green.png b/graphics/boxBG_Green.png new file mode 100644 index 0000000..2f6cd23 Binary files /dev/null and b/graphics/boxBG_Green.png differ diff --git a/graphics/boxBG_Red.grit b/graphics/boxBG_Red.grit new file mode 100644 index 0000000..05abfd6 --- /dev/null +++ b/graphics/boxBG_Red.grit @@ -0,0 +1,6 @@ +# +# Text Box (Background) : 64x64t, 4bpp, SBB-layout, LZ77 compressed. +# Pallet bank 2, copy from 32 to 48. +# +-gt -gB4 -gzl -mR4 -mLs -mp2 -ma64 -mzl -ps0 -pe16 -pT15 + diff --git a/graphics/boxBG_Red.png b/graphics/boxBG_Red.png new file mode 100644 index 0000000..5ae61f4 Binary files /dev/null and b/graphics/boxBG_Red.png differ diff --git a/graphics/boxBG_Silver.grit b/graphics/boxBG_Silver.grit new file mode 100644 index 0000000..05abfd6 --- /dev/null +++ b/graphics/boxBG_Silver.grit @@ -0,0 +1,6 @@ +# +# Text Box (Background) : 64x64t, 4bpp, SBB-layout, LZ77 compressed. +# Pallet bank 2, copy from 32 to 48. +# +-gt -gB4 -gzl -mR4 -mLs -mp2 -ma64 -mzl -ps0 -pe16 -pT15 + diff --git a/graphics/boxBG_Silver.png b/graphics/boxBG_Silver.png new file mode 100644 index 0000000..860a124 Binary files /dev/null and b/graphics/boxBG_Silver.png differ diff --git a/graphics/boxBG_Yellow.grit b/graphics/boxBG_Yellow.grit new file mode 100644 index 0000000..05abfd6 --- /dev/null +++ b/graphics/boxBG_Yellow.grit @@ -0,0 +1,6 @@ +# +# Text Box (Background) : 64x64t, 4bpp, SBB-layout, LZ77 compressed. +# Pallet bank 2, copy from 32 to 48. +# +-gt -gB4 -gzl -mR4 -mLs -mp2 -ma64 -mzl -ps0 -pe16 -pT15 + diff --git a/graphics/boxBG_Yellow.png b/graphics/boxBG_Yellow.png new file mode 100644 index 0000000..53f1aa5 Binary files /dev/null and b/graphics/boxBG_Yellow.png differ diff --git a/graphics/boxBG.png b/graphics/unused graphics/oldboxBG.png similarity index 100% rename from graphics/boxBG.png rename to graphics/unused graphics/oldboxBG.png diff --git a/include/box_menu.h b/include/box_menu.h index aafba9e..6e76126 100644 --- a/include/box_menu.h +++ b/include/box_menu.h @@ -26,7 +26,7 @@ class Box_Menu { public: Box_Menu(); - int box_main(PokeBox* box); + int box_main(PokeBox* box, Version vers); private: int curr_button; int x; diff --git a/include/dbg/debug_mode.h b/include/dbg/debug_mode.h index e1f9e6e..5c2fcc8 100644 --- a/include/dbg/debug_mode.h +++ b/include/dbg/debug_mode.h @@ -130,7 +130,7 @@ extern debug_options g_debug_options; #define POKEMON_INDEX_TO_SKIP 5 // not sure if we want these in the debug menu. -#define DEBUG_GAME RUBY_ID +#define DEBUG_GAME EMERALD_ID #define DEBUG_VERS VERS_1_0 #define DEBUG_LANG LANG_ENG diff --git a/include/link_handler.h b/include/link_handler.h index 554dfb5..d45c600 100644 --- a/include/link_handler.h +++ b/include/link_handler.h @@ -52,7 +52,9 @@ enum GameBoyROM SILVER_SP, SILVER_KOR, CRYSTAL_JP, - CRYSTAL_EN, + CRYSTAL_EN_v0, + CRYSTAL_EN_v1, + CRYSTAL_EN_vA, CRYSTAL_FR, CRYSTAL_IT, CRYSTAL_DE, @@ -105,7 +107,9 @@ const GB_PayloadsFiles GameBoyROMPayloads[] = GB_PayloadsFiles::SPECIFICPAYLOADGEN2_SP_S, // SILVER_SP GB_PayloadsFiles::SPECIFICPAYLOADGEN2_KOR_S, // SILVER_KOR GB_PayloadsFiles::SPECIFICPAYLOADGEN2_JP_C, // CRYSTAL_JP - GB_PayloadsFiles::SPECIFICPAYLOADGEN2_EN_C, // CRYSTAL_EN + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_EN_C, // CRYSTAL_EN_v0 + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_EN_C11, // CRYSTAL_EN_v1 + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_EN_CAU, // CRYSTAL_EN_vA GB_PayloadsFiles::SPECIFICPAYLOADGEN2_FR_C, // CRYSTAL_FR GB_PayloadsFiles::SPECIFICPAYLOADGEN2_IT_C, // CRYSTAL_IT GB_PayloadsFiles::SPECIFICPAYLOADGEN2_DE_C, // CRYSTAL_DE @@ -155,7 +159,9 @@ const Language GameBoyROMLanguages[] = SPANISH, // SILVER_SP KOREAN, // SILVER_KOR JAPANESE, // CRYSTAL_JP - ENGLISH, // CRYSTAL_EN + ENGLISH, // CRYSTAL_EN_v0 + ENGLISH, // CRYSTAL_EN_v1 + ENGLISH, // CRYSTAL_EN_vA FRENCH, // CRYSTAL_FR ITALIAN, // CRYSTAL_IT GERMAN, // CRYSTAL_DE @@ -206,7 +212,9 @@ const Version GameBoyROMVersions[] = SILVER, // SILVER_SP SILVER, // SILVER_KOR CRYSTAL, // CRYSTAL_JP - CRYSTAL, // CRYSTAL_EN + CRYSTAL, // CRYSTAL_EN_v0 + CRYSTAL, // CRYSTAL_EN_v1 + CRYSTAL, // CRYSTAL_EN_vA CRYSTAL, // CRYSTAL_FR CRYSTAL, // CRYSTAL_IT CRYSTAL, // CRYSTAL_DE @@ -256,7 +264,9 @@ const u8 GameBoyROMChecksumTable[][4]{ {0x1C, 0x06, 0x4B, SILVER_SP}, {0xE7, 0x98, 0x5B, SILVER_KOR}, {0x22, 0x9A, 0x40, CRYSTAL_JP}, - {0x26, 0x18, 0xD2, CRYSTAL_EN}, + {0x27, 0x12, 0x9F, CRYSTAL_EN_v0}, + {0x26, 0x18, 0xD2, CRYSTAL_EN_v1}, + {0x17, 0xAF, 0x7C, CRYSTAL_EN_vA}, {0x26, 0xF2, 0xE2, CRYSTAL_FR}, {0x23, 0xDB, 0xBA, CRYSTAL_IT}, {0x28, 0x49, 0x82, CRYSTAL_DE}, diff --git a/include/sprite_data.h b/include/sprite_data.h index 49c6db3..6694cc9 100644 --- a/include/sprite_data.h +++ b/include/sprite_data.h @@ -108,11 +108,21 @@ extern OBJ_ATTR *grabbed_front_sprite; #define LINK_CABLE_PAL 13 #define PULLED_SPRITE_PAL 14 -#define FLEXBG_OPENING 0 -#define FLEXBG_FENNEL 1 -#define FLEXBG_DEX 2 -#define FLEXBG_MAIN_MENU 3 -#define FLEXBG_BOX 4 +enum FlexBackground +{ + FBG_None = -1, + FBG_Opening, + FBG_Fennel, + FBG_Dex, + FBG_Main_Menu, + FBG_Box_Green, + FBG_Box_Red, + FBG_Box_Blue, + FBG_Box_Yellow, + FBG_Box_Gold, + FBG_Box_Silver, + FBG_Box_Crystal, +}; // // VRAM usage is heavily optimized so the rest of it can be used @@ -152,7 +162,7 @@ void load_sprite_compressed(OBJ_ATTR *sprite, const unsigned int objTiles[], void load_background(); void set_background_pal(int curr_rom_id, bool dark, bool fade); void load_textbox_background(); -void load_flex_background(int background_id, int layer); +void load_flex_background(FlexBackground background_id, int layer); void load_eternal_sprites(); void load_temp_box_sprites(PokeBox* box); void load_type_sprites(const u8* pkmn_type_table, int pkmn_index, int dex_offset, bool is_caught); diff --git a/source/box_menu.cpp b/source/box_menu.cpp index 8c61c77..9aeb658 100644 --- a/source/box_menu.cpp +++ b/source/box_menu.cpp @@ -14,7 +14,7 @@ Box_Menu::Box_Menu() {}; -int Box_Menu::box_main(PokeBox* box) +int Box_Menu::box_main(PokeBox* box, Version vers) { PokemonTables pkmnTables; u8 names_decompression_buffer[2048]; @@ -27,7 +27,7 @@ int Box_Menu::box_main(PokeBox* box) FileContainerReader namesReader(chunkList, numChunks, chunkSize); tte_erase_screen(); - load_flex_background(FLEXBG_BOX, 2); + load_flex_background((FlexBackground)((int)FBG_Box_Green + (int)vers), 2); // This is kinda gross, but it works REG_BG1VOFS = 0; REG_BG1HOFS = 0; load_temp_box_sprites(box); @@ -125,7 +125,7 @@ int Box_Menu::box_main(PokeBox* box) obj_hide(party_sprites[i]); } tte_erase_screen(); - load_flex_background(FLEXBG_FENNEL, 2); + load_flex_background(FBG_Fennel, 2); REG_BG2VOFS = BG2VOF_SMALL_TEXTBOX; VBlankIntrWait(); return curr_button; diff --git a/source/global_frame_controller.cpp b/source/global_frame_controller.cpp index 0a51e87..f7ac075 100644 --- a/source/global_frame_controller.cpp +++ b/source/global_frame_controller.cpp @@ -227,7 +227,7 @@ void link_animation_state(int state) void determine_fennel_blink() { - if (get_curr_flex_background() == FLEXBG_FENNEL) + if (get_curr_flex_background() == FBG_Fennel) { if (fennel_blink_timer == 0) { diff --git a/source/link_handler.cpp b/source/link_handler.cpp index 21ad8fa..058c367 100644 --- a/source/link_handler.cpp +++ b/source/link_handler.cpp @@ -210,14 +210,15 @@ void LinkConnection::loadPayloadByROM(GameBoyROM rom) } LZ77UnCompWram(compressed_rom_values, gb_rom_values_buffer); - pccsROMptr = &gb_rom_values_buffer[vers - 1]; + pccsROMptr = &gb_rom_values_buffer[vers]; } void LinkConnection::loadCurrGameFromChecksum() { - if (((dataOutBuffer[0] + dataOutBuffer[1]) & 0x7F) != dataOutBuffer[3]) + if (((dataOutBuffer[0] + dataOutBuffer[1]) & 0x7F) != dataOutBuffer[2]) { currROM = GB_ROM_ERROR; + return; }; int start = RED_JP_v0; @@ -309,12 +310,12 @@ void LinkConnection::startConnection(LinkState startState) exitState = CLOCK_ACQUIRE; REG_TM3D = -DISCOVERY_TIMER_MIN; - REG_TM3CNT = TM_FREQ_1024 | TM_ENABLE; + REG_TM3CNT = TM_FREQ_1024 | TM_IRQ | TM_ENABLE; break; case PACKET_EXCHANGE: REG_TM3D = -0x0040; // REG_TM3D = -0x4000 / 60; - REG_TM3CNT = TM_FREQ_1024 | TM_ENABLE; + REG_TM3CNT = TM_FREQ_1024 | TM_IRQ | TM_ENABLE; break; default: break; @@ -457,7 +458,7 @@ void LinkConnection::handleStateLogic() nextOutData = 0x01; REG_TM3D = -(DISCOVERY_TIMER_MIN + (globalStateCounter & DISCOVERY_TIMER_PHASE_MASK)); - REG_TM3CNT = TM_FREQ_1024 | TM_ENABLE; + REG_TM3CNT = TM_FREQ_1024 | TM_IRQ | TM_ENABLE; exitState = CLOCK_ACQUIRE; break; diff --git a/source/main.cpp b/source/main.cpp index e6fa2d2..1d735c3 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -59,7 +59,7 @@ Button_Menu yes_no_menu(1, 2, 40, 24, false); void load_graphics() { // Load opening background first so it hides everything else - load_flex_background(FLEXBG_OPENING, 1); + load_flex_background(FBG_Opening, 1); load_background(); load_textbox_background(); load_eternal_sprites(); @@ -452,7 +452,7 @@ int main(void) print_mem_section(); curr_GBA_rom.print_rom_info(); } - load_flex_background(FLEXBG_MAIN_MENU, 2); + load_flex_background(FBG_Main_Menu, 2); obj_unhide_multi(ptgb_logo_l, 1, 2); obj_set_pos(ptgb_logo_l, 56, 12); @@ -463,7 +463,7 @@ int main(void) case (BTN_TRANSFER): tte_set_ink(INK_DARK_GREY); obj_hide_multi(ptgb_logo_l, 2); - load_flex_background(FLEXBG_FENNEL, 3); + load_flex_background(FBG_Fennel, 3); text_loop(SCRIPT_TRANSFER); break; case (BTN_POKEDEX): @@ -471,10 +471,10 @@ int main(void) { obj_hide_multi(ptgb_logo_l, 2); // global_next_frame(); - load_flex_background(FLEXBG_DEX, 2); + load_flex_background(FBG_Dex, 2); set_background_pal(curr_GBA_rom.gamecode, true, false); pokedex_loop(); - load_flex_background(FLEXBG_DEX, 3); + load_flex_background(FBG_Dex, 3); set_background_pal(curr_GBA_rom.gamecode, false, false); } break; @@ -497,7 +497,7 @@ int main(void) #if ENABLE_DEBUG_MENU case (BTN_DEBUG_MENU): obj_hide_multi(ptgb_logo_l, 2); - load_flex_background(FLEXBG_FENNEL, 3); + load_flex_background(FBG_Fennel, 3); show_debug_menu(); break; #endif diff --git a/source/script_array.cpp b/source/script_array.cpp index f4a9034..caead46 100644 --- a/source/script_array.cpp +++ b/source/script_array.cpp @@ -585,7 +585,7 @@ bool run_conditional(int index) return false; case CMD_START_LINK: - load_flex_background(FLEXBG_FENNEL, 3); + load_flex_background(FBG_Fennel, 3); link_animation_state(STATE_CONNECTION); box.reset(); if (g_debug_options.ignore_link_cable) @@ -688,7 +688,7 @@ bool run_conditional(int index) boxDataArray); } reload_textbox_background(); - load_flex_background(FLEXBG_FENNEL, 2); + load_flex_background(FBG_Fennel, 2); link_animation_state(0); return true; @@ -700,15 +700,15 @@ bool run_conditional(int index) case CMD_BACK_TO_MENU: set_text_exit(); REG_BG1HOFS = 0; - load_flex_background(FLEXBG_FENNEL, 3); + load_flex_background(FBG_Fennel, 3); return true; case CMD_SHOW_PROF: - // load_flex_background(FLEXBG_FENNEL, 3); + // load_flex_background(FBG_Fennel, 3); return true; case CMD_HIDE_PROF: - // load_flex_background(FLEXBG_FENNEL, 3); + // load_flex_background(FBG_Fennel, 3); return true; case CMD_SET_TUTOR_TRUE: @@ -778,7 +778,7 @@ bool run_conditional(int index) case CMD_BOX_MENU: hide_textbox(); - ret = (box_viewer.box_main(&box) == CONFIRM_BUTTON); + ret = (box_viewer.box_main(&box, globalLinkCable.vers) == CONFIRM_BUTTON); show_textbox(); return ret; diff --git a/source/sprite_data.cpp b/source/sprite_data.cpp index 54b947c..27e1951 100644 --- a/source/sprite_data.cpp +++ b/source/sprite_data.cpp @@ -10,7 +10,7 @@ OBJ_ATTR obj_buffer[128]; OBJ_AFFINE *obj_aff_buffer = (OBJ_AFFINE *)obj_buffer; -int curr_flex_background = -1; +FlexBackground curr_flex_background = FBG_None; int y_offset = 0; int y_offset_timer = 0; int y_offset_direction = 1; @@ -120,7 +120,14 @@ void set_background_pal(int curr_rom_id, bool dark, bool fade) #include "fennelBG.h" #include "dexBG.h" #include "menu_bars.h" -#include "boxBG.h" + +#include "boxBG_Green.h" +#include "boxBG_Red.h" +#include "boxBG_Blue.h" +#include "boxBG_Yellow.h" +#include "boxBG_Gold.h" +#include "boxBG_Silver.h" +#include "boxBG_Crystal.h" struct flex_background { const unsigned short *palette; @@ -131,44 +138,86 @@ struct flex_background { }; static const flex_background FLEX_BACKGROUNDS[] = { - [FLEXBG_OPENING] = { + [FBG_Opening] = { openingBGPal, openingBGPalLen, 96, openingBGTiles, openingBGMap, }, - [FLEXBG_FENNEL] = { + [FBG_Fennel] = { fennelBGPal, fennelBGPalLen, FENNEL_SHIFT, fennelBGTiles, fennelBGMap, }, - [FLEXBG_DEX] = { + [FBG_Dex] = { dexBGPal, dexBGPalLen, 0, dexBGTiles, dexBGMap, }, - [FLEXBG_MAIN_MENU] = { + [FBG_Main_Menu] = { pal_bg_mem, backgroundPalLen, 0, menu_barsTiles, menu_barsMap, }, - [FLEXBG_BOX] = { - boxBGPal, - boxBGPalLen, + [FBG_Box_Green] = { + boxBG_GreenPal, + boxBG_GreenPalLen, 0, - boxBGTiles, - boxBGMap, - } + boxBG_GreenTiles, + boxBG_GreenMap, + }, + [FBG_Box_Red] = { + boxBG_RedPal, + boxBG_RedPalLen, + 0, + boxBG_RedTiles, + boxBG_RedMap, + }, + [FBG_Box_Blue] = { + boxBG_BluePal, + boxBG_BluePalLen, + 0, + boxBG_BlueTiles, + boxBG_BlueMap, + }, + [FBG_Box_Yellow] = { + boxBG_YellowPal, + boxBG_YellowPalLen, + 0, + boxBG_YellowTiles, + boxBG_YellowMap, + }, + [FBG_Box_Gold] = { + boxBG_GoldPal, + boxBG_GoldPalLen, + 0, + boxBG_GoldTiles, + boxBG_GoldMap, + }, + [FBG_Box_Silver] = { + boxBG_SilverPal, + boxBG_SilverPalLen, + 0, + boxBG_SilverTiles, + boxBG_SilverMap, + }, + [FBG_Box_Crystal] = { + boxBG_CrystalPal, + boxBG_CrystalPalLen, + 0, + boxBG_CrystalTiles, + boxBG_CrystalMap, + }, }; -void load_flex_background(int background_id, int layer) +void load_flex_background(FlexBackground background_id, int layer) { if (curr_flex_background != background_id) // Only load the background if it isn't already loaded { @@ -710,7 +759,9 @@ void load_select_sprites(GameBoyROM currROM) break; case CRYSTAL_JP: - case CRYSTAL_EN: + case CRYSTAL_EN_v0: + case CRYSTAL_EN_v1: + case CRYSTAL_EN_vA: case CRYSTAL_FR: case CRYSTAL_IT: case CRYSTAL_DE: @@ -761,7 +812,9 @@ void load_select_sprites(GameBoyROM currROM) case YELLOW_EN: case GOLD_EN: case SILVER_EN: - case CRYSTAL_EN: + case CRYSTAL_EN_v0: + case CRYSTAL_EN_v1: + case CRYSTAL_EN_vA: gb_flag_tiles = flag_engTiles; gb_flag_palette = flag_engPal; break; diff --git a/source/text_engine.cpp b/source/text_engine.cpp index f895ea5..eb4d119 100644 --- a/source/text_engine.cpp +++ b/source/text_engine.cpp @@ -263,9 +263,9 @@ int ptgb_write_textbox(const byte *text, bool instant, bool waitForUser, erase_textbox_tiles(); create_textbox(text_section, text_key, eraseMainBox); // Set up Fennel if we are in a PTGB dialogue box - if (get_curr_flex_background() == FLEXBG_FENNEL && text_section == PTGB_INDEX) + if (get_curr_flex_background() == FBG_Fennel && text_section == PTGB_INDEX) { - load_flex_background(FLEXBG_FENNEL, 2); + load_flex_background(FBG_Fennel, 2); } 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) @@ -385,7 +385,7 @@ int ptgb_write(const byte *text, bool instant, int length, int box_type) } num += 1; } - if (get_curr_flex_background() == FLEXBG_FENNEL && !instant) + if (get_curr_flex_background() == FBG_Fennel && !instant) { fennel_speak(((num / 4) % 4) + 1); } @@ -431,7 +431,7 @@ int ptgb_write_debug(const u16 *charset, const char *text, bool instant) void wait_for_user_to_continue(int right, int bottom) { - if (get_curr_flex_background() == FLEXBG_FENNEL) + if (get_curr_flex_background() == FBG_Fennel) { if (get_missingno_enabled()) { diff --git a/tools/link_helper.lua b/tools/link_helper.lua deleted file mode 100644 index e54aeed..0000000 --- a/tools/link_helper.lua +++ /dev/null @@ -1,580 +0,0 @@ ---- PTGB Link Debug Helper ---- ---- This Lua script is designed to connect PTGB to Gen 1/2 on mGBA. ---- It requires a development build of mGBA. ---- ---- How to use: ---- 1. Load PTGB in mGBA ---- 2. Tools -> Scripting -> Load script, select this file. ---- 3. Check that it says "PTGB Link Debug Script", otherwise your mGBA may lack Lua support ---- 4. Repeat, but for the Gen 1/2 game. ---- ---- Most of the code is adapted from the demo scripts provided with mGBA. - - -console:log("-- PTGB Link Debug Script --") - --- Version check. The latest release as of writing is 0.10.5, which lacks watchpoint support. -- -if C.WATCHPOINT_TYPE == nil then - console:error("This script requires a more recent build of mGBA!") - console:log("You can get a development build at https://mgba.io/downloads.html#development-downloads") - console:log("If you want to build from source, remember to pass -DENABLE_SCRIPTING=1 to CMake.") - return -end - --- Reentrancy check --- --- If you load a script twice, mGBA will execute the script in the same environment --- which causes "address in use" errors. --- --- Requires a development build of mGBA, as watchpoints are a new feature. -if _G["PTGB_REENTRANCY_TEST"] then - Stop() -end -_G["PTGB_REENTRANCY_TEST"] = true - ---[[ - PTGB in Debug mode uses the following protocol, since mGBA doesn't let us write to REG_SIOCNT properly. - - 1. PTGB will write a value to link_debug.output_byte - 2. PTGB will write true to link_debug.has_output - 3. The Lua script will detect this write via a watchpoint and send the byte to the GB part of the script - 4. PTGB will wait on link_debug.has_input - 5. When the Lua script receives a response, it will write the value to link_debug.input_byte, and write true - to link_debug.has_input. -]]-- - - --- Let users know the script is working -- -console:log("Make sure you enable [insert option here] in the Debug Menu") -console:log("If you would like to log the sent bytes, type EnableOutput(\"filename\") in the console and hit Run") --- Port used for the socket. Chosen at random. - -PORT = 31415 -server = nil -sock = nil -watchpoint = -1 -defer_watchpoint = -1 -output_file = nil -poll_callback = -1 -MODE_IDLE = 0 -MODE_SEND = 1 -MODE_RECV = 2 - ---- Make sure these line up with the .link_debug addresses in PTGB. -LINK_DEBUG = 0x0203FFFC - -LD_REG_SIOCNT = LINK_DEBUG -LD_REG_SIODATA8 = LINK_DEBUG + 2 - -function logf(fmt, ...) - local tag = "[UNK]" - if emu and emu:platform() == C.PLATFORM.GBA then - tag = "[GBA]" - elseif emu and emu:platform() == C.PLATFORM.GB then - tag = "[GBC]" - end - - local str = string.format("%s " .. fmt, tag, ...) - console:log(str) -end - -function EnableOutput(filename) - if output_file then - output_file:close() - end - output_file, err = io.open(filename, "wb") - if not output_file then - console:error("Could not open " .. filename .. " for writing: " .. err) - end -end - -function SendByte(byte) - logf("SEND [0x%04x] 0x%02x", emu:currentFrame(), byte) - - local bytes = string.char(byte) - if output_file then - output_file:write(bytes) - output_file:flush() - end - if sock then - sock:send(bytes) - end -end - - -function DisableWatchpoint() - if watchpoint ~= -1 then - emu:clearBreakpoint(watchpoint) - watchpoint = -1 - end -end - -function SocketError() - if sock then - console:error("Socket error") - DisableWatchpoint() - - sock:close() - sock = nil - else - console:error("Unknown socket error") - end -end - -function PollSocket() - if sock then - local status, err = sock:hasdata() - if err then - console:error("Socket error " .. err) - SocketError() - end - - -- SIOCNT START writes can happen while the watchpoint is temporarily - -- disabled during reply handling. Polling here lets us recover - -- transfers that the watchpoint missed. - if emu and emu:platform() == C.PLATFORM.GBA then - GBA_Watchpoint() - end - end -end - -function Stop() - logf("Stopping...") - DisableWatchpoint() - if poll_callback ~= -1 then - callbacks:remove(poll_callback) - poll_callback = -1 - end - - if sock then - sock:close() - sock = nil - end - if output_file then - output_file:close() - output_file = nil - end - if server then - server:close() - server = nil - end - -end - - -frame_callback = -1 -gba_transfer_pending = false -gba_last_start_state = false - -function SerialExchangeByte(input) - if not sock then return false end - -- Check if ready -- - local rSC = read_io(REG_SIOCNT) - if (rSC & SIO_START) == 0 then - - - if defer_watchpoint == -1 then - -- Defer the result until the game is ready. -- - defer_watchpoint = emu:setWatchpoint( - function() - SerialExchangeByte(input) - end, - REG_SIOCNT, - C.WATCHPOINT_TYPE.WRITE - ) - end - if frame_callback == -1 then - frame_callback = callbacks:add("frame", function() SerialExchangeByte(input) end) - else - -- SendByte(0xFF) -- fail - --callbacks:remove(frame_callback) - --frame_callback = -1 - end - return false -- not ready -- - end - -- Disable the watchpoint -- - DisableWatchpoint() - - if defer_watchpoint ~= -1 then - emu:clearBreakpoint(defer_watchpoint) - defer_watchpoint = -1 - end - if frame_callback ~= -1 then - callbacks:remove(frame_callback) - frame_callback = -1 - end - - local output = read_io(REG_SIODATA8) - - -- Log -- - logf("RECV [0x%04x] 0x%02x", emu:currentFrame(), input) - - -- Write the new byte -- - write_io(REG_SIODATA8, input & 0xFF) - - -- Clear the start and ready flags. -- - rSC = (rSC & ~SIO_START) - write_io(REG_SIOCNT, rSC) - - if emu:platform() == C.PLATFORM.GBA then - -- Treat the next SIOCNT START write as a new transaction. - gba_transfer_pending = false - gba_last_start_state = false - end - - -- GB specific code -- - if emu:platform() == C.PLATFORM.GB then - -- GBA sends first. -- - SendByte(output) - - -- Trigger an interrupt -- - local rIF = read_io(REG_IF) - rIF = rIF | IF_SERIAL - write_io(REG_IF, rIF) - end - MODE = MODE_IDLE - EnableWatchpoint() - return true -end - -function HandleReceive() - if not sock then return end - - -- Receive the byte from the GB socket -- - local p, err = sock:receive(1) - if p then - local input = string.byte(p) - - -- DisableWatchpoint() - - -- if emu:platform() == C.PLATFORM.GBA then - -- -- The GBA needs a second flag set to enable transfer -- - -- local rSC = read_io(REG_SIOCNT) - -- rSC = rSC | SIO_READY - -- write_io(REG_SIOCNT, rSC) - -- end - - -- Write the byte from the GB to link_debug.input_byte and write true to has_input -- - SerialExchangeByte(input) - else - if err ~= socket.ERRORS.AGAIN then - SocketError() - end - end -end - ---- Host (GBA) code --- - -function GBA_Watchpoint() - -- if mode == MODE_RECV then return end - - local rSC = read_io(REG_SIOCNT) - local start_set = (rSC & SIO_START) ~= 0 - - -- DisableWatchpoint() - -- rSC = rSC | SIO_READY - -- write_io(REG_SIOCNT, rSC) - -- EnableWatchpoint() - - if not start_set then - gba_last_start_state = false - return - end - - if not sock then return end - if gba_transfer_pending or gba_last_start_state then return end - gba_last_start_state = true - gba_transfer_pending = true - - -- Send it to the GB -- - is_sending = true - - SendByte(read_io(REG_SIODATA8) & 0xFF) - -end - -function GBA_Accept() -- ST_Accept - if poll_callback ~= -1 then - callbacks:remove(poll_callback) - poll_callback = -1 - end - if sock then - -- Reconnection -- - DisableWatchpoint() - sock:close() - sock = nil - end - gba_transfer_pending = false - gba_last_start_state = false - - - -- Accept the connection -- - while true do - local tmp_sock - tmp_sock, err = server:accept() - if err then - if err ~= socket.ERRORS.AGAIN then - console:error("Accept " .. err) - Stop() - return - end - else - -- Setup callbacks -- - sock = tmp_sock - tmp_sock:add("received", HandleReceive) - tmp_sock:add("error", SocketError) - logf("Connected") - - break - end - end - - poll_callback = callbacks:add("frame", PollSocket) - -- Enable the watchpoint to start monitoring for link debug events. -- - -- local rSC = read_io(REG_SIOCNT) - -- rSC = rSC | SIO_READY - -- write_io(REG_SIOCNT, rSC) - - EnableWatchpoint() -end - -function GBA_Setup() - if server ~= nil then - server:close() - server = nil - end - - server, err = socket.bind(nil, PORT) - if err then - console:error("Bind error " .. err) - return false - end - - local ok - ok, err = server:listen() - if err then - console:error("Error listening: " .. err) - server:close() - return false - else - logf("PTGB Link Debug Script: Listening on port %d", PORT) - server:add("received", GBA_Accept) - return true - end - -end - - ---- GB client code --- - ---[[ - The GB requires us to emulate the link cable enough to trick Pokémon. - Thankfully, mGBA is not picky on the GB I/O registers, so this is a simple task. -]]-- - ---- Since mGBA is much more lenient on the GB link cable registers, we can modify memory directly. -- - - -function GB_Error() - console:error("Socket error, disconnecting...") - if sock then - sock:close() - sock = nil - end - GB_TryConnect() -end - -function GB_TryConnect() - local tmp_sock = socket.tcp() - - if tmp_sock and tmp_sock:connect("127.0.0.1", PORT) then - logf("PTGB Link Debug Script: Connected via port %d", PORT) - - if poll_callback ~= -1 then - callbacks:remove(poll_callback) - poll_callback = -1 - end - poll_callback = callbacks:add("frame", PollSocket) - - sock = tmp_sock - tmp_sock:add("received", HandleReceive) - tmp_sock:add("error", GB_Error) - - return true - else - tmp_sock:close() - if poll_callback == -1 then - -- Poll each frame. Only print once -- - logf("Waiting for connection...") - poll_callback = callbacks:add("frame", GB_TryConnect) - end - return false - end -end - --- mGBA doesn't let you get the No-Intro title from Lua, sadly. -- -ROM_INFO = { - -- CRC32 Game Language Rev. No-Intro title -- - - -- Red -- - [0x13652705] = { "Red", "Japanese", 0, "Pocket Monsters - Aka (Japan) (SGB Enhanced)" }, - [0xb77be1e0] = { "Red", "Japanese", 1, "Pocket Monsters - Aka (Japan) (Rev 1) (SGB Enhanced)" }, - [0x9f7fdd53] = { "Red", "English", 0, "Pokemon - Red Version (USA, Europe) (SGB Enhanced)" }, - [0xd8507d8a] = { "Red", "Spanish", 0, "Pokemon - Edicion Roja (Spain) (SGB Enhanced)" }, - [0x89197825] = { "Red", "German", 0, "Pokemon - Rote Edition (Germany) (SGB Enhanced)" }, - [0x337fce11] = { "Red", "French", 0, "Pokemon - Version Rouge (France) (SGB Enhanced)" }, - [0x2945aceb] = { "Red", "Italian", 0, "Pokemon - Versione Rossa (Italy) (SGB Enhanced)" }, - - -- Green -- - [0xbaeacd2b] = { "Green", "Japanese", 0, "Pocket Monsters - Midori (Japan) (SGB Enhanced)" }, - [0x37ae8dc4] = { "Green", "Japanese", 1, "Pocket Monsters - Midori (Japan) (Rev 1) (SGB Enhanced)" }, - - -- Blue -- - [0xe4468d14] = { "Blue", "Japanese", 0, "Pocket Monsters - Ao (Japan) (SGB Enhanced)" }, - [0xd6da8a1a] = { "Blue", "English", 0, "Pokemon - Blue Version (USA, Europe) (SGB Enhanced)" }, - [0xd95416f9] = { "Blue", "Spanish", 0, "Pokemon - Edicion Azul (Spain) (SGB Enhanced)" }, - [0x9c336307] = { "Blue", "German", 0, "Pokemon - Blaue Edition (Germany) (SGB Enhanced)" }, - [0x50e2fc1d] = { "Blue", "French", 0, "Pokemon - Version Bleue (France) (SGB Enhanced)" }, - [0x4d0984a9] = { "Blue", "Italian", 0, "Pokemon - Versione Blu (Italy) (SGB Enhanced)" }, - - -- Yellow -- - [0x4ec85504] = { "Yellow", "Japanese", 0, "Pocket Monsters - Pikachu (Japan) (SGB Enhanced)" }, - [0xa2545d33] = { "Yellow", "Japanese", 1, "Pocket Monsters - Pikachu (Japan) (Rev 1) (SGB Enhanced)" }, - [0xfd3da7ff] = { "Yellow", "Japanese", 2, "Pocket Monsters - Pikachu (Japan) (Rev 2) (SGB Enhanced)" }, - [0xe9e6483a] = { "Yellow", "Japanese", 3, "Pocket Monsters - Pikachu (Japan) (Rev 3) (SGB Enhanced)" }, - [0x7d527d62] = { "Yellow", "English", 0, "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (CGB+SGB Enhanced)" }, - [0x964b7a10] = { "Yellow", "Spanish", 0, "Pokemon - Edicion Amarilla - Edicion Especial Pikachu (Spain) (CGB+SGB Enhanced)" }, - [0x7a01e45a] = { "Yellow", "German", 0, "Pokemon - Gelbe Edition - Special Pikachu Edition (Germany) (CGB+SGB Enhanced)" }, - [0xd03426e9] = { "Yellow", "French", 0, "Pokemon - Version Jaune - Edition Speciale Pikachu (France) (CGB+SGB Enhanced)" }, - [0x8b56fe33] = { "Yellow", "Italian", 0, "Pokemon - Versione Gialla - Speciale Edizione Pikachu (Italy) (CGB+SGB Enhanced)" }, - - -- Gold -- - [0x524478d4] = { "Gold", "Japanese", 0, "Pocket Monsters Kin (Japan) (SGB Enhanced) (GB Compatible)" }, - [0x4ef7f2a5] = { "Gold", "Japanese", 1, "Pocket Monsters Kin (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" }, - [0x6bde3c3e] = { "Gold", "English", 0, "Pokemon - Gold Version (USA, Europe) (SGB Enhanced) (GB Compatible)" }, - [0x3434a92b] = { "Gold", "Spanish", 0, "Pokemon - Edicion Oro (Spain) (SGB Enhanced) (GB Compatible)" }, - [0x4889dfaa] = { "Gold", "German", 0, "Pokemon - Goldene Edition (Germany) (SGB Enhanced) (GB Compatible)" }, - [0x37a70702] = { "Gold", "French", 0, "Pokemon - Version Or (France) (SGB Enhanced) (GB Compatible)" }, - [0x4c184ce3] = { "Gold", "Italian", 0, "Pokemon - Versione Oro (Italy) (SGB Enhanced) (GB Compatible)" }, - [0x249a7a66] = { "Gold", "Korean", 0, "Pocket Monsters Geum (Korea)" }, - - -- Silver -- - [0xbe1b928a] = { "Silver", "Japanese", 0, "Pocket Monsters Gin (Japan) (SGB Enhanced) (GB Compatible)" }, - [0x0aea5383] = { "Silver", "Japanese", 1, "Pocket Monsters Gin (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" }, - [0x8ad48636] = { "Silver", "English", 0, "Pokemon - Silver Version (USA, Europe) (SGB Enhanced) (GB Compatible)" }, - [0x1d9faac5] = { "Silver", "Spanish", 0, "Pokemon - Edicion Plata (Spain) (SGB Enhanced) (GB Compatible)" }, - [0x96c9db95] = { "Silver", "German", 0, "Pokemon - Silberne Edition (Germany) (SGB Enhanced) (GB Compatible)" }, - [0xe0c216ea] = { "Silver", "French", 0, "Pokemon - Version Argent (France) (SGB Enhanced) (GB Compatible)" }, - [0xcba6d2d4] = { "Silver", "Italian", 0, "Pokemon - Versione Argento (Italy) (SGB Enhanced) (GB Compatible)" }, - [0x9cc1f90f] = { "Silver", "Korean", 0, "Pocket Monsters Eun (Korea)" }, - - -- Crystal -- - [0x270c4ecc] = { "Crystal", "Japanese", 0, "Pocket Monsters - Crystal Version (Japan)" }, - [0xee6f5188] = { "Crystal", "English (US)", 0, "Pokemon - Crystal Version (USA)" }, - [0x3358e30a] = { "Crystal", "English (US/EU)", 1, "Pokemon - Crystal Version (USA, Europe) (Rev 1)" }, - [0xbb6dd80c] = { "Crystal", "English (AUS)", 0, "Pokemon - Crystal Version (Australia)" }, - [0xff0a6f8a] = { "Crystal", "Spanish", 0, "Pokemon - Edicion Cristal (Spain)" }, - [0x616d85de] = { "Crystal", "German", 0, "Pokemon - Kristall-Edition (Germany)" }, - [0x878b2aa7] = { "Crystal", "French", 0, "Pokemon - Version Cristal (France)" }, - [0xd45ac039] = { "Crystal", "Italian", 0, "Pokemon - Versione Cristallo (Italy)" }, -} - -function GB_Setup() - - -- Try to identify the ROM -- - local crc32_raw = emu:checksum(C.CHECKSUM.CRC32) - - -- mGBA returns a binary string in big endian, convert it to a number -- - local crc32 = (string.byte(crc32_raw, 1) << 24) | - (string.byte(crc32_raw, 2) << 16) | - (string.byte(crc32_raw, 3) << 8) | - (string.byte(crc32_raw, 4) << 0) - - if ROM_INFO[crc32] then - -- Print info -- - local game_type = ROM_INFO[crc32][1] - local game_lang = ROM_INFO[crc32][2] - local game_rev = ROM_INFO[crc32][3] - local game_title = ROM_INFO[crc32][4] - - logf("Detected an official Pokémon game!") - logf(" - CRC32: 0x%08x", crc32) - logf(" - ROM name: %s", game_title) - logf(" - Game: %s", game_type) - logf(" - Language: %s", game_lang) - logf(" - Revision: %d", game_rev) - else - logf("Warning: Unknown CRC32 0x%08x", crc32) - end - - GB_TryConnect() - return true -end - -function Setup() - if emu then - logf("Setting up...") - if emu:platform() == C.PLATFORM.GBA then - - REG_SIODATA8 = LD_REG_SIODATA8 - REG_SIOCNT = LD_REG_SIOCNT - -- PTGB doesn't actually use serial interrupts, and we can't manually - -- set the interrupts. - REG_IF = 0 - - SIO_START = 0x0080 - SIO_READY = 0x0000 - IF_SERIAL = 0x0080 - - function write_io(addr, val) - emu:write16(addr, val) - end - - function read_io(addr) - return emu:read16(addr) - end - - function EnableWatchpoint() - watchpoint = emu:setWatchpoint(GBA_Watchpoint, REG_SIOCNT, C.WATCHPOINT_TYPE.WRITE) - end - - if not GBA_Setup() then - console:error("Setup failed!") - end - - else - REG_SIODATA8 = 0xFF01 - REG_SIOCNT = 0xFF02 - REG_IF = 0xFF0F - - SIO_START = 0x80 - SIO_READY = 0x00 - IF_SERIAL = 0x08 - function write_io(addr, val) - emu:write8(addr, val) - end - - function read_io(addr) - return emu:read8(addr) - end - - function EnableWatchpoint() - -- watchpoint = emu:setWatchpoint(GB_Watchpoint, REG_SIOCNT, C.WATCHPOINT_TYPE.WRITE) - end - - - if not GB_Setup() then - console:error("Setup failed!") - end - end - end -end - - -callbacks:add("start", Setup) -callbacks:add("stop", Stop) - -if emu then - Setup() -end