Fire VISUALS wave: the authored firesmoke sheet, vertex-alpha effect cards, the case-4 wreck dressing
The "fireballs like the demo vids" arc, decomp/content-grounded end to end,
plus the live-play UX batch verified over the same sessions:
FIRESMOKE SHEET (the PFX fireball fix): every firesmokeN_scr_tex in BTFX.VMF
maps the SAME 64x64 tileable noise image bintA (variants differ only in SCROLL
rate) and firesmoke1_mtl colours it through the "fiery" ramp (0.3,0.1,0.1)->
(0.9,0.7,0.3). The particle layer now bakes ramp(lum(bintA)) as its sprite
colour (noise detail in alpha) and SCROLLS it at firesmoke1's authored rate
via a texture-transform; the port's radial soft-edge mask moved to a second
CLAMPed stage so the WRAPPED scroll rolls flame through the sprite without
scrolling the edge away. Old grit x radial bake kept as the no-BINTA fallback.
Impact hits, damage-band smoke and death booms all ride this layer.
AUTHORED TEXTURE SCROLL in the model path: the BMF TEXTURE records carry
SPECIAL " SCROLL u0 v0 du dv" (tag 0x2037); the draw path always supported
per-op scrolling (SetTextureScrolling) but the BGF loader never parsed it, so
every scrolling material rendered frozen. Wired TexRef -> MatInfo -> batch ->
L4TEXOP.doScroll: the flame cards (flamebig/fire5) now roll fire noise.
VERTEX-ALPHA EFFECT CARDS (the "twisted drill bit of fire" fix): FLAMEBIG's
verts carry authored float RGBA -- white-hot base (1.0,0.99,0.97) -> dark-red
tip fading to alpha -0.2 (the DPL clamp convention). The loader kept a flat
batch colour and drew it OPAQUE = a solid orange spike. Corpus sweep: exactly
14 shipped BGFs carry vertex alpha, ALL effect cards (flames, MUZFLASH,
EXDISK_A/B/C, TMST_A/B/C, beam models, DECLOUDS). Such batches now keep the
authored per-vertex gradient and route to the alpha-blend pass, unlit,
colour = texture x gradient, alpha = the vertex fade; sky objects excluded
(drawAsSky + alphaTest passes NEITHER pass filter -- DECLOUDS stays in the
sky pass). MUZFLASH/EXDISK render correctly for free when the muzzle-model
work lands.
WRECK DRESSING (the 1996 ExplosionScripts case-4 transcription): pieces spawn
HIDDEN and reveal 0.25s after the boom (the InstanceSwitch delay, behind the
dnboom flash); flamebig hangs over the pile, Y-BILLBOARDED at the camera
(SetOffsetYaw + a camera-pos getter -- the dpl_SetDCSReorientAxes analog);
the MakeDCSFall settle arms at the reveal with the two authored rates (hulk/
debris -0.025 t^2, fires -0.01 t^2 -- the flames ride above the sinking pile
and die with it at burial). EMPTY-PLACEHOLDER hulk guard: THRDBR.BGF is a
153-byte zero-geometry stub that "loads fine" -- vertex-count check now routes
it to the gendbr fallback (a Thor wreck was invisible). Hulk content census
recorded: AVADBR==MADDBR==VULDBR geometry (palette-only prefix diffs),
RAPDBR==SNDDBR==STIDBR byte-identical -- wreck variety is materials + the
dressing, not unique piles.
LIVE-PLAY BATCH: muzzle resolve uses the named segmentIndex (raw +0xdc read
was layout garbage); forward launch frame (authored MuzzleVelocity +Z vs the
mech's -Z facing); dock-bottom single window (gauge strip appended below the
world viewport, 1100x600 default, BT_DEV_GAUGES_WINDOW=1 restores the separate
window); portrait sec surface unrotated CW; ammo counters live via typed
bridges (BTAmmoBinCountPtr/BTAmmoBinFeeding/BTWeaponAmmoBin -- raw bin+0x180
and a hand-rolled link walk were garbage); fourth fire key ('4' = Pinky);
panel/arc probes de-aliased (%61 prime).
KB: rendering.md (vertex-alpha card family + scroll), combat-damage.md (hulk
census + THRDBR stub), gauges-hud.md (ammo bridges).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
bb795e2805
commit
48c9c8444f
@@ -109,13 +109,48 @@ static bool DevGaugeComposite()
|
||||
return v != 0;
|
||||
}
|
||||
|
||||
// DOCK-BOTTOM (2026-07-12, single-window mode): the gauge strip is APPENDED to
|
||||
// the main window's bottom band -- the world renders in the top region via a
|
||||
// restricted viewport, the strip in the remainder, everything scales with the
|
||||
// window. Enabled by btl4main when BT_DEV_GAUGES is set (BT_DEV_GAUGES_WINDOW=1
|
||||
// restores the separate-window mode). Strip height = width x (480/1320), the
|
||||
// panel's design aspect.
|
||||
int gBTGaugeDockBottom = 0;
|
||||
static const float kBTDockStripRatio = 480.0f / 1320.0f;
|
||||
|
||||
// The strip's height for a given window width: proportional to width at the
|
||||
// panel's design aspect, CAPPED at the design height (480) -- a very wide
|
||||
// window renders the strip at native 1:1 instead of upscaling it.
|
||||
int BTGaugeStripHeightFor(int width)
|
||||
{
|
||||
int h = (int)((float)width * kBTDockStripRatio);
|
||||
return (h > 480) ? 480 : h;
|
||||
}
|
||||
|
||||
// Restrict rasterization to the WORLD region (target minus the bottom strip).
|
||||
// Called by the main renderer right after BeginScene; no-op unless dock-bottom.
|
||||
void BTApplyWorldViewport(LPDIRECT3DDEVICE9 device)
|
||||
{
|
||||
if (!gBTGaugeDockBottom || device == NULL) return;
|
||||
IDirect3DSurface9 *rt = NULL;
|
||||
if (FAILED(device->GetRenderTarget(0, &rt)) || rt == NULL) return;
|
||||
D3DSURFACE_DESC d;
|
||||
rt->GetDesc(&d);
|
||||
rt->Release();
|
||||
DWORD stripH = (DWORD)BTGaugeStripHeightFor((int)d.Width);
|
||||
if (stripH == 0 || stripH >= d.Height) return;
|
||||
D3DVIEWPORT9 vp = { 0, 0, d.Width, d.Height - stripH, 0.0f, 1.0f };
|
||||
device->SetViewport(&vp);
|
||||
}
|
||||
|
||||
// DEV-COMPOSITE: BT_DEV_GAUGES_DOCK=1 docks the 6-surface panel INTO the main 800x600
|
||||
// window (occludes the 3D view); default (unset) presents them in a SEPARATE window.
|
||||
// window (occludes the 3D view); dock-bottom (above) also counts as docked --
|
||||
// both suppress the separate gauge window and draw via the main-window inset.
|
||||
static bool DevGaugeDocked()
|
||||
{
|
||||
static int v = -1;
|
||||
if (v < 0) v = (getenv("BT_DEV_GAUGES_DOCK") != NULL) ? 1 : 0;
|
||||
return v != 0;
|
||||
return v != 0 || gBTGaugeDockBottom != 0;
|
||||
}
|
||||
|
||||
//===========================================================================//
|
||||
@@ -285,6 +320,22 @@ void BTDrawGaugeSurfaces(LPDIRECT3DDEVICE9 device, float px, float py, float pw,
|
||||
IDirect3DStateBlock9 *stateBlock = NULL;
|
||||
device->CreateStateBlock(D3DSBT_ALL, &stateBlock);
|
||||
|
||||
// DOCK-BOTTOM: the world pass restricted the viewport to the top region;
|
||||
// the strip's pretransformed quads land BELOW it and would be clipped.
|
||||
// Draw with the FULL target viewport (the captured state block restores
|
||||
// the world viewport afterwards).
|
||||
{
|
||||
IDirect3DSurface9 *rt = NULL;
|
||||
if (SUCCEEDED(device->GetRenderTarget(0, &rt)) && rt != NULL)
|
||||
{
|
||||
D3DSURFACE_DESC d;
|
||||
rt->GetDesc(&d);
|
||||
rt->Release();
|
||||
D3DVIEWPORT9 vp = { 0, 0, d.Width, d.Height, 0.0f, 1.0f };
|
||||
device->SetViewport(&vp);
|
||||
}
|
||||
}
|
||||
|
||||
// Reach the shared display once (any present port shares the same SVGA16/pixelBuffer).
|
||||
SVGA16 *svga = NULL;
|
||||
for (int i = 0; i < 6 && svga == NULL; i++)
|
||||
@@ -335,8 +386,23 @@ void BTDrawGaugeSurfaces(LPDIRECT3DDEVICE9 device, float px, float py, float pw,
|
||||
void BTDrawGaugeInset(LPDIRECT3DDEVICE9 device)
|
||||
{
|
||||
if (!DevGaugeComposite() || !DevGaugeDocked() || device == NULL) return;
|
||||
// DOCKED mode only: draw into the main backbuffer (this runs before EndScene).
|
||||
// Keep the new panel's 1320:480 aspect (2.75) so nothing distorts.
|
||||
if (gBTGaugeDockBottom)
|
||||
{
|
||||
// DOCK-BOTTOM: the strip owns the bottom band of the target (the world
|
||||
// viewport excludes it) -- full width, design-aspect height.
|
||||
IDirect3DSurface9 *rt = NULL;
|
||||
if (FAILED(device->GetRenderTarget(0, &rt)) || rt == NULL) return;
|
||||
D3DSURFACE_DESC d;
|
||||
rt->GetDesc(&d);
|
||||
rt->Release();
|
||||
float stripH = (float)BTGaugeStripHeightFor((int)d.Width);
|
||||
if (stripH <= 0.0f || stripH >= (float)d.Height) return;
|
||||
BTDrawGaugeSurfaces(device, 0.0f, (float)d.Height - stripH,
|
||||
(float)d.Width, stripH);
|
||||
return;
|
||||
}
|
||||
// Legacy overlay dock (BT_DEV_GAUGES_DOCK): fixed inset over the 3D view.
|
||||
// Keep the panel's 1320:480 aspect (2.75) so nothing distorts.
|
||||
BTDrawGaugeSurfaces(device, 2.0f, 400.0f, 540.0f, 540.0f / 2.75f);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user