mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-19 20:20:19 +02:00
Expose window margins to tool HUDs
This commit is contained in:
+5
-4
@@ -164,10 +164,11 @@ for a tool to offer a fresh-session action before gameplay begins.
|
|||||||
Ephemeral tools can wrap `save.write(next, game)` and return `false` to veto a
|
Ephemeral tools can wrap `save.write(next, game)` and return `false` to veto a
|
||||||
progress write before world state is captured or any bytes reach disk.
|
progress write before world state is captured or any bytes reach disk.
|
||||||
|
|
||||||
`render.hud` receives `(next, game, viewport)` after visible states draw and
|
`render.hud` receives `(next, game, viewport)` after the finished game frame is
|
||||||
before the UI canvas is presented. `viewport.width` and `viewport.height` are
|
composited and before touch controls draw. The window-space viewport contains
|
||||||
the active UI dimensions, so status indicators can stay visible over normal
|
`width`, `height`, `gameX`, `gameY`, `gameWidth`, `gameHeight`, `scale`, `dpiX`,
|
||||||
and widescreen screens without pushing an updating game state.
|
and `dpiY`, so a tool can use the letterbox margins without drawing over the
|
||||||
|
playfield or pushing an updating game state.
|
||||||
|
|
||||||
Developer mode also arms the mod loader's dev tripwire, which flags mods
|
Developer mode also arms the mod loader's dev tripwire, which flags mods
|
||||||
that reach outside their permission set.
|
that reach outside their permission set.
|
||||||
|
|||||||
+7
-9
@@ -255,14 +255,6 @@ function Game:draw()
|
|||||||
end
|
end
|
||||||
Renderer:beginFrame(worldBelow)
|
Renderer:beginFrame(worldBelow)
|
||||||
self.stack:draw()
|
self.stack:draw()
|
||||||
-- Persistent tool status belongs above every game state but inside the
|
|
||||||
-- active UI canvas, so it composes with palette/render mods and survives
|
|
||||||
-- menus, battles, and transitions without becoming an updating state.
|
|
||||||
if ModRuntime.wantsHook("render.hud") then
|
|
||||||
local width, height = Renderer:uiSize()
|
|
||||||
ModRuntime.call("render.hud", function() end, self,
|
|
||||||
{ width = width, height = height })
|
|
||||||
end
|
|
||||||
-- SGB colorization: the topmost state that knows its palette owns the
|
-- SGB colorization: the topmost state that knows its palette owns the
|
||||||
-- screen (overlays like text boxes inherit from what's beneath them);
|
-- screen (overlays like text boxes inherit from what's beneath them);
|
||||||
-- the overworld's world pass colors each visible map area separately
|
-- the overworld's world pass colors each visible map area separately
|
||||||
@@ -282,7 +274,13 @@ function Game:draw()
|
|||||||
if worldBelow and self.overworld.sgbWorldZones then
|
if worldBelow and self.overworld.sgbWorldZones then
|
||||||
worldZones = self.overworld:sgbWorldZones()
|
worldZones = self.overworld:sgbWorldZones()
|
||||||
end
|
end
|
||||||
Renderer:endFrame(zones, worldZones)
|
local viewport = Renderer:endFrame(zones, worldZones)
|
||||||
|
-- Persistent tool status is screen-space UI: draw it over the completed
|
||||||
|
-- render pipeline with exact playfield/margin geometry, but below mobile
|
||||||
|
-- controls. It never becomes an updating game state.
|
||||||
|
if ModRuntime.wantsHook("render.hud") then
|
||||||
|
ModRuntime.call("render.hud", function() end, self, viewport)
|
||||||
|
end
|
||||||
-- on-screen mobile controls: pure screen-space, over the finished frame
|
-- on-screen mobile controls: pure screen-space, over the finished frame
|
||||||
TouchControls:draw()
|
TouchControls:draw()
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -706,6 +706,13 @@ function Renderer:endFrame(zones, worldZones)
|
|||||||
self.uprightActive = false
|
self.uprightActive = false
|
||||||
self.worldOverride = nil
|
self.worldOverride = nil
|
||||||
PaletteFX.setPass(nil)
|
PaletteFX.setPass(nil)
|
||||||
|
return {
|
||||||
|
width = ww, height = wh,
|
||||||
|
gameX = ox, gameY = oy,
|
||||||
|
gameWidth = vpw, gameHeight = vph,
|
||||||
|
scale = Sp,
|
||||||
|
dpiX = dpiX, dpiY = dpiY,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
return Renderer
|
return Renderer
|
||||||
|
|||||||
@@ -86,9 +86,9 @@ do
|
|||||||
hooks:removeOwner("tool_fixture")
|
hooks:removeOwner("tool_fixture")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- A tool status indicator must draw after every visible game state but before
|
-- A tool status indicator draws in window space after the renderer composites
|
||||||
-- the renderer presents that frame. This keeps the HUD visible over the
|
-- the game. This gives it exact playfield/margin geometry and keeps it crisp
|
||||||
-- overworld, menus, battles, and compatible render pipelines.
|
-- over compatible render pipelines without entering the game canvas.
|
||||||
do
|
do
|
||||||
local Renderer = require("src.render.Renderer")
|
local Renderer = require("src.render.Renderer")
|
||||||
local TouchControls = require("src.core.TouchControls")
|
local TouchControls = require("src.core.TouchControls")
|
||||||
@@ -98,7 +98,15 @@ do
|
|||||||
local order = {}
|
local order = {}
|
||||||
Renderer.setUISize = function() end
|
Renderer.setUISize = function() end
|
||||||
Renderer.beginFrame = function() end
|
Renderer.beginFrame = function() end
|
||||||
Renderer.endFrame = function() order[#order + 1] = "present" end
|
Renderer.endFrame = function()
|
||||||
|
order[#order + 1] = "present"
|
||||||
|
return {
|
||||||
|
width = 1024, height = 768,
|
||||||
|
gameX = 112, gameY = 24,
|
||||||
|
gameWidth = 800, gameHeight = 720,
|
||||||
|
scale = 5,
|
||||||
|
}
|
||||||
|
end
|
||||||
TouchControls.draw = function() order[#order + 1] = "touch" end
|
TouchControls.draw = function() order[#order + 1] = "touch" end
|
||||||
|
|
||||||
local fake = { overworld = {}, stack = { states = {} } }
|
local fake = { overworld = {}, stack = { states = {} } }
|
||||||
@@ -108,15 +116,17 @@ do
|
|||||||
|
|
||||||
hooks:wrap("render.hud", function(nextFn, game, viewport)
|
hooks:wrap("render.hud", function(nextFn, game, viewport)
|
||||||
T.check(game == fake, "render.hud receives the live Game object")
|
T.check(game == fake, "render.hud receives the live Game object")
|
||||||
T.eq(viewport.width, 160, "render.hud receives the UI width")
|
T.eq(viewport.width, 1024, "render.hud receives the window width")
|
||||||
T.eq(viewport.height, 144, "render.hud receives the UI height")
|
T.eq(viewport.height, 768, "render.hud receives the window height")
|
||||||
|
T.eq(viewport.gameX, 112, "render.hud receives the playfield origin")
|
||||||
|
T.eq(viewport.gameWidth, 800, "render.hud receives the playfield width")
|
||||||
order[#order + 1] = "hud"
|
order[#order + 1] = "hud"
|
||||||
return nextFn(game, viewport)
|
return nextFn(game, viewport)
|
||||||
end, 0, "tool_fixture")
|
end, 0, "tool_fixture")
|
||||||
|
|
||||||
require("src.core.Game").draw(fake)
|
require("src.core.Game").draw(fake)
|
||||||
T.eq(table.concat(order, ","), "states,hud,present,touch",
|
T.eq(table.concat(order, ","), "states,present,hud,touch",
|
||||||
"render.hud draws over states before frame presentation")
|
"render.hud draws after frame composition and before touch controls")
|
||||||
hooks:removeOwner("tool_fixture")
|
hooks:removeOwner("tool_fixture")
|
||||||
Renderer.setUISize, Renderer.beginFrame, Renderer.endFrame,
|
Renderer.setUISize, Renderer.beginFrame, Renderer.endFrame,
|
||||||
TouchControls.draw = savedSetUISize, savedBegin, savedEnd, savedTouch
|
TouchControls.draw = savedSetUISize, savedBegin, savedEnd, savedTouch
|
||||||
|
|||||||
Reference in New Issue
Block a user