Files
khallaandClaude Opus 5.5 8a7bdfd99f Framework for Sacred 2 Gold, game log mirror, borderless fullscreen
Ported from sacredK with module-relative addresses, hooks by exported
name and a SHA-256 check of the six game modules (Community Patch
2.65.1). Borderless windowed at monitor size replaces exclusive
fullscreen, whose focus loss during loading made the game quit and
crash on exit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 01:39:44 +01:00

2.4 KiB

Borderless fullscreen

Request (2026-10-31): make the game start without crashing, then borderless fullscreen as the first feature.

The start-up crash

Measured 2026-10-31 (3440x1440, options video.fullscreen = 1):

  • Started through the launcher from a background process, Windows doesn't hand the game window the foreground. In exclusive fullscreen Direct3D then minimises it (style gains WS_MINIMIZE after ~8 s, during "SETUP AI..." on the loading screen), and the game quits ~20 s later. On the way out s2logicai.dll's static destructors call a pure virtual function (a global allocator object at 0x101BF774 is already destroyed), the game's s2_purecall() handler (sacred2.exe 0x489ada) breaks into the debugger: exception 0x80000003 in KERNELBASE.
  • Started with focus (or directly, unmodified), it reaches the main menu.
  • cDX9Base::flip minimises the window and sets device flag 4 when Present returns D3DERR_DEVICELOST.

So the crash was exclusive fullscreen losing the focus; it is gone with borderless.

How the mod works (src/mods/borderless.cpp)

cDX9Base::_initDX(const sInitParams&) (s2render 0x1029a736, exported, the only device set-up, reached through initDX / cDX9Advance::initAdvance) has a windowed path: style 0x12c00000, size clamped to GetSystemMetrics(SM_CXSCREEN/SM_CYSCREEN) minus the frame, window centred, back buffer of that size, presentation interval default. See src/game/render/dx9base.h for sInitParams and the addresses.

  • The hook passes fullscreen = 0 and the primary monitor's size.
  • At startup the four uses of the style constant (0x1029ab49, ab56, ab5b, ab62) become WS_POPUP | WS_VISIBLE, so the game's own code makes a frameless window covering the monitor at (0,0).
  • The launcher passes its foreground right to the game (AllowSetForegroundWindow).

Verified 2026-10-31 by automated runs: started without focus the game keeps loading in the background; with focus it reaches the main menu, survives switching to another window for 6 s and back, and quits cleanly on a close request (no crash report, MemLeaks_sacred2.xml written).

Consequences

  • The resolution and fullscreen settings in Optionen no longer apply; the game always renders at the monitor's resolution.
  • Always the primary monitor.
  • In windowed mode the game presents with vsync (interval default); the options' vsync flag only applies to exclusive fullscreen.