This commit is contained in:
bryanthaboi
2026-08-18 10:36:44 -04:00
parent 25ec896545
commit c2c7fdafcf
2 changed files with 92 additions and 16 deletions
+33 -16
View File
@@ -24,14 +24,18 @@
-- MoneyTopRightMenuHeader menu_coords 11, 0, 19, 2 -- a 9x3 box, and -- MoneyTopRightMenuHeader menu_coords 11, 0, 19, 2 -- a 9x3 box, and
-- PlaceMoneyTextbox writes the amount at -- PlaceMoneyTextbox writes the amount at
-- MenuBoxCoord2Tile + SCREEN_WIDTH + 1 = (12,1) -- MenuBoxCoord2Tile + SCREEN_WIDTH + 1 = (12,1)
-- MenuHeader_Buy menu_coords 1, 3, 19, 11 -- a 19x9 box holding 4 -- MenuHeader_Buy menu_coords 1, 3, 19, 11 -- a 19x9 rect holding 4
-- entries of two rows. ScrollingMenu_UpdateDisplay -- entries of two rows. BuyMenuLoop copies that
-- starts at (2,4); PlaceMenuItemName prints the name -- header and calls ScrollingMenu; it never calls
-- there and .PrintBCDPrices is handed that origin -- InitScrollingMenu or MenuBox, so the rect is NOT
-- plus the menu's own width (8) plus SCREEN_WIDTH, so -- a framed window. ScrollingMenu_UpdateDisplay
-- the price lands at (10,5). The ▲ sits on the box's -- calls ClearWholeMenuBox on it (spaces, no border)
-- top right corner (19,3) and the ▼ on its bottom -- and starts printing at (2,4); PlaceMenuItemName
-- right (19,11). -- prints the name there and .PrintBCDPrices is
-- handed that origin plus the menu's own width (8)
-- plus SCREEN_WIDTH, so the price lands at (10,5).
-- The ▲ sits on the rect's top right (19,3) and
-- the ▼ on its bottom right (19,11).
-- UpdateItemDescription Textbox (0,12) interior 18x4 -- a 20x6 box -- with -- UpdateItemDescription Textbox (0,12) interior 18x4 -- a 20x6 box -- with
-- the description at (1,14) -- the description at (1,14)
-- BuyItem_MenuHeader menu_coords 7, 15, 19, 17 -- a 13x3 box, and -- BuyItem_MenuHeader menu_coords 7, 15, 19, 17 -- a 13x3 box, and
@@ -75,7 +79,9 @@ local SFX_TRANSACTION = "Sfx_Transaction"
local MartMenu = {} local MartMenu = {}
MartMenu.__index = MartMenu MartMenu.__index = MartMenu
-- engine/items/mart.asm:54 -- The top menu overlays the mart (StandardMart .HowMayIHelpYou /
-- .AnythingElse: LoadStandardMenuHeader + PrintText). BuyMenu is
-- FadeToMenu + BlankScreen, so enterBuy shadows this for the list.
MartMenu.isOpaque = false MartMenu.isOpaque = false
-- constants/mart_constants.asm. The `pokemart` macro emits this as one byte -- constants/mart_constants.asm. The `pokemart` macro emits this as one byte
@@ -563,6 +569,10 @@ function MartMenu:enterBuy()
self.phase = "buy" self.phase = "buy"
self.index = 1 self.index = 1
self.scroll = 0 self.scroll = 0
-- BuyMenu (engine/items/mart.asm): `call FadeToMenu / farcall BlankScreen`.
-- BlankScreen fills the tilemap with spaces and the palettes with white, so
-- the mart must not keep drawing in the letterbox under the list.
self.isOpaque = (self.phase == "buy")
end end
function MartMenu:total() function MartMenu:total()
@@ -618,6 +628,8 @@ end
-- BuyMenu returns into StandardMart .Buy, which falls through to -- BuyMenu returns into StandardMart .Buy, which falls through to
-- .AnythingElse; the other three dialog kinds end on their come-again line. -- .AnythingElse; the other three dialog kinds end on their come-again line.
function MartMenu:leaveBuy() function MartMenu:leaveBuy()
-- CloseSubmenu restores the map before .AnythingElse / the come-again line.
self.isOpaque = nil
if self.martType == "STANDARD" then if self.martType == "STANDARD" then
self:enterTop(self.text.askMore) self:enterTop(self.text.askMore)
else else
@@ -885,11 +897,10 @@ function MartMenu:description()
return def and def.description or nil return def and def.description or nil
end end
-- The bottom visible entry's price row IS the box's bottom border row -- The bottom visible entry's price row is MenuHeader_Buy's last line
-- (entry row 10 + SCREEN_WIDTH = 11, MenuHeader_Buy's own last line), and a -- (entry row 10 + SCREEN_WIDTH = 11). A GB glyph REPLACES the tile it
-- GB glyph REPLACES the tile it prints over, border and all. White under -- prints over, so white under the seven money tiles first is that
-- the seven money tiles first is that replacement; on the three rows clear -- replacement. On a BlankScreen field it is white over white.
-- of the border it repaints white over white.
local function printPriceOpaque(amount, ty) local function printPriceOpaque(amount, ty)
local G = love.graphics local G = love.graphics
G.setColor(1, 1, 1, 1) G.setColor(1, 1, 1, 1)
@@ -899,8 +910,10 @@ local function printPriceOpaque(amount, ty)
end end
function MartMenu:drawBuyList() function MartMenu:drawBuyList()
-- engine/items/mart.asm:542 -- ScrollingMenu_UpdateDisplay (engine/menus/scrolling_menu.asm) calls
Chrome.box(LIST_BOX_X, LIST_BOX_Y, LIST_BOX_W, LIST_BOX_H) -- ClearWholeMenuBox, not MenuBox: the MenuHeader_Buy rect is a cleared
-- field, not a framed window. BlankScreen already filled the tilemap
-- with spaces, so the names just land on white.
for row = 1, VISIBLE_ROWS do for row = 1, VISIBLE_ROWS do
local i = row + self.scroll local i = row + self.scroll
local ty = LIST_Y + (row - 1) * LIST_SPACING local ty = LIST_Y + (row - 1) * LIST_SPACING
@@ -960,6 +973,10 @@ function MartMenu:drawUnder()
self:drawTopMenu() self:drawTopMenu()
self:drawTextBox(self.topLines) self:drawTextBox(self.topLines)
elseif phase == "buy" or phase == "buyQuantity" then elseif phase == "buy" or phase == "buyQuantity" then
-- BlankScreen (engine/overworld/player_object.asm): the whole tilemap
-- is spaces before PlaceMoneyTopRight / the scrolling list / the
-- description textbox go down. Only those last two are framed.
Chrome.clear()
self:drawMoneyBox() self:drawMoneyBox()
self:drawBuyList() self:drawBuyList()
self:drawDescription() self:drawDescription()
+59
View File
@@ -179,6 +179,65 @@ check("the cursor is the column-1 arrow on the label row",
check("the cursor starts on the first row", cursorAt and cursorAt.y, 2) check("the cursor starts on the first row", cursorAt and cursorAt.y, 2)
check("FRAME still prints its literal TYPE", findPrint(":TYPE") ~= nil, true) check("FRAME still prints its literal TYPE", findPrint(":TYPE") ~= nil, true)
-- ------------------------------------------------------- mart buy list
--
-- BuyMenu (engine/items/mart.asm) is FadeToMenu + BlankScreen, then
-- PlaceMoneyTopRight and ScrollingMenu_UpdateDisplay's ClearWholeMenuBox.
-- The list is not MenuBox'd; only the money box and UpdateItemDescription's
-- textbox are. The top menu still overlays the mart, so it must not blank.
local MartMenu = require("src.ui.gen2.MartMenu")
local Save = require("src.core.gen2.Save")
local martBoxes, martClears = {}, 0
local martClear, martBox = Chrome.clear, Chrome.box
local martPrint, martCursor = Chrome.print, Chrome.cursor
Chrome.clear = function() martClears = martClears + 1 end
Chrome.box = function(x, y, w, h)
martBoxes[#martBoxes + 1] = { x = x, y = y, w = w, h = h }
end
Chrome.print = function() end
Chrome.cursor = function() end
local function martHasBox(x, y, w, h)
for _, b in ipairs(martBoxes) do
if b.x == x and b.y == y and b.w == w and b.h == h then return true end
end
return false
end
local martSave = Save.newGame()
local martItems = {
POTION = { id = "POTION", name = "POTION", pocket = "ITEM", price = 300,
description = "Restores HP\nby 20." },
}
local mart = MartMenu.new({ save = martSave, data = { items = martItems } }, {
save = martSave,
items = martItems,
marts = { lists = { { "POTION" } } },
})
mart:draw()
check("the top menu does not blank the tilemap", martClears, 0)
check("and frames BUY/SELL/QUIT", martHasBox(0, 0, 12, 9), true)
check("and the welcome speech box", martHasBox(0, 12, 20, 6), true)
check("the top menu is not opaque", mart.isOpaque, false)
martClears, martBoxes = 0, {}
mart:enterBuy()
mart:draw()
check("BUY blanks the screen (BlankScreen)", martClears > 0, true)
check("the money box is framed", martHasBox(11, 0, 9, 3), true)
check("the description box is framed", martHasBox(0, 12, 20, 6), true)
check("the item list is not (ClearWholeMenuBox, not MenuBox)",
martHasBox(1, 3, 19, 9), false)
check("BlankScreen shadows isOpaque so the letterbox is not the mart",
mart.isOpaque, true)
mart:leaveBuy()
check("leaving BUY unshadows isOpaque", mart.isOpaque, false)
Chrome.clear, Chrome.box = martClear, martBox
Chrome.print, Chrome.cursor = martPrint, martCursor
-- ------------------------------------------------------- one blit scale -- ------------------------------------------------------- one blit scale
-- --
-- Every Gold screen paints its 160x144 panel through the same helper. A -- Every Gold screen paints its 160x144 panel through the same helper. A