Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe49fd5eba | ||
|
|
2f9c1146a3 | ||
|
|
ccfa875b65 |
@@ -115,6 +115,28 @@ each, so they cover the foot band too, and the hit test takes the first match
|
|||||||
what keeps 0x16/0x17/0x1F/0x1E reachable. That class of bug is why the verification below tests
|
what keeps 0x16/0x17/0x1F/0x1E reachable. That class of bug is why the verification below tests
|
||||||
first-hit reachability, not mere presence.
|
first-hit reachability, not mere presence.
|
||||||
|
|
||||||
|
**A FLASHING radar button goes RED — `BT_RADAR_FLASH_RED` (2026-08-14, player request)
|
||||||
|
[T2 pixel-measured]. GLASS-ONLY DEVIATION (#154-class).** The radar's buttons are the yellow
|
||||||
|
class, so an alerting lamp pulsed *yellow among yellows* — a brightness change only, and the
|
||||||
|
night-16 miss that also produced the #172 ring and the protrusion bonus. The three desktop
|
||||||
|
renderers now swap the **bright** colour of a **flashing** radar button to the house red
|
||||||
|
(230,70,70 — the MFD family), so an alert reads as a *colour* change. Only the bright phase
|
||||||
|
moves; dim/off keep the yellow family, so a non-alerting radar button is unchanged. One
|
||||||
|
decode, `BTRadarLampBright(lampState)` in `L4VB16.h` beside `BTLampBrightnessOf`, consumed by
|
||||||
|
all three renderers (`CkLampColors` in the surround, `PaintGlass` in the exploded windows,
|
||||||
|
`L4PADPANEL`) so they cannot drift — the lesson of the L4RIOBANK geometry split. `=0` restores
|
||||||
|
the yellow bright. The pod's own buttons are single-colour backlit hardware and cannot do this;
|
||||||
|
the serial RIO lamp path is untouched, so this is desktop-only by construction.
|
||||||
|
|
||||||
|
**Bench hook `BT_LAMPTEST=<addr>[,<state>]` (2026-08-14).** Forces ONE lamp's state at
|
||||||
|
`PadRIO::GetLampState` — the single read point all three desktop renderers share — so lamp
|
||||||
|
rendering can be checked without inducing the fault that would raise it (a generator trip, an
|
||||||
|
ammo alarm). Default state `0x33` = the Panic lamp's alert shape (flashFast + state1Off +
|
||||||
|
state2Bright, a hard dark/bright pulse); addresses and states take `0x` hex. This is how the
|
||||||
|
red-flash change above was verified: `BT_LAMPTEST=0x1b` (GeneratorB's radar lamp, the night-16
|
||||||
|
one) then a pixel tally of the radar window — **620 house-red px with the feature on, 0 with
|
||||||
|
`BT_RADAR_FLASH_RED=0`**, and the yellow count falling by exactly that many (2820 → 2196).
|
||||||
|
|
||||||
## Sticky window placement — BT_GLASS_LAYOUT (2026-07-28) [T2 round-trip-verified]
|
## Sticky window placement — BT_GLASS_LAYOUT (2026-07-28) [T2 round-trip-verified]
|
||||||
|
|
||||||
The `BT_GLASS_PANELS` windows self-place in a pod-faithful ring around the main window
|
The `BT_GLASS_PANELS` windows self-place in a pod-faithful ring around the main window
|
||||||
|
|||||||
@@ -72,13 +72,16 @@ A. FIXED THIS BUILD -- PLEASE VERIFY (headliners first)
|
|||||||
The Nova spawned showing its REAR laser's range pips in the forward
|
The Nova spawned showing its REAR laser's range pips in the forward
|
||||||
view. The HUD now commits the forward view at spawn. (Only the pips
|
view. The HUD now commits the forward view at spawn. (Only the pips
|
||||||
were wrong -- rear weapons never actually fired forward.)
|
were wrong -- rear weapons never actually fired forward.)
|
||||||
#151 (Oracle) Panic eject scored -499
|
#151 (Oracle) Panic eject scored -499 -- CORRECTION: -499 IS the machine
|
||||||
Solved, and the machine agrees with YOUR math: eject = your mech
|
Our line here was wrong (we mis-read our own ticket history; the
|
||||||
self-destructs (scored as self-damage, ~-500) + the death cost
|
correct decode was already on the ticket). Bench-verified: eject
|
||||||
(-500) = about -1000, i.e. 1000 points -> roughly ZERO. The extra
|
is scored as SUICIDE (about -999, the kill value of your own
|
||||||
-500 you saw was the #162 double-death bug, fixed on testing night.
|
mech) PLUS the death cost (-500). 1000 - 999 - 500 = -499
|
||||||
TEST: repeat the maneuver -- you should land within a few points
|
exactly -- the original's own arithmetic, reproduced three times
|
||||||
of zero, not hundreds below.
|
on the bench, never doubled. If you eject tonight and land at
|
||||||
|
-499 again, the machine is RIGHT, not broken.
|
||||||
|
DESIGN CALL (restored): keep the authentic ~-1500 swing, or
|
||||||
|
house-rule a flat eject cost? Opinions to the thread.
|
||||||
FEEL Three more fixes on the original's clock (same bug class as #173):
|
FEEL Three more fixes on the original's clock (same bug class as #173):
|
||||||
the cockpit HIT-SHAKE (was bouncing ~2x too fast -- hits now rock
|
the cockpit HIT-SHAKE (was bouncing ~2x too fast -- hits now rock
|
||||||
you at the pod's pace with less rebound), the FOOTSTEP loudness
|
you at the pod's pace with less rebound), the FOOTSTEP loudness
|
||||||
@@ -200,7 +203,7 @@ G. INTERNAL ENGINEERING BACKLOG (nothing to test)
|
|||||||
|
|
||||||
=============================================================================
|
=============================================================================
|
||||||
End of list. 57 open issues total:
|
End of list. 57 open issues total:
|
||||||
17 verify (3 headliners), 12 reproduce, 6 era questions, 2 design calls,
|
16 verify (3 headliners), 12 reproduce, 6 era questions, 3 design calls,
|
||||||
10 known gaps, 11 internal -- plus 4 "not bugs" that are the real machine.
|
10 known gaps, 11 internal -- plus 4 "not bugs" that are the real machine.
|
||||||
Since Wednesday: 15 fixes fielded, 4 tickets closed by evidence alone, and
|
Since Wednesday: 15 fixes fielded, 4 tickets closed by evidence alone, and
|
||||||
Oracle's questionnaire + soundboard find settled five more. Your reports
|
Oracle's questionnaire + soundboard find settled five more. Your reports
|
||||||
|
|||||||
@@ -1472,14 +1472,21 @@ static void
|
|||||||
const GButton &b = w->buttons[i];
|
const GButton &b = w->buttons[i];
|
||||||
const RECT &r = b.rect;
|
const RECT &r = b.rect;
|
||||||
int held = (b.address == pressedAddress) || latched[b.address & 0x7F];
|
int held = (b.address == pressedAddress) || latched[b.address & 0x7F];
|
||||||
int shade = LampBrightnessOf(PadRIO::GetLampState(b.address), tick);
|
int lampState = PadRIO::GetLampState(b.address);
|
||||||
|
int shade = LampBrightnessOf(lampState, tick);
|
||||||
if (held)
|
if (held)
|
||||||
shade = 3;
|
shade = 3;
|
||||||
|
|
||||||
|
// A FLASHING radar button goes RED at its bright phase (L4VB16.h).
|
||||||
|
unsigned long radarBright = BTRadarLampBright(lampState);
|
||||||
|
COLORREF radarBrightRGB = RGB((radarBright >> 16) & 0xFF,
|
||||||
|
(radarBright >> 8) & 0xFF,
|
||||||
|
radarBright & 0xFF);
|
||||||
|
|
||||||
COLORREF fill, text_color;
|
COLORREF fill, text_color;
|
||||||
if (b.color == ClrYellow)
|
if (b.color == ClrYellow)
|
||||||
{
|
{
|
||||||
fill = (shade == 3) ? RGB(245, 210, 60)
|
fill = (shade == 3) ? radarBrightRGB
|
||||||
: (shade != 0) ? RGB(140, 118, 38)
|
: (shade != 0) ? RGB(140, 118, 38)
|
||||||
: RGB(70, 60, 24);
|
: RGB(70, 60, 24);
|
||||||
text_color = RGB(0, 0, 0);
|
text_color = RGB(0, 0, 0);
|
||||||
@@ -1501,7 +1508,7 @@ static void
|
|||||||
// Solid lamp fill + a bright border. Under the imagery, only the protruding
|
// Solid lamp fill + a bright border. Under the imagery, only the protruding
|
||||||
// edge shows once the surface is blitted on top.
|
// edge shows once the surface is blitted on top.
|
||||||
{
|
{
|
||||||
COLORREF bright = (b.color == ClrYellow) ? RGB(245, 210, 60)
|
COLORREF bright = (b.color == ClrYellow) ? radarBrightRGB
|
||||||
: (b.color == ClrBlue) ? RGB(205, 228, 255)
|
: (b.color == ClrBlue) ? RGB(205, 228, 255)
|
||||||
: RGB(230, 70, 70);
|
: RGB(230, 70, 70);
|
||||||
HBRUSH face = CreateSolidBrush(fill);
|
HBRUSH face = CreateSolidBrush(fill);
|
||||||
|
|||||||
@@ -290,14 +290,21 @@ static void
|
|||||||
// commanded lamp state (with flash phase) decides.
|
// commanded lamp state (with flash phase) decides.
|
||||||
//
|
//
|
||||||
int shade = 0;
|
int shade = 0;
|
||||||
|
int lampState = 0;
|
||||||
if (lamp_capable)
|
if (lamp_capable)
|
||||||
{
|
{
|
||||||
shade = LampBrightnessOf(PadRIO::GetLampState(cell.address), tick);
|
lampState = PadRIO::GetLampState(cell.address);
|
||||||
|
shade = LampBrightnessOf(lampState, tick);
|
||||||
}
|
}
|
||||||
if (held)
|
if (held)
|
||||||
{
|
{
|
||||||
shade = 3;
|
shade = 3;
|
||||||
}
|
}
|
||||||
|
// A FLASHING radar/Sec button goes RED at its bright phase (L4VB16.h).
|
||||||
|
unsigned long radarBright = BTRadarLampBright(lampState);
|
||||||
|
COLORREF radarBrightRGB = RGB((radarBright >> 16) & 0xFF,
|
||||||
|
(radarBright >> 8) & 0xFF,
|
||||||
|
radarBright & 0xFF);
|
||||||
|
|
||||||
COLORREF fill;
|
COLORREF fill;
|
||||||
COLORREF text_color;
|
COLORREF text_color;
|
||||||
@@ -308,7 +315,7 @@ static void
|
|||||||
}
|
}
|
||||||
else if (yellow)
|
else if (yellow)
|
||||||
{
|
{
|
||||||
fill = (shade == 3) ? RGB(245, 210, 60)
|
fill = (shade == 3) ? radarBrightRGB
|
||||||
: (shade != 0) ? RGB(140, 118, 38)
|
: (shade != 0) ? RGB(140, 118, 38)
|
||||||
: RGB(70, 60, 24);
|
: RGB(70, 60, 24);
|
||||||
text_color = RGB(0, 0, 0);
|
text_color = RGB(0, 0, 0);
|
||||||
|
|||||||
@@ -1282,6 +1282,30 @@ int BTPadRIOActive(void)
|
|||||||
int
|
int
|
||||||
PadRIO::GetLampState(int unit)
|
PadRIO::GetLampState(int unit)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// BENCH HOOK (2026-08-14): BT_LAMPTEST=<addr>[,<state>] forces ONE lamp's
|
||||||
|
// state, so the desktop lamp rendering can be checked without inducing the
|
||||||
|
// fault that would raise it (a generator trip, an ammo alarm, ...). The
|
||||||
|
// default state is the alert shape the Panic lamp uses -- flashFast +
|
||||||
|
// state1Off + state2Bright (0x33), a hard dark/bright pulse. Addresses and
|
||||||
|
// states take 0x hex. Read once; every desktop renderer reads its lamps
|
||||||
|
// through here, so one hook covers the surround, the exploded windows and
|
||||||
|
// the pad panel alike.
|
||||||
|
//
|
||||||
|
static int s_testAddr = -2;
|
||||||
|
static int s_testState = 0x33;
|
||||||
|
if (s_testAddr == -2)
|
||||||
|
{
|
||||||
|
s_testAddr = -1;
|
||||||
|
const char *e = getenv("BT_LAMPTEST");
|
||||||
|
if (e != NULL)
|
||||||
|
sscanf(e, "%i,%i", &s_testAddr, &s_testState);
|
||||||
|
}
|
||||||
|
if (s_testAddr >= 0 && unit == s_testAddr)
|
||||||
|
{
|
||||||
|
return s_testState;
|
||||||
|
}
|
||||||
|
|
||||||
if (activeInstance == NULL || unit < 0 || unit >= LampCount)
|
if (activeInstance == NULL || unit < 0 || unit >= LampCount)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1028,12 +1028,17 @@ static void CkFill(LPDIRECT3DDEVICE9 dev, int x, int y, int w, int h, D3DCOLOR c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Lamp fill + border for a button, from the glass PaintGlass color ramps.
|
// Lamp fill + border for a button, from the glass PaintGlass color ramps.
|
||||||
static void CkLampColors(int colorClass, int shade, int inert, D3DCOLOR *fill, D3DCOLOR *border)
|
static void CkLampColors(int colorClass, int shade, int inert, D3DCOLOR *fill, D3DCOLOR *border,
|
||||||
|
int lampState = 0)
|
||||||
{
|
{
|
||||||
if (colorClass == 1) // yellow (radar)
|
if (colorClass == 1) // yellow (radar) -- RED while flashing (see L4VB16.h)
|
||||||
{
|
{
|
||||||
*border = D3DCOLOR_XRGB(245, 210, 60);
|
unsigned long bright = BTRadarLampBright(lampState);
|
||||||
*fill = (shade == 3) ? D3DCOLOR_XRGB(245, 210, 60)
|
D3DCOLOR brightC = D3DCOLOR_XRGB((int)((bright >> 16) & 0xFF),
|
||||||
|
(int)((bright >> 8) & 0xFF),
|
||||||
|
(int)( bright & 0xFF));
|
||||||
|
*border = brightC;
|
||||||
|
*fill = (shade == 3) ? brightC
|
||||||
: (shade != 0) ? D3DCOLOR_XRGB(140, 118, 38)
|
: (shade != 0) ? D3DCOLOR_XRGB(140, 118, 38)
|
||||||
: D3DCOLOR_XRGB(70, 60, 24);
|
: D3DCOLOR_XRGB(70, 60, 24);
|
||||||
}
|
}
|
||||||
@@ -1218,7 +1223,7 @@ void BTDrawCockpitPanels(LPDIRECT3DDEVICE9 device)
|
|||||||
int shade = BTLampBrightnessOf(state, tick);
|
int shade = BTLampBrightnessOf(state, tick);
|
||||||
if (shade < 2) continue; // dark half-cycle: no ring
|
if (shade < 2) continue; // dark half-cycle: no ring
|
||||||
D3DCOLOR fill, border;
|
D3DCOLOR fill, border;
|
||||||
CkLampColors(b.colorClass, 3 /*bright*/, b.inert, &fill, &border);
|
CkLampColors(b.colorClass, 3 /*bright*/, b.inert, &fill, &border, state);
|
||||||
int rx = b.x - kRingGap - kRingWidth;
|
int rx = b.x - kRingGap - kRingWidth;
|
||||||
int ry = b.y - kRingGap - kRingWidth;
|
int ry = b.y - kRingGap - kRingWidth;
|
||||||
int rw = b.w + 2 * (kRingGap + kRingWidth);
|
int rw = b.w + 2 * (kRingGap + kRingWidth);
|
||||||
@@ -1239,7 +1244,7 @@ void BTDrawCockpitPanels(LPDIRECT3DDEVICE9 device)
|
|||||||
int shade = BTLampBrightnessOf(state, tick);
|
int shade = BTLampBrightnessOf(state, tick);
|
||||||
if (gCkPressed == b.address || gCkLatched[b.address & 0x7F]) shade = 3;
|
if (gCkPressed == b.address || gCkLatched[b.address & 0x7F]) shade = 3;
|
||||||
D3DCOLOR fill, border;
|
D3DCOLOR fill, border;
|
||||||
CkLampColors(b.colorClass, shade, b.inert, &fill, &border);
|
CkLampColors(b.colorClass, shade, b.inert, &fill, &border, state);
|
||||||
CkFill(device, b.x, b.y, b.w, b.h, border);
|
CkFill(device, b.x, b.y, b.w, b.h, border);
|
||||||
CkFill(device, b.x + 1, b.y + 1, b.w - 2, b.h - 2, fill);
|
CkFill(device, b.x + 1, b.y + 1, b.w - 2, b.h - 2, fill);
|
||||||
|
|
||||||
|
|||||||
@@ -110,6 +110,46 @@ inline int BTLampBrightnessOf(int state, unsigned long tick)
|
|||||||
return ((tick / half) & 1) ? level2 : level1;
|
return ((tick / half) & 1) ? level2 : level1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Is this lamp FLASHING rather than solid? Bits 0-1 of the wire word are the
|
||||||
|
// flash mode (0 = solid, 1/2/3 = slow/med/fast), so any non-zero value means
|
||||||
|
// the lamp is pulsing -- which is the pod's own way of saying ALERT.
|
||||||
|
//
|
||||||
|
// RADAR FLASH = RED (2026-08-14, player request; GLASS-ONLY DEVIATION). The
|
||||||
|
// radar's buttons are the yellow class, and a yellow lamp pulsing among other
|
||||||
|
// yellow lamps is easy to miss -- the night-16 miss that also produced the
|
||||||
|
// #172 ring and the protrusion bonus. The desktop renderers therefore swap
|
||||||
|
// the BRIGHT colour of a FLASHING radar button to the red family, so an alert
|
||||||
|
// reads as a colour change and not just a brightness change. The pod's own
|
||||||
|
// buttons are physical bicolour-less lamps and cannot do this, so it is a
|
||||||
|
// desktop affordance only -- and it is confined to the three desktop
|
||||||
|
// renderers (surround, exploded windows, pad panel); the serial RIO lamp
|
||||||
|
// path is untouched. BT_RADAR_FLASH_RED=0 restores the yellow bright.
|
||||||
|
//
|
||||||
|
inline int BTLampIsFlashing(int state)
|
||||||
|
{
|
||||||
|
return (state & 0x3) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The bright colour a radar (yellow-class) button should use right now: the
|
||||||
|
// red family while the lamp is flashing, its own yellow otherwise. ONE
|
||||||
|
// definition, consumed by all three desktop renderers so they cannot drift
|
||||||
|
// (the lesson of the L4RIOBANK geometry split). Returns 0x00RRGGBB.
|
||||||
|
//
|
||||||
|
inline unsigned long BTRadarLampBright(int lampState)
|
||||||
|
{
|
||||||
|
static int enabled = -1;
|
||||||
|
if (enabled < 0)
|
||||||
|
{
|
||||||
|
const char *e = getenv("BT_RADAR_FLASH_RED");
|
||||||
|
enabled = (e != 0 && e[0] == '0') ? 0 : 1; // default ON
|
||||||
|
}
|
||||||
|
return (enabled && BTLampIsFlashing(lampState))
|
||||||
|
? 0x00E64646ul // 230,70,70 -- the house red (MFD family)
|
||||||
|
: 0x00F5D23Cul; // 245,210,60 -- the radar's own yellow
|
||||||
|
}
|
||||||
|
|
||||||
//########################################################################
|
//########################################################################
|
||||||
//######################### Video16BitBuffered ###########################
|
//######################### Video16BitBuffered ###########################
|
||||||
//########################################################################
|
//########################################################################
|
||||||
|
|||||||
@@ -394,6 +394,14 @@ static const char *kEnvironIniDefault =
|
|||||||
"# Phosphor colour of the mono MFDs, RRGGBB. Default is a green tube.\n"
|
"# Phosphor colour of the mono MFDs, RRGGBB. Default is a green tube.\n"
|
||||||
"#BT_COCKPIT_TINT=21FF42\n"
|
"#BT_COCKPIT_TINT=21FF42\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"# A FLASHING button on the radar turns RED instead of yellow. The radar's\n"
|
||||||
|
"# buttons are all yellow, so a lamp calling for attention used to change only\n"
|
||||||
|
"# in BRIGHTNESS -- easy to miss with eleven other yellow buttons around it.\n"
|
||||||
|
"# Now the bright half of its flash is red, so an alert changes COLOUR. Only\n"
|
||||||
|
"# a flashing button is affected: a radar button doing nothing looks exactly as\n"
|
||||||
|
"# it always did. 1 = on (the default), 0 = keep the yellow.\n"
|
||||||
|
"#BT_RADAR_FLASH_RED=0\n"
|
||||||
|
"\n"
|
||||||
"# ---- Display ----------------------------------------------------------------\n"
|
"# ---- Display ----------------------------------------------------------------\n"
|
||||||
"\n"
|
"\n"
|
||||||
"# The cockpit is fitted into the window at ONE uniform scale, centred, with\n"
|
"# The cockpit is fitted into the window at ONE uniform scale, centred, with\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user