VDB: live palette strips in the render window (real-time view)
Draw the three VDB display palettes as 256-color bars along the bottom of the GL render window, updated every frame straight from the VDB storage -- a live view (like the Division output) instead of static snapshots. This matters because pal0 (secondary) animates and the earlier file dumps caught pal0/pal2 at their SVGAZeroPalette init (all black); live, pal2 is actually a rich 4-region color map (green/blue/red/gray-purple, 64 entries each) and pal1 the red/green/olive status palette. Toggle with VPX_VDBSTRIP=0. Also: VDB_PALDUMP now keeps the most-lit snapshot per group (max non-black bytes) so file dumps no longer capture the zero-init. VDBPalette storage moved above the render thread so rt_draw can read it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -405,6 +405,13 @@ static void vpx_write(Bitu port, Bitu val, Bitu iolen) {
|
||||
}
|
||||
}
|
||||
|
||||
/* VDB display-palette storage (shared: written by the VDB I/O handler on the
|
||||
* emulator thread, read by the GL thread for the live palette strips).
|
||||
* Declared here so rt_draw() below can see it. */
|
||||
struct VDBPalette { unsigned char waddr, raddr, sub, mask; unsigned char ram[768]; };
|
||||
static VDBPalette vdb_pal[3];
|
||||
static bool vpx_show_vdb_strips = true; /* draw live palette strips (VPX_VDBSTRIP=0 off) */
|
||||
|
||||
/* ================= Phase 3b: live render backend (VPX_RENDER=1) ==========
|
||||
* Reconstructs the DPL scene graph from the FIFO message stream (protocol
|
||||
* established in PHASE3-PROGRESS.md / render_capture.py) and draws each
|
||||
@@ -643,6 +650,34 @@ static void rt_draw(HDC dc, const VFrame &f, int cw, int ch) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_LIGHTING);
|
||||
}
|
||||
/* Live VDB palette strips: the three display color maps (secondary/aux1/
|
||||
* aux2) as 256-wide bars along the bottom, updating in real time as the
|
||||
* game rewrites them (VPX_VDBSTRIP=0 to hide). Read straight from the VDB
|
||||
* storage -- a torn read is invisible at this cadence. */
|
||||
if (vpx_show_vdb_strips) {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_LIGHTING);
|
||||
glMatrixMode(GL_PROJECTION); glLoadIdentity();
|
||||
glOrtho(0, cw, ch, 0, -1, 1); /* screen pixels, y-down */
|
||||
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
|
||||
int barh = 16, gap = 2;
|
||||
int total = 3 * barh + 2 * gap;
|
||||
int y0 = ch - total - 4;
|
||||
for (int g = 0; g < 3; g++) {
|
||||
float y = (float)(y0 + g * (barh + gap));
|
||||
glBegin(GL_QUADS);
|
||||
for (int i = 0; i < 256; i++) {
|
||||
float x0 = (float)i / 256.0f * cw;
|
||||
float x1 = (float)(i + 1) / 256.0f * cw;
|
||||
const unsigned char *e = &vdb_pal[g].ram[i * 3];
|
||||
glColor3ub(e[0], e[1], e[2]);
|
||||
glVertex2f(x0, y); glVertex2f(x1, y);
|
||||
glVertex2f(x1, y + barh); glVertex2f(x0, y + barh);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
SwapBuffers(dc);
|
||||
}
|
||||
|
||||
@@ -1083,8 +1118,6 @@ static void vpx_render_start(void) {}
|
||||
* later; reads return 0xFF. Active when VPXLOG is set; logs to the same file. */
|
||||
static const io_port_t VDB_BASE = 0x300;
|
||||
|
||||
struct VDBPalette { unsigned char waddr, raddr, sub, mask; unsigned char ram[768]; };
|
||||
static VDBPalette vdb_pal[3];
|
||||
static bool vdb_splitter_on = false;
|
||||
/* lazy coalescing of palette data-byte writes so a 768-byte load is one line */
|
||||
static int vdb_data_group = -1;
|
||||
@@ -1115,10 +1148,20 @@ static void vdb_flush_data(void) {
|
||||
fflush(vpx_fp);
|
||||
}
|
||||
if (vdb_paldump && vdb_data_count >= 768) {
|
||||
char path[600];
|
||||
snprintf(path, sizeof path, "%s%d.rgb", vdb_paldump, vdb_data_group);
|
||||
FILE *pf = fopen(path, "wb");
|
||||
if (pf) { fwrite(vdb_pal[vdb_data_group].ram, 1, 768, pf); fclose(pf); }
|
||||
/* keep the MOST-LIT snapshot per group (max non-black bytes), so
|
||||
* the real content is captured no matter when it lands or which
|
||||
* phase an animated palette is sampled in. */
|
||||
static unsigned pal_max_nz[3] = { 0, 0, 0 };
|
||||
int g = vdb_data_group;
|
||||
unsigned nz = 0;
|
||||
for (int i = 0; i < 768; i++) if (vdb_pal[g].ram[i]) nz++;
|
||||
if (nz >= pal_max_nz[g]) {
|
||||
pal_max_nz[g] = nz;
|
||||
char path[600];
|
||||
snprintf(path, sizeof path, "%s%d.rgb", vdb_paldump, g);
|
||||
FILE *pf = fopen(path, "wb");
|
||||
if (pf) { fwrite(vdb_pal[g].ram, 1, 768, pf); fclose(pf); }
|
||||
}
|
||||
}
|
||||
}
|
||||
vdb_data_group = -1; vdb_data_count = 0;
|
||||
@@ -1194,6 +1237,9 @@ void VPXLOG_Init(void) {
|
||||
if (fifo_dump_fp == NULL) LOG_MSG("VPXLOG: cannot open fifodump '%s'", fd);
|
||||
}
|
||||
|
||||
const char *vs = getenv("VPX_VDBSTRIP");
|
||||
if (vs && vs[0] == '0') vpx_show_vdb_strips = false;
|
||||
|
||||
const char *rn = getenv("VPX_RENDER");
|
||||
if (rn && rn[0] && rn[0] != '0') {
|
||||
vpx_render_start();
|
||||
|
||||
Reference in New Issue
Block a user