From c454b2a6e23ca5e4f0226522d37febfe9a153e45 Mon Sep 17 00:00:00 2001 From: GearsProgress Date: Sat, 22 Aug 2026 16:28:29 -0400 Subject: [PATCH 1/4] Adding in support for all latin languages and versions --- PCCS | 2 +- container/GB_Payloads.containerdef | 22 +++++ include/dbg/debug_mode.h | 2 +- include/gb_rom_values/base_gb_rom_struct.h | 1 + include/link_handler.h | 102 ++++++++++++++++----- source/link_handler.cpp | 79 ++++++++++++++-- source/script_array.cpp | 27 ++++-- 7 files changed, 195 insertions(+), 40 deletions(-) diff --git a/PCCS b/PCCS index 31ec2e6..ca9ab8c 160000 --- a/PCCS +++ b/PCCS @@ -1 +1 @@ -Subproject commit 31ec2e656888d7a99e99f67972b2516fa2ed126c +Subproject commit ca9ab8c6ab569cd962074487e5702b989430003b diff --git a/container/GB_Payloads.containerdef b/container/GB_Payloads.containerdef index 8a45c43..62cc30c 100644 --- a/container/GB_Payloads.containerdef +++ b/container/GB_Payloads.containerdef @@ -22,5 +22,27 @@ tools/gb-payload-generator/build/specificPayloadGen1/specificPayloadGen1_fr_y.bi tools/gb-payload-generator/build/specificPayloadGen1/specificPayloadGen1_it_y.bin tools/gb-payload-generator/build/specificPayloadGen1/specificPayloadGen1_de_y.bin tools/gb-payload-generator/build/specificPayloadGen1/specificPayloadGen1_sp_y.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_jp_g.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_jp_g11.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_en_g.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_fr_g.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_it_g.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_de_g.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_sp_g.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_kor_g.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_jp_s.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_jp_s11.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_en_s.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_fr_s.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_it_s.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_de_s.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_sp_s.bin +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_fr_c.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_it_c.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_de_c.bin +tools/gb-payload-generator/build/specificPayloadGen2/specificPayloadGen2_sp_c.bin tools/gb-payload-generator/build/universalPayloadGen1/universalPayloadGen1.bin tools/gb-payload-generator/build/universalPayloadGen2/universalPayloadGen2.bin diff --git a/include/dbg/debug_mode.h b/include/dbg/debug_mode.h index 5c2fcc8..e1f9e6e 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 EMERALD_ID +#define DEBUG_GAME RUBY_ID #define DEBUG_VERS VERS_1_0 #define DEBUG_LANG LANG_ENG diff --git a/include/gb_rom_values/base_gb_rom_struct.h b/include/gb_rom_values/base_gb_rom_struct.h index 7d381d3..3763390 100644 --- a/include/gb_rom_values/base_gb_rom_struct.h +++ b/include/gb_rom_values/base_gb_rom_struct.h @@ -88,6 +88,7 @@ public: u32 garbageDataLocation; // location of random data starting with 0xFD in the ROM u32 wRemoveMonFromBox; // location of wRemoveMonFromBox in RAM + u32 wCurrentBoxNum; // location of wCurrentBoxNum in RAM u32 wBoxCount; // location of wBoxCount in RAM u32 wWhichPokemon; // location of wWhichPokemon in RAM u32 wBoxDataStart; // location of wBoxDataStart in RAM diff --git a/include/link_handler.h b/include/link_handler.h index 490ae31..93e1fa5 100644 --- a/include/link_handler.h +++ b/include/link_handler.h @@ -5,6 +5,7 @@ #include "libraries/gba-link-connection/LinkSPI.hpp" #include "GB_Payloads.h" #include "typeDefs.h" +#include "gb_rom_values/base_gb_rom_struct.h" #define SPI_TEXT_OUT_ARRAY_ELEMENT_SIZE 64 @@ -87,28 +88,28 @@ const GB_PayloadsFiles GameBoyROMPayloads[] = GB_PayloadsFiles::SPECIFICPAYLOADGEN1_IT_Y, // YELLOW_IT GB_PayloadsFiles::SPECIFICPAYLOADGEN1_DE_Y, // YELLOW_DE GB_PayloadsFiles::SPECIFICPAYLOADGEN1_SP_Y, // YELLOW_SP - // GOLD_JP_v0 - // GOLD_JP_v1 - // GOLD_EN - // GOLD_FR - // GOLD_IT - // GOLD_DE - // GOLD_SP - // GOLD_KOR - // SILVER_JP_v0 - // SILVER_JP_v1 - // SILVER_EN - // SILVER_FR - // SILVER_IT - // SILVER_DE - // SILVER_SP - // SILVER_KOR - // CRYSTAL_JP - // CRYSTAL_EN - // CRYSTAL_FR - // CRYSTAL_IT - // CRYSTAL_DE - // CRYSTAL_SP + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_JP_G, // GOLD_JP_v0 + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_JP_G11, // GOLD_JP_v1 + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_EN_G, // GOLD_EN + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_FR_G, // GOLD_FR + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_IT_G, // GOLD_IT + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_DE_G, // GOLD_DE + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_SP_G, // GOLD_SP + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_KOR_G, // GOLD_KOR + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_JP_S, // SILVER_JP_v0 + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_JP_S11, // SILVER_JP_v1 + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_EN_S, // SILVER_EN + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_FR_S, // SILVER_FR + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_IT_S, // SILVER_IT + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_DE_S, // SILVER_DE + 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_FR_C, // CRYSTAL_FR + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_IT_C, // CRYSTAL_IT + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_DE_C, // CRYSTAL_DE + GB_PayloadsFiles::SPECIFICPAYLOADGEN2_SP_C, // CRYSTAL_SP }; const Language GameBoyROMLanguages[] = @@ -161,6 +162,57 @@ const Language GameBoyROMLanguages[] = SPANISH, // CRYSTAL_SP }; +// This would probably make more sense as a "greater than less than" check. +const Version GameBoyROMVersions[] = + { + RED, // RED_JP_v0 + RED, // RED_JP_v1 + RED, // RED_EN + RED, // RED_FR + RED, // RED_IT + RED, // RED_DE + RED, // RED_SP + GREEN, // GREEN_JP_v0 + GREEN, // GREEN_JP_v1 + BLUE, // BLUE_JP + BLUE, // BLUE_EN + BLUE, // BLUE_FR + BLUE, // BLUE_IT + BLUE, // BLUE_DE + BLUE, // BLUE_SP + YELLOW, // YELLOW_JP_v0 + YELLOW, // YELLOW_JP_v1 + YELLOW, // YELLOW_JP_v2 + YELLOW, // YELLOW_JP_v3 + YELLOW, // YELLOW_EN + YELLOW, // YELLOW_FR + YELLOW, // YELLOW_IT + YELLOW, // YELLOW_DE + YELLOW, // YELLOW_SP + GOLD, // GOLD_JP_v0 + GOLD, // GOLD_JP_v1 + GOLD, // GOLD_EN + GOLD, // GOLD_FR + GOLD, // GOLD_IT + GOLD, // GOLD_DE + GOLD, // GOLD_SP + GOLD, // GOLD_KOR + SILVER, // SILVER_JP_v0 + SILVER, // SILVER_JP_v1 + SILVER, // SILVER_EN + SILVER, // SILVER_FR + SILVER, // SILVER_IT + SILVER, // SILVER_DE + SILVER, // SILVER_SP + SILVER, // SILVER_KOR + CRYSTAL, // CRYSTAL_JP + CRYSTAL, // CRYSTAL_EN + CRYSTAL, // CRYSTAL_FR + CRYSTAL, // CRYSTAL_IT + CRYSTAL, // CRYSTAL_DE + CRYSTAL, // CRYSTAL_SP +}; + // This table has the 3 checksums, followed by the enum value const u8 GameBoyROMChecksumTable[][4]{ {0x32, 0xA2, 0xC1, RED_JP_v0}, @@ -244,6 +296,7 @@ enum LinkConnectionError PACKET_TIMED_OUT, CHECKSUM_MISMATCH, ECHO_MISMATCH, + ERROR_FLAG, PACKET_SUCCESS, PACKET_READ, @@ -321,7 +374,10 @@ public: int gen = 0; // The generation we are trading with Language lang = LANGUAGE_UNKNOWN; // The language we are trading with + Version vers = VERSION_UNKNOWN; // The version we are trading with GameBoyROM currROM = NO_GB_ROM; // The GameBoy ROM we're communicating with + const GB_ROM *pccsROMptr = nullptr; // A pointer to the ROM data for the game we're communicating with + byte boxNum = 0; // The current box the user has selected int FF_count = 0; // The number of 0xFF bytes that have been in a row int zero_count = 0; // The number of 0x00 bytes that have been in a row @@ -368,7 +424,7 @@ public: bool LinkCommand_SoftReset(bool waitForCompletion = true); bool LinkCommand_ModifySRAMAccess(bool enableSRAM, byte SRAMbank, bool waitForCompletion = true); bool LinkCommand_RunSecondaryPayload(byte payload[], int payloadLength, bool waitForCompletion = true); - bool LinkCommand_ReadMemorySection(u16 dataPointer, byte outArray[], int outArraySize, bool waitForCompletion = true); + bool LinkCommand_ReadMemorySection(u32 dataPointer, byte outArray[], int outArraySize, bool waitForCompletion = true); // Some operations are too long to be done within the IRQ. // So we need to handle them in the main loop instead to avoid data corruption. diff --git a/source/link_handler.cpp b/source/link_handler.cpp index 69cb5ed..d739129 100644 --- a/source/link_handler.cpp +++ b/source/link_handler.cpp @@ -18,11 +18,23 @@ #include "text_tables.h" #include "translated_text.h" #include "gb_rom_values/base_gb_rom_struct.h" +#include "gb_rom_values/gb_rom_values.h" +#include "gb_rom_values_jpn_lz10_bin.h" +#include "gb_rom_values_eng_lz10_bin.h" +#include "gb_rom_values_fre_lz10_bin.h" +#include "gb_rom_values_ger_lz10_bin.h" +#include "gb_rom_values_ita_lz10_bin.h" +#include "gb_rom_values_spa_lz10_bin.h" +#include "gb_rom_values_kor_lz10_bin.h" #include "GB_Payloads_chunk0_lz10_bin.h" #include "GB_Payloads_chunk1_lz10_bin.h" #include "GB_Payloads_chunk2_lz10_bin.h" #include "GB_Payloads_chunk3_lz10_bin.h" +#include "GB_Payloads_chunk4_lz10_bin.h" +#include "GB_Payloads_chunk5_lz10_bin.h" +#include "GB_Payloads_chunk6_lz10_bin.h" + #include "GB_Payloads.h" LinkSPI linkSPIInstance; @@ -30,7 +42,7 @@ LinkSPI *linkSPI = &linkSPIInstance; // Here's a compilation check to ensure that the size of these structs match our expectations. // Just update it if you changed the struct members. The data-generator process prints their actual sizes. -static_assert(sizeof(struct GB_ROM) == 136); +static_assert(sizeof(struct GB_ROM) == 140); static_assert(sizeof(struct ROM_DATA) == 160); LinkConnection globalLinkCable; @@ -142,8 +154,11 @@ void LinkConnection::loadPayload(GB_PayloadsFiles payload) (const u8 *)GB_Payloads_chunk1_lz10_bin, (const u8 *)GB_Payloads_chunk2_lz10_bin, (const u8 *)GB_Payloads_chunk3_lz10_bin, + (const u8 *)GB_Payloads_chunk4_lz10_bin, + (const u8 *)GB_Payloads_chunk5_lz10_bin, + (const u8 *)GB_Payloads_chunk6_lz10_bin, }; - FileContainerReader reader(chunkList, 4); + FileContainerReader reader(chunkList, 7); const u32 fileIndex = (u32)payload; reader.init(decompressionBuffer, sizeof(decompressionBuffer)); @@ -158,6 +173,38 @@ void LinkConnection::loadPayloadByROM(GameBoyROM rom) { loadPayload(GameBoyROMPayloads[rom]); lang = GameBoyROMLanguages[rom]; + vers = GameBoyROMVersions[rom]; + + static GB_ROM gb_rom_values_buffer[7]; + const u8 *compressed_rom_values; + + switch (lang){ + case JAPANESE: + compressed_rom_values = gb_rom_values_jpn_lz10_bin; + break; + default: + case ENGLISH: + compressed_rom_values = gb_rom_values_eng_lz10_bin; + break; + case FRENCH: + compressed_rom_values = gb_rom_values_fre_lz10_bin; + break; + case ITALIAN: + compressed_rom_values = gb_rom_values_ita_lz10_bin; + break; + case GERMAN: + compressed_rom_values = gb_rom_values_ger_lz10_bin; + break; + case SPANISH: + compressed_rom_values = gb_rom_values_spa_lz10_bin; + break; + case KOREAN: + compressed_rom_values = gb_rom_values_kor_lz10_bin; + break; + } + + LZ77UnCompWram(compressed_rom_values, gb_rom_values_buffer); + pccsROMptr = &gb_rom_values_buffer[vers - 1]; } void LinkConnection::loadCurrGameFromChecksum() @@ -204,7 +251,7 @@ void LinkConnection::exchangeBytes() case WRITE_CABLE_DATA_MODE_OFF: // Normal transfer :-) inData = linkSPI->transfer(outData); - PTGB_MGBA_INFO("in: %X, out: %X", inData, outData); + // PTGB_MGBA_INFO("in: %X, out: %X", inData, outData); break; case WRITE_CABLE_DATA_MODE_SRAM: // Pretend transfer, by loading the bytes from SRAM (where we stored them with writeData() in a previous transfer) @@ -960,11 +1007,13 @@ bool LinkConnection::processPacket() if ((currIncomingPacket->command != CMD_ReadDataRequest) && (dataOutBuffer[INP_DATA_INDEX] & 0x80)) { + currIncomingPacket->latestError = ERROR_FLAG; PTGB_MGBA_INFO("Packet reports GB command failure: packet=%u cmd=%d encodedFirstData=%X decodedFirstData=%X", currIncomingPacket->packetID, currIncomingPacket->command, dataOutBuffer[INP_DATA_INDEX], currIncomingPacket->recievedData[0]); + return false; } if (currIncomingPacket->command != CMD_ReadDataRequest) @@ -1294,26 +1343,39 @@ bool LinkConnection::LinkCommand_RunSecondaryPayload(byte payload[], int payload return true; }; -bool LinkConnection::LinkCommand_ReadMemorySection(u16 dataPointer, byte outArray[], int outArraySize, bool waitForCompletion) +bool LinkConnection::LinkCommand_ReadMemorySection(u32 dataPointer, byte outArray[], int outArraySize, bool waitForCompletion) { if (g_debug_options.ignore_link_cable) { return true; } + if (dataPointer > 0xFFFF) + { + waitForCompletion = true; // We have to wait for completion with the SRAM bank loading, so we can close it + LinkCommand_ModifySRAMAccess(true, dataPointer >> 16); + } + PTGB_MGBA_INFO("Running command: ReadMemorySection"); resetLinkPackets(); linkPacketDataStart = dataPointer; linkPacketDataSize = outArraySize; - linkPacketDataAddr = dataPointer; + linkPacketDataAddr = dataPointer & 0xFFFF; outDataArrayPtr = outArray; for (int i = 0; i < LINK_PACKET_ARRAY_SIZE; i++) { - linkPacketArr[i] = LinkPacket(CMD_ReadDataRequest, 0x00, 0x00, linkPacketDataAddr); - linkPacketDataAddr += 8; + if ((i * 8) < linkPacketDataSize) + { + linkPacketArr[i] = LinkPacket(CMD_ReadDataRequest, 0x00, 0x00, linkPacketDataAddr); + linkPacketDataAddr += 8; + } + else + { + linkPacketArr[i] = dummyPacket; + } } globalLinkCable.startConnection(PACKET_EXCHANGE); @@ -1321,5 +1383,8 @@ bool LinkConnection::LinkCommand_ReadMemorySection(u16 dataPointer, byte outArra { waitForEnd(); } + + LinkCommand_ModifySRAMAccess(false, dataPointer >> 16); + return true; } \ No newline at end of file diff --git a/source/script_array.cpp b/source/script_array.cpp index 66de159..39e1258 100644 --- a/source/script_array.cpp +++ b/source/script_array.cpp @@ -706,16 +706,26 @@ bool run_conditional(int index) load_select_sprites(globalLinkCable.currROM); + obj_unhide(gba_cart, 0); + obj_set_pos(gba_cart, 17 * 8, 14 * 8); + + obj_unhide(cart_shell, 0); + obj_set_pos(cart_shell, (8 * 8), (11 * 8) + 11); + + obj_unhide(cart_label, 0); + obj_set_pos(cart_label, (8 * 8) + 8, (11 * 8) + 11 + 13); + + obj_unhide(gba_flag, 0); + obj_set_pos(gba_flag, 23 * 8, 14 * 8); + obj_unhide(gb_flag, 0); obj_set_pos(gb_flag, 1.5 * 8, 14 * 8); + + globalLinkCable.LinkCommand_ReadMemorySection(globalLinkCable.pccsROMptr->wCurrentBoxNum, &globalLinkCable.boxNum, 1); - globalLinkCable.skipPrint = false; - globalLinkCable.pauseOnPacket = true; - - byte boxDataArray[1122]; - - globalLinkCable.LinkCommand_ReadMemorySection(0xDA80, - boxDataArray, 1122); + byte boxDataArray[globalLinkCable.pccsROMptr->box_data_size]; + globalLinkCable.LinkCommand_ReadMemorySection(globalLinkCable.pccsROMptr->wBoxDataStart, + boxDataArray, globalLinkCable.pccsROMptr->box_data_size); box.loadData(globalLinkCable.gen, globalLinkCable.lang, boxDataArray); @@ -753,6 +763,7 @@ bool run_conditional(int index) { set_missingno(false); } + globalLinkCable.LinkCommand_SoftReset(); return true; case CMD_LANG_MENU: @@ -804,7 +815,7 @@ bool run_conditional(int index) } boxRemovalPayload[arrayIndex] = 0xFF; arrayIndex++; - globalLinkCable.LinkCommand_TransferPokemon(2, boxRemovalPayload, arrayIndex); + globalLinkCable.LinkCommand_TransferPokemon(globalLinkCable.boxNum, boxRemovalPayload, arrayIndex); } return true; From 1afb528c7316eee2f4d6ff0ca4bb7f6cf491caa4 Mon Sep 17 00:00:00 2001 From: GearsProgress Date: Thu, 27 Aug 2026 17:51:37 -0400 Subject: [PATCH 2/4] Re-enabling Dream Dex --- PCCS | 2 +- include/script_array.h | 2 ++ source/main.cpp | 2 +- source/mystery_gift_builder.cpp | 2 ++ source/ptgb_save_data_manager.cpp | 5 +++++ source/script_array.cpp | 4 +++- 6 files changed, 14 insertions(+), 3 deletions(-) diff --git a/PCCS b/PCCS index ca9ab8c..9002c56 160000 --- a/PCCS +++ b/PCCS @@ -1 +1 @@ -Subproject commit ca9ab8c6ab569cd962074487e5702b989430003b +Subproject commit 9002c562363b6525a156074e535a5c623522bd33 diff --git a/include/script_array.h b/include/script_array.h index f43f4db..728127e 100644 --- a/include/script_array.h +++ b/include/script_array.h @@ -5,6 +5,8 @@ #include "rom_data.h" #include "translated_text.h" +extern bool newPkmn; // This is stupid and dumb and stupid but we're storing it like this until this whole mess gets rewritten. + // Commands #define T_SCRIPT_START DIA_END + 0 #define E_SCRIPT_START DIA_END + 1 diff --git a/source/main.cpp b/source/main.cpp index 964ad7d..a0c8870 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -435,7 +435,7 @@ int main(void) set_background_pal(curr_GBA_rom.gamecode, false, true); - if (!g_debug_options.ignore_mg_e4_flags && (!get_tutorial_flag() || g_debug_options.force_tutorial)) + if (!get_tutorial_flag() || g_debug_options.force_tutorial) { obj_hide_multi(ptgb_logo_l, 2); text_loop(BTN_TRANSFER); diff --git a/source/mystery_gift_builder.cpp b/source/mystery_gift_builder.cpp index 5953bb4..ad326ea 100644 --- a/source/mystery_gift_builder.cpp +++ b/source/mystery_gift_builder.cpp @@ -6,6 +6,7 @@ #include "translated_text.h" #include "FileContainerReader.h" #include "text_tables.h" +#include "script_array.h" #define MG_SCRIPT false #define S30_SCRIPT true @@ -339,6 +340,7 @@ void mystery_gift_script::build_script(PokeBox *box) // it won't get called automatically because it's part of the union (and neither will the destructor) new (&decompressed_store.tables.data) PokemonTables(); + newPkmn = false; // TODO make it so that the table is added here(?) box->setTable(&decompressed_store.tables.data); box->convertAll(); diff --git a/source/ptgb_save_data_manager.cpp b/source/ptgb_save_data_manager.cpp index 92bc76c..8d73dbf 100644 --- a/source/ptgb_save_data_manager.cpp +++ b/source/ptgb_save_data_manager.cpp @@ -5,6 +5,7 @@ #include "button_menu.h" #include "pokemon_data.h" #include "libraries/Pokemon-Gen3-to-Gen-X/include/save.h" +#include "script_array.h" byte save_data_array[SAVE_DATA_SIZE]; @@ -31,6 +32,10 @@ bool is_caught(int dex_num) void set_caught(int dex_num) { + if (!is_caught(dex_num)) + { + newPkmn |= true; + } save_data_array[CAUGHT_DATA + (dex_num / 8)] = save_data_array[CAUGHT_DATA + (dex_num / 8)] | (1 << (dex_num % 8)); } diff --git a/source/script_array.cpp b/source/script_array.cpp index 39e1258..9f06fd9 100644 --- a/source/script_array.cpp +++ b/source/script_array.cpp @@ -17,6 +17,7 @@ #include int last_error; +bool newPkmn = false; PokemonTables pokeTable; PokeBox box(&pokeTable); @@ -573,7 +574,8 @@ bool run_conditional(int index) return get_tutorial_flag() && !g_debug_options.force_tutorial; case COND_NEW_POKEMON: - return box.getHasNewPkmn(); + //return box.getHasNewPkmn(); + return newPkmn; case COND_IS_HOENN_RS: return curr_GBA_rom.is_ruby_sapphire(); From 608022a80e76c902c3b89a0bb228b398a614ccd5 Mon Sep 17 00:00:00 2001 From: GearsProgress Date: Sat, 29 Aug 2026 13:23:33 -0400 Subject: [PATCH 3/4] Improving the link cable connection initialization --- include/link_handler.h | 10 +++-- source/link_handler.cpp | 92 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 90 insertions(+), 12 deletions(-) diff --git a/include/link_handler.h b/include/link_handler.h index 93e1fa5..554dfb5 100644 --- a/include/link_handler.h +++ b/include/link_handler.h @@ -266,7 +266,9 @@ const u8 GameBoyROMChecksumTable[][4]{ enum LinkState { INITIAL_CONNECTION = 0x00, - CLOCK, + DISCOVERY_RESET, + CLOCK_ACQUIRE, + CLOCK_CONFIRM, SAVE_SUCCESS, MENU_OPEN, MENU_SUCCESS, @@ -365,9 +367,9 @@ public: LinkConnectionError lastError = NO_ERROR; - uint8_t inData; - uint8_t outData; - uint8_t nextOutData; + uint8_t inData = 0xFF; + uint8_t outData = 0xFF; + uint8_t nextOutData = 0xFF; int globalStateCounter = 0; // The counter for the total number of bytes sent int subStateCounter = 0; // The counter for the total number of bytes sent in this substate diff --git a/source/link_handler.cpp b/source/link_handler.cpp index d739129..21ad8fa 100644 --- a/source/link_handler.cpp +++ b/source/link_handler.cpp @@ -40,6 +40,12 @@ LinkSPI linkSPIInstance; LinkSPI *linkSPI = &linkSPIInstance; +#define INITIAL_LINK_TIMER (0x4000 / 60) +#define DISCOVERY_TIMER_MIN 4 +#define DISCOVERY_TIMER_PHASE_MASK 0x0F +#define DISCOVERY_TIMEOUT_TRANSFERS 2048 +#define DISCOVERY_CONFIRM_TIMEOUT_TRANSFERS 180 + // Here's a compilation check to ensure that the size of these structs match our expectations. // Just update it if you changed the struct members. The data-generator process prints their actual sizes. static_assert(sizeof(struct GB_ROM) == 140); @@ -287,7 +293,22 @@ void LinkConnection::startConnection(LinkState startState) switch (startState) { case INITIAL_CONNECTION: - REG_TM3D = -0x4000 / 60; + // Start searching and make sure the first byte sent requests the external clock + irq_disable(II_TIMER3); + REG_TM3CNT = 0; + REG_IF = (1 << II_TIMER3); + linkSPI->activate(LinkSPI::Mode::MASTER_256KBPS); + + inData = 0xFF; + outData = 0x01; + nextOutData = 0x01; + globalStateCounter = 0; + subStateCounter = 0; + subStateChanged = false; + enterState = CLOCK_ACQUIRE; + exitState = CLOCK_ACQUIRE; + + REG_TM3D = -DISCOVERY_TIMER_MIN; REG_TM3CNT = TM_FREQ_1024 | TM_ENABLE; break; case PACKET_EXCHANGE: @@ -299,7 +320,10 @@ void LinkConnection::startConnection(LinkState startState) break; } - enterState = startState; + if (startState != INITIAL_CONNECTION) + { + enterState = startState; + } irq_enable(II_TIMER3); } @@ -420,15 +444,62 @@ void LinkConnection::handleStateLogic() switch (enterState) { case INITIAL_CONNECTION: - nextOutData = 0xFF; - exitState = CLOCK; + nextOutData = 0x01; + exitState = DISCOVERY_RESET; break; - case CLOCK: + case DISCOVERY_RESET: + // Reset and try a different timer phase + REG_TM3CNT = 0; + REG_IF = (1 << II_TIMER3); + linkSPI->activate(LinkSPI::Mode::MASTER_256KBPS); + outData = 0x01; + nextOutData = 0x01; + REG_TM3D = -(DISCOVERY_TIMER_MIN + + (globalStateCounter & DISCOVERY_TIMER_PHASE_MASK)); + REG_TM3CNT = TM_FREQ_1024 | TM_ENABLE; + exitState = CLOCK_ACQUIRE; + break; + + case CLOCK_ACQUIRE: + nextOutData = 0x01; + + if (inData == 0x02) + { + // Receiving 0x02 while sending 0x01 means the other Game Boy offered + // external-clock mode and should now have selected the GBA as master. + REG_TM3D = -INITIAL_LINK_TIMER; + exitState = CLOCK_CONFIRM; + } + else if (inData == 0xFE) + { + // Keep compatibility with an already-established connection where the + // role-selection byte was completed before discovery began. + REG_TM3D = -INITIAL_LINK_TIMER; + exitState = SAVE_SUCCESS; + nextOutData = 0x01; + } + else if (subStateCounter >= DISCOVERY_TIMEOUT_TRANSFERS) + { + exitState = DISCOVERY_RESET; + } + else + { + REG_TM3D = -(DISCOVERY_TIMER_MIN + + (subStateCounter & DISCOVERY_TIMER_PHASE_MASK)); + } + break; + + case CLOCK_CONFIRM: if (inData == 0xFE) { exitState = SAVE_SUCCESS; - nextOutData = 0x00; + nextOutData = 0x01; + } + else if (subStateCounter >= DISCOVERY_CONFIRM_TIMEOUT_TRANSFERS) + { + exitState = DISCOVERY_RESET; + nextOutData = 0x01; } else { @@ -437,12 +508,17 @@ void LinkConnection::handleStateLogic() break; case SAVE_SUCCESS: - if (inData == 0x60 || inData == 0x61) + nextOutData = 0x01; + + if (inData == 0x02) + { + // Don't exit if we already set the GB as the follower + } + else if (inData == 0x60 || inData == 0x61) { exitState = MENU_OPEN; nextOutData = inData; } - // nextOutData defaults to 0x00 break; case MENU_OPEN: From 52d63bd77e9f248bddb05647659204b009993894 Mon Sep 17 00:00:00 2001 From: GearsProgress Date: Sat, 29 Aug 2026 13:53:26 -0400 Subject: [PATCH 4/4] Updating PCCS --- PCCS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PCCS b/PCCS index 9002c56..5865d76 160000 --- a/PCCS +++ b/PCCS @@ -1 +1 @@ -Subproject commit 9002c562363b6525a156074e535a5c623522bd33 +Subproject commit 5865d76d33a66403bf456e06ff5557112b47aeaa