- Megamap / TAB map zoomed view: heroes' markers and the other symbols (integer 200h centre immediates) follow the view's centre. - Map reveal: the hero's reveal stamp scaled 10x (mods/mapreveal.cpp, docs/map-reveal.md); creatures on the zoomed map shown within 10x the sight range. - Load / save progress screen drawn on the rock background across the full width, the picture blended over it (mods/loadingscreen.cpp); the classic 1024x768 frame is gone. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
109 lines
6.1 KiB
Markdown
109 lines
6.1 KiB
Markdown
# 16:9 menu screens
|
|
|
|
Request (2026-10-20): the game's menu screens are laid out for 1024x768; we
|
|
design our own UIs for them. There is no 16:9 artwork for the game, so the
|
|
background is our own, and the approach is shared by all menu screens. The
|
|
background (user, 2026-10-20: "textured dark", the flat gradient looked
|
|
black): the options window's rock wall, `GUI_OPTION_BACKGROUND<row><column>.TGA`
|
|
(4 x 3 tiles of 256), scaled to cover the render target, tinted down,
|
|
shaded towards the bottom and the sides. Game textures by name:
|
|
`game/ui/texture.h`, drawn with `game::DrawTextured` (game/ui/draw.h). Target: 16:9, 1920x1080, which is
|
|
1365x768 in UI units; wider screens only get more background at the sides
|
|
(not designed for ultrawide).
|
|
|
|
## How a screen works
|
|
|
|
- `mods/screen.{h,cpp}`: a screen replaces a full-screen window's drawing and
|
|
mouse handling. Its render hook calls `screen::Render(window, device, body,
|
|
context)`: the background across the whole render target, then the body in
|
|
canvas coordinates (1365x768, centred: `hud::RenderCanvas`, the HUD
|
|
layer's offset machinery with `Anchor::Canvas`; drawing, the cursor and the
|
|
window's hit tests shifted alike). Mouse events go through `screen::Handle`
|
|
(`hud::HandleCanvas`). Keys stay the window's.
|
|
- The main menu thread renders the full width (no 4:3 frame any more).
|
|
- Parts: `screen::Panel` (dark backdrop and the game's frame, `cUI_Frame`,
|
|
game/ui/frame.h, made anew when its rect changes), `screen::Button` (a
|
|
button of the game's with the look of one of the window's,
|
|
`game::NewButtonLike`), `screen::Text`, `screen::Fill`,
|
|
`screen::DoubleClick`. Spacing constants from measurements: frames reach
|
|
0x20 beyond their rects and need a height of about 0x40, buttons reach 0x21.
|
|
Frames are built of 64-unit pieces: widths and heights in steps of 64
|
|
(`screen::kFrameStep`), other sizes leave gaps (screenshot 2026-10-20).
|
|
- Fonts (logged 2026-10-20): font 0 is another class (no line height field);
|
|
the TrueType fonts 1..7 have line heights 20, 19, 25, 31, 25, 28, 13.
|
|
Screens use font 1; 4 or 6 would suit headings.
|
|
- Inside the canvas scope the HUD layer does not stretch "full 1024 layout"
|
|
quads (`g_canvasScope`).
|
|
|
|
## Main menu frame (2026-10-20)
|
|
|
|
Request: the background on all screens, the main menu's and the options
|
|
window's own pictures removed.
|
|
|
|
- cUI_Manager's UI render (`0x7587b0`, hooked in mods/screen.cpp) on the
|
|
menu thread: the background first, then `hud::RenderMenuFrame` runs the
|
|
render with drawing shifted by (render width - 1024) / 2 and a viewport on
|
|
the frame (3D parts). Windows inside draw in frame coordinates (their own
|
|
HUD scopes are nested, so they do nothing).
|
|
- Mouse positions are given to the game in frame coordinates: the
|
|
borderless mod's `ToGame` subtracts `hud::MenuFrameOffsetX`. The cursor
|
|
sprite (`cMouseCursor::DrawItem` 0x6555e0, drawn after the UI) is shifted
|
|
by drawing only.
|
|
- While a 16:9 screen is shown the frame is not shifted (offset 0): the
|
|
screen draws itself across the width.
|
|
- Full-screen windows in a game (options, `hud::RenderFramed`) get the
|
|
background beside the frame instead of black.
|
|
- The windows' pictures are left out by texture: the HUD layer tracks the
|
|
texture bound to stage 0 (`SetTexture`, device vtable 35) and skips quads
|
|
drawn with a hidden one (`hud::SetHiddenTextures`). Logged on the menu
|
|
thread (texture ids requested from the cache, by caller; names by trying
|
|
the names in the texture pak): main menu GUI_UW_OPTION1..12 + UI_MAIN_SKY,
|
|
options UW_OPTION_1_01..12. This install uses the Underworld versions; the
|
|
Ancaria ones (GUI_OPTION1..12, ...) were not seen and are not listed.
|
|
- The main menu's 3D scene (sky UI_UW_MAIN_CENTER, water with the SACRED
|
|
logo UI_MAIN_REF; render 0x75e620 on the scene object 0x75df10) is called
|
|
from cUI_MainMenu::Render (0x7122c0) at 0x712bd9; that call is redirected
|
|
to an empty function. cUI_Character (0x70f41b) still draws it.
|
|
- Logo top left (2026-10-21), 48 from the edges, 124 high: FX_SACREDLOGO.TGA,
|
|
the emblem (horns around a ring of runes) glowing blue on black without
|
|
alpha, drawn added (blend ONE/ONE, `game::DrawTexturedAdded`) as the
|
|
game's effects draw it. Other candidates: GUI_MAIN_LOGO (plain golden
|
|
lettering), SACREDSYMBOL01/02 (model atlases), the emblem on the loading
|
|
pictures (PAK\loading*.bmp, not in the paks). Screens may overlap it.
|
|
|
|
## Screens
|
|
|
|
- Spielen (the load window, cUI_Savegame): docs/characters.md, "Spielen
|
|
screen".
|
|
|
|
## Fixes (2026-10-21)
|
|
|
|
- The main menu came back unframed (old pictures, frame at the left) after a
|
|
game: the set of shown 16:9 screens kept a window of the in-game UI that
|
|
was destroyed while shown. Now only screens drawn on the menu thread count,
|
|
and an entry expires after 2 menu frames without being drawn
|
|
(`screen::BeginMenuFrame`).
|
|
- Dialogs over a 16:9 screen in the main menu (e.g. "Spielstand laden?") sat
|
|
at the left with the dimming 1024 wide: `hud::OffsetFor` gave every window
|
|
offset 0 while the menu showed. Now only while the menu frame is drawn
|
|
centred (it shifts the windows itself); otherwise dialogs are centred and
|
|
their full-layout dimming stretched, as in a game.
|
|
|
|
## Load / save progress screen (2026-10-25)
|
|
|
|
Request: the progress screen shown while loading / saving should use the
|
|
menu screens' background. The game's screen (`DxDriver7::LoadingScreen`
|
|
`0x6469d0`, thiscall (progress, text)) draws with GDI into the back buffer's
|
|
DC (surface +0xbc, GetDC vf 0x44 / ReleaseDC vf 0x68): the 1024x768 picture
|
|
(HBITMAP +0x200) at 0, 0, the bar (+0x204 / +0x208) and the text at y 700,
|
|
then Flip; it redraws only when the bar moves. Until now it was presented as
|
|
a 1024x768 "classic" frame scaled to the monitor.
|
|
|
|
`mods/loadingscreen.cpp`: before the game's drawing, `DrawBackground` across
|
|
the whole render width in a scene of its own (`DxDriver7` BeginScene
|
|
`0x646f50` / EndScene `0x646fd0`); the game's GDI drawing is moved to the
|
|
centred 1024 frame with `SetViewportOrgEx` on the back buffer's DC, caught in
|
|
`CreateCompatibleDC(hdc)` which the game calls right after getting it. Every
|
|
frame is now presented at the full render width (borderless.cpp has one
|
|
layout).
|