//===========================================================================// // File: btl4gau3.cpp // // Project: BattleTech Brick: Gauge Renderer Manager // // Contents: Cockpit instrument library, part 3 -- multiplayer / tactical HUD // // displays (see btl4gau3.hpp). // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 02/22/96 CPB Initial coding. // //---------------------------------------------------------------------------// // Copyright (C) 1996, Virtual World Entertainment, Inc. All rights reserved // // PROPRIETARY AND CONFIDENTIAL // //===========================================================================// // // RECONSTRUCTED from the shipped binary (BTL4OPT.EXE). Behaviour follows the // Ghidra pseudo-C in recovered/all/part_014.c (@004c9bd0..@004cbea0). Class / // member names from the CODE identification strings; per-method @ADDR cited. // This TU links between btl4gau2.obj and btl4grnd.obj. // // Engine-internal helper map (consistent with btl4gau2.cpp): // FUN_00444818 GraphicGauge ctor FUN_00444870 GraphicGauge dtor // FUN_004700bc NumericDisplay ctor FUN_0047018c ::dtor // FUN_00470430 ::DrawAt FUN_00470758 ::Erase FUN_004703f4 ::Reset // FUN_00442aec/00442c12 BitMapCache AddRef/Release // FUN_00442d2b/00442e51 PixMapCache AddRef/Release // FUN_004700ac InternName FUN_004022e8 FreeName // FUN_00403ad0 NamedNode::Find(dictionary, name) ("Players") // FUN_00421414 ChainOf::Iterator ctor FUN_00421452 ::dtor // FUN_0042076c Subsystem::FindDamageZone -> index // FUN_004c3b98 ColorMapperArmor ctor (btl4gaug) // FUN_004c2f88 -> 7 (selection/blip colour) FUN_004c2f94 entity colour // FUN_0044fc10 score/rank lookup FUN_004b0898 lance-slot mech lookup // FUN_0049fb54 / 0x50bdb4 damage-mapping-group derivation // FUN_00449c88 Pixmap ctor FUN_00449d0c Pixmap dtor // FUN_00407064 Warehouse::FindResource (App+0x68) FUN_004032dc MemoryStream // FUN_004dcd94 Round FUN_004dbb24 DebugStream< #pragma hdrstop #if !defined(BTL4GAU3_HPP) # include #endif #if !defined(APP_HPP) # include #endif // // Unrecovered .data resource pools used by the two Make() factories below. The // concrete bytes (rate/mode/colours/image names) were not recovered from the // optimised image; declared here as typed placeholders so the construction // paths compile. (BEST-EFFORT.) DebugStream is provided by the shared recon // headers. // static int DAT_0051a2bc = 0; // SectorDisplay GaugeRate static int DAT_0051a300 = 0; // SectorDisplay ModeMask static char DAT_0051a344[] = ""; // SectorDisplay grid image name static int DAT_0051b07c = 1; // PlayerStatus player number (1..8) 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 //########################################################################### // PlayerStatusMappingGroup @004c9bd0 //########################################################################### // // @004c9bd0 -- build the 28 ColorMapperArmor zone gauges. For each name in the // damage-zone name table (PTR_s_dz_door_0051a240, 28 entries) build a transient // damage-zone descriptor, resolve its index on the mech (FindDamageZone // @0042076c), allocate (0x70) a ColorMapperArmor and construct it (@004c3b98) // wired to that zone (incrementing the next base colour index each iteration). // @004c9ca8 -- destroy: delete all 28, optionally free the array. // @004c9cf4 -- Execute: run each element's Execute (vtbl+0xc). // @004c9d18 -- SetColor: recolour all 28 (FUN_004c3c38 = ColorMapper SetColor). // //########################################################################### // SectorDisplay @004c9d44 Make / @004c9e10 ctor //########################################################################### // // @004c9d44 -- Make. Allocate (0xc4) and construct "SectorDisplay" from the // resource strings (DAT_0051a2bc..0051a3cc). Then verify the grid image exists // (BitMapCache); if missing, warn "SectorDisplay: Missing image ". // Logical SectorDisplay::Make( int /*display_port_index*/, Vector2DOf /*position*/, Entity *entity, GaugeRenderer *gauge_renderer ) { SectorDisplay *gauge = (SectorDisplay *)operator new(0xc4); if (gauge != NULL) { // // Construct with the recovered grid-image name; the remaining geometry / // colour / font-image arguments were not recovered, so are typed // placeholders. // new (gauge) SectorDisplay( (GaugeRate)DAT_0051a2bc, // rate (ModeMask)DAT_0051a300, // mode mask (L4GaugeRenderer *)gauge_renderer, 0, // graphics port number 0, 0, // x, y (char *)&DAT_0051a344, // grid image (char *)0, // font image 0, // color "SectorDisplay"); } BitMap *grid = gauge_renderer->warehousePointer->bitMapBin.GetIfAlreadyExists( (char *)&DAT_0051a344); // FUN_00442aec (peek, no AddRef) if (grid == NULL) { DebugStream << "SectorDisplay: Missing image " << (char *)&DAT_0051a344 << "\n"; // FUN_004dbb24 x3 } return (grid != NULL); } // // @004c9e10 -- ctor (vtable PTR_FUN_0051beec). GraphicGauge base, interns the // grid image; computes cellWidth = imageWidth/14, gridLeft = cellWidth*12, // gridRight = cellWidth*12 + cellWidth - 1, gridHeight = imageHeight; sets the // port origin; builds two NumericDisplays (this[0x2F] at origin, this[0x30] at // +cellWidth*4). baseLine = dirty = 500. // @004c9f94 -- dtor: release grid, delete both numerics, GraphicGauge::~GraphicGauge. // @004ca038 -- BecameActive: dirty=1; reset both numerics. // @004ca068 -- SetEnable: this[0x24] = enable. // @004ca07c -- Execute: when enabled, DrawAt the two numerics at the rounded // cursor position (+offsets), and on the first pass blit the grid image. // //########################################################################### // TeamStatusDisplay @004ca208 //########################################################################### // // @004ca208 -- ctor (vtable PTR_FUN_0051bea8). GraphicGauge base. rowSpacing = // param_10; originY = param_8 - 0x20; flags = param_12. Reads the font bitmap // width to size the highlight (cellW = w/14; highlightWidth = cellW*8 + 0x86, // plus an extra column when flags&4). Builds 8 rows, each with a number // NumericDisplay (this[0x3B+i]) and -- when flags&4 -- a kill NumericDisplay // (this[0x4C+i]); rows step down by rowSpacing. // @004ca39c -- dtor: delete the 8 numeric pairs, base dtor. // @004ca424 -- SetEnable: this[0x24] = enable. // @004ca438 -- BecameActive: selectedRow = 999; per-row prev = -1, prevScore = // -0.001f (0xba83126f); per-row prevRank = -1. // @004ca478 -- Execute. Resolve the local player's index/team // (App+0x6c mech -> +0x190 -> +0x1cc index, +0x204 team via FUN_0044fc10). // Read the "Players" node (FindByName @00403ad0), slot each player into [0..7] // by entity+0x1cc (skipping spectators, +0x29 bit 0x40). For each row: if the // occupant changed, blit the player's interned name bitmap (App+0xc8 palette // cache lookup) or clear, tinting friendly/self with FUN_004c2f88 (=7). Then // update each kill numeric from entity+0x1c8. When flags&4, also track each // player's rank (entity+0x204 - rankBase via FUN_0044fc10). Finally redraw the // selection underline on the local player's row. // //########################################################################### // PilotList @004ca90c Make / @004ca958 ctor //########################################################################### // // @004ca90c -- Make: allocate (0x178) and construct "PilotList" from // DAT_0051ab4c..0051abd4. // @004ca958 -- ctor (vtable PTR_FUN_0051be64). GraphicGauge base. For each of // 8 entries, read its (x,y,layoutMode) from DAT_0051af88 (stride 3); compute the // three NumericDisplay positions from layoutMode (0/1/2) and build them // (this entry +0x10/+0x14/+0x18). resolvedMech = 0; selected = 0. // @004cab10 -- dtor: delete the 3 numerics per entry (8 entries), base dtor. // @004caba4 -- BecameActive: per-entry resolvedMech (+0x08) = -1; currentSlot = 9. // @004cabd0 -- Execute (one slot per frame). Look up the lance roster // (App+0x6c mech +0x128 -> FUN_004b0898 slot lookup). For the current slot: // if empty, erase the three numerics; else compute the player-name bitmap and // blit it (DrawMechIcon @004cad70 tints by team via FUN_004c2f88), then DrawAt // the mech (+0x27c) and score (+0x280) numerics. Advance currentSlot (wraps 8). // helpers DrawMechIcon @004cad70, DrawAmmoCount @004cae20. // //########################################################################### // PlayerStatus @004cae90 Make / @004cb1a8 ctor //########################################################################### // // @004cae90 -- Make. DAT_0051b07c is the player number; must be 1..8 or // "PlayerStatus: Make player number " is warned. Allocates (200) and // constructs "PlayerStatus" from DAT_0051aff4..0051b1d0. // Logical PlayerStatus::Make( int /*display_port_index*/, Vector2DOf /*position*/, Entity *entity, GaugeRenderer *gauge_renderer ) { int playerNumber = DAT_0051b07c; if (playerNumber < 1 || playerNumber > 8) { DebugStream << "PlayerStatus: Make player number " << playerNumber << " out of range\n"; // FUN_004dbb24 / FUN_004db78c return False; } PlayerStatus *gauge = (PlayerStatus *)operator new(200); if (gauge != NULL) { new (gauge) PlayerStatus( (GaugeRate)DAT_0051aff4, (ModeMask)DAT_0051b038, (L4GaugeRenderer *)gauge_renderer, 0, (int)entity, (int)gauge_renderer, playerNumber, (char *)&DAT_0051b0c0, DAT_0051b104, DAT_0051b148, DAT_0051b18c, DAT_0051b1d0, "PlayerStatus"); } return True; } // // @004cb1a8 -- ctor (vtable PTR_FUN_0051be20). GraphicGauge base; stashes the // four state colours (this[0x29..0x2C]); playerIndex = player_number - 1; sets // the port origin; builds the score NumericDisplay (this[0x2E], helv font, // color/okColor). // @004cb28c -- dtor: delete the score numeric; free the mutant pixmap // (FUN_00449d0c); base dtor. // @004cb310 -- BecameActive: reset score numeric; run mappingGroup BecameActive // (FUN_004c9cf4); dirty flags = 1 / -1. // @004cb358 -- Execute. Find player N in the "Players" node (@00403ad0, // "Players" 0x51bd97, indexed lookup vtbl+0x34). When the player changes and // has a mech (+0x1fc): build a recoloured name pixmap (CreateMutantPixelmap8 // @004cafac) and a fresh PlayerStatusMappingGroup (@004c9bd0, adpal.pcc/ // adpal2.pcc) tinting the mech outline; cache the interned name bitmap. Each // frame: DrawAt the score (+0x1c8); update the armour mapping group when the // damage-mapping derivation (FUN_0049fb54 / 0x50bdb4) changes; on dirty, blit // the name bitmap then the recoloured mech outline; finally pick the frame // colour (aliveColor/deadColor by subsys+0x1c4) and draw the status box. // //########################################################################### // CreateMutantPixelmap8 @004cafac //########################################################################### // // @004cafac -- per-player pixmap recolour. Find the source pixmap resource // (Warehouse @00407064 by id mech+0x1bc); on failure warn "CreateMutantPixelmap8: // couldn't find ...". Open it as a MemoryStream, read the embedded image name // (ReadStreamString @004caf50, 0x50 chars), look it up in the PixMapCache. Copy // the source 8-bit pixels into a (possibly reused) Pixmap, biasing every palette // index >= 0x20 by (palette_base - 0x20) so each player's mech draws in their // own colour ramp. Returns the recoloured Pixmap. // //########################################################################### // MessageBoard @004cb678 Make / @004cb704 ctor //########################################################################### // // @004cb678 -- Make: allocate (0xa4) and construct "MessageBoard" from // DAT_0051b43c..0051b508; verify the strip image exists (BitMapCache). // @004cb704 -- ctor (vtable PTR_FUN_0051bddc). GraphicGauge base; interns + // AddRefs the message strip bitmap (this[0x25]); sets the port origin; color = // param_10 (this[0x26]). // @004cb788 -- dtor: release the strip, free the name, base dtor. // @004cb7fc -- BecameActive: previousNameId = -1; previousMessageId = -2. // @004cb82c -- Execute. Track the local player's mech (this[0x24]). Read its // controller message ids (mech+0x190 controller, +0xc message id, +0x10 name // id). When the message id changes, blit the corresponding 0x80x0x20 cell of // the strip ((id&3)<<7, (id>>2)<<5) tinted by FUN_004c2f88 (=7); -1 clears. // When the name id changes, blit the player's name bitmap (App+0xc8 palette // cache lookup) similarly. // // === btl4grnd.cpp begins at @004cbea0 (BTL4GaugeRenderer ctor) -- not this TU.