Files
sacred_k/docs/screens.md
T
khallaandClaude Opus 5.5 0ef3cf4bbd Shared chest, menu after a game, dialogs over 16:9 screens
- Shared chest: emptied and not saved from the moment a save game is read
  until it reloads; a hero saved inside a load wrote the new world's
  objects (stale ids) as the chest's items.
- Main menu after a game: shown 16:9 screens are tracked on the menu thread
  only and expire after 2 frames; a destroyed in-game window kept the menu
  unframed (old pictures, frame at the left).
- Dialogs over a 16:9 screen in the main menu are centred, their dimming
  covers the screen.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 00:41:12 +02:00

5.1 KiB

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.