Created
January 30, 2026 11:54
-
-
Save FedericoPonzi/b8c20391160d0aafc7b93a37704847a9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- mGBA Golden Sun Password Entry Script | |
| -- Position cursor on 'A' before loading this script | |
| console:log("Script loaded!") | |
| -------------------------------------------------------------------------------- | |
| -- CONFIGURATION | |
| -------------------------------------------------------------------------------- | |
| local INITIAL_DELAY = 60 -- Frames to wait before starting | |
| local PRESS_DELAY = 1 -- Frames between button presses | |
| -- GBA button bitmasks | |
| local BTN = { | |
| A = 1, | |
| RIGHT = 16, | |
| LEFT = 32, | |
| UP = 64, | |
| DOWN = 128 | |
| } | |
| -------------------------------------------------------------------------------- | |
| -- KEYBOARD LAYOUT (matches Golden Sun password entry screen) | |
| -------------------------------------------------------------------------------- | |
| local keyboard = { | |
| {"A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","Space"}, | |
| {"S","T","U","V","W","X","Y","Z","2","3","4","5","6","7","8","9","Return"}, | |
| {"a","b","c","d","e","f","g","h","i","j","k","m","n","p","q","r"}, | |
| {"s","t","u","v","w","x","y","z","!","?","#","&","$","%","+","=","Finish"} | |
| } | |
| local function findChar(char) | |
| if char == "\001" then char = "Finish" end | |
| for y, row in ipairs(keyboard) do | |
| for x, val in ipairs(row) do | |
| if val == char then return x, y end | |
| end | |
| end | |
| return nil, nil | |
| end | |
| -------------------------------------------------------------------------------- | |
| -- PASSWORD CODES | |
| -------------------------------------------------------------------------------- | |
| local codes = | |
| -- Page 1 | |
| "wXCMAJGzWW" .. "38yJk$nB8&" .. "uWxxRrN62v" .. "3P62wGHVfJ" .. "2PJ#RRFAUB" .. | |
| -- Page 2 | |
| "=r9bUcHms3" .. "e62pgx%%vU" .. "J3e%S7KFP=" .. "mmX3kPzWbN" .. "jwxHPXQw&P" .. | |
| -- Page 3 | |
| "9Wb7=Qa597" .. "VKkLAJQ6Az" .. "+pcub%Y4qa" .. "?65hCuXG#x" .. "&8+MLys=nC" .. | |
| -- Page 4 | |
| "b6ZEt$gqp&" .. "V7buZbfy5Y" .. "gk&akq=eqj" .. "vEjvzJpz&y" .. "Pu$ATyAEXS" .. | |
| -- Page 5 | |
| "&FK4=KP8D+" .. "QUvJUYhNYb" .. "5nT59sX9d8" .. "x4ei?8in%!" .. "dptChG7gmD" .. | |
| -- Page 6 | |
| "y#Ms#%vwuS" .. | |
| -- End | |
| "\001" -- Finish marker | |
| -------------------------------------------------------------------------------- | |
| -- STATE MACHINE | |
| -------------------------------------------------------------------------------- | |
| local state = { | |
| curX = 1, -- Current cursor X position | |
| curY = 1, -- Current cursor Y position | |
| charIndex = 1, -- Current character index in codes | |
| moveQueue = {}, -- Queue of buttons to press | |
| pressing = false, -- Currently pressing a button? | |
| waitFrames = INITIAL_DELAY, | |
| done = false, | |
| callbackId = nil | |
| } | |
| local function buildMoveQueue() | |
| if state.charIndex > #codes then | |
| state.done = true | |
| console:log("All done! (" .. #codes - 1 .. " characters typed)") | |
| return | |
| end | |
| local char = codes:sub(state.charIndex, state.charIndex) | |
| local tx, ty = findChar(char) | |
| if not tx then | |
| console:log("ERROR: Character not found: " .. char) | |
| state.charIndex = state.charIndex + 1 | |
| return | |
| end | |
| -- Progress logging | |
| if state.charIndex % 50 == 1 then | |
| local page = math.floor((state.charIndex - 1) / 50) + 1 | |
| console:log("Page " .. page .. " - char " .. state.charIndex .. "/" .. #codes) | |
| end | |
| -- Queue horizontal moves | |
| while state.curX < tx do | |
| state.moveQueue[#state.moveQueue + 1] = BTN.RIGHT | |
| state.curX = state.curX + 1 | |
| end | |
| while state.curX > tx do | |
| state.moveQueue[#state.moveQueue + 1] = BTN.LEFT | |
| state.curX = state.curX - 1 | |
| end | |
| -- Queue vertical moves | |
| while state.curY < ty do | |
| state.moveQueue[#state.moveQueue + 1] = BTN.DOWN | |
| state.curY = state.curY + 1 | |
| end | |
| while state.curY > ty do | |
| state.moveQueue[#state.moveQueue + 1] = BTN.UP | |
| state.curY = state.curY - 1 | |
| end | |
| -- Queue A press to select character | |
| state.moveQueue[#state.moveQueue + 1] = BTN.A | |
| state.charIndex = state.charIndex + 1 | |
| end | |
| -------------------------------------------------------------------------------- | |
| -- MAIN CALLBACK | |
| -------------------------------------------------------------------------------- | |
| local function onKeysRead() | |
| -- Cleanup when done | |
| if state.done then | |
| if state.callbackId then | |
| callbacks:remove(state.callbackId) | |
| state.callbackId = nil | |
| console:log("Callback removed, manual input restored!") | |
| end | |
| return | |
| end | |
| -- Wait if needed | |
| if state.waitFrames > 0 then | |
| state.waitFrames = state.waitFrames - 1 | |
| emu:setKeys(0) | |
| return | |
| end | |
| -- Build moves for next character if queue empty | |
| if #state.moveQueue == 0 then | |
| buildMoveQueue() | |
| if #state.moveQueue == 0 and not state.done then | |
| return | |
| end | |
| end | |
| -- Process queue: alternate press/release | |
| if #state.moveQueue > 0 then | |
| if not state.pressing then | |
| emu:setKeys(state.moveQueue[1]) | |
| state.pressing = true | |
| else | |
| emu:setKeys(0) | |
| table.remove(state.moveQueue, 1) | |
| state.pressing = false | |
| state.waitFrames = PRESS_DELAY | |
| end | |
| end | |
| end | |
| -------------------------------------------------------------------------------- | |
| -- START | |
| -------------------------------------------------------------------------------- | |
| state.callbackId = callbacks:add("keysRead", onKeysRead) | |
| console:log("Starting in " .. INITIAL_DELAY .. " frames... (" .. #codes .. " chars to type)") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment