The renderer walks a sixteen-step rate wheel: one step per full pass over the gauge list, shifted right each pass and reset at the bottom. A gauge redraws only on the step its configured rate names, so the map - on one step - waited a whole turn of the wheel however cheap its redraw was. With the frame budget fixed the wheel turns about fifty times a second and one-in-sixteen would be tolerable. It is still the wrong shape for the map: the thing a pilot reads to navigate should not be the display that updates least often, and RP412MAPRATE says how many of the sixteen steps it draws on. Sixteen by default, one for the old data-driven behaviour. Each extra step costs one gauge's redraw against a pass that runs ninety of them, which measured as nothing. The write has to be QUALIFIED, and that is worth recording because it cost hours. GPS's constructor takes its rate as a parameter also called 'rate', which shadows the inherited Gauge::rate for the whole body - so a bare assignment sets the parameter and leaves the member holding whatever the gauge data asked for. oldRate is not shadowed, so it took the value, and the pair then disagreed: rate=2000, old=ffff. That looked exactly like something writing the member from outside, and there is no such writer - Gauge touches rate in three places, none of which can produce that pair. A hardware write-watch on the member settled it by reporting an address on the STACK. Also here, the terrain-arrival work on the map background. It draws one placement into the cached picture when the static bounds are unchanged, and rebuilds the whole thing only when they move - the bounds set the scale, and the scale is what everything already on the picture was drawn at. It is honest to say this fires rarely: the logs show terrain arriving in one burst at mission load, not streaming in as you drive, so the incremental path is mostly insurance. What it does close is real, though - departures now order a rebuild. Nothing listened for those before, and they had been swept up by the rebuild the next ARRIVAL ordered, which on a track whose terrain all arrives at load is a rebuild that never comes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
598 lines
10 KiB
C++
598 lines
10 KiB
C++
#pragma once
|
|
|
|
#include "..\munga_l4\l4grend.h"
|
|
#include "..\munga_l4\l4gauge.h"
|
|
#include "..\munga\rotation.h"
|
|
#include "..\munga\random.h"
|
|
#include "..\munga\point3d.h"
|
|
|
|
//#########################################################################
|
|
//####################### Various gauge utilities #########################
|
|
//#########################################################################
|
|
extern int
|
|
determineEntityColor(Entity *entity, Entity *local_entity=NULL);
|
|
|
|
//#########################################################################
|
|
class Compass :
|
|
public GraphicGauge
|
|
{
|
|
public:
|
|
static MethodDescription
|
|
methodDescription;
|
|
static Logical
|
|
Make(
|
|
int display_port_index,
|
|
Vector2DOf<int> position,
|
|
Entity *entity,
|
|
GaugeRenderer *gauge_renderer
|
|
);
|
|
|
|
Compass(
|
|
GaugeRate rate,
|
|
ModeMask mode_mask,
|
|
L4GaugeRenderer *renderer,
|
|
unsigned int owner_ID,
|
|
int graphics_port_number,
|
|
|
|
int center_x, int center_y,
|
|
int radius,
|
|
int background_color,
|
|
const char *north_map_name,
|
|
const char *west_map_name,
|
|
const char *south_map_name,
|
|
const char *east_map_name,
|
|
const char *bug_map_name,
|
|
const char *identification_string = "Compass"
|
|
);
|
|
|
|
~Compass();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
void
|
|
ShowInstance(char *indent);
|
|
void
|
|
BecameActive();
|
|
void
|
|
Execute();
|
|
protected:
|
|
enum
|
|
{
|
|
northIndex = 0,
|
|
eastIndex,
|
|
southIndex,
|
|
westIndex,
|
|
bugIndex,
|
|
numberOfItems
|
|
};
|
|
|
|
char
|
|
*imageName[numberOfItems];
|
|
|
|
Vector2DOf<int>
|
|
offset[numberOfItems],
|
|
previousPosition;
|
|
|
|
int
|
|
radius,
|
|
backgroundColor;
|
|
L4GaugeRenderer
|
|
*renderer;
|
|
GraphicsViewRecord
|
|
previousDrawing;
|
|
};
|
|
|
|
class ThreatIndicator :
|
|
public GraphicGauge
|
|
{
|
|
public:
|
|
static MethodDescription
|
|
methodDescription;
|
|
static Logical
|
|
Make(
|
|
int display_port_index,
|
|
Vector2DOf<int> position,
|
|
Entity *entity,
|
|
GaugeRenderer *gauge_renderer
|
|
);
|
|
|
|
ThreatIndicator(
|
|
GaugeRate rate,
|
|
ModeMask mode_mask,
|
|
L4GaugeRenderer *renderer,
|
|
unsigned int owner_ID,
|
|
int graphics_port_number,
|
|
|
|
int center_x, int center_y,
|
|
int inner_radius,
|
|
int outer_radius,
|
|
int bg_color,
|
|
int team_color,
|
|
int other_color,
|
|
Scalar sensing_radius,
|
|
const char *identification_string = "ThreatIndicator"
|
|
);
|
|
|
|
~ThreatIndicator();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
void
|
|
ShowInstance(char *indent);
|
|
void
|
|
BecameActive(); // virtual function in 'GaugeBase'
|
|
void
|
|
Execute();
|
|
protected:
|
|
void
|
|
Select();
|
|
void
|
|
Draw();
|
|
|
|
Scalar
|
|
viewRadius,
|
|
topClosingVelocity;
|
|
|
|
int
|
|
innerRadius,
|
|
outerRadius,
|
|
backgroundColor,
|
|
teamColor,
|
|
otherColor,
|
|
operatingPhase;
|
|
|
|
GaugeEntityList
|
|
movingEntityList;
|
|
|
|
GraphicsViewRecord
|
|
previousDrawing;
|
|
};
|
|
|
|
class NavDisplay;
|
|
|
|
class NavName SIGNATURED // Used exclusively by NavDisplay
|
|
{
|
|
friend class NavDisplay;
|
|
|
|
NavName()
|
|
{}
|
|
~NavName()
|
|
{}
|
|
|
|
Logical
|
|
TestInstance() const
|
|
{
|
|
return True;
|
|
}
|
|
|
|
protected:
|
|
void
|
|
ExtractFromEntity(Entity *entity, AffineMatrix &worldToView);
|
|
static void
|
|
CalculatePositions(NavName *array, int count);
|
|
void
|
|
Draw(GraphicsView *graphics_view, Scalar radius_multiplier);
|
|
|
|
Point3D
|
|
center;
|
|
Vector3D
|
|
direction;
|
|
BitMap
|
|
*nameBitmap;
|
|
int
|
|
color;
|
|
};
|
|
|
|
class NavDisplay :
|
|
public GraphicGauge
|
|
{
|
|
public:
|
|
static MethodDescription
|
|
methodDescription;
|
|
static Logical
|
|
Make(
|
|
int display_port_index,
|
|
Vector2DOf<int> position,
|
|
Entity *entity,
|
|
GaugeRenderer *gauge_renderer
|
|
);
|
|
|
|
NavDisplay(
|
|
GaugeRate rate,
|
|
ModeMask mode_mask,
|
|
L4GaugeRenderer *renderer,
|
|
unsigned int owner_ID,
|
|
int graphics_port_number,
|
|
|
|
int left, int bottom,
|
|
int right, int top,
|
|
int bg_color,
|
|
int static_color,
|
|
Scalar *scale_value_pointer,
|
|
Point3D **position_pointer,
|
|
Quaternion **angle_pointer,
|
|
Logical allow_rock_and_roll=False,
|
|
const char *identification_string = "NavDisplay"
|
|
);
|
|
|
|
~NavDisplay();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
void
|
|
ShowInstance(char *indent);
|
|
void
|
|
BecameActive();
|
|
void
|
|
Execute();
|
|
|
|
protected:
|
|
void
|
|
CalculateBounds();
|
|
void
|
|
SelectStatic();
|
|
void
|
|
SelectMoving();
|
|
void
|
|
DrawStatic(AffineMatrix &worldToView);
|
|
void
|
|
DrawMoving(AffineMatrix &worldToView);
|
|
void
|
|
DrawNames(AffineMatrix &worldToView);
|
|
|
|
enum
|
|
{
|
|
maximumNames = 16
|
|
};
|
|
|
|
NavName
|
|
nameArray[maximumNames];
|
|
|
|
Scalar
|
|
currentScale;
|
|
Point3D *
|
|
currentPositionPointer;
|
|
Quaternion *
|
|
currentAngularPointer;
|
|
|
|
Scalar
|
|
LODIndex,
|
|
pixelsPerMeter,
|
|
metersPerPixel,
|
|
xMin,
|
|
yMin,
|
|
zMin,
|
|
xMax,
|
|
yMax,
|
|
zMax;
|
|
|
|
AffineMatrix
|
|
worldToView;
|
|
|
|
int
|
|
operatingPhase,
|
|
backgroundColor,
|
|
staticColor,
|
|
halfWidth,
|
|
halfHeight;
|
|
|
|
Logical
|
|
rockAndRoll;
|
|
|
|
GaugeEntityList
|
|
staticEntityList,
|
|
movingEntityList;
|
|
|
|
GraphicsViewRecord
|
|
previousDrawing;
|
|
};
|
|
|
|
class GPS :
|
|
public GraphicGauge
|
|
{
|
|
struct GPSRecord
|
|
{
|
|
int x, y, color;
|
|
Logical me;
|
|
};
|
|
|
|
public:
|
|
static MethodDescription
|
|
methodDescription;
|
|
static Logical
|
|
Make(
|
|
int display_port_index,
|
|
Vector2DOf<int> position,
|
|
Entity *entity,
|
|
GaugeRenderer *gauge_renderer
|
|
);
|
|
|
|
GPS(
|
|
GaugeRate rate,
|
|
ModeMask mode_mask,
|
|
L4GaugeRenderer *renderer,
|
|
unsigned int owner_ID,
|
|
int graphics_port_number,
|
|
|
|
int left, int bottom,
|
|
int right, int top,
|
|
Scalar LOD_index,
|
|
const char *identification_string = "GPS"
|
|
);
|
|
|
|
~GPS();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
void
|
|
ShowInstance(char *indent);
|
|
void
|
|
BecameActive(); // virtual function in 'GaugeBase'
|
|
void
|
|
NotifyOfNewInterestingEntity(Entity *entity);
|
|
//
|
|
// Terrain that leaves interest range is dropped from the map, and
|
|
// there is no way to un-draw one placement from a composited picture
|
|
// - so this is the one case that still costs a full rebuild.
|
|
//
|
|
void
|
|
NotifyOfBecomingUninterestingEntity(Entity *entity);
|
|
void
|
|
Execute();
|
|
|
|
protected:
|
|
void
|
|
UpdateStaticEntities();
|
|
//
|
|
// Draw one placement into the cached background, at the scale that
|
|
// background was built at. False if the entity has no GaugeImage and
|
|
// so never appears on the map at all - which on the big tracks is
|
|
// most of the terrain in them.
|
|
//
|
|
Logical
|
|
DrawStaticEntity(Entity *entity);
|
|
|
|
enum
|
|
{
|
|
max_moving_entities=32
|
|
};
|
|
|
|
Logical
|
|
needsStaticUpdate,
|
|
needsScreenUpdate,
|
|
// is there a picture worth adding a single placement to?
|
|
backgroundBuilt;
|
|
//
|
|
// The static bounds the background was last built for. They decide
|
|
// the scale, so terrain arriving inside them can be drawn onto the
|
|
// picture instead of forcing a new one - see
|
|
// GPS::NotifyOfNewInterestingEntity.
|
|
//
|
|
Scalar
|
|
builtMinX, builtMinY, builtMinZ,
|
|
builtMaxX, builtMaxY, builtMaxZ;
|
|
Scalar
|
|
LODIndex,
|
|
metersPerPixel,
|
|
pixelsPerMeter;
|
|
Point3D
|
|
centeringOffset;
|
|
int
|
|
width,
|
|
height,
|
|
numberOfMovingEntities;
|
|
GPSRecord
|
|
previousGPSRecord[max_moving_entities];
|
|
Video8BitBuffered
|
|
*background;
|
|
};
|
|
|
|
//#######################################################################
|
|
// Ranking
|
|
//#######################################################################
|
|
class Ranking :
|
|
public GraphicGauge
|
|
{
|
|
public:
|
|
static MethodDescription
|
|
methodDescription;
|
|
|
|
static Logical
|
|
Make(
|
|
int display_port_index,
|
|
Vector2DOf<int> position,
|
|
Entity *entity,
|
|
GaugeRenderer * gauge_renderer
|
|
);
|
|
|
|
Ranking(
|
|
GaugeRate rate,
|
|
ModeMask mode_mask,
|
|
L4GaugeRenderer *renderer,
|
|
unsigned int owner_ID,
|
|
int graphics_port_number,
|
|
int top, int left,
|
|
const char *font_name,
|
|
int spacing,
|
|
int numeric_color,
|
|
int new_options,
|
|
const char *identification_string = "Ranking"
|
|
);
|
|
|
|
~Ranking();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
void
|
|
ShowInstance(char *indent);
|
|
void
|
|
LinkToEntity(Entity *entity);
|
|
void
|
|
BecameActive();
|
|
void
|
|
Execute();
|
|
|
|
enum
|
|
{
|
|
useTeamColorOption=0x0001,
|
|
showAllScoresOption=0x0002,
|
|
showIcomOption=0x0004
|
|
};
|
|
|
|
protected:
|
|
char
|
|
*messageName;
|
|
|
|
enum
|
|
{
|
|
maximumDisplayedPlayers=8
|
|
};
|
|
|
|
Entity
|
|
*linkedEntity;
|
|
int
|
|
previousRanking;
|
|
int
|
|
x,
|
|
y,
|
|
options,
|
|
spacing,
|
|
width;
|
|
|
|
Player
|
|
*previousArray[maximumDisplayedPlayers];
|
|
Scalar
|
|
previousScore[maximumDisplayedPlayers];
|
|
NumericDisplay
|
|
*numericDisplay[maximumDisplayedPlayers];
|
|
Logical
|
|
previousIntercomEnabled;
|
|
int
|
|
previousChannel[maximumDisplayedPlayers];
|
|
NumericDisplay
|
|
*channelDisplay[maximumDisplayedPlayers];
|
|
};
|
|
|
|
//#######################################################################
|
|
// ConfigMap
|
|
//#######################################################################
|
|
class ConfigMap :
|
|
public GraphicGauge
|
|
{
|
|
public:
|
|
static MethodDescription
|
|
methodDescription;
|
|
|
|
static Logical
|
|
Make(
|
|
int display_port_index,
|
|
Vector2DOf<int> position,
|
|
Entity *entity,
|
|
GaugeRenderer * gauge_renderer
|
|
);
|
|
|
|
ConfigMap(
|
|
GaugeRate rate,
|
|
ModeMask mode_mask,
|
|
L4GaugeRenderer *renderer,
|
|
unsigned int owner_ID,
|
|
int graphics_port_number,
|
|
int top, int bottom,
|
|
const char *unmapped_icon,
|
|
const char *other_icon,
|
|
const char *my_icon,
|
|
const char *both_icon,
|
|
const char *identification_string = "ConfigMap"
|
|
);
|
|
|
|
~ConfigMap();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
void
|
|
ShowInstance(char *indent);
|
|
void
|
|
LinkToEntity(Entity *entity);
|
|
void
|
|
BecameActive();
|
|
void
|
|
Execute();
|
|
|
|
protected:
|
|
Entity
|
|
*linkedEntity;
|
|
char
|
|
*iconName[4];
|
|
int
|
|
previousState[4];
|
|
};
|
|
|
|
//#######################################################################
|
|
// MessageBoard
|
|
//#######################################################################
|
|
class MessageBoard :
|
|
public GraphicGauge
|
|
{
|
|
public:
|
|
static MethodDescription
|
|
methodDescription;
|
|
|
|
static Logical
|
|
Make(
|
|
int display_port_index,
|
|
Vector2DOf<int> position,
|
|
Entity *entity,
|
|
GaugeRenderer * gauge_renderer
|
|
);
|
|
|
|
MessageBoard(
|
|
GaugeRate rate,
|
|
ModeMask mode_mask,
|
|
L4GaugeRenderer *renderer,
|
|
unsigned int owner_ID,
|
|
int graphics_port_number,
|
|
|
|
int left, int bottom,
|
|
int right, int top,
|
|
const char *font_name,
|
|
const char *message_name,
|
|
int bg_color,
|
|
int numeric_color,
|
|
const char *identification_string = "MessageBoard"
|
|
);
|
|
|
|
~MessageBoard();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
void
|
|
ShowInstance(char *indent);
|
|
void
|
|
LinkToEntity(Entity *entity);
|
|
void
|
|
BecameActive();
|
|
void
|
|
Execute();
|
|
|
|
protected:
|
|
NumericDisplay
|
|
*numericDisplay;
|
|
Entity
|
|
*linkedEntity;
|
|
char
|
|
*messageName;
|
|
int
|
|
backgroundColor,
|
|
fontHeight;
|
|
enum
|
|
{
|
|
deliberatelyBogusPointerValue = -1
|
|
};
|
|
Player
|
|
*previousPlayerPointer;
|
|
int
|
|
previousMessageType;
|
|
Scalar
|
|
previousValue;
|
|
};
|