gauges: reconstruct + register oneOfSeveralPixInt -- cockpit button-state lamps
The OneOfSeveral family was declared but undefined. Reconstruct the shared base (OneOfSeveral: ctor @004c4d88, BecameActive @004c4f14, Execute @004c4f28, dtor @004c4e7c) and the OneOfSeveralPixInt subclass (Make @004c5204, ctor @004c52d8, dtor @004c5364) + its methodDescription, and register "oneOfSeveralPixInt". OneOfSeveral is a multi-frame strip selector: the base holds a BitMap or PixMap8 strip of columns*rows frames + the per-frame size (source size / columns,rows); Execute picks frame `selected` (col=selected%columns, row=selected/columns) and blits that sub-rectangle -- DrawPixelMap8(opaque) for a pixmap strip (its own palette, no SetColor), or SetColor(bg)+DrawBitMapOpaque(fg) for a bitmap strip. Added the missing OneOfSeveral::foregroundColor field (@0x9C -- the DrawBitMap Opaque background arg). OneOfSeveralPixInt forces the PixMap path (fromImageStrip =0, bg/fg=0) and wires one GaugeConnectionDirectOf<int> to the frame index. methodDescription = (rate,modeMask,string strip,integer columns,integer rows, attribute state) matching oneOfSeveralPixInt(rate,mode,strip.pcc,cols,rows,attr). Strip resource via warehouse->pixelMap8Bin (WRHOUS.h) .Get/.Release. The config binds the duck / searchlight / display-mode / piloting-mode buttons; ControlsMapper/DisplayMode already resolves (MechControlsMapper table), and DuckState/Searchlight/LightOn degrade to frame 0 (safe) until their tables land. Verified live (BT_DEV_GAUGES): the cockpit button-lamp PixMap8 icons now render (were absent). No /FORCE unresolved externals. Combat un-regressed (TARGET DESTROYED after 8 hits), 0 crashes, no missing-image. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c2c4ab1f67
commit
a538d6438e
@@ -1276,6 +1276,230 @@ void
|
||||
// before chaining to OneOfSeveral::Execute @004c4f28. dtor @004c5500.
|
||||
//
|
||||
|
||||
//
|
||||
// @004c4d88 -- OneOfSeveral base ctor (vtable PTR_FUN_00518bf0). Intern the
|
||||
// image name, hold a ref, read the source strip size from the appropriate cache
|
||||
// (PixMap8Cache if !fromImageStrip, else BitMapCache), divide by columns/rows to
|
||||
// get the per-frame size, and set the graphics-port origin.
|
||||
//
|
||||
OneOfSeveral::OneOfSeveral(
|
||||
GaugeRate rate,
|
||||
ModeMask mode_mask,
|
||||
L4GaugeRenderer *renderer_in,
|
||||
int graphics_port_number,
|
||||
int x,
|
||||
int y,
|
||||
Logical from_image_strip,
|
||||
const char *image_name,
|
||||
int background_color,
|
||||
int foreground_color,
|
||||
int columns_in,
|
||||
int rows_in,
|
||||
const char *identification_string
|
||||
):
|
||||
GraphicGauge(rate, mode_mask, renderer_in, 0, // FUN_00444818 (owner_ID 0)
|
||||
graphics_port_number, identification_string)
|
||||
{
|
||||
backgroundColor = background_color; // @0x98
|
||||
foregroundColor = foreground_color; // @0x9C
|
||||
columns = columns_in; // @0xA0
|
||||
fromImageStrip = from_image_strip; // @0x90
|
||||
|
||||
imageName = new char[strlen(image_name) + 1]; // @0x94 FUN_004700ac
|
||||
strcpy(imageName, image_name);
|
||||
|
||||
L4Warehouse *warehouse = (L4Warehouse *)renderer_in->warehousePointer;
|
||||
if (fromImageStrip == 0) // PixMap8 strip
|
||||
{
|
||||
PixelMap8 *pm = warehouse->pixelMap8Bin.Get(imageName); // FUN_00442d2b (held)
|
||||
frameWidth = (pm != NULL ? pm->Data.Size.x : 0) / columns_in; // @0xA4
|
||||
frameHeight = (pm != NULL ? pm->Data.Size.y : 0) / rows_in; // @0xA8
|
||||
}
|
||||
else // BitMap strip
|
||||
{
|
||||
BitMap *bm = warehouse->bitMapBin.Get(imageName); // FUN_00442aec (held)
|
||||
frameWidth = (bm != NULL ? bm->Data.Size.x : 0) / columns_in;
|
||||
frameHeight = (bm != NULL ? bm->Data.Size.y : 0) / rows_in;
|
||||
}
|
||||
|
||||
localView.SetOrigin(x, y); // this+0x48 vtbl+0x10
|
||||
}
|
||||
|
||||
//
|
||||
// @004c4e7c -- dtor. Release the image from the matching cache (keyed on
|
||||
// imageName, before the free); base chain implicit.
|
||||
//
|
||||
OneOfSeveral::~OneOfSeveral()
|
||||
{
|
||||
L4Warehouse *warehouse = (L4Warehouse *)renderer->warehousePointer;
|
||||
if (fromImageStrip == 0)
|
||||
warehouse->pixelMap8Bin.Release(imageName); // FUN_00442e51
|
||||
else
|
||||
warehouse->bitMapBin.Release(imageName); // FUN_00442c12
|
||||
delete[] imageName; // FUN_004022e8
|
||||
imageName = NULL;
|
||||
}
|
||||
|
||||
Logical
|
||||
OneOfSeveral::TestInstance() const
|
||||
{
|
||||
return GraphicGauge::TestInstance();
|
||||
}
|
||||
|
||||
//
|
||||
// @004c4f14 -- BecameActive: previousSelected = -1 (force the first redraw).
|
||||
//
|
||||
void
|
||||
OneOfSeveral::BecameActive()
|
||||
{
|
||||
previousSelected = -1; // @0xB0
|
||||
}
|
||||
|
||||
//
|
||||
// @004c4f28 -- Execute. On a change of `selected`, compute the frame's (col,row)
|
||||
// within the strip and blit that sub-rectangle: DrawPixelMap8 (opaque) for a
|
||||
// pixmap strip, or SetColor(bg)+DrawBitMapOpaque(fg,..) for a bitmap strip.
|
||||
//
|
||||
void
|
||||
OneOfSeveral::Execute()
|
||||
{
|
||||
if (selected == previousSelected)
|
||||
return;
|
||||
previousSelected = selected;
|
||||
|
||||
int col, row;
|
||||
if (columns == 1)
|
||||
{
|
||||
col = 0;
|
||||
row = selected;
|
||||
}
|
||||
else
|
||||
{
|
||||
col = selected % columns;
|
||||
row = selected / columns;
|
||||
}
|
||||
|
||||
int sx0 = col * frameWidth;
|
||||
int sx1 = frameWidth + sx0 - 1;
|
||||
int sy0 = row * frameHeight;
|
||||
int sy1 = frameHeight + sy0 - 1;
|
||||
|
||||
L4Warehouse *warehouse = (L4Warehouse *)renderer->warehousePointer;
|
||||
if (fromImageStrip == 0) // PixMap8: own palette, no SetColor
|
||||
{
|
||||
PixelMap8 *pm = warehouse->pixelMap8Bin.Get(imageName); // FUN_00442d2b
|
||||
localView.DrawPixelMap8(True, 0, pm, sx0, sy0, sx1, sy1); // vtbl+0x5C (opaque)
|
||||
warehouse->pixelMap8Bin.Release(imageName); // FUN_00442e51
|
||||
}
|
||||
else // BitMap strip
|
||||
{
|
||||
localView.SetColor(backgroundColor); // vtbl+0x18
|
||||
BitMap *bm = warehouse->bitMapBin.Get(imageName); // FUN_00442aec
|
||||
localView.DrawBitMapOpaque(foregroundColor, 0, bm, sx0, sy0, sx1, sy1); // vtbl+0x58
|
||||
warehouse->bitMapBin.Release(imageName); // FUN_00442c12
|
||||
}
|
||||
}
|
||||
|
||||
//###########################################################################
|
||||
// OneOfSeveralPixInt @004c5204 Make / @004c52d8 ctor (vtable PTR_FUN_00518b68)
|
||||
//
|
||||
// The cockpit button-state lamps (config "oneOfSeveralPixInt"): a PixMap8 strip
|
||||
// of N frames selected by an integer game attribute (DuckState / Searchlight/
|
||||
// LightOn / ControlsMapper/DisplayMode). Drawing is inherited from OneOfSeveral;
|
||||
// this subclass just forces the PixMap path and wires the int connection.
|
||||
//###########################################################################
|
||||
|
||||
MethodDescription
|
||||
OneOfSeveralPixInt::methodDescription =
|
||||
{
|
||||
"oneOfSeveralPixInt",
|
||||
OneOfSeveralPixInt::Make,
|
||||
{
|
||||
//
|
||||
// CFG shape (L4GAUGE.CFG:5001):
|
||||
// oneOfSeveralPixInt( rate, mode, strip.pcc, columns, rows, stateAttr )
|
||||
// e.g. oneOfSeveralPixInt(E,ModeAlwaysActive,bduck.pcc,3,1,DuckState);
|
||||
//
|
||||
{ ParameterDescription::typeRate, NULL }, // rate ID
|
||||
{ ParameterDescription::typeModeMask, NULL }, // mode mask
|
||||
{ ParameterDescription::typeString, NULL }, // pixmap strip name
|
||||
{ ParameterDescription::typeInteger, NULL }, // columns (frame count)
|
||||
{ ParameterDescription::typeInteger, NULL }, // rows
|
||||
{ ParameterDescription::typeAttribute, NULL }, // integer state selector
|
||||
PARAMETER_DESCRIPTION_END
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// @004c5204 -- Make. Allocate + construct, then verify the pixmap strip exists.
|
||||
//
|
||||
Logical
|
||||
OneOfSeveralPixInt::Make(
|
||||
int display_port_index,
|
||||
Vector2DOf<int> position,
|
||||
Entity * /*entity -- unused*/,
|
||||
GaugeRenderer *gauge_renderer
|
||||
)
|
||||
{
|
||||
ParameterDescription *p = methodDescription.parameterList;
|
||||
|
||||
OneOfSeveralPixInt *gauge = (OneOfSeveralPixInt *)operator new(0xb4); // FUN_00402298(0xb4)
|
||||
if (gauge != NULL)
|
||||
{
|
||||
new (gauge) OneOfSeveralPixInt( // FUN_004c52d8
|
||||
p[0].data.rate, p[1].data.modeMask,
|
||||
(L4GaugeRenderer *)gauge_renderer,
|
||||
display_port_index, // graphics_port_number
|
||||
position.x, position.y,
|
||||
p[2].data.string, // pixmap strip
|
||||
p[3].data.integer, p[4].data.integer, // columns, rows
|
||||
(int *)p[5].data.attributePointer, // integer state source
|
||||
"OneOfSeveralPixInt");
|
||||
}
|
||||
|
||||
L4Warehouse *warehouse = (L4Warehouse *)gauge_renderer->warehousePointer;
|
||||
if (warehouse->pixelMap8Bin.Get(p[2].data.string) == NULL) // FUN_00442d2b
|
||||
{
|
||||
DebugStream << "OneOfSeveralPixInt: Missing image '" << p[2].data.string << "'\n";
|
||||
return False;
|
||||
}
|
||||
warehouse->pixelMap8Bin.Release(p[2].data.string); // FUN_00442e51
|
||||
return True;
|
||||
}
|
||||
|
||||
//
|
||||
// @004c52d8 -- ctor. OneOfSeveral base with fromImageStrip=0 (PixMap8) and
|
||||
// bg/fg=0 (the pixmap carries its own palette); one int connection -> selected.
|
||||
//
|
||||
OneOfSeveralPixInt::OneOfSeveralPixInt(
|
||||
GaugeRate rate,
|
||||
ModeMask mode_mask,
|
||||
L4GaugeRenderer *renderer_in,
|
||||
int graphics_port_number,
|
||||
int x,
|
||||
int y,
|
||||
const char *image,
|
||||
int columns_in,
|
||||
int rows_in,
|
||||
int *value_pointer,
|
||||
const char *identification_string
|
||||
):
|
||||
OneOfSeveral(rate, mode_mask, renderer_in, graphics_port_number, x, y,
|
||||
False, // fromImageStrip = 0 (PixMap)
|
||||
image, 0, 0, // bg, fg = 0
|
||||
columns_in, rows_in, identification_string)
|
||||
{
|
||||
selected = 0; // @0xAC this[0x2B]
|
||||
AddConnection(new GaugeConnectionDirectOf<int>(0, &selected, value_pointer)); // FUN_004749de
|
||||
}
|
||||
|
||||
//
|
||||
// @004c5364 -- deleting-dtor thunk. All teardown is ~OneOfSeveral; implicit.
|
||||
//
|
||||
OneOfSeveralPixInt::~OneOfSeveralPixInt()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//###########################################################################
|
||||
//###########################################################################
|
||||
|
||||
@@ -358,6 +358,7 @@
|
||||
Logical fromImageStrip; // @0x90 this[0x24]
|
||||
char *imageName; // @0x94 this[0x25]
|
||||
int backgroundColor; // @0x98 this[0x26]
|
||||
int foregroundColor; // @0x9C this[0x27] (DrawBitMapOpaque bg arg)
|
||||
int columns; // @0xA0 this[0x28]
|
||||
int selected; // @0xAC this[0x2B] (connection)
|
||||
int previousSelected; // @0xB0 this[0x2C]
|
||||
@@ -387,10 +388,14 @@
|
||||
public OneOfSeveral
|
||||
{
|
||||
public:
|
||||
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *);
|
||||
OneOfSeveralPixInt(GaugeRate, ModeMask, L4GaugeRenderer *, int,
|
||||
// Registered in BTL4MethodDescription[] (btl4grnd.cpp) as "oneOfSeveralPixInt".
|
||||
static MethodDescription methodDescription;
|
||||
|
||||
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004c5204
|
||||
OneOfSeveralPixInt( // @004c52d8
|
||||
GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number,
|
||||
int x, int y, const char *image, int columns, int rows,
|
||||
int *value_pointer, const char *);
|
||||
int *value_pointer, const char *identification_string);
|
||||
~OneOfSeveralPixInt(); // @004c5364
|
||||
};
|
||||
|
||||
|
||||
@@ -136,6 +136,7 @@ MethodDescription
|
||||
&ColorMapperCritical::methodDescription, // "cmCrit" -- subsystem-critical-state tint
|
||||
&VertTwoPartBar::methodDescription, // "vertBar" -- vertical fill bar (coolant/heat)
|
||||
&SegmentArcRatio::methodDescription, // "segmentArcRatio" -- segmented arc dial (speed)
|
||||
&OneOfSeveralPixInt::methodDescription, // "oneOfSeveralPixInt" -- button-state lamp (duck/light/mode)
|
||||
&BTL4ChainToPrevious
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user