mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-17 11:11:10 +02:00
main menu scrollable when over 8 items
This commit is contained in:
+43
-4
@@ -19,7 +19,16 @@ function Menu.new(game, items, opts)
|
|||||||
self.tx = opts.tx or 10
|
self.tx = opts.tx or 10
|
||||||
self.ty = opts.ty or 0
|
self.ty = opts.ty or 0
|
||||||
self.tw = opts.tw or 10
|
self.tw = opts.tw or 10
|
||||||
self.th = opts.th or (#items * 2 + 2)
|
self.rowStep = opts.rowStep or 2
|
||||||
|
-- maxVisible: cap the box to this many rows and scroll the rest instead
|
||||||
|
-- of growing past it (e.g. the start menu, whose row count varies with
|
||||||
|
-- save state and mod hooks); nil/unset keeps every caller's old
|
||||||
|
-- behavior of sizing the box to fit all items.
|
||||||
|
self.maxVisible = opts.maxVisible
|
||||||
|
self.scroll = 0
|
||||||
|
local visible = (self.maxVisible and math.min(self.maxVisible, #items))
|
||||||
|
or #items
|
||||||
|
self.th = opts.th or (visible * self.rowStep + 2)
|
||||||
self.cancelable = opts.cancelable ~= false
|
self.cancelable = opts.cancelable ~= false
|
||||||
-- Whether START closes the menu. In pokered a menu responds only to the
|
-- Whether START closes the menu. In pokered a menu responds only to the
|
||||||
-- keys in its wMenuWatchedKeys mask; the common PAD_A | PAD_B (and the
|
-- keys in its wMenuWatchedKeys mask; the common PAD_A | PAD_B (and the
|
||||||
@@ -31,9 +40,25 @@ function Menu.new(game, items, opts)
|
|||||||
-- BIT_NO_MENU_BUTTON_SOUND (wMiscFlags): the PC session runs its
|
-- BIT_NO_MENU_BUTTON_SOUND (wMiscFlags): the PC session runs its
|
||||||
-- menus silent (home/window.asm HandleMenuInput_)
|
-- menus silent (home/window.asm HandleMenuInput_)
|
||||||
self.noSound = opts.noSound or false
|
self.noSound = opts.noSound or false
|
||||||
|
self:clampScroll()
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- keeps self.index inside the visible [scroll+1, scroll+maxVisible] window;
|
||||||
|
-- callers that move self.index directly (e.g. restoring a saved cursor
|
||||||
|
-- position) should call this afterwards to scroll it into view
|
||||||
|
function Menu:clampScroll()
|
||||||
|
if not (self.maxVisible and #self.items > self.maxVisible) then
|
||||||
|
self.scroll = 0
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if self.index - self.scroll > self.maxVisible then
|
||||||
|
self.scroll = self.index - self.maxVisible
|
||||||
|
elseif self.index - self.scroll < 1 then
|
||||||
|
self.scroll = self.index - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function Menu:update(dt)
|
function Menu:update(dt)
|
||||||
local input = self.game.input
|
local input = self.game.input
|
||||||
if input:wasPressed("up") then
|
if input:wasPressed("up") then
|
||||||
@@ -61,15 +86,29 @@ function Menu:update(dt)
|
|||||||
self.game.stack:pop()
|
self.game.stack:pop()
|
||||||
if self.onCancel then self.onCancel() end
|
if self.onCancel then self.onCancel() end
|
||||||
end
|
end
|
||||||
|
self:clampScroll()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Menu:draw()
|
function Menu:draw()
|
||||||
Font.drawBox(self.tx, self.ty, self.tw, self.th)
|
Font.drawBox(self.tx, self.ty, self.tw, self.th)
|
||||||
love.graphics.setColor(0, 0, 0, 1)
|
love.graphics.setColor(0, 0, 0, 1)
|
||||||
for i, item in ipairs(self.items) do
|
local visible = (self.maxVisible and math.min(self.maxVisible, #self.items))
|
||||||
Font.draw(item.label, (self.tx + 2) * 8, (self.ty + i * 2 - 1) * 8)
|
or #self.items
|
||||||
|
for row = 1, visible do
|
||||||
|
local item = self.items[self.scroll + row]
|
||||||
|
if not item then break end
|
||||||
|
Font.draw(item.label, (self.tx + 2) * 8,
|
||||||
|
(self.ty + row * self.rowStep - (self.rowStep - 1)) * 8)
|
||||||
|
end
|
||||||
|
local cursorRow = self.index - self.scroll
|
||||||
|
Font.drawCode(Theme.cursor, (self.tx + 1) * 8,
|
||||||
|
(self.ty + cursorRow * self.rowStep - (self.rowStep - 1)) * 8)
|
||||||
|
-- moreArrow ($EE): the same "more below" glyph OptionRows/ManagerState
|
||||||
|
-- use, sat on the bottom border like TextBox's page-advance cursor
|
||||||
|
if self.maxVisible and self.scroll + self.maxVisible < #self.items then
|
||||||
|
Font.drawCode(Theme.moreArrow, (self.tx + self.tw - 2) * 8,
|
||||||
|
(self.ty + self.th - 2) * 8)
|
||||||
end
|
end
|
||||||
Font.drawCode(Theme.cursor, (self.tx + 1) * 8, (self.ty + self.index * 2 - 1) * 8)
|
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+11
-1
@@ -7,6 +7,7 @@
|
|||||||
local Font = require("src.render.Font")
|
local Font = require("src.render.Font")
|
||||||
local Logger = require("src.core.Logger")
|
local Logger = require("src.core.Logger")
|
||||||
local Menu = require("src.ui.Menu")
|
local Menu = require("src.ui.Menu")
|
||||||
|
local Renderer = require("src.render.Renderer")
|
||||||
local Runtime = require("src.mods.Runtime")
|
local Runtime = require("src.mods.Runtime")
|
||||||
local Screens = require("src.ui.Screens")
|
local Screens = require("src.ui.Screens")
|
||||||
|
|
||||||
@@ -117,11 +118,20 @@ function StartMenu.new(game)
|
|||||||
-- the start menu's mask is PAD_DOWN | PAD_UP | PAD_START | PAD_B | PAD_A
|
-- the start menu's mask is PAD_DOWN | PAD_UP | PAD_START | PAD_B | PAD_A
|
||||||
-- (engine/menus/draw_start_menu.asm), so START closes it back to the
|
-- (engine/menus/draw_start_menu.asm), so START closes it back to the
|
||||||
-- overworld -- unlike most menus, whose masks omit PAD_START.
|
-- overworld -- unlike most menus, whose masks omit PAD_START.
|
||||||
|
--
|
||||||
|
-- item count isn't fixed: POKéDEX/LINK/MODS come and go with save state,
|
||||||
|
-- and mods can append their own rows through the hook above, so the
|
||||||
|
-- double-spaced box (the original's style) can grow past the 18-tile
|
||||||
|
-- canvas. Cap it at however many rows actually fit and scroll the rest,
|
||||||
|
-- with Menu's moreArrow showing while there's more below.
|
||||||
|
local rowStep = 2
|
||||||
|
local maxVisible = math.floor((Renderer.HEIGHT / 8 - 2) / rowStep)
|
||||||
local menu = Menu.new(game, items,
|
local menu = Menu.new(game, items,
|
||||||
{ tx = 9, ty = 0, tw = 11, th = #items * 2 + 2, startCloses = true })
|
{ tx = 9, ty = 0, tw = 11, maxVisible = maxVisible, startCloses = true })
|
||||||
-- the cursor position survives closing the menu
|
-- the cursor position survives closing the menu
|
||||||
-- (wBattleAndStartSavedMenuItem, home/start_menu.asm)
|
-- (wBattleAndStartSavedMenuItem, home/start_menu.asm)
|
||||||
menu.index = math.min(game.save.startMenuIndex or 1, #items)
|
menu.index = math.min(game.save.startMenuIndex or 1, #items)
|
||||||
|
menu:clampScroll()
|
||||||
local baseUpdate = menu.update
|
local baseUpdate = menu.update
|
||||||
menu.update = function(self, dt)
|
menu.update = function(self, dt)
|
||||||
baseUpdate(self, dt)
|
baseUpdate(self, dt)
|
||||||
|
|||||||
Reference in New Issue
Block a user