Replicates the RP412 cockpit line into BT411's own architecture -- porting the geometry and keeping our renderers, so BT_SHOT single-frame verification stays intact. MODE RESOLVER. Where the secondary displays go was decided in TWO places with duplicated precedence, and the boot banner read NEITHER -- it announced "per-display cockpit windows" for every glass boot, surround included. The split had also broken BT_COCKPIT=0: documented as the dock-bottom opt-out, the profile block converted it to BT_GLASS_PANELS=1, so the docked strip was UNREACHABLE under the glass profile. One resolver now, consumed by the banner, the pad-panel decision and the window sizing; BT_GLASS_PANELS is explicit-only; dock/window modes auto-raise BT_PAD_PANEL so the button field always has a home. L4RIOBANK -- one button geometry. Both renderers carried their own copy and had drifted: an MFD button was 156x138 reaching under the glass in the exploded window and a 76x24 sliver entirely OUTSIDE the glass in the surround. One module owns it now, both are consumers, placement stays per-renderer. The pod's under-glass rule (RP412 L4MFDVIEW): reach half the glass in behind the display, leave a lamp strip clearing the edge, paint buttons first and imagery over -- so the lamp reads as a bar and practically the whole display is the press target. The strip scales off the display's SHORT axis (the map is portrait) with a readable floor. Retired L4GLASSWIN's three local placers and seven layout constants. LAMP FLASH DECODE was wrong [T1]. BTLampBrightnessOf returned max(state1, state2) and blanked on the alternate phase; RIO::LampState (L4RIO.h [T0]) says solid shows state 1 and flashing ALTERNATES the two. Agrees only when one state is Off -- true for the Panic lamp, which is why it survived -- but L4LAMP.cpp:252 commands flashFast + state1Dim + state2Bright, a dim->bright pulse that rendered as a hard bright->off blink. Three copies existed (l4vb16.h, L4GLASSWIN, L4PADPANEL), all three wrong; the two locals now forward to the one fixed inline. THE COCKPIT SCALES. The fixed canvas was stretched into whatever the client area was, so a window dragged to a different shape squashed the instruments (the projection was aspect-corrected in task #20; the panels never were). Now one uniform scale, centred, leftover black. D3D9 applies it as a Present destination rect, which DISCARD forbids -- so the WINDOWED swap effect becomes COPY when the surround is up and multisampling is off. The click mapping had to follow (mapping against the full client drifts the hit test off every button by the bar width), as did the world aspect (under a uniform scale it is the view rect's own). -fit / -windowed-fullscreen: borderless over the monitor. - ordering trap: the first WM_SIZE beats the device, so a -fit boot logged aspect=3.14 and applied it on frame 1. The letterbox INTENT is decided in btl4main; L4VIDEO only confirms or withdraws it. PLAYER-TUNABLE DISPLAYS. BT_MFD_SCALE (+ _UL/_UC/_UR/_LL/_LR), BT_RADAR_SCALE, BT_RADAR_POS (CENTER/LEFT/RIGHT/MIDLEFT/MIDRIGHT). The surround BANDS derive from the resolved sizes -- that is why the sizes could not stay constants: the band a display hangs in has to grow with it or the canvas clips it. 100% reproduces the historical L276 R276 T223 B336 exactly. A corner map goes flush to the CANVAS edge and the lower MFD slides beside it (measuring off the view edge overlapped them by 232px). MAP LEGEND GRID -- measured, not inherited. scratchpad/measurelegend.py over a native capture: top 3, cell 102, pitch 107 of 640. RP412's map is 13 + 6x102 @ 105 -- same cell height, different top and pitch, so its numbers do NOT transfer. Our old even division had the pitch right by luck and sat 3px high of the labels. environ.ini. It was read ~300 lines into WinMain, AFTER the platform-profile block had run its getenv()s -- so every setting the profile reads was silently ignored FROM THE FILE and only worked as a real env var. It also putenv()'d comments verbatim. Now loaded immediately after the first-breath line, comments skipped, the real environment WINS over the file, and a fully documented default is written on first run (the bindings.txt convention: untracked, so extract-over-top never clobbers a player's settings). VERIFICATION HARNESS (new, reusable): BT_RIOBANK_LOG=1 dumps every bank; checkbank.py proves no address is SHADOWED (an address whose rect is covered by earlier buttons is dead however big it looks -- the overlapping under-glass banks make that a live hazard); clickbank.py posts a real click at every button centre. Verified: 72/72 placed, 0 shadowed, 72/72 dispatched in BOTH modes, after a resize, at 150%/135%, and at 75%+BOTTOMRIGHT; wide/tall drags and -fit undistorted on a 3440x1440; exploded/dock/pod/dev un-regressed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
646 lines
16 KiB
C++
646 lines
16 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);
|
|
|
|
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;
|
|
};
|