From 72355fa4cf952ce0f2d76a17956d0d85d8d0e83f Mon Sep 17 00:00:00 2001 From: TimoVM Date: Tue, 1 Sep 2026 05:10:53 +0200 Subject: [PATCH 1/4] include/link_handler.h added version definitions and checksums for English versions of Crystal (v0, v1, vA) --- include/link_handler.h | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) 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}, From ab69cb7ce03c440db76cc7ae7b6929bfb4cf675d Mon Sep 17 00:00:00 2001 From: GearsProgress Date: Tue, 1 Sep 2026 11:17:39 -0400 Subject: [PATCH 2/4] Fixing link cable timeout --- source/link_handler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/link_handler.cpp b/source/link_handler.cpp index 21ad8fa..5d933af 100644 --- a/source/link_handler.cpp +++ b/source/link_handler.cpp @@ -309,12 +309,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 +457,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; From daeaa4d59cc81fddf54bedb2f064eb089210314f Mon Sep 17 00:00:00 2001 From: GearsProgress Date: Tue, 1 Sep 2026 11:44:49 -0400 Subject: [PATCH 3/4] Deleting link_helper.lua --- tools/link_helper.lua | 580 ------------------------------------------ 1 file changed, 580 deletions(-) delete mode 100644 tools/link_helper.lua 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 From 9cd6dc30c378e70377b2b5dd31a0767d6e9987b1 Mon Sep 17 00:00:00 2001 From: GearsProgress Date: Tue, 1 Sep 2026 18:19:29 -0400 Subject: [PATCH 4/4] Updating box graphics and adding Crystal revisions --- PCCS | 2 +- container/GB_Payloads.containerdef | 2 + graphics/{boxBG.grit => boxBG_Blue.grit} | 2 +- graphics/boxBG_Blue.png | Bin 0 -> 1795 bytes graphics/boxBG_Crystal.grit | 6 ++ graphics/boxBG_Crystal.png | Bin 0 -> 2288 bytes graphics/boxBG_Gold.grit | 6 ++ graphics/boxBG_Gold.png | Bin 0 -> 2504 bytes graphics/boxBG_Green.grit | 6 ++ graphics/boxBG_Green.png | Bin 0 -> 1994 bytes graphics/boxBG_Red.grit | 6 ++ graphics/boxBG_Red.png | Bin 0 -> 2338 bytes graphics/boxBG_Silver.grit | 6 ++ graphics/boxBG_Silver.png | Bin 0 -> 2115 bytes graphics/boxBG_Yellow.grit | 6 ++ graphics/boxBG_Yellow.png | Bin 0 -> 1963 bytes .../oldboxBG.png} | Bin include/box_menu.h | 2 +- include/dbg/debug_mode.h | 2 +- include/sprite_data.h | 22 +++-- source/box_menu.cpp | 6 +- source/global_frame_controller.cpp | 2 +- source/link_handler.cpp | 5 +- source/main.cpp | 12 +-- source/script_array.cpp | 12 +-- source/sprite_data.cpp | 83 ++++++++++++++---- source/text_engine.cpp | 8 +- 27 files changed, 149 insertions(+), 47 deletions(-) rename graphics/{boxBG.grit => boxBG_Blue.grit} (66%) create mode 100644 graphics/boxBG_Blue.png create mode 100644 graphics/boxBG_Crystal.grit create mode 100644 graphics/boxBG_Crystal.png create mode 100644 graphics/boxBG_Gold.grit create mode 100644 graphics/boxBG_Gold.png create mode 100644 graphics/boxBG_Green.grit create mode 100644 graphics/boxBG_Green.png create mode 100644 graphics/boxBG_Red.grit create mode 100644 graphics/boxBG_Red.png create mode 100644 graphics/boxBG_Silver.grit create mode 100644 graphics/boxBG_Silver.png create mode 100644 graphics/boxBG_Yellow.grit create mode 100644 graphics/boxBG_Yellow.png rename graphics/{boxBG.png => unused graphics/oldboxBG.png} (100%) diff --git a/PCCS b/PCCS index 5865d76..cf28a92 160000 --- a/PCCS +++ b/PCCS @@ -1 +1 @@ -Subproject commit 5865d76d33a66403bf456e06ff5557112b47aeaa +Subproject commit cf28a9237f4d140e73f530aa6dee6c74a12ad0bf 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 0000000000000000000000000000000000000000..642cf84e14e554a1b728dfb842fb2174b7ef8425 GIT binary patch literal 1795 zcmaJ?X*8P&7Y<`dwW-8T#u8MNG6thUV|m3ATFq!n(Zv}{5c|?9RYY1#YiUg_O=7&Y zwKYoZp{-$5T0~Q7X(*~1sV&q_$>clp|>#{IPprXS3f^o$d0+Hy!<805y(H7}H2Wp>FN}i-Y&aOSDH0_??XFq^{5S{u8 z(b5l?|Jl_kN2ZN>>Phsc16?iH=npI7& zYcopDjrp*E|T4ZEYaXXvK|x=H2)&Gzg2JvdBEi<#x@(%$YH zZS}voYz*c^>=3_umJQhvwjamF`Id25kZ)+g3Q<3`dJ&ygnIzagy;7QT55JisDc%2p zz_^+_7z9HMfvL3^_B-I2(KFGCLKEfXCBs&su zoMHx`?oL3U1}Bdc6{wMq!o3PbNpeR$B>_^h#zhUN!RfjNLi(WUKp@3kG*8Puh3)m| zcyPVoNYGl4DWLz`Mpvn9;&2K(Q)8u2mC}?SR~AWBg@&3GWh-zT*DbJ3h;UtcaroCn zI-1uci=+&@1WepE7@_VHwx3;r-rrQ_+fOvoV7o6n3vN1?C+(JMT! zGhf)*v%}@C99ZkJBgHI%q(pqA1CWTV(;pYacD4+FDu*5}ZHlJzg^=0OgQ@1)+I*D+ z^zAcPb|VozmJac=fxq|JYBpG`b#Xyg=~KWr`Qk2L44@BG_N1EJexR>CE~f|7v%s@X zaIb?ML$ckP#`Lw(s5PJjO zeC9EpD-OOQSY^rRLKms#Sl7**z4sPyj%;N7f;z=e_3XxhbJuN7+8wH(6ZxCymnsDaI-#j$k+!ejq^K=anq#pD520CEwS;hn&V3YN-b+NTQ7ZvgC6$K%cVJ&l_AB9)ek)*^^UQF8c8x2WZ6$IW6>R*v69B6H|LeSc_N z$Yi%kCM9mIDE^c!LNQ#6TJ$Ht3`8e#GNFIsqw zsxyJV7J~CG9)}vdjm=u9N6jM-*w5G5242%qjKul$j)4QK9C8$+w-+mv{{+XKf89BZ zIN^&0#om134vki13CHiUDh3tp3W6`OoWZMS&y3*NfKWZ6hUuNkaCs!F-UtdCv8iTa zX8twGuHq=#kHt%&OD;L0Qd+^F2^AJIgLCoskwDM=?#rjjha7%T-#c=nZS(boh4yK| z3p7?t_nwnh3@6M*TEv-Avf>a(GsBl5RQ@FYyAfAlhaP&e1~0*-vwbponlbBpv;7PY z{*QQRG3S*3ZPx$C$Nvk}>c&Kqm_^;+4*=a+qs3%y5imC1XBeT4i>+I+T4(u7m_(d` c_R9!<7>)QFr;^N+6FxTx-rg1W6!0Pc1Ir;&Qvd(} literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..60799de7737f16c47be3e7e475e53449c5f456b2 GIT binary patch literal 2288 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 Mj=R~_;R0^`4Y?+|>Hq)$ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..5ae61f4a12bea97d25c36931a5ce5b4a987d9c2b GIT binary patch literal 2338 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..860a1245f2923aa5f16326880fe4383b8002b907 GIT binary patch literal 2115 zcmaKudpHw}7sqGXtZ6Q9E@9OuGPxwHB`JnNj5K%VUX$Cfxt9CbOjMJ5Y)Vu_^-4vP z;GM*!APJuuZ)wDY)%InLbK3DuMg4ig}j z)$w6ccgC$7DyTxcZ{x~UQPXA1>dRwVigwp3Nq)LauqoW9ZSU(qBP~4CY#=wITCbjw zKbRlgIJ$V{6jk-(@Mox)Di9-j&WM13LSUvM ztVDGLN(z($E=}MX$w(>w9@3t`b=N*NaSA<<-IbMY!972aHr%P7i91SZsRETC2TL*! zz5cQ3StEt>ni|L2r$O=+)a&tNZQg6UxjVUZEp>Ustvz3xOn^pzrA+Dh5!go$mgQ`2 z9O``MsTa8-k$H0U^M^qNMZntpZus!R2;DHxX4+9(qazS57u`S7^tNPOY_b}Rv#NPg zc$sLK+VMq&?hk{{nmnn=pSfiGeC!RBXhp~bWla=3px?wMYKyreHyrd91Dcyc6CEvp z7)Eo*k=PBbpz^pkg~7f&)W9Hl(BGGk9`z0;=p+({=0f~3c7B>^ePwOSLYAHlwBitn zm3!OmYurU;3)GPv#m+UNX_7EyRN3f6@CX!{`?U@9 z0^S#@2bBlQ{=N`HZP7dxJxo2mAM`jqVY?JW>#50jT|ra#!;uhI%@N|V5{3@rHqFqM z-S7o_0h#>W7`n;{doEnOeXi^mAaC>Hwv?RHhj85NW3hSfd-~Qrj^$j0Xk8;d>*QYE zzfQGV?(!u|MnpK{0+v~niOG5L{>aN_{RJ(^Jvc&pR2Ke*+F6=)@R2DpSqVoNF`hkYg&It^q%ttqeheIZAL@$IyCnYsfqgGGE>ox3`>6_60?q|jVr4Y;ep z?Lh4nn8IL2o3Z$npsQ~FwY*WwyAnM$?|)v)8`Zy(EJsiM%N&6^S4DPTcID`qV3xMC zy{dlHy`2~opbVt+&97Mj8E(`^ywP4AbWr9ElaUh~aU20GpQ3&G*en>JAV7KWlu@#z zC#C7(-JkqXJp;4}C8jdUy-Jv?+OhlOT2+)#`>`ksd86o_`mN&YhTdTUj*?V?+|HvJ zbm?{DM-5Hhan0K>J6~r!uf5s+4duoA8GaCmIloBmGie)|fIzJI%tLagG{?gY1W7v& zB48>d59YUIkb*n#3{6rLaE)-KFo7i2Sp>sK#zkK!Ka!#**0j`R9srl=O$v)X86K+- zLZGy!bEkIo6{T`_bcB~1+C=A6oN3?ED|j+LTldZ4GjarF zeP-f|pLf+$P`&YLtU+1-2yrYjWUW9cTMu=QfO43w6?f$5pd|*K9*0(ZZCt7H23=pe ztHw4f6^`kSGl_naVUbtDz5My?^Z-8Dy)!IbX8WaXrIBx~)`wf}d-(AIp()%2eGghf zr&4HJGNi#j#={!~BNrVU#tzRk3h%IYs)@*B_ZCA8 zzxOdLkDvNkVa|UO(kLHgUvB7ODJ{e};d-FEHGP1CF z9{dD%(lb6M%GVkuFkP5-=xD(gV>zt7m?vq!%uJIN9f2&>9ek;hHt_(sHihd=|I@~2 zoPD9jrz}|GzWtXwX=g%CMFhQh^Vidc@kxZ>vV1C(1E33*Ku0?V z79KG%Jj+j|elM{Py3!IN3biV@fi2F=oqPPed`i_T&g9(43&OnSrv1K{;!1=8tE z0+5y8RFQlEwB_iDJ2;w$q)KFJB{cr!>jlnPK=(`%0(FX;jurXG|Kr?ZzP(!cV;aZ` z@LSS;j2>Q{%P&9cl4(KE(8}g|1eXSqbp=w_uTA|2Ti#K!5%z6KrKkmKHdA{e~bD!s)`~76PIN8IXNT`U2 z2n_FF<0f3c2uCSIR5-tCq#B8cfMfACRvrlt_{A0(%AU$y#NcYb{Ln0o)fZ$PliGar z{XCr1a0Wx>X*(BcRYqlgqh3?|Ak7wu*Y6!8)7DEtjlQ*m04T9 zY}9O;LJi{{OsyrGJN`T{HRZR3dcE87`uggC!Ju@DX}E~TmtnR=V9X@wr}1-PM?1U& z=UUGDwe9pcG2~QzHBK<>2{V7e>#?WV%V2CJ&N=ch=|E{-i#B>SaJ&qYal$?p|!+8OP4^?iNE3)$EnQK*gmlD5zjz4ayz z>)~V^Yf`hAcV5v>DPXk5#Y~FN7$~X7SZ{=!Q*rWdXeHhC&S%smt_~dgBs<=fwnQpg z=OB(R%7_P%;xm-x`cRh*U~pfkgTJJQuvECOI0gJ!lx3@SKI+s_ZVs&}yj3e%#+RJP zJVU(O-@kD#%1s@@S4mwoxn~^oVfxei{kiy8myq;yx45<9)%)u~S5;XID!8i+-?zPe z>SCQQa-{VFoSvSNsk%^Xz%5ueAlxNYMRfv9AT)>lJ zBej>PUP7Kh4EJmo!L#>~XXM3n1ybca*YXmBQ1Ee0Dd|YO zPVKD?;StnKYeJ`|9jC|}KIT7x<5@a~W%mU*4PUO8RJU%nO4Gy-ttUE;O$cIgAt!

%D#A1l6Nls*}DguULd zUeAWnCCb0(K_*p#H|@A8a*-4Q^NOpEpA3>qj17H&;E=y%1qA^H@)i{)w}CIBY~l~z zRduH;WszC-B&d6xa;32UW*6%yft!RnnM&CvvkDkQ*D$1nSUnFGTO#oxlR7O5%dKu^ zDozvF+dxfOse|9fMORZwlQ-{R-U})BonsQ|`o1mptz-ZEY`bU0W1Q)K6)FoP81-Lo z*l4(u*Ro!I1zn#NBn0N`lh|z%Dw2$rW-97n@PH((`(j14Xz03y(z-_g=u|3)K5$hb zq2EXPmGE~)ugwf^E#~)JS$FpvfQlP1zqfrfdPv~#`(^j$xDw@}vr+B4d6AC>baycX z@9~EXBwG#?n@23ETo}`}50&(LKA{#;me66Ei7t9bgVJbGO7E*uZt6|rv8|ZuknaUU z4^xu&Ixf~K$wLDx!kl-Vc>|-wv*Wvb+NhpOJBN4Na9eS2cq_F0PTMQ7QAeP2M?f&w z{O$^my8*BPwnYHyK7&WNim(lg1&)NP;Dy{`+!w!EZuOtUj;tQa9wSmi=L2 z7#(4=dq7zJHs>)7BuKvd1O6s(@^oU>PQ;6BOw%&BVB|@ee#Ze+2|-6#RW>t8LA&r{ zL(3xwv&QPx8w{8v?v~m(PaiA)!tO~~;VQ$YqiZ7@h&ArVysFj14(OP;cKw-<>uC?x zqI}gIgq%S4%*DW$F1{OneomW${WUn^Xf-PFF%Ill*ozst8B;kex1bGy{VTGbhSFBd zQ2xun|MqrBav_Oglt?*x@!88VQe5w4ozDzY>vYeGvI~$;`kVz`;#y11&n`?320B^D zQ5cxcq-fG)ynLyXXbs>DmZPn``J_tbz>$@na%2Xm<}Yfz3FZA!GTo=4uBwBsI>~`f z?(f_)