//===========================================================================//
// 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<Player*>::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<<char*  FUN_004db78c <<int
//      DAT_004efc94 the Application (App+0x24 dictionary, +0x68 warehouse,
//                   +0xc8 palette cache, +0x6c local mech)
//
// Recovered string evidence:
//      "SectorDisplay: Missing image " 0x51bc90   "Players" 0x51bcba/0x51bd97
//      "PlayerStatus: Make player number " 0x51bcd9
//      "CreateMutantPixelmap8: couldn't ..." 0x51bd0d/0x51bd40/0x51bd6d
//      "PilotList" 0x51bb4a   "PlayerStatus" 0x51bb54   "MessageBoard" 0x51bb61
//      "adpal.pcc" 0x51bd9f  "adpal2.pcc" 0x51bda9  "PlayerStatusMappingGroup" 0x51bdb4
//

// See btl4gaug.cpp: suppress heat.hpp's optional DebugStream so the shared
// mechrecon ReconStream definition is the only one active in this TU.
#define BT_DEBUGSTREAM_DEFINED

#include <bt.hpp>
#pragma hdrstop

#if !defined(BTL4GAU3_HPP)
#	include <btl4gau3.hpp>
#endif
#if !defined(APP_HPP)
#	include <app.hpp>
#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 <name>".
//
Logical
	SectorDisplay::Make(
		int				/*display_port_index*/,
		Vector2DOf<int>	/*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 <n>" is warned.  Allocates (200) and
// constructs "PlayerStatus" from DAT_0051aff4..0051b1d0.
//
Logical
	PlayerStatus::Make(
		int				/*display_port_index*/,
		Vector2DOf<int>	/*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.
