mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-10-09 01:59:15 -04:00
99 lines
4.1 KiB
Lua
99 lines
4.1 KiB
Lua
-- The caller-ID box an incoming phone call puts across the top of the screen:
|
|
-- Phone_TextboxWithName (pokegold engine/phone/phone.asm:582), which is
|
|
--
|
|
-- Phone_TextboxWithName:
|
|
-- push bc
|
|
-- call Phone_CallerTextbox
|
|
-- hlcoord 1, 1
|
|
-- ld [hl], '☎'
|
|
-- inc hl
|
|
-- inc hl
|
|
-- ld d, h
|
|
-- ld e, l
|
|
-- pop bc
|
|
-- call GetCallerClassAndName
|
|
-- ret
|
|
--
|
|
-- Phone_CallerTextbox:
|
|
-- hlcoord 0, 0
|
|
-- ld b, 2
|
|
-- ld c, SCREEN_WIDTH - 2
|
|
-- call Textbox
|
|
-- ret
|
|
--
|
|
-- so the box is the top four rows of the screen (b/c are INTERIOR rows and
|
|
-- columns, hence 20x4 on screen), the phone icon sits at (1,1), and
|
|
-- GetCallerClassAndName places the caller's name from (3,1) -- hl after the
|
|
-- two `inc hl` -- with a ':' written straight after it. A trainer contact
|
|
-- then gets its class name a further `SCREEN_WIDTH + 3` on, which is (6,2);
|
|
-- a non-trainer (Mom, ELM, the wrong number) stops at the colon and has no
|
|
-- second line at all (:635-666).
|
|
--
|
|
-- WHEN IT IS UP. RingTwice_StartCall (:458-469) flashes the box on and off
|
|
-- against Phone_Wait20Frames while SFX_CALL plays, and nothing ever erases it
|
|
-- afterwards: it was written straight into wTilemap rather than through a
|
|
-- window, so CloseText restores it along with everything else under the
|
|
-- speech box and it survives until the overworld redraws its tilemap at the
|
|
-- end of the call. This port has no twenty-frame flash to hang the middle
|
|
-- beats on (src/core/gen2/PhoneRing.lua explains why: its text box holds for
|
|
-- A where the cart's PrintText returns), so the box goes UP with the ring and
|
|
-- stays for the whole call, which is the state the player actually reads.
|
|
--
|
|
-- A state, not a widget: it rides src/core/StateStack.lua UNDER the call's
|
|
-- text pages, so those draw over it exactly as the cart's speech box draws
|
|
-- over the tilemap. Deliberately no `update` -- src/core/Game2.lua's fixed
|
|
-- step hands the tick to the TOP state and returns, so an update here would
|
|
-- stop the world (and with it the script VM that is running the call) the
|
|
-- moment the last text page popped.
|
|
--
|
|
-- Pushed and popped by the two callasm handlers in src/script/gen2/CallAsm.lua
|
|
-- that src/core/gen2/PhoneRing.lua's rows name.
|
|
|
|
local Chrome = require("src.ui.gen2.Chrome")
|
|
local PhoneRing = require("src.core.gen2.PhoneRing")
|
|
|
|
local CallerBox = {}
|
|
CallerBox.__index = CallerBox
|
|
|
|
-- Phone_CallerTextbox's own coordinates, kept as names so the two draw calls
|
|
-- below read like the ASM they came from.
|
|
local BOX_X, BOX_Y = 0, 0
|
|
local BOX_INTERIOR_W, BOX_INTERIOR_H = 18, 2
|
|
local ICON_X, ICON_Y = 1, 1
|
|
local NAME_X, NAME_Y = 3, 1
|
|
local CLASS_X, CLASS_Y = 6, 2
|
|
|
|
-- charmap.asm:88 `charmap "☎", $62`. The glyph itself is
|
|
-- PokegearPhoneIconGFX, which _LoadFontsExtra copies over vTiles2 tile $62
|
|
-- (engine/gfx/load_font.asm:12-15) on top of the three bold letters FontExtra
|
|
-- ships there; a cache whose font_extra page still carries FontExtra's own
|
|
-- $62 draws a bold C in its place, which is an extractor gap and not a
|
|
-- layout one, so the sequence is written out here the way the cart writes it.
|
|
local PHONE_ICON = "\xe2\x98\x8e"
|
|
|
|
-- `name` / `className` are what src/core/gen2/Phone.lua contactName answers:
|
|
-- the caller's name, and the trainer class under it or nil for a non-trainer.
|
|
function CallerBox.new(name, className)
|
|
return setmetatable({
|
|
name = name or "",
|
|
className = className,
|
|
-- The overworld has to keep drawing behind it (this is a strip across the
|
|
-- top, not a page), so the stack must not treat it as a base.
|
|
isOpaque = false,
|
|
}, CallerBox)
|
|
end
|
|
|
|
function CallerBox:draw()
|
|
Chrome.textbox(BOX_X, BOX_Y, BOX_INTERIOR_W, BOX_INTERIOR_H)
|
|
Chrome.print(PHONE_ICON, ICON_X, ICON_Y)
|
|
-- GetCallerName places the name and then writes ':' into the cell the
|
|
-- string ended on, which is what PhoneRing.callerId already composes for
|
|
-- the ring page -- same colon, same source, so the two can never drift.
|
|
Chrome.print(PhoneRing.callerId(self.name), NAME_X, NAME_Y)
|
|
if self.className and self.className ~= "" then
|
|
Chrome.print(self.className, CLASS_X, CLASS_Y)
|
|
end
|
|
end
|
|
|
|
return CallerBox
|