# OH1 evidence — retail alpha classification and list contract **Campaign:** OVERHAUL / OH1 **Status:** evidence complete; behavior belongs to OH7 **Retail build:** September 2013 End of Retail **Arbitration:** named-retail pseudo-C plus Ghidra/disassembly for field offsets This note closes the bounded alpha ambiguity left by the first OH1 synthesis. It is an executable contract for OH7, not permission to change alpha order before OH5 restores the landscape/building/object walk that owns the barriers. ## 1. Retail anchors | Retail symbol | Address | Contract established here | |---|---:|---| | `D3DPolyRender::ConstructMesh` | `0x0059DFA0` | initial/final subset mask | | `D3DPolyRender::DrawMesh` | `0x0059D4A0` | immediate versus delayed branch table | | `D3DPolyRender::AddMeshToAlphaList` | `0x0059C230` | list selection, capacity, entry state | | `D3DPolyRender::FlushAlphaList` | `0x0059D2E0` | threshold and drain order | | `D3DPolyRender::RenderMeshSubset` | `0x0059CA10` | delayed replay/detail behavior | | `D3DPolyRender::SetSurface` | `0x0059C4D0` | clip-map override behavior | | `D3DPolyRender::Begin` | `0x0059EAD0` | delay-mask registry binding | | `RenderDeviceD3D::DrawEnvCell` | `0x0059F170` | environment-detail owner | | `RenderDeviceD3D::DrawBuilding` | `0x0059F2A0` | building-detail owner and barrier | | `RenderDeviceD3D::DrawPartCell` | `0x005A07A0` | ordinary-object detail reset | | `RenderDeviceD3D::DrawBlock` | `0x005A18D0` | per-land-cell emergency barrier | | `PView::DrawCells` | `0x005A4840` | post-landscape full barrier | | `SmartBox::RenderNormalMode` | `0x00453AA0` | top-level full barrier | | `LScape::CleanupDetailSurfaces` | `0x00504AE0` | detail-surface release/reset | | `LScape::SetDetailTexturing` | `0x00506B40` | detail-surface regeneration | | `LScape::ChangeRegion` | `0x00506CB0` | detail preference application | | `GameSky::Draw` | `0x00506FF0` | `m_currentlyDrawingSky` producer | | `Render::SetOverallGraphicsQuality` | `0x0054B020` | `MultiPassAlpha` quality defaults | | `Render::Startup` | `0x0054E9B0` | preference registration/safe override | The named-retail pseudo-C establishes the control flow. Ghidra and instruction disassembly arbitrate the two facts for which a wrong field name changes the branch meaning: the renderer byte at `+0x7E0` is `m_currentlyDrawingSky`, while material-alpha mode is at `+0x794`; and polygon stippling is compared as a **signed** byte. ## 2. Exact constructed subset mask For each source surface, `ConstructMesh` chooses exactly one initial mask by this priority: ```text if (Surface.Type & 0x00010300) != 0: mask = 0x02 else if (Surface.Type & 0x00000004) != 0: mask = 0x08 else if (Surface.Type & 0x00000010) != 0: mask = 0x04 else: mask = 0x00 ``` `0x00010300` is the union of `ALPHA (0x100)`, `INVALPHA (0x200)`, and `ADDITIVE (0x10000)`. The order is material: a surface carrying both an alpha-family bit and `BASE1_CLIPMAP` receives mask `0x02`, not `0x08`. For each polygon, retail then ORs bit `0x01` into the **positive surface's** mask only when `(signed char)polygon.stippling > 0`. Raw bytes `0x80..0xFF` therefore do not set the bit. The complete constructed mask domain is: | Surface class | Without positive stippling | With positive stippling | |---|---:|---:| | plain | `0x00` | `0x01` | | alpha / inverse-alpha / additive | `0x02` | `0x03` | | translucent | `0x04` | `0x05` | | clip map | `0x08` | `0x09` | Bit `0x01` is absent from the registry help text, but a configured delay mask still intersects it normally. It is a retail quirk, not a flag to normalize. ## 3. Delay-mask and preference state `s_AlphaDelayMask @ 0x00820D88` has static default `0x0E`. Its only behavior read is in `DrawMesh`; `D3DPolyRender::Begin` exposes it as `RenderD3D.AlphaDelayMask` with help for Alpha=`2`, Translucent=`4`, and ClipMap=`8`. The registry may replace the value. Unsupported higher bits can keep the outer delay gate nonzero but never intersect a constructed mask. `m_RenderPrefs.MultiPassAlpha @ 0x0081EF96` has static default false. `SetOverallGraphicsQuality` selects false for quality levels 1–3 and true for levels 4–5. Startup registers the user preference, and the safe-render branch forces it false. `DrawMesh` is its sole draw-path reader; `DetermineOverallGraphicsQuality` also reads it while deriving the aggregate quality setting. The building and environment detail globals default null. Their only writers are `SetBuildingDetailSurface` and `SetEnvironmentDetailSurface`; region cleanup clears/releases them, and region detail setup regenerates both from the `EnvironmentDetailTextures` preference. Generation may still yield null. ## 4. Exact `DrawMesh` branch table After the subset passes its ordinary draw-eligibility gate, apply these rows in order: | Priority | Condition | Result | |---:|---|---| | 1 | `m_currentlyDrawingSky` **or** delay mask is zero **or** `curr_detail_surface != null` | render immediately; enqueue nothing | | 2 | `MultiPassAlpha && (subsetMask & 0x08) != 0` | append to **CLIP** with `overrideClipmap=true`, then also render immediately with `overrideClipmap=false` | | 3 | `(delayMask & subsetMask) != 0` | append to **CLIP** iff bit `0x08` is set, otherwise **ALPHA**; no immediate draw | | 4 | `(delayMask & 0x04) != 0 && currentMaterial != null && currentMaterial.has_alpha != 0` | append to **ALPHA**; no immediate draw | | 5 | otherwise | render immediately | Row 2 depends on the global delay mask being nonzero because it is inside the outer delay gate, but it does **not** require delay-mask bit `0x08`. It is the clip-map base pass now plus an alpha-blended second pass later. Under default delay mask `0x0E`: - masks `0x02/0x03` and `0x04/0x05` enter ALPHA; - masks `0x08/0x09` enter CLIP, with the additional immediate pass when `MultiPassAlpha` is true; - masks `0x00/0x01` are immediate unless the material-alpha fallback applies. `overrideClipmap=false` lets `SetSurface` enable the clip-map alpha-test arm. `overrideClipmap=true` selects the alpha-blend arm and suppresses that clip-map alpha-test arm. Immediate rendering passes `detailEnabled=(curr_detail_surface != null)`; delayed replay always passes `detailEnabled=false`. ## 5. List entry, capacity, and replay Retail owns two independent static arrays of 3000 `AlphaListEntry` records and two `uint16` counts. `AddMeshToAlphaList` appends strictly FIFO; it performs no distance or material sort. Each `DrawMesh` invocation owns two independent `first-for-this-list` flags. The first subset appended to each list captures the current `CMaterial` and object matrix and sets `bNewObject=true`. Later entries for that list inherit that state during replay. The entry also stores `overrideClipmap`; it stores no portal view, clip planes, cell, or part identity. When a list is already at capacity, append returns false. A non-multipass delayed subset has no immediate fallback draw. Exact capacity behavior must be preserved and tested rather than silently expanded or recovered differently. `FlushAlphaList(threshold)` returns false without changing either list only when **both** counts are below `threshold * 3000`. Otherwise it drains the entire CLIP list in append order, resets it, then drains the entire ALPHA list in append order and resets it. It restores the object matrix after replay; it does not restore the material. The DrawBlock threshold is the immutable global `0.75`, so equality at 2250 in either list triggers a full two-list drain. ## 6. Detail owner consequences - `DrawEnvCell` installs the environment detail surface, calls the built `DrawMesh(skipNoTexture=true)` path, then clears the current detail. A non-null environment detail makes every eligible subset immediate. - `DrawBuilding` installs building detail, performs `FlushAlphaList(0)` before portal/part/shell work, then draws its forced portal-BSP pass and normal built shell. A non-null building detail makes the shell immediate. - `DrawBuildingLeaf` preserves outer state, but `DrawPartCell` explicitly forces current detail null. Ordinary leaf parts can therefore enqueue even when their containing building shell uses detail. - Ordinary object-cell GfxObj paths do not install the separate object detail surface; their current detail is normally null. ## 7. Exact normal-world flush barriers 1. `DrawBuilding` calls `FlushAlphaList(0)` after installing building detail and before any building portal/leaf/shell draw. Delayed replay itself has detail disabled. 2. `DrawBlock` visits each admitted land cell as `DrawLandCell` followed by `DrawSortCell` (building, then objects), then calls `FlushAlphaList(0.75)`. This is normally an emergency capacity drain. 3. `PView::DrawCells` calls `FlushAlphaList(0)` after outside landscape and before the mid-frame stamp/depth-clear/interior repaint block. 4. `SmartBox::RenderNormalMode` calls `FlushAlphaList(0)` after the complete world path. The fifth retail caller is the private `CreatureMode::Render @ 0x004529D0` (call site `0x00452BF0`). After `DrawObjCellForDummies(creature_cell)` and its frame pop, that private presentation mode calls `FlushAlphaList(0)`. It is not part of the normal-world OH5/OH7 ordering cutover, but it must remain an exact consumer of the shared two-list implementation. Consequently, OH7 cannot be implemented faithfully while current acdream still stages all terrain before all building/object turns. OH5 must first restore the per-cell landscape interleave on which these barriers operate. ## 8. Required OH7 cutover Current `RetailAlphaQueue` is a single scope-global, viewer-distance-sorted stream with an approximate `FlushFartherThan`. Retail instead requires: - separate CLIP and ALPHA FIFO lists; - no queue-level sort; - preservation of upstream cell order, `CShadowPart` order, and authored subset order; - raw surface type plus the exact constructed mask and positive-surface stippling ownership; - `overrideClipmap` and independent per-list object-boundary state; - the multipass clip-map immediate-plus-delayed duplicate; - material `has_alpha` fallback; - sky/detail immediate gates and delayed `detailEnabled=false`; - exact capacity and threshold behavior; - full drains at the exact building, landscape, and top-level barriers. Runtime state remains configurable: registry may override delay mask, the user preference may override MultiPassAlpha, and detail generation may return null. Those are input states to the exact branch table, not unresolved branch sense.