Skip to content

Commit

Permalink
Implement framework for rendering hud gauges in config mode
Browse files Browse the repository at this point in the history
  • Loading branch information
MjnMixael committed Dec 30, 2024
1 parent 7536f21 commit e0f3784
Show file tree
Hide file tree
Showing 40 changed files with 587 additions and 374 deletions.
480 changes: 283 additions & 197 deletions code/hud/hud.cpp

Large diffs are not rendered by default.

55 changes: 27 additions & 28 deletions code/hud/hud.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ class HudGauge
int popUpActive() const;

virtual void preprocess();
virtual void render(float frametime);
virtual void render(float frametime, bool config = false);
virtual bool canRender() const;
virtual void pageIn();
virtual void initialize();
Expand All @@ -337,25 +337,24 @@ class HudGauge
void resetCockpitTarget();

void setFont();
void setGaugeColor(int bright_index = HUD_C_NONE);
void setGaugeColor(int bright_index = HUD_C_NONE, bool config = false);
void setGaugeCoords(int _x, int _y);
void setGaugeFrame(int frame_offset);

// rendering functions
void renderBitmap(int x, int y);
void renderBitmap(int frame, int x, int y);
void renderBitmapColor(int frame, int x, int y);
void renderBitmapUv(int frame, int x, int y, int w, int h, float u0, float v0, float u1, float v1);
void renderBitmapEx(int frame, int x, int y, int w, int h, int sx, int sy);
void renderString(int x, int y, const char *str);
void renderString(int x, int y, int gauge_id, const char *str);
void renderStringAlignCenter(int x, int y, int area_width, const char *s);
void renderPrintf(int x, int y, SCP_FORMAT_STRING const char* format, ...) SCP_FORMAT_STRING_ARGS(4, 5);
void renderPrintf(int x, int y, int gauge_id, SCP_FORMAT_STRING const char* format, ...) SCP_FORMAT_STRING_ARGS(5, 6);
void renderLine(int x1, int y1, int x2, int y2);
void renderGradientLine(int x1, int y1, int x2, int y2);
void renderRect(int x, int y, int w, int h);
void renderCircle(int x, int y, int diameter, bool filled = true);
void renderBitmap(int x, int y, float scale = 1.0f, bool config = false) const;
void renderBitmap(int frame, int x, int y, float scale = 1.0f, bool config = false) const;
void renderBitmapColor(int frame, int x, int y, float scale = 1.0f, bool config = false) const;
void renderBitmapEx(int frame, int x, int y, int w, int h, int sx, int sy, float scale = 1.0f, bool config = false) const;
void renderString(int x, int y, const char *str, float scale = 1.0f, bool config = false);
void renderString(int x, int y, int gauge_id, const char *str, float scale = 1.0f, bool config = false);
void renderStringAlignCenter(int x, int y, int area_width, const char *s, float scale = 1.0f, bool config = false);
void renderPrintf(int x, int y, float scale, bool config, SCP_FORMAT_STRING const char* format, ...) SCP_FORMAT_STRING_ARGS(6, 7);
void renderPrintfWithGauge(int x, int y, int gauge_id, float scale, bool config, SCP_FORMAT_STRING const char* format, ...) SCP_FORMAT_STRING_ARGS(7, 8);
void renderLine(int x1, int y1, int x2, int y2, bool config = false) const;
void renderGradientLine(int x1, int y1, int x2, int y2, bool config = false) const;
void renderRect(int x, int y, int w, int h, bool config = false) const;
void renderCircle(int x, int y, int diameter, bool filled = true, bool config = false) const;

void unsize(int *x, int *y);
void unsize(float *x, float *y);
Expand Down Expand Up @@ -391,7 +390,7 @@ class HudGaugeMissionTime: public HudGauge // HUD_MISSION_TIME
void initBitmaps(const char *fname);
void initTextOffsets(int x, int y);
void initValueOffsets(int x, int y);
void render(float frametime) override;
void render(float frametime, bool config = false) override;
void pageIn() override;
};

Expand All @@ -401,7 +400,7 @@ class HudGaugeTextWarnings: public HudGauge // HUD_TEXT_FLASH
bool flash_flags;
public:
HudGaugeTextWarnings();
void render(float frametime) override;
void render(float frametime, bool config = false) override;
void initialize() override;
int maybeTextFlash();
};
Expand All @@ -417,7 +416,7 @@ class HudGaugeKills: public HudGauge
void initBitmaps(const char *fname);
void initTextOffsets(int x, int y);
void initTextValueOffsets(int x, int y);
void render(float frametime) override;
void render(float frametime, bool config = false) override;
void pageIn() override;
};

Expand All @@ -430,7 +429,7 @@ class HudGaugeLag: public HudGauge
public:
HudGaugeLag();
void initBitmaps(const char *fname);
void render(float frametime) override;
void render(float frametime, bool config = false) override;
void pageIn() override;

void startFlashLag(int duration = 1400);
Expand Down Expand Up @@ -461,7 +460,7 @@ class HudGaugeObjectiveNotify: public HudGauge
void initRedAlertTextOffsetY(int y);
void initRedAlertValueOffsetY(int y);

void render(float frametime) override;
void render(float frametime, bool config = false) override;
void startFlashNotify(int duration = 1400);
bool maybeFlashNotify(bool flash_fast = false);
void renderObjective();
Expand Down Expand Up @@ -525,7 +524,7 @@ class HudGaugeDamage: public HudGauge
void initBottomBgOffset(int offset);
void initLineHeight(int h);
void initDisplayValue(bool value);
void render(float frametime) override;
void render(float frametime, bool config = false) override;
void pageIn() override;
void initialize() override;
};
Expand All @@ -548,7 +547,7 @@ class HudGaugeSupport: public HudGauge
void initTextDockOffsetX(int x);
void initTextDockValueOffsetX(int x);
void initRearmTimer(bool choice);
void render(float frametime) override;
void render(float frametime, bool config = false) override;
void pageIn() override;
};

Expand All @@ -558,30 +557,30 @@ class HudGaugeMultiMsg: public HudGauge
public:
HudGaugeMultiMsg();
bool canRender() const override;
void render(float frametime) override;
void render(float frametime, bool config = false) override;
};

class HudGaugeVoiceStatus: public HudGauge
{
protected:
public:
HudGaugeVoiceStatus();
void render(float frametime) override;
void render(float frametime, bool config = false) override;
};

class HudGaugePing: public HudGauge
{
protected:
public:
HudGaugePing();
void render(float frametime) override;
void render(float frametime, bool config = false) override;
};

class HudGaugeSupernova: public HudGauge
{
public:
HudGaugeSupernova();
void render(float frametime) override;
void render(float frametime, bool config = false) override;
};

class HudGaugeFlightPath: public HudGauge3DAnchor
Expand All @@ -593,7 +592,7 @@ class HudGaugeFlightPath: public HudGauge3DAnchor
HudGaugeFlightPath();
void initBitmap(const char *fname);
void initHalfSize(int w, int h);
void render(float frametime) override;
void render(float frametime, bool config = false) override;
};

HudGauge *hud_get_custom_gauge(const char *name, bool check_all_gauges = false);
Expand Down
7 changes: 6 additions & 1 deletion code/hud/hudbrackets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,13 @@ void HudGaugeBrackets::initBitmaps(char *fname)
}
}

void HudGaugeBrackets::render(float /*frametime*/)
void HudGaugeBrackets::render(float /*frametime*/, bool config)
{
// Brackets are do not support config settings
if (config) {
return;
}

// don't display brackets if we're warping out.
if ( Player->control_mode != PCM_NORMAL ) {
return;
Expand Down
2 changes: 1 addition & 1 deletion code/hud/hudbrackets.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class HudGaugeBrackets: public HudGauge3DAnchor
void initMinTargetBoxSizes(int w, int h);
void initMinSubTargetBoxSizes(int w, int h);
void initBitmaps(char *fname);
void render(float frametime) override;
void render(float frametime, bool config = false) override;
void renderObjectBrackets(object *targetp, color *clr, int w_correction, int h_correction, int flags);
void renderNavBrackets(vec3d* nav_pos, vertex* nav_point, color* clr, char* string);
void renderBoundingBrackets(int x1, int y1, int x2, int y2, int w_correction, int h_correction, float distance, int target_objnum, int flags);
Expand Down
46 changes: 46 additions & 0 deletions code/hud/hudconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ int HC_gauge_description_coords[GR_NUM_RESOLUTIONS][3] = {
}
};

int HC_resize_mode = GR_RESIZE_MENU;
const char *HC_gauge_descriptions(int n)
{
switch(n) {
Expand Down Expand Up @@ -512,6 +513,8 @@ static UI_WINDOW HC_ui_window;
int HC_gauge_hot; // mouse is over this gauge
int HC_gauge_selected; // gauge is selected
float HC_gauge_scale; // scale used for drawing the hud gauges
int HC_gauge_coordinates[6]; // x1, x2, y1, y1, w, h of the example HUD render area. Used for calculating new gauge coordinates
BoundingBox HC_gauge_mouse_coords[NUM_HUD_GAUGES];

// HUD colors
typedef struct hc_col {
Expand Down Expand Up @@ -606,6 +609,11 @@ void hud_config_init_ui(bool API_Access, int x, int y, int w)
HC_gauge_coords.clear();
HC_gauge_coords.resize(NUM_HUD_GAUGES);

// Clear the mouse coords array
for (auto& coord : HC_gauge_mouse_coords) {
coord = {-1, -1, -1, -1};
}

if (w < 0) {
HC_gauge_scale = 1.0f;
} else {
Expand Down Expand Up @@ -851,6 +859,44 @@ void hud_config_popup_flag_clear(int i)
}
}

void hud_config_set_mouse_coords(int gauge_config, int x1, int x2, int y1, int y2) {
HC_gauge_mouse_coords[gauge_config] = {x1, x2, y1, y2};
}

void hud_config_convert_coords(int x, int y, float scale, int& outX, int& outY)
{
outX = HC_gauge_coordinates[0] + static_cast<int>(x * scale);
outY = HC_gauge_coordinates[2] + static_cast<int>(y * scale);
}

void hud_config_convert_coords(float x, float y, float scale, float& outX, float& outY)
{
outX = HC_gauge_coordinates[0] + x * scale;
outY = HC_gauge_coordinates[2] + y * scale;
}

void hud_config_get_scale(int baseW, int baseH, float& outScale)
{
// Determine the scaling factor
float scaleX = static_cast<float>(HC_gauge_coordinates[4]) / baseW;
float scaleY = static_cast<float>(HC_gauge_coordinates[5]) / baseH;

// Use the smallest scale factor
outScale = std::min(scaleX, scaleY);
}

void hud_config_convert_coord_sys(int x, int y, int baseW, int baseH, int& outX, int& outY, float& outScale)
{
hud_config_get_scale(baseW, baseH, outScale);
hud_config_convert_coords(x, y, outScale, outX, outY);
}

void hud_config_convert_coord_sys(float x, float y, int baseW, int baseH, float& outX, float& outY, float& outScale)
{
hud_config_get_scale(baseW, baseH, outScale);
hud_config_convert_coords(x, y, outScale, outX, outY);
}

/*!
* @brief render all the hud config gauges
*
Expand Down
76 changes: 76 additions & 0 deletions code/hud/hudconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ extern int HUD_default_popup_mask2;
extern int HUD_config_default_flags;
extern int HUD_config_default_flags2;

extern const int HC_gauge_config_coords[GR_NUM_RESOLUTIONS][4];
extern int HC_resize_mode;

/**
* @brief Contains core HUD configuration data
* @note Is not default init'd. Assumes new player, PLR, or CSG reads will correctly set data.
Expand Down Expand Up @@ -92,6 +95,45 @@ struct HC_gauge_region
HC_gauge_region(const char *name, int x1, int y1, int h, int iff, int cp, int b, int nf, int cl) : filename(name), x(x1), y(y1), hotspot(h), use_iff(iff), can_popup(cp), bitmap(b), nframes(nf), color(cl){}
};

class BoundingBox {
public:
int x1, x2, y1, y2;

// Default constructor (initializes to invalid state)
BoundingBox() : x1(-1), x2(-1), y1(-1), y2(-1) {}

// Constructor
BoundingBox(int nx1, int nx2, int ny1, int ny2) : x1(nx1), x2(nx2), y1(ny1), y2(ny2) {}

bool isOverlapping(const BoundingBox& other) const
{
return (x2 >= other.x1 && // Not completely to the left
x1 <= other.x2 && // Not completely to the right
y2 >= other.y1 && // Not completely above
y1 <= other.y2); // Not completely below
}

// Check if the bounding box is valid (no negative coordinates)
bool isValid() const
{
return x1 >= 0 && x2 >= 0 && y1 >= 0 && y2 >= 0;
}

// Static function to check if any bounding box in an array overlaps with a new one
static bool isOverlappingAny(const BoundingBox mouse_coords[NUM_HUD_GAUGES], const BoundingBox& newBox, int self_index)
{
for (int i = 0; i < NUM_HUD_GAUGES; i++) {
if (i == self_index) {
continue;
}
if (mouse_coords[i].isValid() && mouse_coords[i].isOverlapping(newBox)) {
return true;
}
}
return false;
}
};

/*!
* @brief Array of hud gauges to be displayed in the hud config ui and configured by the player
* @note main definition in hudconfig.cpp
Expand All @@ -102,6 +144,8 @@ extern int HC_gauge_hot;
extern int HC_gauge_selected;
extern int HC_select_all;
extern float HC_gauge_scale;
extern int HC_gauge_coordinates[6]; // x1, x2, y1, y2, w, h for gauge rendering
extern BoundingBox HC_gauge_mouse_coords[NUM_HUD_GAUGES];

const char* HC_gauge_descriptions(int n);

Expand Down Expand Up @@ -203,5 +247,37 @@ void hud_config_color_load(const char *name);
*/
void hud_config_color_save(const char* name);

/*!
* @brief same as hud_config_covert_coords but only returns the scale and doesn't convert any coords
*/
void hud_config_get_scale(int baseW, int baseH, float& outScale);

/*!
* @brief converts a set of coordinates to HUD Config's rendering coordinates
*/
void hud_config_convert_coords(int x, int y, float scale, int& outX, int& outY);

/*!
* @brief converts a set of coordinates to HUD Config's rendering coordinates
*/
void hud_config_convert_coords(float x, float y, float scale, float& outX, float& outY);

/*!
* @brief convert the given HUD gauge position coordinates to a set more appropriate for the HUD Config UI and return the smaller scale value used
* so that other offsets and positions can be multiplied in turn
*/
void hud_config_convert_coord_sys(int x, int y, int baseW, int baseH, int& outX, int& outY, float& outScale);

/*!
* @brief convert the given HUD gauge position coordinates to a set more appropriate for the HUD Config UI and return
* the smaller scale value used so that other offsets and positions can be multiplied in turn
*/
void hud_config_convert_coord_sys(float x, float y, int baseW, int baseH, float& outX, float& outY, float& outScale);

/*!
* @brief save gauge coords during rendering time so hud config can check if the mouse is hovering over the gauge
*/
void hud_config_set_mouse_coords(int gauge_config, int x1, int x2, int y1, int y2);

#endif

8 changes: 4 additions & 4 deletions code/hud/hudescort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ int HudGaugeEscort::setGaugeColorEscort(int index, int team)
return is_flashing;
}

void HudGaugeEscort::render(float /*frametime*/)
void HudGaugeEscort::render(float /*frametime*/, bool /*config*/)
{
int i = 0;

Expand Down Expand Up @@ -398,7 +398,7 @@ void HudGaugeEscort::renderIcon(int x, int y, int index)
}
}
}
renderPrintf( x+ship_integrity_offsets[0] + offset, y+ship_integrity_offsets[1], EG_NULL, "%d", screen_integrity);
renderPrintfWithGauge( x+ship_integrity_offsets[0] + offset, y+ship_integrity_offsets[1], EG_NULL, 1.0f, false, "%d", screen_integrity);

//Let's be nice.
setGaugeColor();
Expand Down Expand Up @@ -453,9 +453,9 @@ void HudGaugeEscort::renderIconDogfight(int x, int y, int index)

// show ship integrity
if(objp == NULL){
renderPrintf( x+ship_integrity_offsets[0] - stat_shift, y+ship_integrity_offsets[1], EG_NULL, "%d", Net_players[np_index].m_player->stats.m_kill_count_ok);
renderPrintfWithGauge( x+ship_integrity_offsets[0] - stat_shift, y+ship_integrity_offsets[1], EG_NULL, 1.0f, false, "%d", Net_players[np_index].m_player->stats.m_kill_count_ok);
} else {
renderPrintf( x+ship_integrity_offsets[0] - stat_shift, y+ship_integrity_offsets[1], EG_NULL, "(%d%%) %d", hull_integrity, Net_players[np_index].m_player->stats.m_kill_count_ok);
renderPrintfWithGauge( x+ship_integrity_offsets[0] - stat_shift, y+ship_integrity_offsets[1], EG_NULL, 1.0f, false, "(%d%%) %d", hull_integrity, Net_players[np_index].m_player->stats.m_kill_count_ok);
}
}

Expand Down
2 changes: 1 addition & 1 deletion code/hud/hudescort.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class HudGaugeEscort: public HudGauge
void initShipNameMaxWidth(int w);
void initRightAlignNames(bool align);
int setGaugeColorEscort(int index, int team);
void render(float frametime) override;
void render(float frametime, bool config = false) override;
void pageIn() override;
void renderIcon(int x, int y, int index);
void renderIconDogfight(int x, int y, int index);
Expand Down
Loading

0 comments on commit e0f3784

Please sign in to comment.