The interactive 2-node playtest wave -- every fix decomp-grounded and live-verified: COLLISION ECONOMY (the ram one-shot): StaticBounce mutates worldLinearVelocity per contact and ProcessCollisionList walks EVERY touched solid per frame; with 2007 terrain-as-solids the reflections compounded x4-x40 within one frame and a walking bump one-shot a pristine mech for 112,375 pts (62-pt authentic economy). Fix: frameEntryWorldVelocity restore per contact (damage always priced at the real approach speed -- all the binary's physics ever saw); Mech::Reset zeroes the mover motion (respawn = teleport); [collide-tx]/[mp-hdlr] telemetry. Gotcha #16 (engine-facility drift class). MISSILES: peer-visible salvos (the launcher record extension carries a salvo counter + aim point; ForceUpdate actually enqueues it -- the dirty flag alone never serialized), the authentic arc (authored MuzzleVelocity vector + the Seeker's 200m/0.1/300 loft + gain-4 steering, decoded from @004beae4/@004bef78), world-impact bursts (rounds detonate on cave geometry instead of phasing through), contact-only damage (flight-cap expiry = fizzle, no more teleport damage), live re-lead, and ballistic (unguided) shells for autocannons. projweap's stale BTPushProjectile extern (the /FORCE signature trap, gotcha #6 corollary) crashed the Avatar's first AFC100 shot -- fixed + sweep rule recorded. RADAR: two transcription bugs made the scope permanently empty -- FUN_0040b244 is the affine INVERSE (not a copy) and FUN_0040adec writes ONLY the 3x3 rotation (never the translation); worldToView now Invert(view) built rotation-first. CulturalIcons sorted out of the moving grid (the phantom red pips were map props), visible-radius culls on all three draw passes, live pip verified at |delta| x ppm px. Gotcha #17 (verify the FUN_ body, not its call shape). WEAPON PANELS (the frozen-dial hunt): the binary's *(subsystem+0x40) means FAILED -- the recon's 'operating' name was backwards, inverting the destroyed-X lamps, the panel look, the children enable and the ready-lamp gate (which had NEVER executed). Polarity chain corrected end-to-end (failedState, fed by real damage saturation). Root cause of the freezes: MFD page-mode gating -- the dev composite shows ALL pages at once, so off-page dials legitimately stopped; under BT_DEV_GAUGES the 15 page-plane bits stay active (the exclusive secondary trio untouched). The SEH gauge guard now names its kills; repaint-heal resets the incremental arc after panel repaints; [panel]/[arc] probes added. COMM/SCORE: MessageBoard LIVE (the engine already shipped the whole Player__StatusMessage queue; wired the binary's one producer -- the kill branch, victim's name, 6s -- plus the consumer bridge and a lazy source bind); MP DEATHS counted via the observed-death tally (each node scores every pilot from locally observed events, the same model as the KILLS credit) and the -2/-1 engine seed clamped for display. DEV UX: node-tagged window titles (-net port), gauge panel reworked (1320x480, true 4:3 MFD cells, the portrait secondary UNROTATED upright, linear filtering, BT_GAUGE_SCALE), fixed close spawns via BT_SPAWN_XZ, Boreas flies an Avatar (first second-chassis live outing). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
523 lines
9.3 KiB
C++
523 lines
9.3 KiB
C++
#pragma once
|
|
|
|
#include "..\munga\graph2d.h"
|
|
#include "..\munga\time.h"
|
|
#include <D3DX9.h>
|
|
#include <D3DX9math.h>
|
|
|
|
|
|
class L4graphicsPort;
|
|
|
|
//########################################################################
|
|
//######################### 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[8]; // DEV-COMPOSITE: one texture per gauge surface
|
|
// (sec/radar + the 5 MFD bit-planes), 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);
|
|
};
|
|
|
|
//########################################################################
|
|
//########################## 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;
|
|
};
|