diff --git a/src/import/gba/games/emerald.lua b/src/import/gba/games/emerald.lua index 6a46dc1c..07da0c1e 100644 --- a/src/import/gba/games/emerald.lua +++ b/src/import/gba/games/emerald.lua @@ -3,7 +3,7 @@ local VersionsRse = require("src.import.gba.versions_rse") local V = VersionsRse.new("emerald") local sym, count = V.sym, V.count -V.CACHE_VERSION = 12 +V.CACHE_VERSION = 13 V.NATIVE_VERSION = 2 V.OW_VERSION = 1 V.ANIM_VERSION = 1 diff --git a/src/import/gba/plans/rse/boot.lua b/src/import/gba/plans/rse/boot.lua index 9711f1f4..12b0375f 100644 --- a/src/import/gba/plans/rse/boot.lua +++ b/src/import/gba/plans/rse/boot.lua @@ -21,9 +21,10 @@ return { { name = R .. "extract_birch_rse", label = "Professor Birch" }, { name = R .. "extract_naming_rse", label = "Naming Screen" }, { name = R .. "extract_wallclock_rse", label = "Wall Clock" }, + { name = R .. "reset_rtc_extract", label = "Reset RTC" }, }, }, }, sequential = { "em_boot_intro", "em_boot_screens" }, - dirs = { "/intro/rse", "/intro/rse/scenery", "/intro/rse_extra", "/title", "/birch", "/naming", "/wallclock" }, + dirs = { "/intro/rse", "/intro/rse/scenery", "/intro/rse_extra", "/title", "/birch", "/naming", "/wallclock", "/reset_rtc" }, } diff --git a/src/import/gba/rse/reset_rtc_extract.lua b/src/import/gba/rse/reset_rtc_extract.lua new file mode 100644 index 00000000..9cd71ac5 --- /dev/null +++ b/src/import/gba/rse/reset_rtc_extract.lua @@ -0,0 +1,33 @@ +local K = require("src.import.gba.rse.boot_gfx") + +local M = {} + +M.SUB = "reset_rtc" + +local O = "reset_rtc_screen.o:" + +M.FILES = { "arrow.png" } +M.REQUIRED = K.required(M.SUB, M.FILES) + +function M.run(rom, cache, opts) + local c = K.context(rom, cache, opts, M.SUB) + + -- pokeemerald/src/reset_rtc_screen.c:179 + local gfx = c:raw(O .. "sArrowDown_Gfx") .. c:raw(O .. "sArrowRight_Gfx") + local pal = c:pal(O .. "sArrow_Pal", 4) + + -- pokeemerald/src/reset_rtc_screen.c:225 + local tpl = c:readTemplate(O .. "sSpriteTemplate_Arrow") + local arrow = c:spriteFrames("arrow", gfx, tpl, pal) + + return true, c:finish({ + screen = "reset_rtc", + sprites = { arrow = arrow }, + }) +end + +function M.ready(cache, cacheRoot) + return K.ready(M.SUB, cache, cacheRoot) +end + +return M diff --git a/src/ui/game3/rse/reset_rtc_screen.lua b/src/ui/game3/rse/reset_rtc_screen.lua index 5b3bac50..4841f71e 100644 --- a/src/ui/game3/rse/reset_rtc_screen.lua +++ b/src/ui/game3/rse/reset_rtc_screen.lua @@ -27,6 +27,22 @@ local WIN_INPUT = { left = 4, top = 9, width = 21, height = 2 } -- pokeemerald/src/reset_rtc_screen.c:239 local CURSOR_X = { [SEL.DAYS] = 53, [SEL.HOURS] = 86, [SEL.MINS] = 101, [SEL.SECS] = 116, [SEL.CONFIRM] = 153 } +-- pokeemerald/src/reset_rtc_screen.c:218 +local ARROW = { DOWN = 1, UP = 2, RIGHT = 3 } + +-- pokeemerald/src/reset_rtc_screen.c:194 +local function drawArrow(anim, cx, cy) + local man = Kit.manifest("reset_rtc") + local spr = man and man.sprites and man.sprites.arrow + local img = spr and Kit.image(spr.png) + local cmd = spr and spr.anims[anim] and spr.anims[anim][1] + if not (img and cmd) then return end + local w, h = spr.w, spr.h + local quad = love.graphics.newQuad(0, cmd.frame * h, w, h, img:getDimensions()) + love.graphics.setColor(1, 1, 1, 1) + love.graphics.draw(img, quad, cx - w / 2, cy - h / 2 + (cmd.vFlip and h or 0), 0, 1, cmd.vFlip and -1 or 1) +end + -- pokeemerald/src/event_data.c:156 function ResetRtc.canReset(store, version) local C = Constants.of(version or "emerald") @@ -236,10 +252,10 @@ function ResetRtc:draw() local cx = CURSOR_X[self.selection] if cx then if self.selection == SEL.CONFIRM then - FrlgFont.draw(RomText.plain("gText_SelectorArrow3"), cx - 4, 80 - 8, { colors = colors }) + drawArrow(ARROW.RIGHT, cx, 80) else - Kit.glyphArrow("up", cx, 68, 0) - Kit.glyphArrow("down", cx, 92, 0) + drawArrow(ARROW.UP, cx, 68) + drawArrow(ARROW.DOWN, cx, 92) end end end diff --git a/tests/drivers/em_reset_rtc_arrows.lua b/tests/drivers/em_reset_rtc_arrows.lua new file mode 100644 index 00000000..0856681b --- /dev/null +++ b/tests/drivers/em_reset_rtc_arrows.lua @@ -0,0 +1,68 @@ +local U = require("tests.drivers.util") +local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/em_reset_rtc_arrows" + +local failures = 0 +local function check(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then failures = failures + 1 end + return ok +end + +local function finish() + print((failures == 0 and "PASS" or "FAIL") .. " em_reset_rtc_arrows failures=" .. failures) + love.event.quit(failures == 0 and 0 or 1) + U.wait(10) +end + +return function(game) + for _ = 1, 900 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + if not check(game.boot ~= nil, "boot reached") then return finish() end + + local Kit = require("src.ui.game3.rse.scene_kit") + local fakeSave = { + engine = "game3", + flags = {}, + vars = {}, + lastBerryTreeUpdate = { days = 3, hours = 12, minutes = 30, seconds = 0 }, + } + Kit.loadRawSave = function() return fakeSave end + + local Boot = require("src.ui.game3.boot") + local BootModules = require("src.ui.game3.boot_modules") + BootModules.startCombo(Boot, game.boot, "resetRtc") + U.wait(60) + local screen = game.boot.custom and game.boot.custom.combo + if not check(screen ~= nil and screen.state ~= nil, "reset rtc screen created (" .. tostring(screen and screen.state) .. ")") then + return finish() + end + + for _ = 1, 400 do + if screen.state == "prompt" then break end + U.wait(1) + end + check(screen.state == "prompt", "reached the confirm prompt (" .. tostring(screen.state) .. ")") + U.still(game, DIR .. "/01_prompt.png") + + U.tap(game, "a") + for _ = 1, 200 do + if screen.state == "set_time" then break end + U.wait(1) + end + check(screen.state == "set_time" and screen.input ~= nil, "time input open (" .. tostring(screen.state) .. ")") + U.wait(10) + U.still(game, DIR .. "/02_hours_up_down_arrows.png") + + local seen = { screen.selection } + for _ = 1, 6 do + U.tap(game, "right") + U.wait(6) + seen[#seen + 1] = screen.selection + U.still(game, DIR .. "/03_selection_" .. tostring(screen.selection) .. ".png") + end + print("[driver] selections: " .. table.concat(seen, ",")) + check(#seen >= 2, "cursor moved across fields") + return finish() +end