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; } }