mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-28 06:49:29 -04:00
41935aa2a2
Second batch of the Gen 3 review work: the review lanes closed their queues and the test gate grew with them. Review census: 139 routed findings -- 118 fixed, 14 invalid (the report had Gen 4+ semantics in more than one place), 6 struck as stale after re-verification, 1 re-routed. Every fix carries its own pret citation in docs/game3/review-v3-triage.md; the E10 opcode closure is itemised in docs/game3/e10-opcode-spec.md (18 ops wired, 2 reclassified to the seam class). Representative ROM-grounded changes: - The POKéMON start-menu entry is now gated on FLAG_SYS_POKEMON_GET the way retail does it (pokefirered/src/start_menu.c:217-218, flag 0x828). - Money ops read their amount raw and gate the change on the disable byte (pokefirered/src/scrcmd.c:1798-1830, pokefirered/asm/macros/event.inc:1166-1186); random and the warp family VarGet theirs (pokefirered/src/scrcmd.c:455-461, :719-731). - The HM table matches FRLG: there is no Whirlpool HM (pokefirered/include/constants/items.h:411-418). - The day-care party-full guard follows src/daycare.c:525, :1081. - Knock Off keeps its battle-scoped send-out mask (pokefirered/src/battle_script_commands.c:2730-2752, :4489), carried from the first batch. Structural work: the I6/I9/J1 architecture items landed as seams (profile selector, capability flags, font provider, virtual-object layer), the adopted footprint register keeps a KEEP verdict, the quantizer target is met, and the 30 drain items plus carves 1-4 are folded in. Tests: T6 now runs 282 top-level suites (273 + 9 new), the re-sweep ends at 267 pass / 0 fail, the engine tier is 634 suites, modkit 37, and the full gate ran green twice with T3 active on an imported Red cache. Documented skips are the lua5.4 oversize-save oracle where lua5.4 is absent and the config-partials listed in docs/game3/game3-artifact-conversions-v3.md. Docs shipped: review-v3-triage.md, e10-opcode-spec.md, rse-seams.md, game3-suite-sweep-v113.md, game3-artifact-conversions-v3.md, test-baseline-v3.md (plus the first-batch docs already on the branch).
102 lines
4.7 KiB
Lua
102 lines
4.7 KiB
Lua
-- Sections 5.5/5.6 of docs/game3/e10-opcode-spec.md: the help MESSAGE window
|
|
-- behind `loadhelp` / `unloadhelp`. Unwired (the dispatch cases are the
|
|
-- Finisher's), so this suite pins the contract they will call: open/close,
|
|
-- pret's idempotency, the window geometry, and that resolution of the opcode's
|
|
-- word argument is deliberately NOT this module's job.
|
|
-- luajit tests/engine/game3_help_window_test.lua
|
|
|
|
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
|
|
local T = require("tests.harness")
|
|
local check, eq = T.check, T.eq
|
|
|
|
love = love or require("tests.love_stub")
|
|
|
|
local Display = require("src.core.game3.display")
|
|
local HelpWindow = require("src.ui.game3.help_window")
|
|
|
|
HelpWindow.reset()
|
|
|
|
-- ------------------------------------------------------------ module boundary
|
|
|
|
check(package.loaded["src.ui.game3.help_system"] == nil,
|
|
"help_window does not load the L/R Help browser (help_system.lua)")
|
|
|
|
-- -------------------------------------------------------- geometry (pret-anchored)
|
|
|
|
local o = HelpWindow.OUTER
|
|
eq(o.left, 0, "outer left is 0")
|
|
eq(o.top, 15, "outer top is 15 (pret src/help_message.c:13-19)")
|
|
eq(o.width, 30, "outer width is 30 tiles")
|
|
eq(o.height, 5, "outer height is 5 tiles")
|
|
eq(o.paletteNum, 15, "outer palette is 15")
|
|
|
|
local c = HelpWindow.CONTENT
|
|
eq(c.left - 1, o.left, "content is the outer rect inset one tile left")
|
|
eq(c.top - 1, o.top, "content is the outer rect inset one tile top")
|
|
eq(c.width + 2, o.width, "frame width = content + the two border tiles")
|
|
eq(c.height + 2, o.height, "frame height = content + the two border tiles")
|
|
|
|
-- The engine canvas is the GBA grid, so pret's rect maps 1:1.
|
|
eq(Display.COLS, o.width, "engine grid is 30 tiles wide (display.lua:10)")
|
|
eq(Display.ROWS, o.top + o.height, "engine grid is 20 rows: the window sits on the bottom 5")
|
|
eq(Display.TILE, 8, "engine tile is 8px")
|
|
|
|
-- pret PrintHelpMessageText text placement (src/help_message.c:95-98).
|
|
eq(HelpWindow.TEXT_OFFSET.x, 2, "text x offset is pret's 2px")
|
|
eq(HelpWindow.TEXT_OFFSET.y, 5, "text y offset is pret's 5px")
|
|
check(c.width * 8 - HelpWindow.TEXT_OFFSET.x * 2 > 0,
|
|
"the printable width stays positive")
|
|
check(c.top * 8 + HelpWindow.TEXT_OFFSET.y < (o.top + o.height) * 8,
|
|
"the text baseline lands inside the outer window")
|
|
|
|
-- ---------------------------------------------------------------- lifecycle
|
|
|
|
check(HelpWindow.isOpen() == false, "starts closed")
|
|
eq(HelpWindow.getText(), "", "starts with no text")
|
|
check(HelpWindow.draw() == false, "draw with nothing open is a no-op")
|
|
|
|
check(HelpWindow.show("MOVE ID: STRENGTH") == true, "show opens the window")
|
|
check(HelpWindow.isOpen() == true, "isOpen reads back open")
|
|
eq(HelpWindow.getText(), "MOVE ID: STRENGTH", "getText reads back the text")
|
|
check(HelpWindow.draw() == true, "draw renders while open (headless)")
|
|
|
|
-- pret PrintTextOnHelpMessageWindow takes an already-resolved pointer; the
|
|
-- engine handler resolves the opcode's word with resolve_text (ops_a.lua:36-45)
|
|
-- and passes a string. This module must not interpret pointers itself.
|
|
check(HelpWindow.show("0x08012345") == true, "a pointer-looking string is accepted")
|
|
eq(HelpWindow.getText(), "0x08012345", "text is stored verbatim, never resolved here")
|
|
|
|
-- Re-showing replaces the content (pret's second DrawHelpMessageWindowWithText).
|
|
check(HelpWindow.show("BICYCLE") == true, "re-show is allowed")
|
|
eq(HelpWindow.getText(), "BICYCLE", "re-show replaces the text")
|
|
eq(HelpWindow.isOpen(), true, "still open after re-show")
|
|
|
|
-- Non-string input degrades to empty content rather than erroring (the handler
|
|
-- may pass nil when resolve_text misses; pret falls back to ctx->data[0]).
|
|
check(HelpWindow.show(nil) == true, "show(nil) still opens")
|
|
eq(HelpWindow.getText(), "", "show(nil) means empty text, not an error")
|
|
check(HelpWindow.show(123) == true, "show(number) still opens")
|
|
eq(HelpWindow.getText(), "", "non-string text degrades to empty")
|
|
|
|
-- ------------------------------------------------------------------- closing
|
|
|
|
check(HelpWindow.close() == true, "close hides the window")
|
|
check(HelpWindow.isOpen() == false, "closed reads back closed")
|
|
eq(HelpWindow.getText(), "", "close clears the text")
|
|
check(HelpWindow.draw() == false, "draw after close is a no-op")
|
|
|
|
check(HelpWindow.close() == true, "closing twice is safe (pret DestroyHelpMessageWindow_ is idempotent)")
|
|
|
|
check(HelpWindow.show("AGAIN") == true, "open → close → open works")
|
|
eq(HelpWindow.getText(), "AGAIN", "the reopened window carries its text")
|
|
check(HelpWindow.draw() == true, "draw works after reopen")
|
|
|
|
HelpWindow.reset()
|
|
check(HelpWindow.isOpen() == false, "reset closes the window")
|
|
eq(HelpWindow.getText(), "", "reset clears the text")
|
|
HelpWindow.reset()
|
|
check(HelpWindow.isOpen() == false, "reset is safe to repeat")
|
|
|
|
T.finish("game3_help_window_test")
|