The pod drove five monochrome MFDs from the color channels of two video outputs - SVGA16 packs bit-slices of the shared gauge canvas into R/G/B of gauge window 3 (upper MFDs) and R/G of window 4 (lower MFDs), with the map palettized on the secondary and physically mounted portrait. The desktop reconstruction previously required an external BitBlt-mirror wrapper. With L4MFDSPLIT=1, SVGA16 renders each display into its own window (MFDSplitView, plain GDI) straight from the canvas + port bit-masks: five green-screen MFD windows and the 90CW-rotated Map, tiled in the pod grid to the right of the main view (L4MFDSCALE percent, default 50). The packed D3D windows stay hidden but keep presenting off-screen, leaving the original path untouched. Handles spanning mode (2-window setups). Also: the plasma glass now opens directly below the main view (clamped to the work area; L4PLASMAPOS=x,y overrides) per playtest feedback. Verified: window grid comes up as main + 5 MFDs + Map + plasma with the packed windows hidden; screenshots confirm a green MFD score readout and the portrait tactical map rendering correctly. dist packer and BUILD.md updated; the launcher wrapper is obsolete for split-mode use. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
537 lines
9.1 KiB
C++
537 lines
9.1 KiB
C++
#pragma once
|
|
|
|
#include "..\munga\graph2d.h"
|
|
#include "..\munga\time.h"
|
|
#include <D3DX9.h>
|
|
#include <D3DX9math.h>
|
|
|
|
|
|
class L4graphicsPort;
|
|
class MFDSplitView;
|
|
|
|
//########################################################################
|
|
//######################### 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;
|
|
|
|
//------------------------------------------------------------------
|
|
// Split-view mode (L4MFDSPLIT=1): the five channel-packed MFDs and
|
|
// the rotated map render as their own desktop windows; the packed
|
|
// D3D gauge windows stay hidden. See L4MFDVIEW.h.
|
|
//------------------------------------------------------------------
|
|
enum SplitViewID {
|
|
SplitMFDUpperLeft = 0,
|
|
SplitMFDUpperCenter,
|
|
SplitMFDUpperRight,
|
|
SplitMFDLowerLeft,
|
|
SplitMFDLowerRight,
|
|
SplitMap,
|
|
SplitViewCount
|
|
};
|
|
|
|
void
|
|
FillSplitMFD(
|
|
SplitViewID view,
|
|
DWORD mask16,
|
|
int shift
|
|
);
|
|
|
|
Logical
|
|
splitViews;
|
|
MFDSplitView
|
|
*splitView[SplitViewCount];
|
|
};
|
|
|
|
//########################################################################
|
|
//########################## 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;
|
|
}
|
|
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;
|
|
};
|