diff --git a/src/core/Game2.lua b/src/core/Game2.lua index 28deaeaa..4ce17192 100644 --- a/src/core/Game2.lua +++ b/src/core/Game2.lua @@ -109,6 +109,12 @@ local function makeStack() return StateStack end +local function visibleBaseState(stack) + if not stack then return nil end + local state = stack.states[stack:visibleBase()] + return stack:renderVisible(state) and state or nil +end + local function loadGenerated(path) local chunk = love.filesystem.load(path) if not chunk then return nil end @@ -1441,8 +1447,7 @@ end -- them but the Pokegear, whose paper is RGB 28,31,20. Nil means white, which -- is what Font.drawBox does by default. function Game2:textboxPaper() - local base = self.stack and self.stack.states - and self.stack.states[self.stack:visibleBase()] + local base = visibleBaseState(self.stack) if base and base.paperColor then return base:paperColor() end return nil end @@ -1455,10 +1460,11 @@ function Game2:drawScene(w, h) if self:inFillBoot() then local top = self.stack:top() - local base = self.stack.states[self.stack:visibleBase()] + local base = visibleBaseState(self.stack) -- Title (and friends) paint sky/clouds edge-to-edge; Oak speech and -- name pick paint a paper-white surround via drawWidescreen. - local wide = (top and top.drawsWidescreen and top:drawsWidescreen() + local wide = (self.stack:renderVisible(top) + and top.drawsWidescreen and top:drawsWidescreen() and top.drawWidescreen) and top or (base and base.drawsWidescreen and base:drawsWidescreen() and base.drawWidescreen and base) @@ -1507,8 +1513,9 @@ function Game2:drawScene(w, h) -- PARTY, PACK, #DEX, PC, DAY-CARE, MAILBOX and TRADE screens whenever a -- TextBox goes up over them. local top = self.stack:top() - local base = self.stack.states[self.stack:visibleBase()] - local wide = (top and top.drawsWidescreen and top:drawsWidescreen() + local base = visibleBaseState(self.stack) + local wide = (self.stack:renderVisible(top) + and top.drawsWidescreen and top:drawsWidescreen() and top.drawWidescreen) and top or (base and base.drawsWidescreen and base:drawsWidescreen() and base.drawWidescreen and base) diff --git a/tests/modkit/cases/screen_render_visible.lua b/tests/modkit/cases/screen_render_visible.lua index eb8d246a..68d039e9 100644 --- a/tests/modkit/cases/screen_render_visible.lua +++ b/tests/modkit/cases/screen_render_visible.lua @@ -5,6 +5,7 @@ package.path = "./?.lua;./?/init.lua;" .. package.path local T = require("tests.modkit") local Game = require("src.core.Game") +local Game2 = require("src.core.Game2") local Runtime = require("src.mods.Runtime") local StateStack = require("src.core.StateStack") local Renderer = require("src.render.Renderer") @@ -92,6 +93,43 @@ do "the hidden menu remains the active top state") game.stack:update(1 / 60) T.eq(menu.updates, 1, "the hidden menu keeps its update ownership") + + -- Gold keeps the overworld outside its state stack. A companion-opened + -- screen can therefore be the stack's only state; visibleBase() still + -- returns index 1, but that hidden state must not become the direct base. + for _, boot in ipairs({ false, true }) do + local stack = setmetatable({}, { __index = StateStack }) + stack:init() + local hidden = { + screenId = "BagMenu", + isOpaque = true, + draws = 0, + wideDraws = 0, + draw = function(self) self.draws = self.draws + 1 end, + drawsWidescreen = function() return true end, + drawWidescreen = function(self) + self.wideDraws = self.wideDraws + 1 + end, + } + stack:push(hidden) + local world = { + map = {}, draws = 0, + draw = function(self) self.draws = self.draws + 1 end, + fitScale = function() return 1 end, + } + game = { stack = stack, world = world } + game.inFillBoot = function() return boot end + game.letterbox = function() end + setmetatable(game, { __index = Game2 }) + + game:drawScene(1280, 720) + T.eq(hidden.wideDraws, 0, + "Gold omits a hidden widescreen top (boot=" .. tostring(boot) .. ")") + T.eq(hidden.draws, 0, + "Gold omits its hidden GB canvas (boot=" .. tostring(boot) .. ")") + T.eq(world.draws, boot and 0 or 1, + "Gold reveals its external world (boot=" .. tostring(boot) .. ")") + end run.release() end