Reworks the flat per-row shear into the authentic sync-loss-and-relock
transition the playtesters described, on both render paths (surround
DrawDevSurface + glass ExpandPlaneToBGRA, native + rotated radar):
1. COLLAPSE -- the image squeezes to a thin centred vertical line.
2. HOLD (~0.8s, the window the card held the detuned CRTC) -- the line's
content scrolls WILDLY fast and decelerates, plus a violent per-frame
SHAKE (LCG jitter: vertical row bounce + horizontal scroll jitter).
3. RECOVERY (~0.5s) -- the line broadens back to full while the scroll,
tear and shake settle to zero.
4. LOCK -- clean full display.
Mechanism: FunkyVideo(on, dur) records start+hold; ScrambleParams is a
two-phase envelope (hold: deep collapse + decelerating scroll = integral of
v(t)=rollMax*(1-t/hold); recovery: smoothstep broaden + settle). The read
loops map the source through it -- `scale` sets a black-bordered collapse
band, `rollOff` SCROLLS (wraps) within it, `shear` is a per-row diagonal,
`shakeRow` bounces the source row. The SVGA16 owns the full hold+recovery
clock, so FunkyVideo(False) is a no-op (the card restoring sync is where the
recovery begins) -- the recovery isn't cut off when the 0.8s latch clears.
Tunable by eye (pod-monitor PLL look isn't recoverable from the binary):
BT_SCRAMBLE_COLLAPSE (0.03), _ROLL (9000 px/s), _SHAKE (10 px), _SHEAR (3),
_DUR (hold), _RECOVER (0.5s). BT_SCRAMBLE_TEST loops the transition for
tuning; BT_SCRAMBLE_CYCLE loops it stepping the roll speed.
Verified: Release links clean; surround loops the effect at slowed + true
full speed, all secondaries + radar collapse/roll/shake/recover together,
main view clean, no crash. SHIPPING with these defaults for playtester
feedback.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
666 lines
17 KiB
C++
666 lines
17 KiB
C++
#pragma once
|
|
|
|
#include "..\munga\graph2d.h"
|
|
#include "..\munga\time.h"
|
|
#include <D3DX9.h>
|
|
#include <D3DX9math.h>
|
|
|
|
|
|
class L4graphicsPort;
|
|
class GaugeRenderer;
|
|
|
|
// GLASS: resolve the gauge renderer / main window. DEFINED in game/btl4main.cpp
|
|
// off the REAL app + window pointers it holds as locals -- NOT off the
|
|
// `application`/`ghWnd` globals, which are duplicate-defined and bind
|
|
// non-deterministically per link under /FORCE (the "duplicate-symbol race" --
|
|
// CMakeLists.txt:186), so a newly-added engine TU (L4GLASSWIN) can read NULL.
|
|
GaugeRenderer *BTResolveGaugeRenderer();
|
|
void *BTResolveMainWindow(); // HWND (kept void* -- no windows.h dependency)
|
|
|
|
//########################################################################
|
|
//#################### COCKPIT SURROUND (BT_COCKPIT) #####################
|
|
//########################################################################
|
|
//
|
|
// The pod-faithful single-window layout: the 3D world view CENTERED, with the
|
|
// six live gauge surfaces composited AROUND it at 1/2 native scale (the pod
|
|
// monitors physically clip the eyeport, so the corner MFDs / top-center / etc.
|
|
// overlap the view edges) and clickable RIO button lamps. DEFAULT under
|
|
// BT_DEV_GAUGES (BT_COCKPIT=0 falls back to the dock-bottom strip).
|
|
//
|
|
// The layout is the SINGLE SOURCE OF TRUTH -- computed from the backbuffer
|
|
// (canvas) size and consumed by the window sizing, the world viewport, the
|
|
// panel/button draw, the aspect calc, and the mouse hit-test. See L4VB16.cpp.
|
|
//
|
|
struct BTCockpitBtn
|
|
{
|
|
int address; // RIO buttonGroup address (0x00-0x47)
|
|
int x, y, w, h; // backbuffer-space rect (full hit target; only the
|
|
// protruding lamp edge shows after the surface draws over)
|
|
int colorClass; // 0 = red (MFD), 1 = yellow (radar), 2 = blue (flight)
|
|
int inert; // 1 = no authored .CTL mapping -> drawn greyed
|
|
const char *label; // non-NULL (blue flight block) -> face is drawn + labeled
|
|
};
|
|
|
|
struct BTCockpitLayout
|
|
{
|
|
int canvasW, canvasH;
|
|
int viewX, viewY, viewW, viewH; // centered world view
|
|
int surfX[6], surfY[6], surfW[6], surfH[6]; // Heat,Mfd2,Mfd1,Mfd3,sec,Comm dest rects
|
|
BTCockpitBtn buttons[80]; // 5*8 red + 16 yellow + 16 blue = 72
|
|
int buttonCount;
|
|
};
|
|
|
|
extern int gBTGaugeCockpit; // mode select; set once by btl4main
|
|
extern int gBTCockpitCanvasW, gBTCockpitCanvasH; // backbuffer canvas dims (for the aspect calc)
|
|
|
|
//
|
|
// LETTERBOX FIT (2026-07-26). The cockpit canvas is a FIXED size -- D3D9
|
|
// stretches it into whatever the client area is, so a window dragged to a
|
|
// different shape used to squash the instruments (the projection was
|
|
// aspect-corrected, but the panels, lamps and MFD glass were not).
|
|
//
|
|
// Now the canvas is fitted at ONE uniform scale, centred, with the leftover
|
|
// left black: the cockpit scales both ways and never distorts, whatever the
|
|
// window (drag, maximise, -fit borderless). D3D9 does the scaling at Present
|
|
// time via a destination rect, which D3DSWAPEFFECT_DISCARD forbids -- so the
|
|
// WINDOWED swap effect becomes D3DSWAPEFFECT_COPY when the surround is up and
|
|
// multisampling is off (COPY cannot multisample). gBTCockpitLetterbox says
|
|
// whether that happened; when it is 0 the old full-client stretch stands, so
|
|
// an MSAA run still works, just without the letterbox.
|
|
//
|
|
extern int gBTCockpitLetterbox; // 1 = the swap chain can take a dest rect
|
|
|
|
// The uniform-scale centred rect for a client area. Returns 1 when it differs
|
|
// from the full client (letterboxing needed), 0 when it fills it exactly.
|
|
int BTCockpitFitRect(int clientW, int clientH, RECT *out);
|
|
|
|
// Present destination for the main device window, or NULL for the full client.
|
|
const RECT *BTCockpitPresentDest(void *hwnd, RECT *storage);
|
|
|
|
void BTCockpitCanvasFor(int viewW, int viewH, int *canvasW, int *canvasH);
|
|
void BTCockpitComputeLayout(int canvasW, int canvasH, BTCockpitLayout *out);
|
|
void BTDrawCockpitPanels(LPDIRECT3DDEVICE9 device);
|
|
int BTCockpitMouseDown(int cx, int cy, int clientW, int clientH, int rightButton); // 1 = consumed
|
|
void BTCockpitMouseUp(void);
|
|
|
|
// Lamp brightness decode (RIOBase::LampState) -- shared by the cockpit draw and
|
|
// the glass per-display windows. Returns 0 (off) / 1 (dim) / 3 (bright).
|
|
//
|
|
// The wire word is TWO brightness fields plus a flash mode (L4RIO.h [T0]):
|
|
// bits 0-1 solid=0 / flashSlow=1 / flashMed=2 / flashFast=3
|
|
// bits 2-3 state 1 brightness (state1Off=0, state1Dim=1, state1Bright=3)
|
|
// bits 4-5 state 2 brightness (state2Off=0, state2Dim=1, state2Bright=3)
|
|
// Solid shows state 1; flashing ALTERNATES state 1 and state 2 at a
|
|
// 500/250/125 ms half-period.
|
|
//
|
|
// ⚠ FIXED 2026-07-26: this used to return max(state1,state2) and blank to 0 on
|
|
// the alternate phase. That agrees with the enum only when one state is Off --
|
|
// true for the Panic lamp (L4CTRL.cpp flashFast+state1Off+state2Bright) and for
|
|
// L4LAMP's off/dim pulse, which is why it went unnoticed -- but L4LAMP.cpp:252
|
|
// commands flashFast + state1Dim + state2Bright, a DIM-to-BRIGHT pulse that
|
|
// rendered as a hard BRIGHT-to-OFF blink. RP412's L4MFDVIEW LampLevel has the
|
|
// faithful formula; this is it.
|
|
inline int BTLampBrightnessOf(int state, unsigned long tick)
|
|
{
|
|
int level1 = (state >> 2) & 0x3;
|
|
int level2 = (state >> 4) & 0x3;
|
|
int flash = state & 0x3;
|
|
if (flash == 0) return level1;
|
|
unsigned long half = (flash == 1) ? 500 : (flash == 2) ? 250 : 125;
|
|
return ((tick / half) & 1) ? level2 : level1;
|
|
}
|
|
|
|
//########################################################################
|
|
//######################### Video16BitBuffered ###########################
|
|
//########################################################################
|
|
//
|
|
// X/Y values passed to these routines are assumed to be in
|
|
// the VIDEO DISPLAY COORDINATE SYSTEM, with (0,0) at the top left.
|
|
//
|
|
class Video16BitBuffered :
|
|
public GraphicsDisplay
|
|
{
|
|
public:
|
|
Video16BitBuffered(int x, int y);
|
|
|
|
~Video16BitBuffered();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
|
|
void
|
|
ShowInstance(char *indent);
|
|
|
|
void
|
|
DrawPoint(
|
|
int color,
|
|
int bitmask,
|
|
Enumeration operation,
|
|
int x, int y
|
|
);
|
|
|
|
void
|
|
DrawLine(
|
|
int color,
|
|
int bitmask,
|
|
Enumeration operation,
|
|
int x1, int y1,
|
|
int x2, int y2,
|
|
Logical include_last_pixel
|
|
);
|
|
|
|
void
|
|
DrawFilledRectangle(
|
|
int color,
|
|
int bitmask,
|
|
Enumeration operation,
|
|
int x1, int y1,
|
|
int x2, int y2
|
|
);
|
|
|
|
void
|
|
DrawText(
|
|
int color,
|
|
int bitmask,
|
|
Enumeration operation,
|
|
Logical opaque,
|
|
int rotation,
|
|
Enumeration fontNumber,
|
|
Logical vertical,
|
|
GraphicsDisplay::Justification justification,
|
|
Rectangle2D *clippingRectanglePtr,
|
|
char *stringPointer
|
|
);
|
|
|
|
void
|
|
DrawBitMap(
|
|
int color,
|
|
int bitmask,
|
|
Enumeration operation,
|
|
int rotation,
|
|
int x, int y,
|
|
BitMap *bitmap,
|
|
int sx1, int sy1, int sx2, int sy2 // these are SOURCE coordinates
|
|
);
|
|
|
|
void
|
|
DrawBitMapOpaque(
|
|
int color,
|
|
int background,
|
|
int bitmask,
|
|
Enumeration operation,
|
|
int rotation,
|
|
int x, int y,
|
|
BitMap *bitmap,
|
|
int sx1, int sy1, int sx2, int sy2 // these are SOURCE coordinates
|
|
);
|
|
|
|
void
|
|
DrawPixelMap8(
|
|
int *translation_table,
|
|
int bitmask,
|
|
Enumeration operation,
|
|
Logical opaque,
|
|
int rotation,
|
|
int x, int y,
|
|
PixelMap8 *pixelmap,
|
|
int sx1, int sy1, int sx2, int sy2 // these are SOURCE coordinates
|
|
);
|
|
|
|
void
|
|
DrawPixelMap8SingleColor(
|
|
int color,
|
|
int bitmask,
|
|
Enumeration operation,
|
|
int rotation,
|
|
int x, int y,
|
|
PixelMap8 *pixelmap,
|
|
int sx1, int sy1, int sx2, int sy2 // these are SOURCE coordinates
|
|
);
|
|
|
|
protected:
|
|
void
|
|
MarkChangedLines(int screenTop, int screenBottom);
|
|
|
|
void
|
|
buildDestPointer(
|
|
int x, int y,
|
|
Word **pixelPointer,
|
|
LWord **changed_bit_pointer,
|
|
LWord *changed_bit
|
|
);
|
|
|
|
Logical
|
|
valid;
|
|
int
|
|
width,
|
|
changedBitWidth,
|
|
height,
|
|
maximumX,
|
|
maximumY;
|
|
|
|
PixelMap16
|
|
pixelBuffer;
|
|
Byte
|
|
*changedLine;
|
|
LWord
|
|
*changedBit;
|
|
};
|
|
|
|
|
|
//########################################################################
|
|
//################################ SVGA16 ################################
|
|
//########################################################################
|
|
struct SVGA16Palette
|
|
{
|
|
Word
|
|
hardwarePort;
|
|
Logical
|
|
modified;
|
|
Palette8
|
|
paletteData;
|
|
Scalar
|
|
flashAccumulator,
|
|
flashRate;
|
|
|
|
enum PaletteID
|
|
{
|
|
maskStates=4
|
|
};
|
|
unsigned char
|
|
mask[maskStates];
|
|
int
|
|
previousMaskState;
|
|
};
|
|
|
|
|
|
class SVGA16 :
|
|
public Video16BitBuffered
|
|
{
|
|
friend class L4GraphicsPort; // for palette access
|
|
|
|
public:
|
|
enum PaletteID {
|
|
NativePalette=0,
|
|
SecondaryPalette,
|
|
AuxiliaryPalette1,
|
|
AuxiliaryPalette2,
|
|
PaletteCount
|
|
};
|
|
|
|
SVGA16(
|
|
int mode,
|
|
int width,
|
|
int height,
|
|
int page_size,
|
|
int mem_granularity,
|
|
int bytes_per_line,
|
|
int page_function_pointer,
|
|
int special_interface,
|
|
bool windowed,
|
|
int *secondaryIndex,
|
|
int *aux1Index,
|
|
int *aux2Index
|
|
);
|
|
|
|
~SVGA16();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
|
|
void
|
|
ShowInstance(char *indent);
|
|
|
|
Logical
|
|
Update(Logical forceall);
|
|
void
|
|
Refresh();
|
|
void
|
|
UpdatePalette();
|
|
|
|
void
|
|
FadeToPalettes(Scalar fade_time);
|
|
void
|
|
FadeToWhite(Scalar fade_time);
|
|
void
|
|
FlashPalette(
|
|
int palette_number,
|
|
Scalar rate,
|
|
unsigned char *stateList
|
|
);
|
|
void
|
|
UnflashPalette(int palette_number);
|
|
|
|
void
|
|
FunkyVideo(Logical on_off, Scalar duration = 0.0f);
|
|
|
|
// PPC sync-scramble (phase-14): the modern stand-in for the VGA CRTC
|
|
// Horizontal-Total detune, animated as a RECOVERY over the effect window -- at
|
|
// the hit the image collapses horizontally toward a line, then broadens back
|
|
// out as the tear + roll decay, and LOCKS to the full clean display at the end.
|
|
// FunkyVideo(on, dur) records the start + duration; ScrambleParams derives the
|
|
// per-frame envelope (returns True while active + fills scale/shear/rollOff/
|
|
// centerX); DrawDevSurface (surround) + ExpandPlaneToBGRA (glass) map the
|
|
// pixelBuffer read through it, so all secondary surfaces recover together and
|
|
// the main 3D view is untouched. Tunable by eye: BT_SCRAMBLE_SHEAR (max
|
|
// px/line), BT_SCRAMBLE_ROLL (max px/sec), BT_SCRAMBLE_COLLAPSE (min width
|
|
// fraction 0..1), BT_SCRAMBLE_DUR (anim seconds override). BT_SCRAMBLE_TEST
|
|
// loops the transition for tuning; BT_SCRAMBLE_CYCLE loops it stepping the
|
|
// max shear. (Exact look depended on each pod monitor's PLL -- not recoverable.)
|
|
Logical
|
|
ScrambleParams(int width, double *scale, double *shear,
|
|
double *rollOff, int *centerX, int *shakeRow) const;
|
|
Logical scrambleActive;
|
|
unsigned long scrambleStartMs;
|
|
double scrambleDurationS;
|
|
|
|
protected:
|
|
|
|
void BuildWindows(unsigned int width, unsigned int height, bool windowed, int *secondaryIndex, int *aux1Gauge, int *aux2Gauge);
|
|
|
|
|
|
void
|
|
ResetUpdatePosition();
|
|
|
|
int
|
|
pageSize,
|
|
pageDelta,
|
|
widthInBytes,
|
|
pageFcnPtr,
|
|
specialInterface;
|
|
|
|
int
|
|
currentPageNumber,
|
|
nextPageNumber,
|
|
lineNumber;
|
|
long
|
|
destOffset;
|
|
Byte
|
|
*changedLinePointer;
|
|
Word
|
|
*sourcePointer;
|
|
LWord
|
|
*changedBitPointer;
|
|
|
|
enum PaletteFadeState
|
|
{
|
|
staticPalette,
|
|
fadeToWhite,
|
|
whitePalette,
|
|
fadeToColor
|
|
};
|
|
|
|
PaletteFadeState
|
|
paletteFadeState;
|
|
Scalar
|
|
fadeAlpha,
|
|
fadeUnitsPerSecond;
|
|
Time
|
|
previousFadeTime;
|
|
|
|
// This array is closely linked to the PaletteID enumeration, above
|
|
SVGA16Palette
|
|
palette[PaletteCount];
|
|
|
|
private:
|
|
int NUMGAUGEWINDOWS;
|
|
HWND *gaugeWindows;
|
|
LPDIRECT3DDEVICE9 *mDevice;
|
|
D3DPRESENT_PARAMETERS *mPresentParams;
|
|
LPDIRECT3DVERTEXBUFFER9 *mVertBuffers;
|
|
LPDIRECT3DTEXTURE9 *mSurfaces;
|
|
DWORD *mLockFlags;
|
|
RECT *mSurfaceRects;
|
|
|
|
int mDisplayToUpdate;
|
|
|
|
LPDIRECT3DTEXTURE9 mDevSurfaceTex[10]; // DEV-COMPOSITE: one texture per gauge surface
|
|
// (sec/radar + the 5 MFD bit-planes + the Eng1-3
|
|
// preset-page planes, Gitea #9), on the MAIN device.
|
|
public:
|
|
// DEV-COMPOSITE: extract ONE gauge surface from the shared pixelBuffer into
|
|
// mDevSurfaceTex[slot] on the given (main) device + draw it as a quad at (dstX,dstY,
|
|
// dstW,dstH). monoTint < 0 -> palette-expand (sec/radar, case-0 LUT); monoTint >= 0
|
|
// -> mono bit-plane expand ((word & mask) ? tint : 0) for an MFD plane. See
|
|
// BTDrawGaugeSurfaces (L4VB16.cpp).
|
|
// rotateCCW: 0 = as-is; 1/3 = display the texture turned 90 degrees (the
|
|
// pod's portrait-mounted secondary CRT; the dev panel unrotates it).
|
|
void DrawDevSurface(LPDIRECT3DDEVICE9 device, int slot, int mask, int paletteID,
|
|
int monoTint, float dstX, float dstY, float dstW, float dstH,
|
|
int rotateCCW = 0);
|
|
|
|
// GLASS (per-display windows, L4GLASSWIN): CPU-expand ONE gauge surface (a
|
|
// bit-plane of the shared pixelBuffer) into a 32-bit BGRA image for GDI
|
|
// StretchDIBits -- no D3D. Same pixel rule as DrawDevSurface: monoTint < 0 ->
|
|
// palette-expand via palette[paletteID]; else fill (word & mask) ? monoTint : 0
|
|
// (monoTint is a 0x00RRGGBB value here, NOT R5G6B5). rotateQuadrant: 0 = native
|
|
// (outW=bufW, outH=bufH); 1 = 90 CCW / 3 = 90 CW -> transposed (outW=bufH,
|
|
// outH=bufW), for the portrait secondary CRT. `dst` must hold >= bufW*bufH
|
|
// dwords; the image is written TOP-DOWN. *outW/*outH receive the produced size.
|
|
void ExpandPlaneToBGRA(int mask, int paletteID, int monoTint, int rotateQuadrant,
|
|
unsigned long *dst, int *outW, int *outH);
|
|
};
|
|
|
|
//########################################################################
|
|
//########################## L4GraphicsPort ##############################
|
|
//########################################################################
|
|
//
|
|
// X/Y values passed to these routines are assumed to be in
|
|
// the GRAPHICS COORDINATE SYSTEM, with (0,0) at the bottom left.
|
|
//
|
|
class L4GraphicsPort :
|
|
public GraphicsPort
|
|
{
|
|
public:
|
|
enum ChannelEnableID {
|
|
RedChannel,
|
|
GreenChannel,
|
|
BlueChannel,
|
|
AllChannels,
|
|
|
|
DirectColor,
|
|
BlankColor,
|
|
|
|
RedChannelTransparentZero=0x80,
|
|
GreenChannelTransparentZero,
|
|
BlueChannelTransparentZero,
|
|
AllChannelsTransparentZero
|
|
};
|
|
|
|
L4GraphicsPort(
|
|
Video16BitBuffered *graphics_display,
|
|
const char *name,
|
|
int rotation,
|
|
int bit_mask,
|
|
SVGA16::PaletteID palette_ID,
|
|
L4GraphicsPort::ChannelEnableID channel_enable
|
|
);
|
|
|
|
~L4GraphicsPort();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
|
|
void
|
|
ShowInstance(char *indent);
|
|
|
|
void
|
|
SetSecondaryPalette(
|
|
Palette8 *source_palette
|
|
);
|
|
|
|
void
|
|
SetAuxiliaryPalette();
|
|
|
|
void
|
|
SetColor(
|
|
PaletteTriplet *source_color,
|
|
int color_index
|
|
);
|
|
|
|
void
|
|
DrawPoint(
|
|
int color,
|
|
Enumeration operation,
|
|
int x, int y
|
|
);
|
|
|
|
void
|
|
DrawLine(
|
|
int color,
|
|
Enumeration operation,
|
|
int x1, int y1,
|
|
int x2, int y2,
|
|
Logical include_last_pixel
|
|
);
|
|
|
|
void
|
|
DrawFilledRectangle(
|
|
int color,
|
|
Enumeration operation,
|
|
int x1, int y1,
|
|
int x2, int y2
|
|
);
|
|
|
|
void
|
|
DrawText(
|
|
int color,
|
|
Enumeration operation,
|
|
Logical opaque,
|
|
int rotation,
|
|
Enumeration fontNumber,
|
|
Logical vertical,
|
|
GraphicsDisplay::Justification justification,
|
|
Rectangle2D *clippingRectanglePtr,
|
|
char *stringPointer
|
|
);
|
|
|
|
void
|
|
DrawBitMap(
|
|
int color,
|
|
Enumeration operation,
|
|
int rotation,
|
|
int x, int y,
|
|
BitMap *bitmap,
|
|
int sx1, int sy1, int sx2, int sy2 // these are SOURCE coordinates
|
|
);
|
|
|
|
void
|
|
DrawBitMapOpaque(
|
|
int color,
|
|
int background,
|
|
Enumeration operation,
|
|
int rotation,
|
|
int x, int y,
|
|
BitMap *bitmap,
|
|
int sx1, int sy1, int sx2, int sy2 // these are SOURCE coordinates
|
|
);
|
|
|
|
void
|
|
DrawPixelMap8(
|
|
Enumeration operation,
|
|
Logical opaque,
|
|
int rotation,
|
|
int x, int y,
|
|
PixelMap8 *pixelmap,
|
|
int sx1, int sy1, int sx2, int sy2 // these are SOURCE coordinates
|
|
);
|
|
|
|
void
|
|
DrawPixelMap8SingleColor(
|
|
int color,
|
|
Enumeration operation,
|
|
int rotation,
|
|
int x, int y,
|
|
PixelMap8 *pixelmap,
|
|
int sx1, int sy1, int sx2, int sy2 // these are SOURCE coordinates
|
|
);
|
|
|
|
void
|
|
SetPaletteID(SVGA16::PaletteID palette_ID)
|
|
{
|
|
Check(this);
|
|
paletteID = palette_ID;
|
|
}
|
|
|
|
void
|
|
SetEnableID(L4GraphicsPort::ChannelEnableID channel_enable)
|
|
{
|
|
Check(this);
|
|
channelEnable = channel_enable;
|
|
}
|
|
|
|
int
|
|
GetBitMask()
|
|
{
|
|
Check(this);
|
|
return bitMask;
|
|
}
|
|
// DEV-COMPOSITE (Gitea #9): the dock honors the live reconfigure state --
|
|
// a plane whose channel is currently BlankColor contributes nothing on the
|
|
// pod's shared-word palette LUT, so the dev panel skips drawing it.
|
|
L4GraphicsPort::ChannelEnableID
|
|
GetEnableID()
|
|
{
|
|
Check(this);
|
|
return channelEnable;
|
|
}
|
|
SVGA16::PaletteID
|
|
paletteID;
|
|
|
|
protected:
|
|
void
|
|
convertPortPair(
|
|
int *xp,
|
|
int *yp,
|
|
int x,
|
|
int y
|
|
);
|
|
|
|
void
|
|
BuildDirectTranslation(
|
|
Palette8 *source_palette
|
|
);
|
|
|
|
void
|
|
BuildSecondaryPalette(
|
|
Palette8 *source_palette
|
|
);
|
|
|
|
void
|
|
BuildAuxiliaryPalette();
|
|
|
|
void
|
|
BuildSecondaryTranslation();
|
|
|
|
void
|
|
BuildAuxiliaryTranslation();
|
|
|
|
void
|
|
BlankPalette();
|
|
|
|
void
|
|
BuildSecondaryColor(
|
|
PaletteTriplet *source_triplet,
|
|
int color_number
|
|
);
|
|
//------------------------------------------------------------
|
|
// Protected data
|
|
//------------------------------------------------------------
|
|
int
|
|
translationTable[256];
|
|
unsigned char
|
|
myColor[256];
|
|
|
|
int
|
|
baseRotation,
|
|
bitMask,
|
|
numberOfBits,
|
|
maximumX,
|
|
maximumY;
|
|
|
|
|
|
L4GraphicsPort::ChannelEnableID
|
|
channelEnable;
|
|
};
|