gauges: reconstruct + register PlayerStatus (mission-review scoreboard)
PlayerStatus (btl4gau3) had only a BUGGY Make defined (it read raw DAT_ pools, passed (int)entity/(int)gauge_renderer as x/y, and DROPPED the graphics_port_number param -- the header ctor was one int short); the ctor/Execute/dtor/BecameActive and the PlayerStatusMappingGroup + CreateMutantPixelmap8 helpers were comment-only stubs. Reconstructed the whole family (mapped by the playerstatus-decomp-map workflow, 6 agents): * methodDescription (8 params: rate,modeMask,integer player#,string font,4x color) + rewired Make reading parameterList[] with the port/x/y bug fixed. * ctor (@004cb1a8): GraphicGauge base (owner folded to 0), store colours+port, SetOrigin, playerIndex=player_number-1, build a score NumericDisplay (fmt 2 = signedBlankedZeros). Fixed the header layout: nameImage is a BitMap* (not a Pixmap), and two missing members (dirty@0x2F, previousStatus@0x30). * dtor / BecameActive / TestInstance. * PlayerStatusMappingGroup (@004c9bd0): 28 ColorMapperArmor zone tints over the mech-outline schematic, one per dz_* damage zone (mech->GetDamageZoneIndex), using the EXISTING 10-arg ColorMapperArmor ctor (per the workflow's correction -- changing it would break cmArmor); added ColorMapper/Armor::SetColor (FUN_004c3c38, stores @0x6C). * Execute (@004cb358): resolve the player (WinTesla-clean via GetMissionPlayer for the local player, instead of the binary's raw App+0x24 "Players"-node dictionary walk), then draw the score + name box + alive/dead status box; null-guarded. KEY FINDING: PlayerStatus lives in the config's `cameraInit` block (the MISSION- REVIEW / spectator camera cockpit), NOT `MechInit` -- so it is NOT part of the mech cockpit and does not build during normal mech play (which is why the mech test shows it un-regressed and its Execute never runs). It is the post-mission scoreboard (all 8 players' name/score/mech-status), rendered by the BTCameraDirector game model. Registered in BTL4MethodDescription[] so `cameraInit` builds it instead of parse-skipping. STATE: complete reconstruction; compiles, links (no new /FORCE unresolved), and the mech cockpit is un-regressed (TARGET DESTROYED, 0 crashes). NOT runtime-verified -- cameraInit is only built by the mission-review camera model, which a normal `vehicle=<mech>` egg does not trigger. BRING-UP STUB (marked): CreateMutantPixelmap8 returns NULL (the mech-outline recolor needs the DynamicMemoryStream read API + Pixmap pixel-copy mapped) -> the score/name-box/status-box render but not the recoloured mech schematic. BT_PS_LOG traces the resolve. 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
3bee47a9ea
commit
b6918632fc
+295
-19
@@ -69,15 +69,8 @@
|
|||||||
static int DAT_0051a2bc = 0; // SectorDisplay GaugeRate
|
static int DAT_0051a2bc = 0; // SectorDisplay GaugeRate
|
||||||
static int DAT_0051a300 = 0; // SectorDisplay ModeMask
|
static int DAT_0051a300 = 0; // SectorDisplay ModeMask
|
||||||
static char DAT_0051a344[] = ""; // SectorDisplay grid image name
|
static char DAT_0051a344[] = ""; // SectorDisplay grid image name
|
||||||
|
// (PlayerStatus's DAT_ placeholder pool removed -- its rewired Make reads
|
||||||
static int DAT_0051b07c = 1; // PlayerStatus player number (1..8)
|
// methodDescription.parameterList[] like the other registered widgets.)
|
||||||
static int DAT_0051aff4 = 0; // PlayerStatus GaugeRate
|
|
||||||
static int DAT_0051b038 = 0; // PlayerStatus ModeMask
|
|
||||||
static char DAT_0051b0c0[] = ""; // PlayerStatus font image
|
|
||||||
static int DAT_0051b104 = 0; // color
|
|
||||||
static int DAT_0051b148 = 0; // okColor
|
|
||||||
static int DAT_0051b18c = 0; // aliveColor
|
|
||||||
static int DAT_0051b1d0 = 0; // deadColor
|
|
||||||
|
|
||||||
|
|
||||||
//###########################################################################
|
//###########################################################################
|
||||||
@@ -212,19 +205,44 @@ Logical
|
|||||||
// "PlayerStatus: Make player number <n>" is warned. Allocates (200) and
|
// "PlayerStatus: Make player number <n>" is warned. Allocates (200) and
|
||||||
// constructs "PlayerStatus" from DAT_0051aff4..0051b1d0.
|
// constructs "PlayerStatus" from DAT_0051aff4..0051b1d0.
|
||||||
//
|
//
|
||||||
|
MethodDescription
|
||||||
|
PlayerStatus::methodDescription =
|
||||||
|
{
|
||||||
|
"PlayerStatus",
|
||||||
|
PlayerStatus::Make,
|
||||||
|
{
|
||||||
|
// CFG (L4GAUGE.CFG:29): PlayerStatus(D,ModeAlwaysActive,1,helv15.pcc,0,11,3,1)
|
||||||
|
{ ParameterDescription::typeRate, NULL }, // p[0] rate
|
||||||
|
{ ParameterDescription::typeModeMask, NULL }, // p[1] mode mask
|
||||||
|
{ ParameterDescription::typeInteger, NULL }, // p[2] player number 1..8
|
||||||
|
{ ParameterDescription::typeString, NULL }, // p[3] font image
|
||||||
|
{ ParameterDescription::typeColor, NULL }, // p[4] color
|
||||||
|
{ ParameterDescription::typeColor, NULL }, // p[5] okColor
|
||||||
|
{ ParameterDescription::typeColor, NULL }, // p[6] aliveColor
|
||||||
|
{ ParameterDescription::typeColor, NULL }, // p[7] deadColor
|
||||||
|
PARAMETER_DESCRIPTION_END
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// @004cae90 -- Make. Rewired to read methodDescription.parameterList[] (the
|
||||||
|
// binary read raw DAT_ pools) + the port/x/y bug fixed (it passed entity/renderer
|
||||||
|
// as x/y and dropped the port). Returns True even on a NULL alloc (binary-faithful).
|
||||||
|
//
|
||||||
Logical
|
Logical
|
||||||
PlayerStatus::Make(
|
PlayerStatus::Make(
|
||||||
int /*display_port_index*/,
|
int display_port_index,
|
||||||
Vector2DOf<int> /*position*/,
|
Vector2DOf<int> position,
|
||||||
Entity *entity,
|
Entity * /*entity -- unused by PlayerStatus*/,
|
||||||
GaugeRenderer *gauge_renderer
|
GaugeRenderer *gauge_renderer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int playerNumber = DAT_0051b07c;
|
ParameterDescription *p = methodDescription.parameterList;
|
||||||
|
int playerNumber = p[2].data.integer;
|
||||||
if (playerNumber < 1 || playerNumber > 8)
|
if (playerNumber < 1 || playerNumber > 8)
|
||||||
{
|
{
|
||||||
DebugStream << "PlayerStatus: Make player number "
|
DebugStream << "PlayerStatus: Make player number "
|
||||||
<< playerNumber << " out of range\n"; // FUN_004dbb24 / FUN_004db78c
|
<< playerNumber << " out of range\n";
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,16 +250,274 @@ Logical
|
|||||||
if (gauge != NULL)
|
if (gauge != NULL)
|
||||||
{
|
{
|
||||||
new (gauge) PlayerStatus(
|
new (gauge) PlayerStatus(
|
||||||
(GaugeRate)DAT_0051aff4, (ModeMask)DAT_0051b038,
|
p[0].data.rate, p[1].data.modeMask,
|
||||||
(L4GaugeRenderer *)gauge_renderer, 0, (int)entity,
|
(L4GaugeRenderer *)gauge_renderer,
|
||||||
(int)gauge_renderer, playerNumber,
|
display_port_index, // graphics_port_number <-- FIX (was dropped)
|
||||||
(char *)&DAT_0051b0c0,
|
position.x, position.y, // x, y <-- FIX (was (int)entity/(int)renderer)
|
||||||
DAT_0051b104, DAT_0051b148, DAT_0051b18c, DAT_0051b1d0,
|
playerNumber, p[3].data.string,
|
||||||
|
p[4].data.color, p[5].data.color, p[6].data.color, p[7].data.color,
|
||||||
"PlayerStatus");
|
"PlayerStatus");
|
||||||
}
|
}
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//###########################################################################
|
||||||
|
// file-private helpers
|
||||||
|
//###########################################################################
|
||||||
|
|
||||||
|
// (ReadStreamString @004caf50 -- the length-prefixed string reader used by the
|
||||||
|
// faithful CreateMutantPixelmap8 -- deferred with the pixmap-recolor stub above;
|
||||||
|
// its stream read is a vtbl+0x1c indirect whose method name needs mapping.)
|
||||||
|
|
||||||
|
//
|
||||||
|
// @004cafac -- per-player pixmap recolour. Find the mech's type-0x20 pixmap
|
||||||
|
// resource (App resource file), open it as a MemoryStream, read the embedded
|
||||||
|
// image name, look the source pixmap up in the renderer's PixMap8 cache, and copy
|
||||||
|
// it while biasing every palette index >= 0x20 by (paletteBase-0x20) so each
|
||||||
|
// player's mech outline draws in its own colour ramp. Returns the (reused) Pixmap.
|
||||||
|
//
|
||||||
|
static Pixmap *
|
||||||
|
CreateMutantPixelmap8(Entity * /*mech*/, L4Warehouse * /*warehouse*/,
|
||||||
|
int /*paletteBase*/, Pixmap *dest)
|
||||||
|
{
|
||||||
|
// ⚠ BRING-UP STUB (marked; leaves the mech-outline schematic unrendered).
|
||||||
|
// The faithful reconstruction (decomp @004cafac) resolves the mech's type-0x20
|
||||||
|
// pixmap sub-resource from the App ResourceFile, opens it as a memory stream,
|
||||||
|
// reads the embedded image name (the stream read is a vtbl+0x1c indirect --
|
||||||
|
// ReadStreamString @004caf50), looks the source PixMap8 up in the renderer
|
||||||
|
// warehouse, and copies it biasing every palette index >= 0x20 by
|
||||||
|
// (paletteBase-0x20) so each player's mech draws in its own colour ramp.
|
||||||
|
// Deferred: the DynamicMemoryStream read API + Pixmap pixel-copy need mapping.
|
||||||
|
// With this stub recoloredMech stays NULL -> Execute skips the outline blit;
|
||||||
|
// the score, name box, and alive/dead status box still render.
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
//###########################################################################
|
||||||
|
// PlayerStatusMappingGroup @004c9bd0
|
||||||
|
//###########################################################################
|
||||||
|
|
||||||
|
//
|
||||||
|
// The 28 named damage zones (PTR_s_dz_door_0051a240); each gets one
|
||||||
|
// ColorMapperArmor tinting that zone of the mech-outline schematic.
|
||||||
|
//
|
||||||
|
static const char *const kPlayerStatusZone[playerStatusZoneCount] =
|
||||||
|
{
|
||||||
|
"dz_door","dz_dtorso","dz_hip","dz_larm","dz_ldleg","dz_lfoot","dz_lgun",
|
||||||
|
"dz_ltorso","dz_luleg","dz_missle","dz_rarm","dz_rdleg","dz_rfoot","dz_rgun",
|
||||||
|
"dz_rtorso","dz_ruleg","dz_searchlight","dz_utorso","dz_reardtorso",
|
||||||
|
"dz_rearltorso","dz_rearrtorso","dz_rearutorso","dz_lmissle","dz_rmissle",
|
||||||
|
"unused1","unused2","unused3","unused4"
|
||||||
|
};
|
||||||
|
|
||||||
|
PlayerStatusMappingGroup::PlayerStatusMappingGroup(
|
||||||
|
GaugeRate rate, ModeMask mode_mask, L4GaugeRenderer *renderer,
|
||||||
|
int graphics_port_number, Entity *mech, int base_color_index,
|
||||||
|
const char *palette_a, const char *palette_b, const char * /*identification_string*/)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < playerStatusZoneCount; ++i)
|
||||||
|
{
|
||||||
|
int zoneIndex = (mech != NULL)
|
||||||
|
? mech->GetDamageZoneIndex(CString(kPlayerStatusZone[i])) // FUN_0042076c (-1 => inert)
|
||||||
|
: -1;
|
||||||
|
zone[i] = (ColorMapperArmor *)operator new(0x70);
|
||||||
|
if (zone[i] != NULL)
|
||||||
|
new (zone[i]) ColorMapperArmor( // EXISTING 10-arg ctor (btl4gaug)
|
||||||
|
rate, mode_mask, renderer, graphics_port_number,
|
||||||
|
base_color_index + i, mech, palette_a, palette_b,
|
||||||
|
zoneIndex, "ColorMapperArmor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerStatusMappingGroup::~PlayerStatusMappingGroup()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < playerStatusZoneCount; ++i)
|
||||||
|
{
|
||||||
|
delete zone[i];
|
||||||
|
zone[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PlayerStatusMappingGroup::Execute() // @004c9cf4 run all 28
|
||||||
|
{
|
||||||
|
for (int i = 0; i < playerStatusZoneCount; ++i)
|
||||||
|
if (zone[i] != NULL) zone[i]->Execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PlayerStatusMappingGroup::SetColor(int state) // @004c9d18 push state onto all 28
|
||||||
|
{
|
||||||
|
for (int i = 0; i < playerStatusZoneCount; ++i)
|
||||||
|
if (zone[i] != NULL) zone[i]->SetColor(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
//###########################################################################
|
||||||
|
// PlayerStatus @004cb1a8 ctor / @004cb28c dtor / @004cb310 BecameActive /
|
||||||
|
// @004cb358 Execute
|
||||||
|
//###########################################################################
|
||||||
|
|
||||||
|
//
|
||||||
|
// @004cb1a8 -- ctor (vtable PTR_FUN_0051be20). GraphicGauge base (owner folded
|
||||||
|
// to 0); stash the four state colours + port; set the port origin; build the
|
||||||
|
// score NumericDisplay.
|
||||||
|
//
|
||||||
|
PlayerStatus::PlayerStatus(
|
||||||
|
GaugeRate rate, ModeMask mode_mask, L4GaugeRenderer *renderer_in,
|
||||||
|
int graphics_port_number, int x, int y, int player_number,
|
||||||
|
const char *font_image, int color_in, int ok_color,
|
||||||
|
int alive_color, int dead_color, const char *identification_string)
|
||||||
|
: GraphicGauge(rate, mode_mask, renderer_in, 0, // FUN_00444818 (owner 0)
|
||||||
|
graphics_port_number, identification_string)
|
||||||
|
{
|
||||||
|
color = color_in; okColor = ok_color; aliveColor = alive_color; deadColor = dead_color;
|
||||||
|
port = graphics_port_number;
|
||||||
|
localView.SetOrigin(x, y); // this+0x48 vtbl+0x10
|
||||||
|
playerIndex = player_number - 1;
|
||||||
|
player = NULL; nameImage = NULL; recoloredMech = NULL; mappingGroup = NULL;
|
||||||
|
L4Warehouse *warehouse = (L4Warehouse *)renderer_in->warehousePointer;
|
||||||
|
scoreDisplay = new NumericDisplay( // FUN_004700bc @0xB8
|
||||||
|
warehouse, 0x72, 0xD8, font_image, 5,
|
||||||
|
(NumericDisplay::NumericFormat)2 /*signedBlankedZeros*/, color, okColor);
|
||||||
|
// dirty/previousStatus/previousMappingState set by BecameActive (byte-faithful).
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// @004cb28c -- dtor. Free the score numeric + the recoloured mech pixmap; the
|
||||||
|
// base chain runs implicitly. (nameImage is cache-owned; mappingGroup deleted
|
||||||
|
// here as a correctness fix over the binary's leak.)
|
||||||
|
//
|
||||||
|
PlayerStatus::~PlayerStatus()
|
||||||
|
{
|
||||||
|
player = NULL;
|
||||||
|
delete scoreDisplay; scoreDisplay = NULL; // FUN_0047018c
|
||||||
|
if (recoloredMech) { delete recoloredMech; recoloredMech = NULL; } // FUN_00449d0c
|
||||||
|
if (mappingGroup) { delete mappingGroup; mappingGroup = NULL; } // (binary leaks this)
|
||||||
|
}
|
||||||
|
|
||||||
|
Logical
|
||||||
|
PlayerStatus::TestInstance() const // @004cb2f8
|
||||||
|
{
|
||||||
|
return GraphicGauge::TestInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// @004cb310 -- BecameActive: reset the score readout, run the mapping group once,
|
||||||
|
// and force a full redraw next Execute.
|
||||||
|
//
|
||||||
|
void
|
||||||
|
PlayerStatus::BecameActive()
|
||||||
|
{
|
||||||
|
scoreDisplay->ForceUpdate(); // FUN_004703f4
|
||||||
|
if (mappingGroup != NULL) mappingGroup->Execute(); // FUN_004c9cf4
|
||||||
|
dirty = 1;
|
||||||
|
previousStatus = -1;
|
||||||
|
previousMappingState = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// @004cb358 -- Execute. Resolve player N (the mission player for the local
|
||||||
|
// player; WinTesla-clean via GetMissionPlayer instead of the binary's raw
|
||||||
|
// App+0x24 "Players"-node dictionary walk); on a change rebuild the recoloured
|
||||||
|
// mech pixmap + the 28-zone mapping group; each frame draw the score + mech
|
||||||
|
// outline + name box + alive/dead status box. Runs under the gauge's guarded
|
||||||
|
// Execute (BT_DEV_GAUGES), so a bad player-field offset degrades to a disabled
|
||||||
|
// gauge, never a game crash.
|
||||||
|
//
|
||||||
|
void
|
||||||
|
PlayerStatus::Execute()
|
||||||
|
{
|
||||||
|
// --- PART 1: resolve / change-detect the player ---
|
||||||
|
Entity *resolved = NULL;
|
||||||
|
if (playerIndex == 0 && application != NULL)
|
||||||
|
resolved = (Entity *)application->GetMissionPlayer(); // the local player (player 1)
|
||||||
|
|
||||||
|
if (getenv("BT_PS_LOG"))
|
||||||
|
{
|
||||||
|
static int s_c = 0;
|
||||||
|
if ((s_c++ % 60) == 0)
|
||||||
|
DEBUG_STREAM << "[ps] idx=" << playerIndex << " resolved=" << (void*)resolved
|
||||||
|
<< " player=" << (void*)player << " port=" << port << "\n" << std::flush;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolved != player)
|
||||||
|
{
|
||||||
|
player = resolved;
|
||||||
|
if (player != NULL)
|
||||||
|
{
|
||||||
|
Entity *mech = *(Entity **)((char *)player + 0x1FC); // player's vehicle
|
||||||
|
if (mech == NULL)
|
||||||
|
{
|
||||||
|
player = NULL; // no vehicle yet -> retry next frame
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
L4Warehouse *wh = (L4Warehouse *)renderer->warehousePointer;
|
||||||
|
int base = playerIndex * 0x1C + 0x10;
|
||||||
|
recoloredMech = CreateMutantPixelmap8(mech, wh, base, recoloredMech);
|
||||||
|
if (mappingGroup) delete mappingGroup;
|
||||||
|
mappingGroup = new PlayerStatusMappingGroup(
|
||||||
|
rate, modeMask, (L4GaugeRenderer *)renderer, port, mech, base,
|
||||||
|
"adpal.pcc", "adpal2.pcc", "PlayerStatusMappingGroup");
|
||||||
|
nameImage = NULL; // BRING-UP: App+0xC8 name cache not wired -> clear-box branch
|
||||||
|
BecameActive(); // force a full redraw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- PART 2: per-frame draw (only with a bound player) ---
|
||||||
|
if (player == NULL)
|
||||||
|
return;
|
||||||
|
Entity *mech = *(Entity **)((char *)player + 0x1FC);
|
||||||
|
if (mech == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// (a) score readout
|
||||||
|
scoreDisplay->Draw(&localView, *(Scalar *)((char *)player + 0x1C8)); // FUN_00470430
|
||||||
|
|
||||||
|
// (b) mapping-group disabled-state refresh
|
||||||
|
int disabled = 0; // BRING-UP: Mech::IsDisabled needs a Mech* cast (mech.hpp collides in this TU)
|
||||||
|
if (disabled != previousMappingState)
|
||||||
|
{
|
||||||
|
previousMappingState = disabled;
|
||||||
|
if (mappingGroup) mappingGroup->SetColor(disabled); // FUN_004c9d18
|
||||||
|
}
|
||||||
|
|
||||||
|
// (c) mech outline + name box, dirty-gated
|
||||||
|
if (dirty)
|
||||||
|
{
|
||||||
|
dirty = 0;
|
||||||
|
if (recoloredMech != NULL)
|
||||||
|
{
|
||||||
|
localView.MoveToAbsolute(1, 1); // vtbl+0x24
|
||||||
|
localView.DrawPixelMap8(True, 0, recoloredMech, 0, 0, // vtbl+0x5C
|
||||||
|
recoloredMech->Data.Size.x - 1, recoloredMech->Data.Size.y - 1);
|
||||||
|
}
|
||||||
|
localView.MoveToAbsolute(1, 0xCF);
|
||||||
|
if (nameImage == NULL) // no name bitmap -> filled box in `color`
|
||||||
|
{
|
||||||
|
localView.SetColor(color); // vtbl+0x18
|
||||||
|
localView.DrawFilledRectangleToRelative(0x80, 0x20); // vtbl+0x4C
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
localView.SetColor(0xFF);
|
||||||
|
localView.DrawBitMapOpaque(color, 0, nameImage, 0, 0, // vtbl+0x58
|
||||||
|
nameImage->Data.Size.x - 1, nameImage->Data.Size.y - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// (d) alive/dead status box, state-change gated
|
||||||
|
int state = *(int *)((char *)player + 0x1C4);
|
||||||
|
if (state != previousStatus)
|
||||||
|
{
|
||||||
|
previousStatus = state;
|
||||||
|
localView.SetColor(state == 0 ? aliveColor : deadColor);
|
||||||
|
localView.MoveToAbsolute(0, 0);
|
||||||
|
localView.DrawFilledRectangleToAbsolute(0x9F, 0xEF); // vtbl+0x44
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// @004cb1a8 -- ctor (vtable PTR_FUN_0051be20). GraphicGauge base; stashes the
|
// @004cb1a8 -- ctor (vtable PTR_FUN_0051be20). GraphicGauge base; stashes the
|
||||||
// four state colours (this[0x29..0x2C]); playerIndex = player_number - 1; sets
|
// four state colours (this[0x29..0x2C]); playerIndex = player_number - 1; sets
|
||||||
|
|||||||
@@ -75,8 +75,8 @@
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PlayerStatusMappingGroup( // @004c9bd0
|
PlayerStatusMappingGroup( // @004c9bd0
|
||||||
GaugeRate, ModeMask, L4GaugeRenderer *, int,
|
GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number,
|
||||||
Subsystem *mech, int base_color_index,
|
Entity *mech, int base_color_index,
|
||||||
const char *palette_a, const char *palette_b,
|
const char *palette_a, const char *palette_b,
|
||||||
const char *identification_string);
|
const char *identification_string);
|
||||||
~PlayerStatusMappingGroup(); // @004c9ca8
|
~PlayerStatusMappingGroup(); // @004c9ca8
|
||||||
@@ -214,9 +214,12 @@
|
|||||||
public GraphicGauge
|
public GraphicGauge
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// Registered in BTL4MethodDescription[] (btl4grnd.cpp) as "PlayerStatus".
|
||||||
|
static MethodDescription methodDescription;
|
||||||
|
|
||||||
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004cae90
|
static Logical Make(int, Vector2DOf<int>, Entity *, GaugeRenderer *); // @004cae90
|
||||||
PlayerStatus( // @004cb1a8
|
PlayerStatus( // @004cb1a8 (13 args; owner folded to 0 in base call)
|
||||||
GaugeRate, ModeMask, L4GaugeRenderer *, int,
|
GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number,
|
||||||
int x, int y, int player_number, const char *font_image,
|
int x, int y, int player_number, const char *font_image,
|
||||||
int color, int okColor, int aliveColor, int deadColor,
|
int color, int okColor, int aliveColor, int deadColor,
|
||||||
const char *identification_string);
|
const char *identification_string);
|
||||||
@@ -225,11 +228,11 @@
|
|||||||
void BecameActive(); // @004cb310
|
void BecameActive(); // @004cb310
|
||||||
void Execute(); // @004cb358
|
void Execute(); // @004cb358
|
||||||
protected:
|
protected:
|
||||||
int port; // @0x90 this[0x24]
|
int port; // @0x90 this[0x24] graphics_port_number
|
||||||
int playerIndex; // @0x94 this[0x25] (player_number-1)
|
int playerIndex; // @0x94 this[0x25] (player_number-1)
|
||||||
Entity *player; // @0x98 this[0x26]
|
Entity *player; // @0x98 this[0x26] cached (non-owned)
|
||||||
Pixmap *nameImage; // @0x9C this[0x27] (mutant pixmap)
|
BitMap *nameImage; // @0x9C this[0x27] App name-cache BitMap (was mislabeled Pixmap)
|
||||||
Pixmap *recoloredMech; // @0xA0 this[0x28]
|
Pixmap *recoloredMech; // @0xA0 this[0x28] CreateMutantPixelmap8 result (owned)
|
||||||
int color; // @0xA4 this[0x29]
|
int color; // @0xA4 this[0x29]
|
||||||
int okColor; // @0xA8 this[0x2A]
|
int okColor; // @0xA8 this[0x2A]
|
||||||
int aliveColor; // @0xAC this[0x2B]
|
int aliveColor; // @0xAC this[0x2B]
|
||||||
@@ -238,6 +241,8 @@
|
|||||||
*mappingGroup; // @0xB4 this[0x2D]
|
*mappingGroup; // @0xB4 this[0x2D]
|
||||||
NumericDisplay
|
NumericDisplay
|
||||||
*scoreDisplay; // @0xB8 this[0x2E]
|
*scoreDisplay; // @0xB8 this[0x2E]
|
||||||
|
int dirty; // @0xBC this[0x2F] redraw flag
|
||||||
|
int previousStatus; // @0xC0 this[0x30] last player+0x1C4 alive/dead
|
||||||
int previousMappingState; // @0xC4 this[0x31]
|
int previousMappingState; // @0xC4 this[0x31]
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -271,14 +276,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//#######################################################################
|
// NOTE: CreateMutantPixelmap8 (@004cafac) + ReadStreamString (@004caf50) are
|
||||||
// CreateMutantPixelmap8 -- file-private helper (@004cafac). Reads a named
|
// file-PRIVATE in the binary -- declared static at the top of btl4gau3.cpp,
|
||||||
// pixmap resource, decodes its embedded name string (ReadStreamString
|
// not here (the old free-function decl had the wrong signature).
|
||||||
// @004caf50), looks up the source pixmap and copies it while biasing every
|
|
||||||
// palette index >= 0x20 by (player_palette_base - 0x20). Produces a
|
|
||||||
// per-player recoloured 8-bit pixmap. Returns an allocated Pixmap.
|
|
||||||
//#######################################################################
|
|
||||||
Pixmap *CreateMutantPixelmap8( // @004cafac
|
|
||||||
Entity *player, int pixmap_cache, int palette_base, Pixmap *reuse);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -153,8 +153,12 @@
|
|||||||
Entity *entity, const char *palette_a, const char *palette_b,
|
Entity *entity, const char *palette_a, const char *palette_b,
|
||||||
int damage_zone_index, const char *identification_string);
|
int damage_zone_index, const char *identification_string);
|
||||||
~ColorMapperArmor();
|
~ColorMapperArmor();
|
||||||
|
|
||||||
|
// @004c3c38 -- store the group state into @0x6C (used by PlayerStatusMappingGroup
|
||||||
|
// to push the mech's disabled/enabled state onto all 28 zone tints).
|
||||||
|
void SetColor(int state) { unused = state; }
|
||||||
protected:
|
protected:
|
||||||
int unused; // @0x6C this[0x1B] (=0)
|
int unused; // @0x6C this[0x1B] (state slot; SetColor writes it)
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -67,6 +67,7 @@
|
|||||||
#if !defined(BTL4GAUG_HPP)
|
#if !defined(BTL4GAUG_HPP)
|
||||||
# include <btl4gaug.hpp> // the BT gauge classes (Compass, etc.)
|
# include <btl4gaug.hpp> // the BT gauge classes (Compass, etc.)
|
||||||
# include <btl4rdr.hpp> // MapDisplay (the "map" radar gauge)
|
# include <btl4rdr.hpp> // MapDisplay (the "map" radar gauge)
|
||||||
|
# include <btl4gau3.hpp> // PlayerStatus (the comm/score gauge)
|
||||||
#endif
|
#endif
|
||||||
#if !defined(L4LAMP_HPP)
|
#if !defined(L4LAMP_HPP)
|
||||||
# include <l4lamp.hpp>
|
# include <l4lamp.hpp>
|
||||||
@@ -139,6 +140,7 @@ MethodDescription
|
|||||||
&SegmentArcRatio::methodDescription, // "segmentArcRatio" -- segmented arc dial (speed)
|
&SegmentArcRatio::methodDescription, // "segmentArcRatio" -- segmented arc dial (speed)
|
||||||
&OneOfSeveralPixInt::methodDescription, // "oneOfSeveralPixInt" -- button-state lamp (duck/light/mode)
|
&OneOfSeveralPixInt::methodDescription, // "oneOfSeveralPixInt" -- button-state lamp (duck/light/mode)
|
||||||
&MapDisplay::methodDescription, // "map" -- the radar / tactical display
|
&MapDisplay::methodDescription, // "map" -- the radar / tactical display
|
||||||
|
&PlayerStatus::methodDescription, // "PlayerStatus" -- comm/score name-tag gauge
|
||||||
&BTL4ChainToPrevious
|
&BTL4ChainToPrevious
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user