A map viewer that draws tracks the way the map screen does
Pan with the arrows, zoom with plus and minus, [ and ] for the next track. Self-contained HTML with the track data and palette embedded; nothing here ships, and pack-dist.ps1 does not look at it. It follows the engine rather than approximating it. NavDisplay derives metersPerPixel from the zoom and sets LODIndex to it; L4GaugeImage::Draw takes the first LOD whose scale is at least that value and draws nothing once the value runs past the largest, so objects vanish rather than simplify. Both map gauges are here because they disagree - nav is the 448x416 radar screen with LOD following zoom, gps the 125x203 panel whose config pins LOD at 1.0. The HUD reports what is dropped, and is honest that this content barely exercises it: every placement in every track is cn3 with one LOD at scale 1000. The map is not a phosphor screen. Primitives carry palette indices and the palette is whichever the port was configured with - for the pod's secondary port, configure(0,sec,270,0x00ff,clut0,rgb,secpal.pcc). PCC is PCX, so the palette is the last 769 bytes. Walls are grey because index 51 is #4b4b4b; background is index 0, black; a primitive with colour 0 keeps the display's staticColor, 0x3C. Per-file palettes, not a global one - 39 of 40 gauge PCCs differ - so the port's configured palette is the one that counts.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
:root {
|
||||
/* Chrome only. Everything inside the screen is painted from the game's
|
||||
own palette (secpal.pcc) and must not be tinted by any of this. */
|
||||
--chrome: #17181a;
|
||||
--panel: #1e2023;
|
||||
--rule: #2f3237;
|
||||
--ink: #e6e4e0;
|
||||
--ink-mid: #9aa0a6;
|
||||
--ink-low: #6d737a;
|
||||
--accent: #bf9300; /* palette 56, the map's own amber */
|
||||
--mono: ui-monospace, "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace;
|
||||
}
|
||||
|
||||
html, body { height: 100%; }
|
||||
body {
|
||||
margin: 0; background: var(--chrome); color: var(--ink);
|
||||
font: 400 13px/1.5 var(--mono); overflow: hidden;
|
||||
display: grid; grid-template-columns: 1fr 17rem;
|
||||
}
|
||||
|
||||
/* The screen. Background is palette index 0 - black - so the chrome must
|
||||
not bleed into it: this is what the gauge actually draws onto. */
|
||||
#screen { position: relative; background: #000; overflow: hidden; }
|
||||
#view { display: block; width: 100%; height: 100%; touch-action: none; cursor: grab; }
|
||||
#view:active { cursor: grabbing; }
|
||||
|
||||
#scale {
|
||||
position: absolute; left: 1rem; bottom: 1rem;
|
||||
display: flex; align-items: center; gap: .5rem;
|
||||
color: var(--ink-mid); font-size: 11px; letter-spacing: .08em;
|
||||
text-shadow: 0 0 4px #000, 0 0 4px #000;
|
||||
}
|
||||
#barline { height: 0; border-top: 2px solid var(--ink-mid); }
|
||||
|
||||
aside {
|
||||
background: var(--panel); border-left: 1px solid var(--rule);
|
||||
padding: 1rem; overflow-y: auto;
|
||||
display: flex; flex-direction: column; gap: 1rem;
|
||||
}
|
||||
|
||||
h1 { font: 700 15px/1.2 var(--mono); margin: 0; letter-spacing: .02em; }
|
||||
#key { color: var(--ink-low); font-size: 11px; letter-spacing: .14em; margin: .2rem 0 0; }
|
||||
|
||||
select {
|
||||
width: 100%; font: 400 12px var(--mono); padding: .45rem .5rem;
|
||||
background: var(--chrome); color: var(--ink); border: 1px solid var(--rule);
|
||||
}
|
||||
select:focus-visible, #view:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
||||
|
||||
dl#stats {
|
||||
margin: 0; display: grid; grid-template-columns: 1fr auto;
|
||||
gap: .3rem .75rem; font-size: 12px;
|
||||
}
|
||||
dl#stats dt { color: var(--ink-low); }
|
||||
dl#stats dd {
|
||||
margin: 0; text-align: right; color: var(--ink);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.note {
|
||||
border-top: 1px solid var(--rule); padding-top: .8rem;
|
||||
color: var(--ink-low); font-size: 11px; line-height: 1.6;
|
||||
}
|
||||
.note b { color: var(--ink-mid); font-weight: 500; }
|
||||
|
||||
kbd {
|
||||
display: inline-block; min-width: 1.5em; text-align: center;
|
||||
border: 1px solid var(--rule); border-bottom-width: 2px;
|
||||
padding: .1em .35em; margin-right: .15em; border-radius: 3px;
|
||||
background: var(--chrome); color: var(--ink-mid); font: 400 11px var(--mono);
|
||||
}
|
||||
.keys { display: grid; grid-template-columns: auto 1fr; gap: .35rem .6rem; font-size: 11px; }
|
||||
.keys span:nth-child(even) { color: var(--ink-low); align-self: center; }
|
||||
|
||||
@media (max-width: 700px) {
|
||||
body { grid-template-columns: 1fr; grid-template-rows: 1fr auto; }
|
||||
aside { border-left: 0; border-top: 1px solid var(--rule); max-height: 45vh; }
|
||||
}
|
||||
Reference in New Issue
Block a user