More menu work.
This commit is contained in:
parent
08415da805
commit
9bf4d9beb2
5 changed files with 95 additions and 27 deletions
13
CHANGELOG
13
CHANGELOG
|
|
@ -1259,11 +1259,14 @@ Fixes
|
||||||
has both may delete the ".game" one; what was in it is rebuilt.
|
has both may delete the ".game" one; what was in it is rebuilt.
|
||||||
|
|
||||||
- Both menus scroll their details. When a games.dat entry has more to say
|
- Both menus scroll their details. When a games.dat entry has more to say
|
||||||
than fits, the text walks down by itself a line at a time and rests at
|
than fits, the text walks down by itself a line at a time, rests, and
|
||||||
each end: up and down belong to the library, and a cabinet has no key to
|
walks back up to the start rather than jumping there: up and down belong
|
||||||
spare for scrolling a paragraph. The document renderer's description box
|
to the library, and a cabinet has no key to spare for scrolling a
|
||||||
had a scroll bar the style sheet gave it and nothing to drive it with;
|
paragraph. The document renderer's description box had a scroll bar the
|
||||||
the overlay renderer clipped and left it at that.
|
style sheet gave it and nothing to drive it with; the overlay renderer
|
||||||
|
clipped and left it at that. Page up and page down override the walk for
|
||||||
|
whoever does have a keyboard, and it carries on from where they leave it.
|
||||||
|
Both menus say so along the bottom.
|
||||||
|
|
||||||
- The overlay menu -- the one a machine with no GPU gets -- shows what a
|
- The overlay menu -- the one a machine with no GPU gets -- shows what a
|
||||||
games.dat says about a game. Its details had the attract video's column
|
games.dat says about a game. Its details had the attract video's column
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
<div id="description"></div>
|
<div id="description"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
<div id="hints">Up / Down: select Left / Right: page Start or button: play Service: tools</div>
|
<div id="hints">Up / Down: select Left / Right: page PgUp / PgDn: details Start or button: play Service: tools</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Every service tool draws through this one page: Singe/Tools.singe hands the menu a list of
|
<!-- Every service tool draws through this one page: Singe/Tools.singe hands the menu a list of
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,17 @@ function onOverlayUpdate()
|
||||||
|
|
||||||
-- Are we displaying the grid background?
|
-- Are we displaying the grid background?
|
||||||
if menuActive() then
|
if menuActive() then
|
||||||
|
-- The page keys take the details over from the walk they do by themselves; the walk picks
|
||||||
|
-- up from wherever they leave it once its pause is up. They arrive as a scancode rather
|
||||||
|
-- than a switch because they are not one: a cabinet has no page keys and loses nothing.
|
||||||
|
local key = keyboardGetLastDown()
|
||||||
|
|
||||||
|
if key == SCANCODE.PAGEDOWN.value then
|
||||||
|
MENU_RENDER.scrollDetails(1)
|
||||||
|
elseif key == SCANCODE.PAGEUP.value then
|
||||||
|
MENU_RENDER.scrollDetails(-1)
|
||||||
|
end
|
||||||
|
|
||||||
-- The attract clip runs between the two frames the game's entry names.
|
-- The attract clip runs between the two frames the game's entry names.
|
||||||
if videoGetFrame(VIDEO_ATTRACT) > GAME_LIST[GAME_SELECTED].ATTRACT_END then
|
if videoGetFrame(VIDEO_ATTRACT) > GAME_LIST[GAME_SELECTED].ATTRACT_END then
|
||||||
videoSeek(VIDEO_ATTRACT, GAME_LIST[GAME_SELECTED].ATTRACT_START)
|
videoSeek(VIDEO_ATTRACT, GAME_LIST[GAME_SELECTED].ATTRACT_START)
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,8 @@ local VIDEO_ASPECT_H = 200
|
||||||
|
|
||||||
local videoX, videoY, videoW, videoH = 0, 0, 0, 0
|
local videoX, videoY, videoW, videoH = 0, 0, 0, 0
|
||||||
local scrollPending = false
|
local scrollPending = false
|
||||||
local detailScroll = 0 -- How far down the description has walked, in pixels.
|
local detailScroll = 0 -- How far down the description has walked, in pixels,
|
||||||
|
local detailDown = true -- and which way it is walking.
|
||||||
local detailClock = 0
|
local detailClock = 0
|
||||||
local SCROLL_HOLD = 3.0 -- Seconds it rests at each end before moving, as in the overlay
|
local SCROLL_HOLD = 3.0 -- Seconds it rests at each end before moving, as in the overlay
|
||||||
local SCROLL_STEP = 1.1 -- renderer, and seconds a step while it is moving.
|
local SCROLL_STEP = 1.1 -- renderer, and seconds a step while it is moving.
|
||||||
|
|
@ -281,6 +282,7 @@ MENU_RENDER.showGame = function(game)
|
||||||
guiSetValue(GUI, DOCUMENT, "description", menuEscape(game.DESCRIPTION))
|
guiSetValue(GUI, DOCUMENT, "description", menuEscape(game.DESCRIPTION))
|
||||||
menuElement("description").scroll_top = 0
|
menuElement("description").scroll_top = 0
|
||||||
detailScroll = 0
|
detailScroll = 0
|
||||||
|
detailDown = true
|
||||||
detailClock = 0
|
detailClock = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -305,10 +307,10 @@ MENU_RENDER.pageSize = function()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- The description walks down by itself when there is more of it than fits, the same way the overlay
|
-- The description walks by itself when there is more of it than fits -- down to the end, a rest,
|
||||||
-- renderer's details do. The style sheet gives this box a scroll bar, but nothing drives one from a
|
-- and back up to the start -- the same way the overlay renderer's details do. The style sheet
|
||||||
-- joystick and up and down belong to the game list, so a long description was simply unreadable
|
-- gives this box a scroll bar, but nothing drives one from a joystick and up and down belong to the
|
||||||
-- past its first few lines.
|
-- game list, so a long description was simply unreadable past its first few lines.
|
||||||
local function menuScrollDetails()
|
local function menuScrollDetails()
|
||||||
local element = menuElement("description")
|
local element = menuElement("description")
|
||||||
local room = element.scroll_height - element.client_height
|
local room = element.scroll_height - element.client_height
|
||||||
|
|
@ -322,11 +324,32 @@ local function menuScrollDetails()
|
||||||
detailClock = singeGetTicks()
|
detailClock = singeGetTicks()
|
||||||
end
|
end
|
||||||
|
|
||||||
local last = detailScroll >= room
|
local resting = (detailScroll <= 0) or (detailScroll >= room)
|
||||||
local rest = (last or (detailScroll == 0)) and SCROLL_HOLD or SCROLL_STEP
|
|
||||||
|
|
||||||
if (singeGetTicks() - detailClock) >= (rest * 1000) then
|
if (singeGetTicks() - detailClock) >= ((resting and SCROLL_HOLD or SCROLL_STEP) * 1000) then
|
||||||
detailScroll = last and 0 or math.min(detailScroll + SCROLL_LINE, room)
|
if detailDown and (detailScroll >= room) then
|
||||||
|
detailDown = false
|
||||||
|
elseif not detailDown and (detailScroll <= 0) then
|
||||||
|
detailDown = true
|
||||||
|
end
|
||||||
|
detailScroll = math.max(math.min(detailScroll + (detailDown and SCROLL_LINE or -SCROLL_LINE), room), 0)
|
||||||
|
detailClock = singeGetTicks()
|
||||||
|
element.scroll_top = detailScroll
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Page up and page down, by as much as is on show less a line to read across. The walk resumes
|
||||||
|
-- from where this leaves it, in the direction it was sent, after its usual rest.
|
||||||
|
MENU_RENDER.scrollDetails = function(direction)
|
||||||
|
local element = menuElement("description")
|
||||||
|
local room = element.scroll_height - element.client_height
|
||||||
|
|
||||||
|
if room > 0 then
|
||||||
|
local page = math.max(element.client_height - SCROLL_LINE, SCROLL_LINE)
|
||||||
|
|
||||||
|
detailScroll = math.max(math.min(detailScroll + direction * page, room), 0)
|
||||||
|
detailDown = (direction > 0)
|
||||||
detailClock = singeGetTicks()
|
detailClock = singeGetTicks()
|
||||||
element.scroll_top = detailScroll
|
element.scroll_top = detailScroll
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,9 @@
|
||||||
-- One game is on screen at a time, as it always was here, so there is no list to page through
|
-- One game is on screen at a time, as it always was here, so there is no list to page through
|
||||||
-- visually: up and down move one game, left and right move a page, and the line above the details
|
-- visually: up and down move one game, left and right move a page, and the line above the details
|
||||||
-- says where in the library the selection is. An entry with more to say than fits walks down by
|
-- says where in the library the selection is. An entry with more to say than fits walks down by
|
||||||
-- itself, a line at a time, resting at each end: up and down belong to the library, and a cabinet
|
-- itself a line at a time, rests, and walks back up again: up and down belong to the library, and
|
||||||
-- has no key to spare for scrolling a paragraph.
|
-- a cabinet has no key to spare for scrolling a paragraph. Page up and page down override it for
|
||||||
|
-- whoever does have a keyboard.
|
||||||
|
|
||||||
|
|
||||||
local MARGIN_X = 25
|
local MARGIN_X = 25
|
||||||
|
|
@ -50,9 +51,11 @@ local LABEL_W = 150
|
||||||
local SUB_INDENT = 20
|
local SUB_INDENT = 20
|
||||||
local PAGE_ROWS = 10
|
local PAGE_ROWS = 10
|
||||||
local WRAP_BREAK = " [!wb!] "
|
local WRAP_BREAK = " [!wb!] "
|
||||||
local HINTS = "Up / Down: select Left / Right: page Start or button: play Service: tools"
|
local HINTS = "Up / Down: select Left / Right: page PgUp / PgDn: details Start or button: play Service: tools"
|
||||||
|
|
||||||
local font = nil
|
local font = nil
|
||||||
|
local hintFont = nil -- Smaller: the hints are a footnote, and at the body's size the line
|
||||||
|
-- of them ran off the end of a 720 pixel overlay.
|
||||||
local introDone = false
|
local introDone = false
|
||||||
local videoX, videoY, videoW, videoH = 0, 0, 0, 0
|
local videoX, videoY, videoW, videoH = 0, 0, 0, 0
|
||||||
local marqueeX, marqueeY, marqueeW, marqueeH = 0, 0, 0, 0
|
local marqueeX, marqueeY, marqueeW, marqueeH = 0, 0, 0, 0
|
||||||
|
|
@ -63,7 +66,8 @@ local spriteCabinet = nil
|
||||||
local spriteMarquee = nil
|
local spriteMarquee = nil
|
||||||
local textSprites = {}
|
local textSprites = {}
|
||||||
local textShadows = {}
|
local textShadows = {}
|
||||||
local textFirst = 0 -- The first line of the details on show, which walks down by itself.
|
local textFirst = 0 -- The first line of the details on show, which walks by itself.
|
||||||
|
local textDown = true -- and which way it is walking.
|
||||||
local textClock = 0
|
local textClock = 0
|
||||||
local SHADOW = 2 -- How far the shadow sits down and across from the text.
|
local SHADOW = 2 -- How far the shadow sits down and across from the text.
|
||||||
local SCROLL_HOLD = 3.0 -- Seconds the details rest at each end before moving.
|
local SCROLL_HOLD = 3.0 -- Seconds the details rest at each end before moving.
|
||||||
|
|
@ -225,6 +229,7 @@ MENU_RENDER = {}
|
||||||
|
|
||||||
MENU_RENDER.begin = function()
|
MENU_RENDER.begin = function()
|
||||||
font = fontLoad("Singe/FreeSansBold.ttf", 18)
|
font = fontLoad("Singe/FreeSansBold.ttf", 18)
|
||||||
|
hintFont = fontLoad("Singe/FreeSansBold.ttf", 13)
|
||||||
fontQuality(FONT_QUALITY_BLENDED)
|
fontQuality(FONT_QUALITY_BLENDED)
|
||||||
fontSelect(font)
|
fontSelect(font)
|
||||||
end
|
end
|
||||||
|
|
@ -235,6 +240,10 @@ MENU_RENDER.finish = function()
|
||||||
fontUnload(font)
|
fontUnload(font)
|
||||||
font = nil
|
font = nil
|
||||||
end
|
end
|
||||||
|
if hintFont then
|
||||||
|
fontUnload(hintFont)
|
||||||
|
hintFont = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -359,6 +368,7 @@ MENU_RENDER.showGame = function(game)
|
||||||
end
|
end
|
||||||
textLimit = (textHeight > 0) and math.max(math.floor((textH - LINE_HEIGHT) / textHeight), 1) or 1
|
textLimit = (textHeight > 0) and math.max(math.floor((textH - LINE_HEIGHT) / textHeight), 1) or 1
|
||||||
textFirst = 0
|
textFirst = 0
|
||||||
|
textDown = true
|
||||||
textClock = 0
|
textClock = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -387,6 +397,19 @@ MENU_RENDER.hideGame = function()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Page up and page down, by as much as is on show less a line to read across. The walk resumes
|
||||||
|
-- from where this leaves it, in the direction it was sent, after its usual rest.
|
||||||
|
MENU_RENDER.scrollDetails = function(direction)
|
||||||
|
local room = #textSprites - textLimit
|
||||||
|
|
||||||
|
if room > 0 then
|
||||||
|
textFirst = math.max(math.min(textFirst + direction * math.max(textLimit - 1, 1), room), 0)
|
||||||
|
textDown = (direction > 0)
|
||||||
|
textClock = singeGetTicks()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
MENU_RENDER.pageSize = function()
|
MENU_RENDER.pageSize = function()
|
||||||
return PAGE_ROWS
|
return PAGE_ROWS
|
||||||
end
|
end
|
||||||
|
|
@ -418,9 +441,10 @@ MENU_RENDER.frame = function()
|
||||||
colorForeground(255, 211, 90, 255)
|
colorForeground(255, 211, 90, 255)
|
||||||
fontPrint(textX, textY, title)
|
fontPrint(textX, textY, title)
|
||||||
|
|
||||||
-- What the game is. More of it than fits walks down a line at a time and starts over, so
|
-- What the game is. More of it than fits walks a line at a time, down to the end and back up
|
||||||
-- everything an entry says is seen without a key to scroll it.
|
-- to the start, so everything an entry says is seen without a key to scroll it -- and without
|
||||||
local last = textFirst + textLimit >= #textSprites
|
-- the jump back to the top that reading the last line used to end in.
|
||||||
|
local room = #textSprites - textLimit
|
||||||
|
|
||||||
-- The clock starts when the details are first drawn, not when they were built: the menu is
|
-- The clock starts when the details are first drawn, not when they were built: the menu is
|
||||||
-- behind the intro for the first seven seconds, and a page that had already scrolled itself by
|
-- behind the intro for the first seven seconds, and a page that had already scrolled itself by
|
||||||
|
|
@ -428,11 +452,16 @@ MENU_RENDER.frame = function()
|
||||||
if textClock == 0 then
|
if textClock == 0 then
|
||||||
textClock = singeGetTicks()
|
textClock = singeGetTicks()
|
||||||
end
|
end
|
||||||
if #textSprites > textLimit then
|
if room > 0 then
|
||||||
local rest = (last or (textFirst == 0)) and SCROLL_HOLD or SCROLL_STEP
|
local resting = (textFirst <= 0) or (textFirst >= room)
|
||||||
|
|
||||||
if (singeGetTicks() - textClock) >= (rest * 1000) then
|
if (singeGetTicks() - textClock) >= ((resting and SCROLL_HOLD or SCROLL_STEP) * 1000) then
|
||||||
textFirst = last and 0 or (textFirst + 1)
|
if textDown and (textFirst >= room) then
|
||||||
|
textDown = false
|
||||||
|
elseif not textDown and (textFirst <= 0) then
|
||||||
|
textDown = true
|
||||||
|
end
|
||||||
|
textFirst = math.max(math.min(textFirst + (textDown and 1 or -1), room), 0)
|
||||||
textClock = singeGetTicks()
|
textClock = singeGetTicks()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -449,10 +478,12 @@ MENU_RENDER.frame = function()
|
||||||
-- Which key does what. The document renderer says the same thing along its footer; here
|
-- Which key does what. The document renderer says the same thing along its footer; here
|
||||||
-- there was nothing at all, so the only way to learn that up and down move one game and left
|
-- there was nothing at all, so the only way to learn that up and down move one game and left
|
||||||
-- and right move a page was to be told.
|
-- and right move a page was to be told.
|
||||||
|
fontSelect(hintFont)
|
||||||
colorForeground(0, 0, 0, 255)
|
colorForeground(0, 0, 0, 255)
|
||||||
fontPrint(hintsX + SHADOW, hintsY + SHADOW, HINTS)
|
fontPrint(hintsX + SHADOW, hintsY + SHADOW, HINTS)
|
||||||
colorForeground(178, 196, 224, 255)
|
colorForeground(178, 196, 224, 255)
|
||||||
fontPrint(hintsX, hintsY, HINTS)
|
fontPrint(hintsX, hintsY, HINTS)
|
||||||
|
fontSelect(font)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue