From f82db707cfa68f100f02fe4aa108b46c7235087b Mon Sep 17 00:00:00 2001
From: PeachyPeachSM64 <72323920+PeachyPeachSM64@users.noreply.github.com>
Date: Sun, 15 Mar 2026 15:33:15 +0100
Subject: [PATCH] Fix nametags color and rendering order
---
autogen/convert_functions.py | 1 +
autogen/lua_definitions/functions.lua | 26 ++++-
docs/lua/functions-3.md | 68 +++++++++++
docs/lua/functions-6.md | 20 ----
docs/lua/functions.md | 4 +-
src/game/area.c | 3 +
src/game/level_update.c | 2 +
src/game/object_helpers.c | 15 ---
src/game/object_helpers.h | 1 -
src/game/object_list_processor.c | 2 +
src/pc/djui/djui.c | 1 +
src/pc/djui/djui_hud_utils.c | 104 +++++++++++++----
src/pc/djui/djui_hud_utils.h | 8 ++
src/pc/djui/djui_text.c | 6 +-
src/pc/lua/smlua_functions_autogen.c | 75 +++++++++----
src/pc/nametags.c | 156 +++++++++++++++-----------
16 files changed, 343 insertions(+), 149 deletions(-)
diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py
index 9a9f7d53a..19d9ad16b 100644
--- a/autogen/convert_functions.py
+++ b/autogen/convert_functions.py
@@ -118,6 +118,7 @@ override_disallowed_functions = {
"src/game/mario.h": [ " init_mario" ],
"src/pc/djui/djui_console.h": [ " djui_console_create", "djui_console_message_create", "djui_console_message_dequeue" ],
"src/pc/djui/djui_chat_message.h": [ "create_from" ],
+ "src/pc/djui/djui_hud_utils.h": [ "djui_hud_clear_interp_data" ],
"src/game/interaction.h": [ "process_interaction", "_handle_" ],
"src/game/sound_init.h": [ "_loop_", "thread4_", "set_sound_mode" ],
"src/pc/network/network_utils.h": [ "network_get_player_text_color[^_]" ],
diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index 746a8f4c4..0930f3bda 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -3856,6 +3856,26 @@ function djui_hud_reset_color()
-- ...
end
+--- @return DjuiColor
+--- Gets the current DJUI HUD text default color
+function djui_hud_get_text_color()
+ -- ...
+end
+
+--- @param r integer
+--- @param g integer
+--- @param b integer
+--- @param a integer
+--- Sets the current DJUI HUD text default color
+function djui_hud_set_text_color(r, g, b, a)
+ -- ...
+end
+
+--- Resets the current DJUI HUD text default color
+function djui_hud_reset_text_color()
+ -- ...
+end
+
--- @return integer rotation
--- @return number pivotX
--- @return number pivotY
@@ -9077,12 +9097,6 @@ function cur_obj_check_anim_frame_in_range(startFrame, rangeLength)
-- ...
end
---- @param a0 Pointer_integer
---- @return integer
-function cur_obj_check_frame_prior_current_frame(a0)
- -- ...
-end
-
--- @param m MarioState
--- @return integer
function mario_is_in_air_action(m)
diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md
index 8e4f8c230..00c87ebfe 100644
--- a/docs/lua/functions-3.md
+++ b/docs/lua/functions-3.md
@@ -2923,6 +2923,74 @@ Resets the current DJUI HUD color
+## [djui_hud_get_text_color](#djui_hud_get_text_color)
+
+### Description
+Gets the current DJUI HUD text default color
+
+### Lua Example
+`local djuiColorValue = djui_hud_get_text_color()`
+
+### Parameters
+- None
+
+### Returns
+- [DjuiColor](structs.md#DjuiColor)
+
+### C Prototype
+`struct DjuiColor* djui_hud_get_text_color(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_hud_set_text_color](#djui_hud_set_text_color)
+
+### Description
+Sets the current DJUI HUD text default color
+
+### Lua Example
+`djui_hud_set_text_color(r, g, b, a)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| r | `integer` |
+| g | `integer` |
+| b | `integer` |
+| a | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void djui_hud_set_text_color(u8 r, u8 g, u8 b, u8 a);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_hud_reset_text_color](#djui_hud_reset_text_color)
+
+### Description
+Resets the current DJUI HUD text default color
+
+### Lua Example
+`djui_hud_reset_text_color()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void djui_hud_reset_text_color(void);`
+
+[:arrow_up_small:](#)
+
+
+
## [djui_hud_get_rotation](#djui_hud_get_rotation)
### Description
diff --git a/docs/lua/functions-6.md b/docs/lua/functions-6.md
index 41b220737..5033fa01d 100644
--- a/docs/lua/functions-6.md
+++ b/docs/lua/functions-6.md
@@ -1615,26 +1615,6 @@ Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ?
-## [cur_obj_check_frame_prior_current_frame](#cur_obj_check_frame_prior_current_frame)
-
-### Lua Example
-`local integerValue = cur_obj_check_frame_prior_current_frame(a0)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| a0 | `Pointer` <`integer`> |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_check_frame_prior_current_frame(s16 *a0);`
-
-[:arrow_up_small:](#)
-
-
-
## [mario_is_in_air_action](#mario_is_in_air_action)
### Lua Example
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index 4076375df..c6faca7ad 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -760,6 +760,9 @@
- [djui_hud_get_color](functions-3.md#djui_hud_get_color)
- [djui_hud_set_color](functions-3.md#djui_hud_set_color)
- [djui_hud_reset_color](functions-3.md#djui_hud_reset_color)
+ - [djui_hud_get_text_color](functions-3.md#djui_hud_get_text_color)
+ - [djui_hud_set_text_color](functions-3.md#djui_hud_set_text_color)
+ - [djui_hud_reset_text_color](functions-3.md#djui_hud_reset_text_color)
- [djui_hud_get_rotation](functions-3.md#djui_hud_get_rotation)
- [djui_hud_set_rotation](functions-3.md#djui_hud_set_rotation)
- [djui_hud_set_rotation_interpolated](functions-3.md#djui_hud_set_rotation_interpolated)
@@ -1609,7 +1612,6 @@
- [cur_obj_check_if_at_animation_end](functions-6.md#cur_obj_check_if_at_animation_end)
- [cur_obj_check_anim_frame](functions-6.md#cur_obj_check_anim_frame)
- [cur_obj_check_anim_frame_in_range](functions-6.md#cur_obj_check_anim_frame_in_range)
- - [cur_obj_check_frame_prior_current_frame](functions-6.md#cur_obj_check_frame_prior_current_frame)
- [mario_is_in_air_action](functions-6.md#mario_is_in_air_action)
- [mario_is_dive_sliding](functions-6.md#mario_is_dive_sliding)
- [cur_obj_set_y_vel_and_animation](functions-6.md#cur_obj_set_y_vel_and_animation)
diff --git a/src/game/area.c b/src/game/area.c
index 36448abd5..c22fa22eb 100644
--- a/src/game/area.c
+++ b/src/game/area.c
@@ -26,6 +26,7 @@
#include "pc/network/network.h"
#include "pc/lua/smlua_hooks.h"
#include "pc/djui/djui.h"
+#include "pc/djui/djui_hud_utils.h"
#include "pc/djui/djui_panel_pause.h"
#include "pc/nametags.h"
#include "engine/lighting_engine.h"
@@ -254,6 +255,7 @@ void clear_areas(void) {
le_clear();
geo_clear_interp_data();
+ djui_hud_clear_interp_data();
}
void clear_area_graph_nodes(void) {
@@ -313,6 +315,7 @@ void unload_area(void) {
le_clear();
geo_clear_interp_data();
+ djui_hud_clear_interp_data();
}
void load_mario_area(void) {
diff --git a/src/game/level_update.c b/src/game/level_update.c
index 1ad390601..9f5db53cb 100644
--- a/src/game/level_update.c
+++ b/src/game/level_update.c
@@ -43,6 +43,7 @@
#include "pc/configfile.h"
#include "pc/network/network.h"
#include "pc/djui/djui.h"
+#include "pc/djui/djui_hud_utils.h"
// used for getting gMainMenuSounds
#include "pc/djui/djui_panel_menu_options.h"
#include "pc/lua/smlua_hooks.h"
@@ -1766,6 +1767,7 @@ s32 update_level(void) {
s32 init_level(void) {
sync_objects_clear();
geo_clear_interp_data();
+ djui_hud_clear_interp_data();
reset_dialog_render_state();
s32 val4 = 0;
diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c
index f0bf4d162..ff35fe280 100644
--- a/src/game/object_helpers.c
+++ b/src/game/object_helpers.c
@@ -1333,21 +1333,6 @@ s32 cur_obj_check_anim_frame_in_range(s32 startFrame, s32 rangeLength) {
}
}
-s32 cur_obj_check_frame_prior_current_frame(s16 *a0) {
- if (!o) { return 0; }
- s16 sp6 = o->header.gfx.animInfo.animFrame;
-
- while (*a0 != -1) {
- if (*a0 == sp6) {
- return TRUE;
- }
-
- a0++;
- }
-
- return FALSE;
-}
-
s32 mario_is_in_air_action(struct MarioState* m) {
if (!m) { return 0; }
if (m->action & ACT_FLAG_AIR) {
diff --git a/src/game/object_helpers.h b/src/game/object_helpers.h
index fc65f764a..d004ecbeb 100644
--- a/src/game/object_helpers.h
+++ b/src/game/object_helpers.h
@@ -158,7 +158,6 @@ s32 cur_obj_check_if_near_animation_end(void);
s32 cur_obj_check_if_at_animation_end(void);
s32 cur_obj_check_anim_frame(s32 frame);
s32 cur_obj_check_anim_frame_in_range(s32 startFrame, s32 rangeLength);
-s32 cur_obj_check_frame_prior_current_frame(s16 *a0);
s32 mario_is_in_air_action(struct MarioState* m);
s32 mario_is_dive_sliding(struct MarioState* m);
void cur_obj_set_y_vel_and_animation(f32 sp18, s32 sp1C);
diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c
index 1752ae7b4..98fd6174c 100644
--- a/src/game/object_list_processor.c
+++ b/src/game/object_list_processor.c
@@ -25,6 +25,7 @@
#include "engine/math_util.h"
#include "pc/network/network.h"
#include "pc/lua/smlua.h"
+#include "pc/djui/djui_hud_utils.h"
/**
* Flags controlling what debug info is displayed.
@@ -605,6 +606,7 @@ void clear_objects(void) {
clear_dynamic_surfaces();
geo_clear_interp_data();
+ djui_hud_clear_interp_data();
}
/**
diff --git a/src/pc/djui/djui.c b/src/pc/djui/djui.c
index 3bd9fc8b1..43218a151 100644
--- a/src/pc/djui/djui.c
+++ b/src/pc/djui/djui.c
@@ -171,6 +171,7 @@ void djui_reset_hud_params(void) {
djui_hud_set_rotation(0, ROTATION_PIVOT_X_LEFT, ROTATION_PIVOT_Y_TOP);
djui_hud_set_text_alignment(TEXT_HALIGN_LEFT, TEXT_VALIGN_TOP);
djui_hud_reset_color();
+ djui_hud_reset_text_color();
djui_hud_set_filter(FILTER_NEAREST);
djui_hud_reset_viewport();
djui_hud_reset_scissor();
diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c
index 8ad0a5b15..a181bb73a 100644
--- a/src/pc/djui/djui_hud_utils.c
+++ b/src/pc/djui/djui_hud_utils.c
@@ -35,6 +35,7 @@ struct HudUtilsState {
enum HudUtilsFilter filter;
enum DjuiFontType font;
struct DjuiColor color;
+ struct DjuiColor textColor;
struct {
InterpFieldF32 degrees;
InterpFieldF32 pivotX;
@@ -51,6 +52,7 @@ static struct HudUtilsState sHudUtilsState = {
.filter = FILTER_NEAREST,
.font = FONT_NORMAL,
.color = { 255, 255, 255, 255 },
+ .textColor = { 255, 255, 255, 255 },
.rotation = {
.degrees = INTERP_INIT(0),
.pivotX = INTERP_INIT(ROTATION_PIVOT_X_LEFT),
@@ -63,6 +65,7 @@ static struct HudUtilsState sHudUtilsState = {
};
static struct DjuiColor sRefColor = { 255, 255, 255, 255 };
+static struct DjuiColor sRefTextColor = { 255, 255, 255, 255 };
f32 gDjuiHudUtilsZ = 0;
bool gDjuiHudLockMouse = false;
@@ -144,8 +147,6 @@ static void djui_hud_translate_positions(f32 *outX, f32 *outY, f32 *outW, f32 *o
// interp //
////////////
-#define MAX_INTERP_HUD 512
-
enum InterpHudType {
INTERP_HUD_TRANSLATION,
INTERP_HUD_ROTATION,
@@ -170,9 +171,9 @@ struct InterpHud {
struct GrowingArray *gfx;
};
-static struct InterpHud sInterpHuds[MAX_INTERP_HUD] = { 0 };
-static u16 sInterpHudCount = 0;
-static u8 sColorAltered = FALSE;
+static struct GrowingArray *sInterpHuds = NULL;
+static u32 sInterpHudCount = 0;
+static bool sColorAltered = false;
void patch_djui_hud_before(void) {
sInterpHudCount = 0;
@@ -183,8 +184,8 @@ void patch_djui_hud(f32 delta) {
Gfx* savedHeadPos = gDisplayListHead;
struct HudUtilsState savedState = sHudUtilsState;
- for (u16 i = 0; i < sInterpHudCount; i++) {
- struct InterpHud* interp = &sInterpHuds[i];
+ for (u32 i = 0; i < sInterpHudCount; i++) {
+ struct InterpHud *interp = sInterpHuds->buffer[i];
f32 x = delta_interpolate_f32(interp->posX.prev, interp->posX.curr, delta);
f32 y = delta_interpolate_f32(interp->posY.prev, interp->posY.curr, delta);
@@ -260,22 +261,32 @@ void patch_djui_hud(f32 delta) {
gDjuiHudUtilsZ = savedZ;
}
-struct InterpHud *djui_hud_create_interp() {
- if (sInterpHudCount >= MAX_INTERP_HUD) { return NULL; }
+static struct InterpHud *djui_hud_create_interp() {
+ if (!sInterpHuds) {
+ sInterpHuds = growing_array_init(sInterpHuds, 16, malloc, free);
+ }
- struct InterpHud *interp = &sInterpHuds[sInterpHudCount++];
- interp->z = gDjuiHudUtilsZ;
- interp->state = sHudUtilsState;
- if (!interp->gfx) {
- interp->gfx = growing_array_init(NULL, 8, malloc, free);
- } else {
- interp->gfx->count = 0;
+ struct InterpHud *interp = (
+ sInterpHudCount < sInterpHuds->count ?
+ sInterpHuds->buffer[sInterpHudCount] :
+ growing_array_alloc(sInterpHuds, sizeof(struct InterpHud))
+ );
+
+ if (interp) {
+ interp->z = gDjuiHudUtilsZ;
+ interp->state = sHudUtilsState;
+ if (!interp->gfx) {
+ interp->gfx = growing_array_init(NULL, 8, malloc, free);
+ } else {
+ interp->gfx->count = 0;
+ }
+ sInterpHudCount++;
}
return interp;
}
-InterpHudGfx *djui_hud_create_interp_gfx(struct InterpHud *interp, enum InterpHudType type) {
+static InterpHudGfx *djui_hud_create_interp_gfx(struct InterpHud *interp, enum InterpHudType type) {
if (!interp) { return NULL; }
InterpHudGfx *gfx = growing_array_alloc(interp->gfx, sizeof(InterpHudGfx));
@@ -284,6 +295,19 @@ InterpHudGfx *djui_hud_create_interp_gfx(struct InterpHud *interp, enum InterpHu
return gfx;
}
+void djui_hud_clear_interp_data() {
+ if (sInterpHuds) {
+ for (u32 i = 0; i < sInterpHuds->count; ++i) {
+ struct InterpHud *interp = sInterpHuds->buffer[i];
+ if (interp) {
+ growing_array_free(&interp->gfx);
+ }
+ }
+ growing_array_free(&sInterpHuds);
+ }
+ sInterpHudCount = 0;
+}
+
////////////
// others //
////////////
@@ -328,7 +352,7 @@ void djui_hud_set_color(u8 r, u8 g, u8 b, u8 a) {
sHudUtilsState.color.g = g;
sHudUtilsState.color.b = b;
sHudUtilsState.color.a = a;
- sColorAltered = TRUE;
+ sColorAltered = true;
gDPSetEnvColor(gDisplayListHead++, r, g, b, a);
}
@@ -338,11 +362,33 @@ void djui_hud_reset_color(void) {
sHudUtilsState.color.g = 255;
sHudUtilsState.color.b = 255;
sHudUtilsState.color.a = 255;
- sColorAltered = FALSE;
+ sColorAltered = false;
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
}
}
+struct DjuiColor* djui_hud_get_text_color(void) {
+ sRefTextColor.r = sHudUtilsState.textColor.r;
+ sRefTextColor.g = sHudUtilsState.textColor.g;
+ sRefTextColor.b = sHudUtilsState.textColor.b;
+ sRefTextColor.a = sHudUtilsState.textColor.a;
+ return &sRefTextColor;
+}
+
+void djui_hud_set_text_color(u8 r, u8 g, u8 b, u8 a) {
+ sHudUtilsState.textColor.r = r;
+ sHudUtilsState.textColor.g = g;
+ sHudUtilsState.textColor.b = b;
+ sHudUtilsState.textColor.a = a;
+}
+
+void djui_hud_reset_text_color(void) {
+ sHudUtilsState.textColor.r = 255;
+ sHudUtilsState.textColor.g = 255;
+ sHudUtilsState.textColor.b = 255;
+ sHudUtilsState.textColor.a = 255;
+}
+
void djui_hud_get_rotation(RET s16 *rotation, RET f32 *pivotX, RET f32 *pivotY) {
*rotation = degrees_to_sm64(sHudUtilsState.rotation.degrees.curr);
*pivotX = sHudUtilsState.rotation.pivotX.curr;
@@ -582,13 +628,26 @@ static void djui_hud_print_text_internal(const char* message, f32 x, f32 y, f32
f32 lineWidth = 0;
f32 textHeight = font->lineHeight;
+ // apply text color
+ gDPSetEnvColor(gDisplayListHead++,
+ (sHudUtilsState.color.r * sHudUtilsState.textColor.r) / 255,
+ (sHudUtilsState.color.g * sHudUtilsState.textColor.g) / 255,
+ (sHudUtilsState.color.b * sHudUtilsState.textColor.b) / 255,
+ (sHudUtilsState.color.a * sHudUtilsState.textColor.a) / 255
+ );
+
font->render_begin();
while (*c != '\0') {
// check color code
struct DjuiColor parsedColor;
- if (djui_text_parse_color(c, end, false, &sHudUtilsState.color, &c, &parsedColor)) {
- gDPSetEnvColor(gDisplayListHead++, parsedColor.r, parsedColor.g, parsedColor.b, parsedColor.a);
+ if (djui_text_parse_color(c, end, false, &sHudUtilsState.textColor, &c, &parsedColor)) {
+ gDPSetEnvColor(gDisplayListHead++,
+ (sHudUtilsState.color.r * parsedColor.r) / 255,
+ (sHudUtilsState.color.g * parsedColor.g) / 255,
+ (sHudUtilsState.color.b * parsedColor.b) / 255,
+ (sHudUtilsState.color.a * parsedColor.a) / 255
+ );
continue;
}
@@ -651,6 +710,9 @@ static void djui_hud_print_text_internal(const char* message, f32 x, f32 y, f32
// pop
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
+
+ // reset color
+ gDPSetEnvColor(gDisplayListHead++, sHudUtilsState.color.r, sHudUtilsState.color.g, sHudUtilsState.color.b, sHudUtilsState.color.a);
}
void djui_hud_print_text(const char* message, f32 x, f32 y, f32 scale) {
diff --git a/src/pc/djui/djui_hud_utils.h b/src/pc/djui/djui_hud_utils.h
index 353ee3511..efe1d7cf0 100644
--- a/src/pc/djui/djui_hud_utils.h
+++ b/src/pc/djui/djui_hud_utils.h
@@ -62,6 +62,8 @@ extern struct GlobalTextures gGlobalTextures;
extern f32 gDjuiHudUtilsZ;
extern bool gDjuiHudLockMouse;
+void djui_hud_clear_interp_data();
+
/* |description|Gets the current DJUI HUD resolution|descriptionEnd| */
u8 djui_hud_get_resolution(void);
/* |description|Sets the current DJUI HUD resolution|descriptionEnd| */
@@ -80,6 +82,12 @@ struct DjuiColor* djui_hud_get_color(void);
void djui_hud_set_color(u8 r, u8 g, u8 b, u8 a);
/* |description|Resets the current DJUI HUD color|descriptionEnd| */
void djui_hud_reset_color(void);
+/* |description|Gets the current DJUI HUD text default color|descriptionEnd| */
+struct DjuiColor* djui_hud_get_text_color(void);
+/* |description|Sets the current DJUI HUD text default color|descriptionEnd| */
+void djui_hud_set_text_color(u8 r, u8 g, u8 b, u8 a);
+/* |description|Resets the current DJUI HUD text default color|descriptionEnd| */
+void djui_hud_reset_text_color(void);
/* |description|Gets the current DJUI HUD rotation|descriptionEnd| */
void djui_hud_get_rotation(RET s16 *rotation, RET f32 *pivotX, RET f32 *pivotY);
/* |description|Sets the current DJUI HUD rotation|descriptionEnd| */
diff --git a/src/pc/djui/djui_text.c b/src/pc/djui/djui_text.c
index 26fd4ea9c..577e2fd01 100644
--- a/src/pc/djui/djui_text.c
+++ b/src/pc/djui/djui_text.c
@@ -382,8 +382,10 @@ static void djui_text_render_line(struct DjuiText* text, char* c1, char* c2, f32
for (char* c = c1; c < c2;) {
struct DjuiColor parsedColor;
if (djui_text_parse_color(c, c2, true, &sDjuiTextDefaultColor, &c, &parsedColor)) {
- gDPSetEnvColor(gDisplayListHead++, parsedColor.r, parsedColor.g, parsedColor.b, parsedColor.a);
- sDjuiTextCurrentColor = parsedColor;
+ sDjuiTextCurrentColor.r = parsedColor.r;
+ sDjuiTextCurrentColor.g = parsedColor.g;
+ sDjuiTextCurrentColor.b = parsedColor.b;
+ gDPSetEnvColor(gDisplayListHead++, sDjuiTextCurrentColor.r, sDjuiTextCurrentColor.g, sDjuiTextCurrentColor.b, sDjuiTextCurrentColor.a);
continue;
}
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index e227a54aa..979858fe4 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -12318,6 +12318,59 @@ int smlua_func_djui_hud_reset_color(UNUSED lua_State* L) {
return 1;
}
+int smlua_func_djui_hud_get_text_color(UNUSED lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 0) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "djui_hud_get_text_color", 0, top);
+ return 0;
+ }
+
+
+ smlua_push_object(L, LOT_DJUICOLOR, djui_hud_get_text_color(), NULL);
+
+ return 1;
+}
+
+int smlua_func_djui_hud_set_text_color(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 4) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "djui_hud_set_text_color", 4, top);
+ return 0;
+ }
+
+ u8 r = smlua_to_integer(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "djui_hud_set_text_color"); return 0; }
+ u8 g = smlua_to_integer(L, 2);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "djui_hud_set_text_color"); return 0; }
+ u8 b = smlua_to_integer(L, 3);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "djui_hud_set_text_color"); return 0; }
+ u8 a = smlua_to_integer(L, 4);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "djui_hud_set_text_color"); return 0; }
+
+ djui_hud_set_text_color(r, g, b, a);
+
+ return 1;
+}
+
+int smlua_func_djui_hud_reset_text_color(UNUSED lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 0) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "djui_hud_reset_text_color", 0, top);
+ return 0;
+ }
+
+
+ djui_hud_reset_text_color();
+
+ return 1;
+}
+
int smlua_func_djui_hud_get_rotation(lua_State* L) {
if (L == NULL) { return 0; }
@@ -26858,24 +26911,6 @@ int smlua_func_cur_obj_check_anim_frame_in_range(lua_State* L) {
return 1;
}
-int smlua_func_cur_obj_check_frame_prior_current_frame(lua_State* L) {
- if (L == NULL) { return 0; }
-
- int top = lua_gettop(L);
- if (top != 1) {
- LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "cur_obj_check_frame_prior_current_frame", 1, top);
- return 0;
- }
-
- s16 * a0 = (s16 *)smlua_to_cpointer(L, 1, LVT_S16_P);
- if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "cur_obj_check_frame_prior_current_frame"); return 0; }
-
- extern s32 cur_obj_check_frame_prior_current_frame(s16 *a0);
- lua_pushinteger(L, cur_obj_check_frame_prior_current_frame(a0));
-
- return 1;
-}
-
int smlua_func_mario_is_in_air_action(lua_State* L) {
if (L == NULL) { return 0; }
@@ -37457,6 +37492,9 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "djui_hud_get_color", smlua_func_djui_hud_get_color);
smlua_bind_function(L, "djui_hud_set_color", smlua_func_djui_hud_set_color);
smlua_bind_function(L, "djui_hud_reset_color", smlua_func_djui_hud_reset_color);
+ smlua_bind_function(L, "djui_hud_get_text_color", smlua_func_djui_hud_get_text_color);
+ smlua_bind_function(L, "djui_hud_set_text_color", smlua_func_djui_hud_set_text_color);
+ smlua_bind_function(L, "djui_hud_reset_text_color", smlua_func_djui_hud_reset_text_color);
smlua_bind_function(L, "djui_hud_get_rotation", smlua_func_djui_hud_get_rotation);
smlua_bind_function(L, "djui_hud_set_rotation", smlua_func_djui_hud_set_rotation);
smlua_bind_function(L, "djui_hud_set_rotation_interpolated", smlua_func_djui_hud_set_rotation_interpolated);
@@ -38240,7 +38278,6 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "cur_obj_check_if_at_animation_end", smlua_func_cur_obj_check_if_at_animation_end);
smlua_bind_function(L, "cur_obj_check_anim_frame", smlua_func_cur_obj_check_anim_frame);
smlua_bind_function(L, "cur_obj_check_anim_frame_in_range", smlua_func_cur_obj_check_anim_frame_in_range);
- smlua_bind_function(L, "cur_obj_check_frame_prior_current_frame", smlua_func_cur_obj_check_frame_prior_current_frame);
smlua_bind_function(L, "mario_is_in_air_action", smlua_func_mario_is_in_air_action);
smlua_bind_function(L, "mario_is_dive_sliding", smlua_func_mario_is_dive_sliding);
smlua_bind_function(L, "cur_obj_set_y_vel_and_animation", smlua_func_cur_obj_set_y_vel_and_animation);
diff --git a/src/pc/nametags.c b/src/pc/nametags.c
index 37fe27bf8..19506cc3b 100644
--- a/src/pc/nametags.c
+++ b/src/pc/nametags.c
@@ -18,34 +18,26 @@ struct StateExtras {
};
static struct StateExtras sStateExtras[MAX_PLAYERS];
-void name_without_hex(char* input) {
- s32 i, j;
- bool inSlash = false;
- for (i = j = 0; input[i] != '\0'; i++) {
- if (input[i] == '\\') {
- inSlash = !inSlash;
- } else if (!inSlash) {
- input[j++] = input[i]; // it just works
- }
- }
-
- input[j] = '\0';
-}
-
void djui_hud_print_outlined_text_interpolated(const char* text, f32 prevX, f32 prevY, f32 prevScale, f32 x, f32 y, f32 scale, u8 r, u8 g, u8 b, u8 a, f32 outlineDarkness) {
f32 offset = 1 * (scale * 2);
f32 prevOffset = 1 * (prevScale * 2);
+ djui_hud_set_text_color(r, g, b, 255);
+
// render outline
- djui_hud_set_color(r * outlineDarkness, g * outlineDarkness, b * outlineDarkness, a);
+ djui_hud_set_color(255 * outlineDarkness, 255 * outlineDarkness, 255 * outlineDarkness, a);
djui_hud_print_text_interpolated(text, prevX - prevOffset, prevY, prevScale, x - offset, y, scale);
djui_hud_print_text_interpolated(text, prevX + prevOffset, prevY, prevScale, x + offset, y, scale);
djui_hud_print_text_interpolated(text, prevX, prevY - prevOffset, prevScale, x, y - offset, scale);
djui_hud_print_text_interpolated(text, prevX, prevY + prevOffset, prevScale, x, y + offset, scale);
+
// render text
- djui_hud_set_color(r, g, b, a);
+ djui_hud_set_color(255, 255, 255, a);
djui_hud_print_text_interpolated(text, prevX, prevY, prevScale, x, y, scale);
+
+ // reset colors
djui_hud_set_color(255, 255, 255, 255);
+ djui_hud_set_text_color(255, 255, 255, 255);
}
void nametags_render(void) {
@@ -59,7 +51,21 @@ void nametags_render(void) {
djui_hud_set_resolution(RESOLUTION_N64);
djui_hud_set_font(FONT_SPECIAL);
- for (u8 i = gNametagsSettings.showSelfTag ? 0 : 1; i < MAX_PLAYERS; i++) {
+ struct NametagInfo {
+ s32 playerIndex;
+ Vec3f pos;
+ f32 scale;
+ char name[MAX_CONFIG_STRING];
+ };
+ struct NametagInfo nametags[MAX_PLAYERS] = {0};
+ s32 numNametags = 0;
+
+ extern bool gDjuiHudToWorldCalcViewport;
+ gDjuiHudToWorldCalcViewport = false;
+
+ // sort nametags by their distance to the camera
+ // insertion sort is quick enough for such small array
+ for (s32 i = gNametagsSettings.showSelfTag ? 0 : 1; i < MAX_PLAYERS; i++) {
struct MarioState* m = &gMarioStates[i];
if (!is_player_active(m)) { continue; }
struct NetworkPlayer* np = &gNetworkPlayers[i];
@@ -84,8 +90,6 @@ void nametags_render(void) {
vec3f_copy(pos, m->marioBodyState->headPos);
pos[1] += 100;
- extern bool gDjuiHudToWorldCalcViewport;
- gDjuiHudToWorldCalcViewport = false;
if ((i != 0 || (i == 0 && m->action != ACT_FIRST_PERSON)) &&
djui_hud_world_pos_to_screen_pos(pos, out)) {
@@ -96,61 +100,85 @@ void nametags_render(void) {
snprintf(name, MAX_CONFIG_STRING, "%s", hookedString);
} else {
snprintf(name, MAX_CONFIG_STRING, "%s", np->name);
- name_without_hex(name);
}
if (!djui_hud_world_pos_to_screen_pos(pos, out)) {
continue;
}
- u8* color = network_get_player_text_color(m->playerIndex);
f32 scale = -300 / out[2] * djui_hud_get_fov_coeff();
- f32 measure = djui_hud_measure_text(name) * scale * 0.5f;
- out[1] -= 16 * scale;
- u8 alpha = (i == 0 ? 255 : MIN(np->fadeOpacity << 3, 255)) * clamp(FADE_SCALE - scale, 0.f, 1.f);
-
- struct StateExtras* e = &sStateExtras[i];
- if (!e->inited) {
- vec3f_copy(e->prevPos, out);
- e->prevScale = scale;
- e->inited = true;
+ s32 j = 0;
+ for (; j < numNametags; ++j) {
+ if (scale < nametags[j].scale) {
+ memmove(nametags + j + 1, nametags + j, sizeof(struct NametagInfo) * (numNametags - j));
+ break;
+ }
}
- // Apply viewport for credits
- extern Vp *gViewportOverride;
- extern Vp *gViewportClip;
- extern Vp gViewportFullscreen;
- Vp *viewport = gViewportOverride == NULL ? gViewportClip : gViewportOverride;
- if (viewport) {
- make_viewport_clip_rect(viewport);
- gSPViewport(gDisplayListHead++, viewport);
- }
-
- djui_hud_print_outlined_text_interpolated(name,
- e->prevPos[0] - measure, e->prevPos[1], e->prevScale,
- out[0] - measure, out[1], scale,
- color[0], color[1], color[2], alpha, 0.25);
-
- if (i != 0 && gNametagsSettings.showHealth) {
- djui_hud_set_color(255, 255, 255, alpha);
- f32 healthScale = 90 * scale;
- f32 prevHealthScale = 90 * e->prevScale;
- hud_render_power_meter_interpolated(m->health,
- e->prevPos[0] - (prevHealthScale * 0.5f), e->prevPos[1] - 72 * scale, prevHealthScale, prevHealthScale,
- out[0] - ( healthScale * 0.5f), out[1] - 72 * scale, healthScale, healthScale
- );
- }
-
- // Reset viewport
- if (viewport) {
- gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, BORDER_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - BORDER_HEIGHT);
- gSPViewport(gDisplayListHead++, &gViewportFullscreen);
- }
-
- vec3f_copy(e->prevPos, out);
- e->prevScale = scale;
+ nametags[j].playerIndex = i;
+ vec3f_copy(nametags[j].pos, out);
+ nametags[j].scale = scale;
+ memcpy(nametags[j].name, name, sizeof(name));
+ numNametags++;
}
- gDjuiHudToWorldCalcViewport = true;
+ }
+
+ gDjuiHudToWorldCalcViewport = true;
+
+ // render nametags
+ for (s32 k = 0; k < numNametags; ++k) {
+ struct NametagInfo *nametag = &nametags[k];
+ struct MarioState *m = &gMarioStates[nametag->playerIndex];
+ struct NetworkPlayer *np = &gNetworkPlayers[nametag->playerIndex];
+
+ u8* color = network_get_player_text_color(m->playerIndex);
+ f32 measure = djui_hud_measure_text(nametag->name) * nametag->scale * 0.5f;
+ nametag->pos[1] -= 16 * nametag->scale;
+
+ u8 alpha = (nametag->playerIndex == 0 ? 255 : MIN(np->fadeOpacity << 3, 255)) * clamp(FADE_SCALE - nametag->scale, 0.f, 1.f);
+
+ struct StateExtras* e = &sStateExtras[nametag->playerIndex];
+ if (!e->inited) {
+ vec3f_copy(e->prevPos, nametag->pos);
+ e->prevScale = nametag->scale;
+ e->inited = true;
+ }
+
+ // Apply viewport for credits
+ extern Vp *gViewportOverride;
+ extern Vp *gViewportClip;
+ extern Vp gViewportFullscreen;
+ Vp *viewport = gViewportOverride == NULL ? gViewportClip : gViewportOverride;
+ if (viewport) {
+ make_viewport_clip_rect(viewport);
+ gSPViewport(gDisplayListHead++, viewport);
+ }
+
+ // render name
+ djui_hud_print_outlined_text_interpolated(nametag->name,
+ e->prevPos[0] - measure, e->prevPos[1], e->prevScale,
+ nametag->pos[0] - measure, nametag->pos[1], nametag->scale,
+ color[0], color[1], color[2], alpha, 0.25);
+
+ // render power meter
+ if (nametag->playerIndex != 0 && gNametagsSettings.showHealth) {
+ djui_hud_set_color(255, 255, 255, alpha);
+ f32 healthScale = 90 * nametag->scale;
+ f32 prevHealthScale = 90 * e->prevScale;
+ hud_render_power_meter_interpolated(m->health,
+ e->prevPos[0] - (prevHealthScale * 0.5f), e->prevPos[1] - 72 * nametag->scale, prevHealthScale, prevHealthScale,
+ nametag->pos[0] - ( healthScale * 0.5f), nametag->pos[1] - 72 * nametag->scale, healthScale, healthScale
+ );
+ }
+
+ // Reset viewport
+ if (viewport) {
+ gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, BORDER_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - BORDER_HEIGHT);
+ gSPViewport(gDisplayListHead++, &gViewportFullscreen);
+ }
+
+ vec3f_copy(e->prevPos, nametag->pos);
+ e->prevScale = nametag->scale;
}
}