Dated source reference. Current release status: handoff state. Full original relative paths are in the developer archive.
Graphics device boot and frame boundary
Historical supporting milestone. Runtime/build observations, paths and next-step statements below belong to their recorded source/date. They are not a current native-engine objective or current machine-installation inventory. Use current state, plan and API verification for active work; original research evidence remains unchanged.
Current scope (October13,2026): Windows-first deep editing and a public extension API; Mac/Linux compatibility follows later. Earlier native-port goals and next-step proposals in this evidence history are superseded. Technical observations and verification limits remain as recorded.
Investigation of the supplied original NBA 2K14 executable on October 12, 2026. Executable SHA-256: becdfca16a88f656bc20dde608bd38becf0b8e04bf41c8041d344e37d20e1d67; addresses are preferred VAs at base 0x00400000.
Historical checkpoint: this document describes the original CD executable before the supplied ISO variant became available. Later Windows gameplay and runtime-loop evidence are in APPLICATION-LOOP.md; the old launch blockers below are not the current project status.
The graphics worker now connects statically to actual Direct3D device creation, BeginScene, EndScene and Present, beyond the adapter enumeration identified earlier. These routines have not executed in the reference-game launch, which still stops at SecuROM 8016. No native engine or native device implementation is claimed here. The alternate executable remains in the user's Trash until they restore/copy it through Finder; direct filesystem access was denied.
Two distinct interfaces
The game's graphics-module interface and Microsoft's COM interfaces are different tables. For the DEFAULT and LOCKSTEP modules, their original tables at 0x00FDF2E4 and 0x00FDF334 contain:
| Game module byte offset | Module method | Final boundary |
|---|---|---|
+0x14 |
0x00E0D660 |
Direct3DCreate9(32) through delayed thunk 0x00E1BBB6 |
+0x18 |
0x00E0D760 |
Tail-jumps to device-creation wrapper 0x00E0D560 |
+0x3C |
0x00E0D720 |
Tail-jumps to 0x00E0BA60, which calls IDirect3DDevice9 BeginScene, COM offset +0xA4 |
+0x40 |
0x00E0D730 |
Tail-jumps to 0x00E0BB00, which calls EndScene, COM offset +0xA8 |
+0x44 |
0x00E0D740 |
Tail-jumps to 0x00E0BBC0, which calls Present, COM offset +0x44 |
COM offsets are independently enumerated from the archived Wine 11.18 d3d9.h declaration, including IUnknown's first three slots. This avoids confusing IDirect3D9::CreateDevice at +0x40 with another interface's method at the same offset. Exact instruction and table evidence.
CreateDevice wrapper: original bytes exercised
0x00E0D560 receives the graphics object in ECX and a presentation-parameter buffer in EDX. It calls builder 0x00E0B650, using the object's HWND at +0x850 and settings returned by 0x00DA3A90. It then chooses an IDirect3D9 interface by current thread:
| Thread comparison | Global-state interface field |
|---|---|
Current thread equals state +0x21D38 |
+0x21E94 |
Otherwise equals state +0x21E88 |
+0x21E8C |
| Otherwise | +0x21E80 |
The call at 0x00E0D627 uses IDirect3D9 vtable offset +0x40. Its x86 stack arguments, excluding the return address, are:
- Selected interface pointer (
this). - Adapter index from settings
+0x50. - Device type from graphics object
+0. - Focus window: graphics object
+0x850, or fallback context+0xCif zero. - Behavior flags from graphics object
+4. - Presentation-parameter buffer supplied in EDX.
- Address of the local output device pointer.
The wrapper returns the output pointer only when HRESULT is exactly zero; any nonzero result returns null. Do not silently replace this with a generic nonnegative-HRESULT predicate when reproducing the wrapper. Presentation-buffer construction occurs before choosing the fallback focus window, so its HWND input can be zero while CreateDevice's focus window is nonzero.
Probe script executes the original 223-byte wrapper in Unicorn 2.1.4. 18 cases passed: three thread selections, existing/fallback window, and HRESULT values 0, 1, 0x8876086A. Each checks all seven call arguments, exactly one builder/CreateDevice invocation, buffer forwarding, return value, balanced stack and preserved EBX/ESI/EDI/EBP. The source image is hash-locked. Report records exact bytes, Capstone disassembly, package versions, source-header hash and every case: device boot probe.
Mocked dependencies: global/settings/fallback accessors, parameter builder, GetCurrentThreadId and CreateDevice. The test validates the original wrapper's ABI/data flow, not those dependencies, a real GPU, Wine behavior or native reconstruction. Fixture adapter/flags/handles are deliberately distinguishable values and are not measurements of shipped settings.
Work dispatch and per-frame path
The previously identified worker uses the work-record index at +0xC. Its tables and the synchronous lifecycle dispatcher at 0x00E0E440 agree on these entries:
| Index | Identified action |
|---|---|
| 2 | Worker exit flag path |
| 3 | 0x00E0C730: invoke module window creation (+0x2C), obtain/store HWND, then module show/configuration method (+0x28) |
| 4 | Invoke module window teardown (+0x30) |
| 5 | 0x00E0D900: create/store IDirect3D9 through module +0x14, query capabilities/formats, create/store device through module +0x18 |
| 6 | 0x00E0C280: release resources/interfaces through module methods and clear cached pointers |
| 7 | Module +0x48 -> 0x00E0E850 -> 0x00E0DE00; reconfiguration/reset candidate, exact behavior unresolved |
| 8 | 0x00E0D1FB branch in 0x00E0D1A0: frame-work path using global state +0x308C, calls 0x00E0C7C0 |
Table entries are statically verified for these indices; valid caller ranges and all work-record contracts remain unproved. Index 0 also reaches 0x00E0C7C0 with different inputs; do not assume every invocation draws a frame.
0x00E0C7C0 selects a device from state fields +0x21E98, +0x21E90 or +0x21E84, using corresponding thread checks. It invokes TestCooperativeLevel (COM +0xC) and recognizes 0x88760868/69 (DEVICELOST/DEVICENOTRESET in the archived header). It conditionally runs scene begin/end, invokes additional resource/render work, clears several bindings, then calls the graphics module's Present method. Exact shader/draw workload and higher-level simulation/menu setup are not recovered.
The Present wrapper's COM call at 0x00E0BC4E passes the selected device and four null optional arguments. It also manages a separate query ring/wait path, which remains outside the tested CreateDevice wrapper. This evidence identifies a frame-submission boundary; it does not verify a displayed frame.
Reproduction and next dependency
.venv/bin/python tools/recover_d3d_boundary.py
.venv/bin/python tools/probe_device_boot.py
The static exporter checks twelve complete instruction ranges, five shared game-module slots, and three dispatch tables. Read-only Ghidra exports are retained in worker handlers and D3D boundaries. Ghidra fails to decompile 0x00E0D1A0 after its indexed branch and sees only the entry of 0x00E0E440; exact Capstone instruction ranges and table bytes fill that evidence gap. Other pseudocode still has incorrect stack/calling-convention assumptions and is not portable source.
This historical boot investigation identified useful graphics boundaries. The Windows reference game now runs; current renderer work should serve a concrete custom-presentation or device-lifetime requirement. Replacing D3D9 or reconstructing native boot is not a prerequisite for the current deep-editing plan. See the current scope and API integration log.
Follow-up: application-side startup establishes ordered window/device work submissions and identifies the readable repeated-render callers as loading-animation routines, not the full game loop.