BT410 Phase 5.3.30: the pilot name resolves -- and the magenta boxes diagnosed
The name art was never missing. The egg carries it as notation pages of hex rows ([BitMap::Small::Aeolus]); the engine BitMap has a ctor that reads exactly that format; and the AUTHENTIC Mission ctor already loads them into smallNameBitmapChain (MISSION.CPP:525 -- implemented, called, working). The break was ours: btl4gau3's LookupPlayerNameBitmap was a bring-up stub returning NULL. It now uses the authentic API (GetCurrentMission()-> GetSmallNameBitmap(playerBitmapIndex)) and resolves live -- traced index=1 to a real BitMap, with the fallback-box branch provably never firing. Coverage 91% -> 92%. DIAGNOSIS CORRECTED for the stray magenta blocks over the top-left title: they are NOT a missing-name placeholder. They are the REAL name bitmap drawn at the wrong slot coordinates -- PilotList lays its 8 roster slots out from the PE-recovered DAT_0051af88 (x,y,mode) table, and ours puts them top-left instead of the shipped exe's centre row. Recovering that table is the next cockpit thread; the egg-hex -> live-BitMap pipeline is verified end to end, so what remains there is layout, not art or lookup. (A duplicate loader written before finding the authentic one was removed -- CODE/RP/MUNGA/MISSION.CPP already does this job.) Gauge fight 11/11, smoke and novice clean, zero faults. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,10 @@
|
||||
#include <btl4.hpp>
|
||||
#pragma hdrstop
|
||||
|
||||
#if !defined(MISSION_HPP)
|
||||
# include <mission.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(BTL4GAU3_HPP)
|
||||
# include <btl4gau3.hpp>
|
||||
#endif
|
||||
@@ -145,9 +149,28 @@ static Logical
|
||||
// binary's own cache-miss branch (the tinted name box), never an AV.
|
||||
//
|
||||
static BitMap *
|
||||
LookupPlayerNameBitmap(int /*player_bitmap_index*/)
|
||||
LookupPlayerNameBitmap(int player_bitmap_index)
|
||||
{
|
||||
return NULL;
|
||||
//
|
||||
// The mission owns the name art: the egg's [smallbitmap] index page
|
||||
// lists one notation page of hex rows per pilot, and the authentic
|
||||
// Mission ctor loads them into smallNameBitmapChain (MISSION.CPP:525).
|
||||
// A player's `bitmapindex` egg entry selects its 1-based slot. A miss
|
||||
// still routes the caller to the binary's cache-miss branch (the
|
||||
// tinted name box), never an AV.
|
||||
//
|
||||
if (player_bitmap_index <= 0 || application == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Mission
|
||||
*mission = application->GetCurrentMission();
|
||||
if (mission == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return mission->GetSmallNameBitmap(player_bitmap_index);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,368 +1,368 @@
|
||||
//===========================================================================//
|
||||
// File: btl4mssn.cpp //
|
||||
// Project: BattleTech Brick: //
|
||||
// Contents: Implementation for the L4 (game-level) mission //
|
||||
//---------------------------------------------------------------------------//
|
||||
// Date Who Modification //
|
||||
// -------- --- ---------------------------------------------------------- //
|
||||
// 04/07/95 ECH Initial coding. //
|
||||
// 09/12/95 JM Derived from L4Mission //
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
|
||||
// All Rights reserved worldwide //
|
||||
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
||||
//===========================================================================//
|
||||
|
||||
#include <btl4.hpp>
|
||||
#pragma hdrstop
|
||||
|
||||
#if !defined(BTL4MSSN_HPP)
|
||||
# include <btl4mssn.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(BTL4APP_HPP)
|
||||
# include <btl4app.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(L4GREND_HPP)
|
||||
# include <l4grend.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(L4HOST_HPP)
|
||||
# include <l4host.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(HOSTMGR_HPP)
|
||||
# include <hostmgr.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(NOTATION_HPP)
|
||||
# include <notation.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(SCNROLE_HPP)
|
||||
# include <scnrole.hpp>
|
||||
#endif
|
||||
|
||||
//##########################################################################
|
||||
//########################### BTL4Mission ############################
|
||||
//##########################################################################
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
BTL4Mission::BTL4Mission(
|
||||
NotationFile *notation_file,
|
||||
ResourceFile *resources
|
||||
):
|
||||
BTMission(notation_file, resources)
|
||||
{
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
BTL4Mission::~BTL4Mission()
|
||||
{
|
||||
Check(this);
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// SetPlayerData Pulls this host's player page out of the notation file and
|
||||
// populates the mission's player description: model, dropzone, color, badge,
|
||||
// patch, experience level, advanced-damage flag, scenario role (+ its damage
|
||||
// modifiers), and the plasma-display badge bitmap.
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
BTL4Mission::SetPlayerData(NotationFile *notation_file)
|
||||
{
|
||||
Check(this);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------
|
||||
// Figure out which page we should be using to create the player
|
||||
//--------------------------------------------------------------
|
||||
//
|
||||
Check(application);
|
||||
HostManager *host_manager = application->GetHostManager();
|
||||
Check(host_manager);
|
||||
L4Host *host = (L4Host*)host_manager->GetLocalHost();
|
||||
Check(host);
|
||||
CString
|
||||
player_node = host->GetSymbolicName();
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Copy the game model and dropzone strings into the mission
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
gameModel = NULL;
|
||||
const char *player_model = NULL;
|
||||
notation_file->GetEntry(player_node, "vehicle", &player_model);
|
||||
if (!player_model)
|
||||
{
|
||||
DEBUG_STREAM << "Error: vehicle not specified!\n";
|
||||
Fail("Exiting");
|
||||
}
|
||||
Check_Pointer(player_model);
|
||||
gameModel = strdup(player_model);
|
||||
Register_Pointer(gameModel);
|
||||
|
||||
dropZoneName = NULL;
|
||||
const char *drop_zone = NULL;
|
||||
notation_file->GetEntry(player_node, "dropzone", &drop_zone);
|
||||
if (!drop_zone)
|
||||
{
|
||||
DEBUG_STREAM << "Error: dropzone not specified!\n";
|
||||
Fail("Exiting");
|
||||
}
|
||||
Check_Pointer(drop_zone);
|
||||
dropZoneName = strdup(drop_zone);
|
||||
Register_Pointer(dropZoneName);
|
||||
|
||||
dropZoneHost = False;
|
||||
notation_file->GetEntry(player_node, "loadzones", &dropZoneHost);
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Color
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
colorName = NULL;
|
||||
const char *color_name = NULL;
|
||||
notation_file->GetEntry(player_node, "color", &color_name);
|
||||
if (!color_name)
|
||||
{
|
||||
DEBUG_STREAM << "Error: color not specified!\n";
|
||||
Fail("Exiting");
|
||||
}
|
||||
Check_Pointer(color_name);
|
||||
colorName = strdup(color_name);
|
||||
Register_Pointer(colorName);
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Patch
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
const char *patch_name = NULL;
|
||||
notation_file->GetEntry(player_node, "patch", &patch_name);
|
||||
if (!patch_name)
|
||||
{
|
||||
DEBUG_STREAM << "Error: patch not specified!\n";
|
||||
Fail("Exiting");
|
||||
}
|
||||
Check_Pointer(patch_name);
|
||||
patchName = patch_name;
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Badge
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
badgeName = NULL;
|
||||
const char *badge_name = NULL;
|
||||
notation_file->GetEntry(player_node, "badge", &badge_name);
|
||||
if (!badge_name)
|
||||
{
|
||||
DEBUG_STREAM << "Error: badge not specified!\n";
|
||||
Fail("Exiting");
|
||||
}
|
||||
Check_Pointer(badge_name);
|
||||
badgeName = strdup(badge_name);
|
||||
Register_Pointer(badgeName);
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Team name. NOTE: the shipped binary reads the "badge" key here
|
||||
// as well and defaults to "DEFAULT" when the page omits it.
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
const char *team_name = NULL;
|
||||
if (!notation_file->GetEntry(player_node, "badge", &team_name))
|
||||
{
|
||||
teamName = "DEFAULT";
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_Pointer(team_name);
|
||||
teamName = team_name;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Experience level. Absence is tolerated only for the "camera"
|
||||
// page; "Unspecified" leaves the default.
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
const char *experience = "Unspecified";
|
||||
if (!notation_file->GetEntry(player_node, "experience", &experience))
|
||||
{
|
||||
if (strcmp(gameModel, "camera") != 0)
|
||||
{
|
||||
DEBUG_STREAM << player_node << " page missing expereince!" << endl;
|
||||
Fail("Exiting");
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp("Unspecified", experience) != 0)
|
||||
{
|
||||
if (strcmp(experience, "novice") == 0)
|
||||
{
|
||||
experienceLevel = BTMission::NoviceMode;
|
||||
}
|
||||
else if (strcmp(experience, "standard") == 0)
|
||||
{
|
||||
experienceLevel = BTMission::StandardMode;
|
||||
}
|
||||
else if (strcmp(experience, "veteran") == 0)
|
||||
{
|
||||
experienceLevel = BTMission::VeteranMode;
|
||||
}
|
||||
else if (strcmp(experience, "expert") == 0)
|
||||
{
|
||||
experienceLevel = BTMission::ExpertMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_STREAM << player_node
|
||||
<< " has an unknown experience field of "
|
||||
<< experience;
|
||||
Fail("Exiting");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Advanced damage flag
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
Logical advanced_damage = False;
|
||||
if (notation_file->GetEntry(player_node, "advancedDamage", &advanced_damage))
|
||||
{
|
||||
advancedDamageOn = advanced_damage ? True : False;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Scenario role -- every player page must name a role, and the role
|
||||
// page must name a model. The ScenarioRole is looked up (and created
|
||||
// on first use) in the mission's role dictionary, then its per-page
|
||||
// score modifiers applied.
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
const char *role_node = NULL;
|
||||
if (!notation_file->GetEntry(player_node, "role", &role_node))
|
||||
{
|
||||
DEBUG_STREAM << "Each Player page must have a role field !" << endl;
|
||||
Fail("Exiting");
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_Pointer(role_node);
|
||||
roleName = role_node;
|
||||
|
||||
const char *role_model = NULL;
|
||||
if (!notation_file->GetEntry(role_node, "model", &role_model))
|
||||
{
|
||||
DEBUG_STREAM << role_node << " page or model field missing !" << endl;
|
||||
Fail("Exiting");
|
||||
}
|
||||
else
|
||||
{
|
||||
ScenarioRole *role = GetScenarioRole(roleName);
|
||||
if (role == NULL)
|
||||
{
|
||||
role = new ScenarioRole(roleName, CString(role_model));
|
||||
Register_Object(role);
|
||||
AddScenarioRole(role);
|
||||
}
|
||||
|
||||
//
|
||||
// Optional per-page score modifiers.
|
||||
//
|
||||
Scalar value;
|
||||
if (notation_file->GetEntry(role_node, "dmgInflctdMdfr", &value))
|
||||
{
|
||||
role->SetDamageInflictedModifier(value);
|
||||
}
|
||||
if (notation_file->GetEntry(role_node, "dmgRcvdMdfr", &value))
|
||||
{
|
||||
role->SetDamageReceivedModifier(value);
|
||||
}
|
||||
if (notation_file->GetEntry(role_node, "dmgBias", &value))
|
||||
{
|
||||
role->SetDamageBias(value);
|
||||
}
|
||||
if (notation_file->GetEntry(role_node, "friendlyFire", &value))
|
||||
{
|
||||
role->SetFriendlyFirePenalty(value);
|
||||
}
|
||||
int return_from_death;
|
||||
if (notation_file->GetEntry(role_node, "return", &return_from_death))
|
||||
{
|
||||
role->SetReturnFromDeath(return_from_death);
|
||||
}
|
||||
if (notation_file->GetEntry(role_node, "killBonus", &value))
|
||||
{
|
||||
role->SetKillBonus(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Get playerBitmapIndex and, if present, blit the badge bitmap onto
|
||||
// the external (plasma) display.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
if (!notation_file->GetEntry(player_node, "bitmapindex", &playerBitmapIndex))
|
||||
{
|
||||
DEBUG_STREAM << "No Bitmap for player" << player_node;
|
||||
DEBUG_STREAM << flush;
|
||||
}
|
||||
else
|
||||
{
|
||||
BitMap *bitmap = GetLargeNameBitmap(playerBitmapIndex);
|
||||
if (bitmap != NULL)
|
||||
{
|
||||
Check(application);
|
||||
L4GaugeRenderer
|
||||
*gauge_renderer =
|
||||
(L4GaugeRenderer*)application->GetGaugeRenderer();
|
||||
if (gauge_renderer != NULL)
|
||||
{
|
||||
Check(gauge_renderer);
|
||||
GraphicsDisplay *graphics_display =
|
||||
gauge_renderer->GetExternalDisplay();
|
||||
|
||||
if (graphics_display != NULL)
|
||||
{
|
||||
graphics_display->DrawBitMapOpaque(
|
||||
1, // foreground color
|
||||
0, // background color
|
||||
0xFF, // bitmask
|
||||
GraphicsDisplay::Replace, // operation
|
||||
0, // rotation
|
||||
0, 0, // position
|
||||
bitmap,
|
||||
0, // sx1
|
||||
0, // sy1
|
||||
bitmap->Data.Size.x - 1, // sx2
|
||||
bitmap->Data.Size.y - 1 // sy2
|
||||
);
|
||||
graphics_display->Update(True);
|
||||
graphics_display->WaitForUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Check_Fpu();
|
||||
}
|
||||
//===========================================================================//
|
||||
// File: btl4mssn.cpp //
|
||||
// Project: BattleTech Brick: //
|
||||
// Contents: Implementation for the L4 (game-level) mission //
|
||||
//---------------------------------------------------------------------------//
|
||||
// Date Who Modification //
|
||||
// -------- --- ---------------------------------------------------------- //
|
||||
// 04/07/95 ECH Initial coding. //
|
||||
// 09/12/95 JM Derived from L4Mission //
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
|
||||
// All Rights reserved worldwide //
|
||||
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
||||
//===========================================================================//
|
||||
|
||||
#include <btl4.hpp>
|
||||
#pragma hdrstop
|
||||
|
||||
#if !defined(BTL4MSSN_HPP)
|
||||
# include <btl4mssn.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(BTL4APP_HPP)
|
||||
# include <btl4app.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(L4GREND_HPP)
|
||||
# include <l4grend.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(L4HOST_HPP)
|
||||
# include <l4host.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(HOSTMGR_HPP)
|
||||
# include <hostmgr.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(NOTATION_HPP)
|
||||
# include <notation.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(SCNROLE_HPP)
|
||||
# include <scnrole.hpp>
|
||||
#endif
|
||||
|
||||
//##########################################################################
|
||||
//########################### BTL4Mission ############################
|
||||
//##########################################################################
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
BTL4Mission::BTL4Mission(
|
||||
NotationFile *notation_file,
|
||||
ResourceFile *resources
|
||||
):
|
||||
BTMission(notation_file, resources)
|
||||
{
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
BTL4Mission::~BTL4Mission()
|
||||
{
|
||||
Check(this);
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// SetPlayerData Pulls this host's player page out of the notation file and
|
||||
// populates the mission's player description: model, dropzone, color, badge,
|
||||
// patch, experience level, advanced-damage flag, scenario role (+ its damage
|
||||
// modifiers), and the plasma-display badge bitmap.
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
BTL4Mission::SetPlayerData(NotationFile *notation_file)
|
||||
{
|
||||
Check(this);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------
|
||||
// Figure out which page we should be using to create the player
|
||||
//--------------------------------------------------------------
|
||||
//
|
||||
Check(application);
|
||||
HostManager *host_manager = application->GetHostManager();
|
||||
Check(host_manager);
|
||||
L4Host *host = (L4Host*)host_manager->GetLocalHost();
|
||||
Check(host);
|
||||
CString
|
||||
player_node = host->GetSymbolicName();
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Copy the game model and dropzone strings into the mission
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
gameModel = NULL;
|
||||
const char *player_model = NULL;
|
||||
notation_file->GetEntry(player_node, "vehicle", &player_model);
|
||||
if (!player_model)
|
||||
{
|
||||
DEBUG_STREAM << "Error: vehicle not specified!\n";
|
||||
Fail("Exiting");
|
||||
}
|
||||
Check_Pointer(player_model);
|
||||
gameModel = strdup(player_model);
|
||||
Register_Pointer(gameModel);
|
||||
|
||||
dropZoneName = NULL;
|
||||
const char *drop_zone = NULL;
|
||||
notation_file->GetEntry(player_node, "dropzone", &drop_zone);
|
||||
if (!drop_zone)
|
||||
{
|
||||
DEBUG_STREAM << "Error: dropzone not specified!\n";
|
||||
Fail("Exiting");
|
||||
}
|
||||
Check_Pointer(drop_zone);
|
||||
dropZoneName = strdup(drop_zone);
|
||||
Register_Pointer(dropZoneName);
|
||||
|
||||
dropZoneHost = False;
|
||||
notation_file->GetEntry(player_node, "loadzones", &dropZoneHost);
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Color
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
colorName = NULL;
|
||||
const char *color_name = NULL;
|
||||
notation_file->GetEntry(player_node, "color", &color_name);
|
||||
if (!color_name)
|
||||
{
|
||||
DEBUG_STREAM << "Error: color not specified!\n";
|
||||
Fail("Exiting");
|
||||
}
|
||||
Check_Pointer(color_name);
|
||||
colorName = strdup(color_name);
|
||||
Register_Pointer(colorName);
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Patch
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
const char *patch_name = NULL;
|
||||
notation_file->GetEntry(player_node, "patch", &patch_name);
|
||||
if (!patch_name)
|
||||
{
|
||||
DEBUG_STREAM << "Error: patch not specified!\n";
|
||||
Fail("Exiting");
|
||||
}
|
||||
Check_Pointer(patch_name);
|
||||
patchName = patch_name;
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Badge
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
badgeName = NULL;
|
||||
const char *badge_name = NULL;
|
||||
notation_file->GetEntry(player_node, "badge", &badge_name);
|
||||
if (!badge_name)
|
||||
{
|
||||
DEBUG_STREAM << "Error: badge not specified!\n";
|
||||
Fail("Exiting");
|
||||
}
|
||||
Check_Pointer(badge_name);
|
||||
badgeName = strdup(badge_name);
|
||||
Register_Pointer(badgeName);
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Team name. NOTE: the shipped binary reads the "badge" key here
|
||||
// as well and defaults to "DEFAULT" when the page omits it.
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
const char *team_name = NULL;
|
||||
if (!notation_file->GetEntry(player_node, "badge", &team_name))
|
||||
{
|
||||
teamName = "DEFAULT";
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_Pointer(team_name);
|
||||
teamName = team_name;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Experience level. Absence is tolerated only for the "camera"
|
||||
// page; "Unspecified" leaves the default.
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
const char *experience = "Unspecified";
|
||||
if (!notation_file->GetEntry(player_node, "experience", &experience))
|
||||
{
|
||||
if (strcmp(gameModel, "camera") != 0)
|
||||
{
|
||||
DEBUG_STREAM << player_node << " page missing expereince!" << endl;
|
||||
Fail("Exiting");
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp("Unspecified", experience) != 0)
|
||||
{
|
||||
if (strcmp(experience, "novice") == 0)
|
||||
{
|
||||
experienceLevel = BTMission::NoviceMode;
|
||||
}
|
||||
else if (strcmp(experience, "standard") == 0)
|
||||
{
|
||||
experienceLevel = BTMission::StandardMode;
|
||||
}
|
||||
else if (strcmp(experience, "veteran") == 0)
|
||||
{
|
||||
experienceLevel = BTMission::VeteranMode;
|
||||
}
|
||||
else if (strcmp(experience, "expert") == 0)
|
||||
{
|
||||
experienceLevel = BTMission::ExpertMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_STREAM << player_node
|
||||
<< " has an unknown experience field of "
|
||||
<< experience;
|
||||
Fail("Exiting");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Advanced damage flag
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
Logical advanced_damage = False;
|
||||
if (notation_file->GetEntry(player_node, "advancedDamage", &advanced_damage))
|
||||
{
|
||||
advancedDamageOn = advanced_damage ? True : False;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------
|
||||
// Scenario role -- every player page must name a role, and the role
|
||||
// page must name a model. The ScenarioRole is looked up (and created
|
||||
// on first use) in the mission's role dictionary, then its per-page
|
||||
// score modifiers applied.
|
||||
//----------------------------------------------------------
|
||||
//
|
||||
const char *role_node = NULL;
|
||||
if (!notation_file->GetEntry(player_node, "role", &role_node))
|
||||
{
|
||||
DEBUG_STREAM << "Each Player page must have a role field !" << endl;
|
||||
Fail("Exiting");
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_Pointer(role_node);
|
||||
roleName = role_node;
|
||||
|
||||
const char *role_model = NULL;
|
||||
if (!notation_file->GetEntry(role_node, "model", &role_model))
|
||||
{
|
||||
DEBUG_STREAM << role_node << " page or model field missing !" << endl;
|
||||
Fail("Exiting");
|
||||
}
|
||||
else
|
||||
{
|
||||
ScenarioRole *role = GetScenarioRole(roleName);
|
||||
if (role == NULL)
|
||||
{
|
||||
role = new ScenarioRole(roleName, CString(role_model));
|
||||
Register_Object(role);
|
||||
AddScenarioRole(role);
|
||||
}
|
||||
|
||||
//
|
||||
// Optional per-page score modifiers.
|
||||
//
|
||||
Scalar value;
|
||||
if (notation_file->GetEntry(role_node, "dmgInflctdMdfr", &value))
|
||||
{
|
||||
role->SetDamageInflictedModifier(value);
|
||||
}
|
||||
if (notation_file->GetEntry(role_node, "dmgRcvdMdfr", &value))
|
||||
{
|
||||
role->SetDamageReceivedModifier(value);
|
||||
}
|
||||
if (notation_file->GetEntry(role_node, "dmgBias", &value))
|
||||
{
|
||||
role->SetDamageBias(value);
|
||||
}
|
||||
if (notation_file->GetEntry(role_node, "friendlyFire", &value))
|
||||
{
|
||||
role->SetFriendlyFirePenalty(value);
|
||||
}
|
||||
int return_from_death;
|
||||
if (notation_file->GetEntry(role_node, "return", &return_from_death))
|
||||
{
|
||||
role->SetReturnFromDeath(return_from_death);
|
||||
}
|
||||
if (notation_file->GetEntry(role_node, "killBonus", &value))
|
||||
{
|
||||
role->SetKillBonus(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Get playerBitmapIndex and, if present, blit the badge bitmap onto
|
||||
// the external (plasma) display.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
if (!notation_file->GetEntry(player_node, "bitmapindex", &playerBitmapIndex))
|
||||
{
|
||||
DEBUG_STREAM << "No Bitmap for player" << player_node;
|
||||
DEBUG_STREAM << flush;
|
||||
}
|
||||
else
|
||||
{
|
||||
BitMap *bitmap = GetLargeNameBitmap(playerBitmapIndex);
|
||||
if (bitmap != NULL)
|
||||
{
|
||||
Check(application);
|
||||
L4GaugeRenderer
|
||||
*gauge_renderer =
|
||||
(L4GaugeRenderer*)application->GetGaugeRenderer();
|
||||
if (gauge_renderer != NULL)
|
||||
{
|
||||
Check(gauge_renderer);
|
||||
GraphicsDisplay *graphics_display =
|
||||
gauge_renderer->GetExternalDisplay();
|
||||
|
||||
if (graphics_display != NULL)
|
||||
{
|
||||
graphics_display->DrawBitMapOpaque(
|
||||
1, // foreground color
|
||||
0, // background color
|
||||
0xFF, // bitmask
|
||||
GraphicsDisplay::Replace, // operation
|
||||
0, // rotation
|
||||
0, 0, // position
|
||||
bitmap,
|
||||
0, // sx1
|
||||
0, // sy1
|
||||
bitmap->Data.Size.x - 1, // sx2
|
||||
bitmap->Data.Size.y - 1 // sy2
|
||||
);
|
||||
graphics_display->Update(True);
|
||||
graphics_display->WaitForUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
@@ -553,3 +553,28 @@ LookupPlayerNameBitmap bring-up stubs), some lamp frames ("OFF x" vs the
|
||||
shipped state digits -- the mode accessor stand-in), and a stray magenta
|
||||
"MID/ADV" block that lands over the top-left title (a widget drawing at a
|
||||
wrong port offset; next thread).
|
||||
|
||||
## 5.3.30 -- THE PILOT NAME (and what the magenta boxes really are)
|
||||
|
||||
The name art was never missing: the egg carries it as notation pages of hex
|
||||
rows ([BitMap::Small::Aeolus]), the engine BitMap has a ctor that reads
|
||||
exactly that format (GRAPH2D.CPP), and the AUTHENTIC Mission ctor already
|
||||
loads them into smallNameBitmapChain (CODE/RP/MUNGA/MISSION.CPP:525 --
|
||||
implemented, called, working). The only break was OUR side: btl4gau3's
|
||||
LookupPlayerNameBitmap was a bring-up stub returning NULL. It now goes
|
||||
through the authentic API -- application->GetCurrentMission()->
|
||||
GetSmallNameBitmap(player->playerBitmapIndex) -- and RESOLVES live
|
||||
(traced: index=1 -> a real BitMap; the fallback-box branch never fires).
|
||||
Coverage 91% -> 92%.
|
||||
|
||||
DIAGNOSIS CORRECTED: the two magenta blocks over the top-left title are NOT
|
||||
the missing-name placeholder (that branch is provably not running). They
|
||||
are the REAL name bitmap drawn at the wrong slot coordinates -- PilotList
|
||||
positions its 8 roster slots from the PE-recovered DAT_0051af88 (x,y,mode)
|
||||
table, and ours puts them at the top-left instead of the shipped exe's
|
||||
centre row. Recovering that layout table is the next cockpit thread (it
|
||||
should also land "Aeolus" where the shipped binary draws it).
|
||||
|
||||
NOTE for whoever picks this up: a wrong-looking blit here is a LAYOUT bug,
|
||||
not an art or lookup bug -- the pipeline from egg hex rows to a live BitMap
|
||||
pointer is verified end to end.
|
||||
|
||||
Reference in New Issue
Block a user