Unreal-family demo installers
Status: verified locally on 2026-09-13. These are proprietary demos and remain
localOnly candidate-corpus fixtures. No host Wine was used.
Sources
| Candidate | Archive.org item | File | Size | SHA-1 |
|---|---|---|---|---|
| Unreal Special Edition | unreal-special-edition.-7z |
Unreal Special Edition.7z |
128,609,961 | f3f25896a51cbf37dcdb94833198b86f394d8853 |
| Unreal Tournament | unreal-tournament-demo-version-348 |
UTDEMO348.EXE |
55,647,232 | faf2c18852a1a53c59db490e044e0d3e100e8fed |
| Unreal Tournament 2003 | UT2K3Demo |
UT2003Demo2206.exe |
148,976,640 | 372a8b712cb7f2b1539af72430923d290a67e701 |
| Unreal Tournament 2004 | UnrealTournament2004Demo |
Ut2004-NewDemo.exe |
296,049,152 | 5e224a3de711da9085cddd9929499789690043c7 |
| Unreal Tournament 3 | setuput3demo |
setuput3demo.exe |
777,027,962 | 86d4bad740d0c25438a65c48939ee6dcfc88bb02 |
The host archive reader only unwraps the outer 7-Zip/WinZip container. Candidate
preparation then executes the original setup program inside Wine Assembly,
exports the VFS it wrote, and boots the installed game. This distinction is
enforced by tools/install-unreal-demo.js.
Installer and launch results
| Candidate | Authentic setup result | Installed payload | Installed-game result |
|---|---|---|---|
| Unreal Special Edition | InstallShield bootstrap launched _INS*.MP; license and destination flow completed |
191 MB, System/Unreal.exe SHA-256 5fbc5853a8669a802446ac12e102351053bc6a5ce9f554b03483eb634269f408 |
Software launch loads SoftDrv, opens WindowsViewport0, initializes the game engine/player, and renders the playable intro |
| Unreal Tournament 348 | Unreal System/Setup.exe completed |
104 MB, System/UnrealTournament.exe |
Reaches the renderer-selection wizard |
| UT2003 2206 | Unreal System/Setup.exe completed with the shipped MSVCR70.dll |
344 MB, System/UT2003.exe SHA-256 97e027dc9765f048beacfa461bc93c71ba1831cd3e8dff0cd7d71c1b478f88a2 |
The D3D8 wrapper renders textured first-person Antalus gameplay; an authentic dedicated server and direct-connect client exchange the native protocol over vln/1 |
| UT2004 new demo | Unreal System/Setup.exe completed with the shipped MSVCR71.dll |
525 MB, System/UT2004.exe SHA-256 2a95e2fa8c22ae94eb1c361fdb49ea8ec44c5e2a93faa00831308c01e951db8d |
Uses the same pre-renderer D3D8 probe; further post-probe launch diagnosis remains |
Seeding the bundled Visual C++ runtimes matters. Without MSVCR70.dll, the
UT2003 setup appears to require unimplemented CRT imports beginning with
wcschr; with its own runtime loaded, setup completes without any new emulator
API. The same rule applies to UT2004 and MSVCR71.dll.
OpenGL and software-renderer attempts
UT2003 and UT2004 both ship OpenGLDrv.dll. Their installed and default INIs
were changed locally to OpenGLDrv.OpenGLRenderDevice, fullscreen was disabled,
and the browser launch used -opengl -window with a real WebGL context through
SwiftShader. This still does not bypass D3D8: both main executables import and
call Direct3DCreate8 during startup hardware detection, before either render
driver is loaded.
Direct3DCreate8 now returns a deliberately narrow, non-rendering
IDirect3D8 capability object. It preserves the complete 16-slot factory ABI,
implements COM lifetime, one adapter, one display mode, identifier and caps
queries, and deliberately returns D3DERR_NOTAVAILABLE from format/device
creation checks. An authentic UT2003 run successfully called
GetDeviceCaps, CheckDeviceFormat, GetAdapterIdentifier, and Release, so
the old missing/null-factory branch is gone. It still throws later, before
OpenGLDrv loads; this does not establish that an IDirect3DDevice8 is needed.
Unreal Special Edition does not ship OpenGLDrv.dll; it has SoftDrv.dll,
GlideDrv.dll, and SglDrv.dll. Its former startup exception was an encoded
resource-submenu mismatch in DeleteMenu. With resource-menu deletion and
compaction implemented, a five-minute authentic software-renderer run loaded
SoftDrv.dll, opened WindowsViewport0, logged Game engine initialized, and
sustained the render loop. Its gray viewport was a separate USER delivery bug:
the viewport is a secondary top-level window, but ShowWindow only queued an
initial WM_SIZE for children. Extending first-show sizing to non-main
top-level windows made WinDrv allocate its 514x386x32 DIB and produced 159
successful BitBlt frames in a 65-second authentic run. The captured intro is
rendered and prompts PRESS ESC TO BEGIN. A subsequent controlled run traversed
Game -> New Game -> Easy -> player setup, entered the first-person level with
HUD active, and produced distinct before/after movement frames, so interactive
gameplay is verified rather than inferred from the intro.
The initial capability facade has since grown into a deliberately bounded D3D8
translation layer over the D3D9 backend. It preserves the exact 97-slot device
and 19-slot texture ABIs, translates D3D8 presentation parameters, textures,
vertex/index buffers and fixed-function declarations, retains D3D8's
BaseVertexIndex from SetIndices for indexed draws, and adapts the implicit
swap-chain argument of GetBackBuffer. Unsupported methods remain explicit
failures rather than silent successes.
An authentic -d3d -window -nosound run now reaches textured first-person
gameplay on DM-Antalus. The no-sound flag isolates graphics from the separate
missing Vorbis ov_open import. test/test-ut2003-vlan-candidate.js runs the
game's own non-rendering dedicated-server mode beside a direct-connect client.
It verifies native UDP in both directions over vln/1, waits for D3D device
creation before taking a PNG, rejects the loading screen and spectator join
prompt, and rejects the flat-pale weapon signature that exposed the rendering
bug.
Getting the textured materials working had two layers. D3D8 sampler controls
are texture-stage states 13--21 and 25, but D3D9 moved them into sampler-state
slots 1--10. Forwarding
the D3D8 numbers directly to the D3D9 texture-stage bank returned
D3DERR_INVALIDCALL, leaving filter and address state at defaults. Translating
those states activates the mip-atlas shaders; the native headless desktop GLSL
1.10 compiler then rejected their ESSL-only
GL_OES_standard_derivatives : require directive even though dFdx/dFdy
are core there. The desktop port now removes only that directive. The corrected
capture has a textured dark-metal/green assault rifle and textured terrain
rather than the former nearly uniform white weapon inside the native GL frame.
The remaining pale-rifle CLI capture was a headless presentation bug, not a
D3D8 material bug. WebGL requests an opaque default framebuffer with
alpha:false, but the native desktop GL context still stores fragment alpha;
the readback path passed those low alpha bytes to the software compositor and
blended otherwise-correct rifle RGB toward white. Headless readback now honors
the requested WebGL contract by forcing alpha to 255. The focused regression
draws RGB with alpha zero and verifies opaque readback, while the frozen VLAN
replay verifies the textured rifle survives composition and that held movement
changes the first-person scene.
The final acceptance was repeated from a clean worktree at commit fecc3e2f.
The authentic dedicated server entered DM-Antalus, the client and server
exchanged native UDP through vln/1, the client created its D3D viewport, Fire
transitioned it from the join prompt to an owned pawn, and the captured frame
showed the HUD plus textured weapon and terrain. Both emulator processes exited
cleanly. The committed wall-clock test proves join and rendered gameplay;
deterministic held-key movement was additionally proved with a frozen
tools/ctl.js replay.
A fixed-wall-time profile of the map-load window (batches 6000--12000) retired
938 million handler operations. Raw x87 instructions were 26.85% of them, with
no single block over 2.23%, so the load is broad Unreal transform/material
work rather than one stuck loop. Enabling the existing experimental x87 fold
executed 27.3 million fused regions and advanced 25,179 batches in 140 seconds
versus 20,818 without it, about 21% farther on this run. The CLI candidate uses
--x87-fusion; browser runs can opt in with ?x87-fold.
SSE is now a separate per-app CPU policy rather than a global claim. The
ut2003_demo client and server advertise a Pentium III with CPUID EDX bit 25;
the default personality and the not-yet-exercised UT2004 entry still hide SSE.
Following the authentic UT2003 path added the instructions it actually reached:
exact SFENCE, MOVNTQ, memory MOVLPS, all eight CMPPS predicates, and
MOVMSKPS. Unknown SSE encodings continue to trap.
That policy also selects three MSVC/D3DDrv 64-byte MMX copy loops, including a
79-byte three-register pipelined MOVNTQ body at original D3DDrv VA
0x10001100. Each is recognized by a complete address-independent byte hash
and lowered through H419 to memory.copy only for proved-disjoint, page-local
mappings; overlap and split mappings retain the original instruction ordering.
The regression compares ordinary decoding with each lowering for copied bytes,
GPRs, flags, final MMX registers, overlap, page splits, and a one-byte near miss.
A clean authentic run reaches D3DDrv with no SSE decoder trap, but the shared
machine was under heavy concurrent load during the final timing run, so that
run is evidence of compatibility, not a defensible wall-time speedup measure.
The CLI software D3D backend reaches the same engine loop without an unimplemented API but rejects its GPU draw opcode; the native/browser WebGL backend remains the authoritative graphics verification.
UT3 API analysis
The fixed UT3 installer was executed directly in Wine Assembly. Its verified first runtime blocker is:
UuidToStringAat installer EIP0x00422225(batch 0).
Static PE import comparison against src/api_table.json found nine imported
names which are not implemented:
AdjustTokenPrivilegesGetThreadContextLookupPrivilegeValueARpcStringFreeASetThreadContextUuidToStringAVerLanguageNameAVirtualProtectExWriteProcessMemory
Installer strings also name seven MSI APIs resolved dynamically, so they do not appear in the static import table:
MsiCloseHandleMsiGetProductInfoAMsiGetSummaryInformationAMsiOpenDatabaseAMsiQueryProductStateAMsiSourceListEnumSourcesAMsiSummaryInfoGetPropertyA
Only MsiQueryProductStateW currently exists in the API table. UuidCreate is
already implemented through CoCreateGuid. This is an analysis inventory only;
none of the UT3 gaps were implemented.