diff --git a/autogen/exposed_lists.py b/autogen/exposed_lists.py
index 98b5bf351..50e836d02 100644
--- a/autogen/exposed_lists.py
+++ b/autogen/exposed_lists.py
@@ -51,6 +51,7 @@
"include/PR/gbi.h",
"include/PR/gbi_extension.h",
"src/pc/gfx/gfx_pc.h",
+ "src/pc/djui/djui_gfx.h",
"src/engine/surface_load.h",
"src/pc/lua/utils/smlua_audio_utils.h",
]
@@ -117,6 +118,7 @@
"src/pc/lua/smlua_hooks.h": [ "^LUA_BEHAVIOR_.*", "MAX_HOOKED_.*", "^HOOK_RETURN_.*", "^ACTION_HOOK_.*", "^MOD_MENU_ELEMENT_.*" ],
"src/pc/djui/djui_panel_menu.h": [ "RAINBOW_TEXT_LEN" ],
"src/pc/mods/mod_fs.h": [ "INT_TYPE_MAX", "FLOAT_TYPE_MAX", "FILE_SEEK_MAX" ],
+ "src/pc/djui/djui_gfx.h": [ "MTX_" ],
"src/engine/surface_load.h": [ "NUM_CELLS" ],
"src/pc/network/version.h": [ "VERSION_OFFSET" ],
}
diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua
index 1050eaab8..f29d67b36 100644
--- a/autogen/lua_definitions/constants.lua
+++ b/autogen/lua_definitions/constants.lua
@@ -2753,6 +2753,33 @@ CONSOLE_MESSAGE_ERROR = 2 --- @type ConsoleMessageLevel
--- | `CONSOLE_MESSAGE_WARNING`
--- | `CONSOLE_MESSAGE_ERROR`
+CS_KEEP = -1 --- @type CombinerSource
+CS_0 = 0 --- @type CombinerSource
+CS_1 = 1 --- @type CombinerSource
+CS_TEXTURE = 2 --- @type CombinerSource
+CS_COLOR = 3 --- @type CombinerSource
+CS_TEXT = 4 --- @type CombinerSource
+CS_COMBINED = 5 --- @type CombinerSource
+CS_NOISE = 6 --- @type CombinerSource
+CS_TEXTURE_ALPHA = 7 --- @type CombinerSource
+CS_COLOR_ALPHA = 8 --- @type CombinerSource
+CS_TEXT_ALPHA = 9 --- @type CombinerSource
+CS_COMBINED_ALPHA = 10 --- @type CombinerSource
+
+--- @alias CombinerSource
+--- | `CS_KEEP`
+--- | `CS_0`
+--- | `CS_1`
+--- | `CS_TEXTURE`
+--- | `CS_COLOR`
+--- | `CS_TEXT`
+--- | `CS_COMBINED`
+--- | `CS_NOISE`
+--- | `CS_TEXTURE_ALPHA`
+--- | `CS_COLOR_ALPHA`
+--- | `CS_TEXT_ALPHA`
+--- | `CS_COMBINED_ALPHA`
+
--- @type number
ROTATION_PIVOT_X_LEFT = 0.0
diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index c3309bfd2..f47f0b668 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -3980,6 +3980,19 @@ function djui_hud_set_color(r, g, b, a)
-- ...
end
+--- @param prevR integer
+--- @param prevG integer
+--- @param prevB integer
+--- @param prevA integer
+--- @param r integer
+--- @param g integer
+--- @param b integer
+--- @param a integer
+--- Sets the current DJUI HUD global color interpolated
+function djui_hud_set_color_interpolated(prevR, prevG, prevB, prevA, r, g, b, a)
+ -- ...
+end
+
--- Resets the current DJUI HUD global color
function djui_hud_reset_color()
-- ...
@@ -4005,6 +4018,30 @@ function djui_hud_reset_text_color()
-- ...
end
+--- @param cycles integer
+--- Sets the number of cycles used by the combiner
+function djui_hud_set_combiner_cycles(cycles)
+ -- ...
+end
+
+--- @param cycle integer
+--- @param alpha boolean
+--- @param a? CombinerSource
+--- @param b? CombinerSource
+--- @param c? CombinerSource
+--- @param d? CombinerSource
+--- Sets the current DJUI HUD combiner.
+--- Each part uses the following equation: `P = (A - B) * C + D`.
+--- Cycle 2 may be used to extend the equation, with the result of the previous cycle accessible through CS_COMBINED
+function djui_hud_set_combiner(cycle, alpha, a, b, c, d)
+ -- ...
+end
+
+--- Resets the current DJUI HUD combiner
+function djui_hud_reset_combiner()
+ -- ...
+end
+
--- @return integer rotation
--- @return number pivotX
--- @return number pivotY
@@ -4014,8 +4051,8 @@ function djui_hud_get_rotation()
end
--- @param rotation integer
---- @param pivotX number
---- @param pivotY number
+--- @param pivotX? number
+--- @param pivotY? number
--- Sets the current DJUI HUD rotation
function djui_hud_set_rotation(rotation, pivotX, pivotY)
-- ...
@@ -4161,6 +4198,38 @@ function djui_hud_reset_scissor()
-- ...
end
+--- @param x number
+--- @param y number
+--- @param scaleX number
+--- @param scaleY number
+--- Applies a transformation (translate, rotate, scale) to subsequent DJUI HUD elements until closed
+function djui_hud_transform(x, y, scaleX, scaleY)
+ -- ...
+end
+
+--- @param prevX number
+--- @param prevY number
+--- @param prevScaleX number
+--- @param prevScaleY number
+--- @param x number
+--- @param y number
+--- @param scaleX number
+--- @param scaleY number
+--- Applies an interpolated transformation (translate, rotate, scale) to subsequent DJUI HUD elements until closed
+function djui_hud_transform_interpolated(prevX, prevY, prevScaleX, prevScaleY, x, y, scaleX, scaleY)
+ -- ...
+end
+
+--- Closes the previous transformation
+function djui_hud_close_transform()
+ -- ...
+end
+
+--- Resets the transformation to a fullscreen state
+function djui_hud_reset_transform()
+ -- ...
+end
+
--- @param message string
--- @return number width
--- @return number height
diff --git a/docs/lua/constants.md b/docs/lua/constants.md
index 9ca604dd7..c7ff9b094 100644
--- a/docs/lua/constants.md
+++ b/docs/lua/constants.md
@@ -17,6 +17,8 @@
- [enum DialogId](#enum-DialogId)
- [djui_console.h](#djui_consoleh)
- [enum ConsoleMessageLevel](#enum-ConsoleMessageLevel)
+- [djui_gfx.h](#djui_gfxh)
+ - [enum CombinerSource](#enum-CombinerSource)
- [djui_hud_utils.h](#djui_hud_utilsh)
- [enum HudUtilsResolution](#enum-HudUtilsResolution)
- [enum HudUtilsFilter](#enum-HudUtilsFilter)
@@ -1193,6 +1195,28 @@
+## [djui_gfx.h](#djui_gfx.h)
+
+### [enum CombinerSource](#CombinerSource)
+| Identifier | Value |
+| :--------- | :---- |
+| CS_KEEP | -1 |
+| CS_0 | 0 |
+| CS_1 | 1 |
+| CS_TEXTURE | 2 |
+| CS_COLOR | 3 |
+| CS_TEXT | 4 |
+| CS_COMBINED | 5 |
+| CS_NOISE | 6 |
+| CS_TEXTURE_ALPHA | 7 |
+| CS_COLOR_ALPHA | 8 |
+| CS_TEXT_ALPHA | 9 |
+| CS_COMBINED_ALPHA | 10 |
+
+[:arrow_up_small:](#)
+
+
+
## [djui_hud_utils.h](#djui_hud_utils.h)
- ROTATION_PIVOT_X_LEFT
- ROTATION_PIVOT_X_CENTER
diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md
index bfa5ffcf9..c239b73ef 100644
--- a/docs/lua/functions-3.md
+++ b/docs/lua/functions-3.md
@@ -3095,6 +3095,36 @@ Sets the current DJUI HUD global color
+## [djui_hud_set_color_interpolated](#djui_hud_set_color_interpolated)
+
+### Description
+Sets the current DJUI HUD global color interpolated
+
+### Lua Example
+`djui_hud_set_color_interpolated(prevR, prevG, prevB, prevA, r, g, b, a)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| prevR | `integer` |
+| prevG | `integer` |
+| prevB | `integer` |
+| prevA | `integer` |
+| r | `integer` |
+| g | `integer` |
+| b | `integer` |
+| a | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void djui_hud_set_color_interpolated(u8 prevR, u8 prevG, u8 prevB, u8 prevA, u8 r, u8 g, u8 b, u8 a);`
+
+[:arrow_up_small:](#)
+
+
+
## [djui_hud_reset_color](#djui_hud_reset_color)
### Description
@@ -3184,6 +3214,80 @@ Resets the current DJUI HUD text default color. This color is overridden by colo
+## [djui_hud_set_combiner_cycles](#djui_hud_set_combiner_cycles)
+
+### Description
+Sets the number of cycles used by the combiner
+
+### Lua Example
+`djui_hud_set_combiner_cycles(cycles)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| cycles | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void djui_hud_set_combiner_cycles(u8 cycles);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_hud_set_combiner](#djui_hud_set_combiner)
+
+### Description
+Sets the current DJUI HUD combiner.
+Each part uses the following equation: `P = (A - B) * C + D`.
+Cycle 2 may be used to extend the equation, with the result of the previous cycle accessible through CS_COMBINED
+
+### Lua Example
+`djui_hud_set_combiner(cycle, alpha, a, b, c, d)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| cycle | `integer` |
+| alpha | `boolean` |
+| a | [enum CombinerSource](constants.md#enum-CombinerSource) |
+| b | [enum CombinerSource](constants.md#enum-CombinerSource) |
+| c | [enum CombinerSource](constants.md#enum-CombinerSource) |
+| d | [enum CombinerSource](constants.md#enum-CombinerSource) |
+
+### Returns
+- None
+
+### C Prototype
+`void djui_hud_set_combiner(u8 cycle, bool alpha, OPTIONAL enum CombinerSource a, OPTIONAL enum CombinerSource b, OPTIONAL enum CombinerSource c, OPTIONAL enum CombinerSource d);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_hud_reset_combiner](#djui_hud_reset_combiner)
+
+### Description
+Resets the current DJUI HUD combiner
+
+### Lua Example
+`djui_hud_reset_combiner()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void djui_hud_reset_combiner();`
+
+[:arrow_up_small:](#)
+
+
+
## [djui_hud_get_rotation](#djui_hud_get_rotation)
### Description
@@ -3226,7 +3330,7 @@ Sets the current DJUI HUD rotation
- None
### C Prototype
-`void djui_hud_set_rotation(s16 rotation, f32 pivotX, f32 pivotY);`
+`void djui_hud_set_rotation(s16 rotation, OPTIONAL f32 pivotX, OPTIONAL f32 pivotY);`
[:arrow_up_small:](#)
@@ -3701,6 +3805,104 @@ Resets the scissor rectangle to a fullscreen state
+## [djui_hud_transform](#djui_hud_transform)
+
+### Description
+Applies a transformation (translate, rotate, scale) to subsequent DJUI HUD elements until closed
+
+### Lua Example
+`djui_hud_transform(x, y, scaleX, scaleY)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| x | `number` |
+| y | `number` |
+| scaleX | `number` |
+| scaleY | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void djui_hud_transform(f32 x, f32 y, f32 scaleX, f32 scaleY);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_hud_transform_interpolated](#djui_hud_transform_interpolated)
+
+### Description
+Applies an interpolated transformation (translate, rotate, scale) to subsequent DJUI HUD elements until closed
+
+### Lua Example
+`djui_hud_transform_interpolated(prevX, prevY, prevScaleX, prevScaleY, x, y, scaleX, scaleY)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| prevX | `number` |
+| prevY | `number` |
+| prevScaleX | `number` |
+| prevScaleY | `number` |
+| x | `number` |
+| y | `number` |
+| scaleX | `number` |
+| scaleY | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void djui_hud_transform_interpolated(f32 prevX, f32 prevY, f32 prevScaleX, f32 prevScaleY, f32 x, f32 y, f32 scaleX, f32 scaleY);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_hud_close_transform](#djui_hud_close_transform)
+
+### Description
+Closes the previous transformation
+
+### Lua Example
+`djui_hud_close_transform()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void djui_hud_close_transform(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_hud_reset_transform](#djui_hud_reset_transform)
+
+### Description
+Resets the transformation to a fullscreen state
+
+### Lua Example
+`djui_hud_reset_transform()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void djui_hud_reset_transform(void);`
+
+[:arrow_up_small:](#)
+
+
+
## [djui_hud_measure_text](#djui_hud_measure_text)
### Description
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index 35ac3c04e..bff4c6e0b 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -769,10 +769,14 @@
- [djui_hud_set_font](functions-3.md#djui_hud_set_font)
- [djui_hud_get_color](functions-3.md#djui_hud_get_color)
- [djui_hud_set_color](functions-3.md#djui_hud_set_color)
+ - [djui_hud_set_color_interpolated](functions-3.md#djui_hud_set_color_interpolated)
- [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_set_combiner_cycles](functions-3.md#djui_hud_set_combiner_cycles)
+ - [djui_hud_set_combiner](functions-3.md#djui_hud_set_combiner)
+ - [djui_hud_reset_combiner](functions-3.md#djui_hud_reset_combiner)
- [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)
@@ -796,6 +800,10 @@
- [djui_hud_reset_viewport](functions-3.md#djui_hud_reset_viewport)
- [djui_hud_set_scissor](functions-3.md#djui_hud_set_scissor)
- [djui_hud_reset_scissor](functions-3.md#djui_hud_reset_scissor)
+ - [djui_hud_transform](functions-3.md#djui_hud_transform)
+ - [djui_hud_transform_interpolated](functions-3.md#djui_hud_transform_interpolated)
+ - [djui_hud_close_transform](functions-3.md#djui_hud_close_transform)
+ - [djui_hud_reset_transform](functions-3.md#djui_hud_reset_transform)
- [djui_hud_measure_text](functions-3.md#djui_hud_measure_text)
- [djui_hud_render_texture](functions-3.md#djui_hud_render_texture)
- [djui_hud_render_texture_tile](functions-3.md#djui_hud_render_texture_tile)
diff --git a/src/pc/crash_handler.c b/src/pc/crash_handler.c
index 7f5f51903..2390e9d38 100644
--- a/src/pc/crash_handler.c
+++ b/src/pc/crash_handler.c
@@ -218,8 +218,8 @@ static void crash_handler_produce_one_frame_callback(void) {
gDPSetPrimColor(gDisplayListHead++, 0, 0, 255, 255, 255, 255);
for (CrashHandlerText* text = sCrashHandlerText; text->s[0] != 0; ++text) {
- s32 x = GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(text->x * aspectScale);
- s32 y = SCREEN_HEIGHT - 8 - text->y * aspectScale;
+ s32 x = text->x * aspectScale;
+ s32 y = 8 + text->y * aspectScale;
gDPPipeSync(gDisplayListHead++);
create_dl_translation_matrix(DJUI_MTX_PUSH, x, y, 0);
diff --git a/src/pc/djui/djui.c b/src/pc/djui/djui.c
index 400c50f93..392830f5f 100644
--- a/src/pc/djui/djui.c
+++ b/src/pc/djui/djui.c
@@ -184,16 +184,17 @@ void djui_reset_hud_params(void) {
djui_hud_set_text_alignment(TEXT_HALIGN_LEFT, TEXT_VALIGN_TOP);
djui_hud_reset_color();
djui_hud_reset_text_color();
+ djui_hud_reset_combiner();
djui_hud_set_filter(FILTER_NEAREST);
djui_hud_reset_viewport();
djui_hud_reset_scissor();
+ djui_hud_reset_transform();
}
void djui_render(void) {
if (!sDjuiInited || gDjuiDisabled) { return; }
sSavedDisplayListHead = gDisplayListHead;
- gDjuiHudUtilsZ = 0;
djui_reset_hud_params();
create_dl_ortho_matrix();
diff --git a/src/pc/djui/djui_base.c b/src/pc/djui/djui_base.c
index e4d85a506..9c9fa5745 100644
--- a/src/pc/djui/djui_base.c
+++ b/src/pc/djui/djui_base.c
@@ -232,7 +232,7 @@ static f32 djui_base_render_border_piece(struct DjuiBase* base, f32 x1, f32 y1,
// translate position
f32 translatedX = x1;
f32 translatedY = y1;
- djui_gfx_position_translate(&translatedX, &translatedY);
+ djui_gfx_dimension_translate(&translatedX, &translatedY);
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
// translate size
@@ -242,6 +242,7 @@ static f32 djui_base_render_border_piece(struct DjuiBase* base, f32 x1, f32 y1,
create_dl_scale_matrix(DJUI_MTX_NOPUSH, translatedWidth, translatedHeight, 1.0f);
// render
+ djui_gfx_update_combine_mode(CS_COLOR);
gDPSetEnvColor(gDisplayListHead++, base->borderColor.r, base->borderColor.g, base->borderColor.b, base->borderColor.a);
gSPDisplayList(gDisplayListHead++, dl_djui_simple_rect);
diff --git a/src/pc/djui/djui_gfx.c b/src/pc/djui/djui_gfx.c
index aa5332970..48b9caef3 100644
--- a/src/pc/djui/djui_gfx.c
+++ b/src/pc/djui/djui_gfx.c
@@ -21,45 +21,131 @@ const Gfx dl_djui_display_list_end[] = {
gsSPEndDisplayList(),
};
+static Mat4 sDjuiCoordinateMtx = {
+ { 1, 0, 0, 0 },
+ { 0, -1, 0, 0 },
+ { 0, 0, 1, 0 },
+ { 0, 240, 0, 1 },
+};
+
void djui_gfx_displaylist_begin(void) {
gSPDisplayList(gDisplayListHead++, dl_djui_display_list_begin);
+
+ // translate to DJUI coordinate system
+ sDjuiCoordinateMtx[3][0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(0);
+ gSPMatrix(gDisplayListHead++, (Mtx*) &sDjuiCoordinateMtx, G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
}
void djui_gfx_displaylist_end(void) {
gSPDisplayList(gDisplayListHead++, dl_djui_display_list_end);
+ gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
+}
+
+struct CombinerState gCombinerState = { .cycles = 1 };
+bool gCombinerUpdated = false;
+bool gCombinerOverride = false;
+static Gfx sDjuiCombineMode = { 0 };
+static u32 sCombinerCycleType = G_CYC_1CYCLE;
+
+static u8 djui_gfx_translate_combiner_source(u8 cycle, bool alpha, enum CombinerSource source) {
+ if (!alpha) {
+ switch (source) {
+ default: return G_CCMUX_0;
+ case CS_1: return G_CCMUX_1;
+ case CS_TEXTURE: return cycle ? G_CCMUX_TEXEL1 : G_CCMUX_TEXEL0;
+ case CS_COLOR: return G_CCMUX_ENVIRONMENT;
+ case CS_TEXT: return G_CCMUX_PRIMITIVE;
+ case CS_COMBINED: return G_CCMUX_COMBINED;
+ case CS_NOISE: return G_CCMUX_NOISE;
+ case CS_TEXTURE_ALPHA: return cycle ? G_CCMUX_TEXEL1_ALPHA : G_CCMUX_TEXEL0_ALPHA;
+ case CS_COLOR_ALPHA: return G_CCMUX_ENV_ALPHA;
+ case CS_TEXT_ALPHA: return G_CCMUX_PRIMITIVE_ALPHA;
+ case CS_COMBINED_ALPHA: return G_CCMUX_COMBINED_ALPHA;
+ }
+ } else {
+ switch (source) {
+ default: return G_ACMUX_0;
+ case CS_1: return G_ACMUX_1;
+ case CS_TEXTURE:
+ case CS_TEXTURE_ALPHA: return cycle ? G_ACMUX_TEXEL1 : G_ACMUX_TEXEL0;
+ case CS_COLOR:
+ case CS_COLOR_ALPHA: return G_ACMUX_ENVIRONMENT;
+ case CS_TEXT:
+ case CS_TEXT_ALPHA: return G_ACMUX_PRIMITIVE;
+ case CS_COMBINED:
+ case CS_COMBINED_ALPHA: return G_ACMUX_COMBINED;
+ }
+
+ }
+}
+
+void djui_gfx_update_combine_mode(enum CombinerSource mode) {
+ u32 cycleType = G_CYC_1CYCLE;
+
+ if (gCombinerOverride) {
+ cycleType = (gCombinerState.cycles - 1) << G_MDSFT_CYCLETYPE;
+
+ if (gCombinerUpdated) {
+ u8 p[16];
+ for (u8 i = 0; i < 8 * gCombinerState.cycles; i++) {
+ p[i] = djui_gfx_translate_combiner_source(i >> 3, i >> 2 & 1,
+ gCombinerState.cycle[i >> 3][i >> 2 & 1][i & 3]);
+ }
+
+ gDPSetCombineLERPNoString(&sDjuiCombineMode,
+ p[ 0], p[ 1], p[ 2], p[ 3],
+ p[ 4], p[ 5], p[ 6], p[ 7],
+ p[ 8], p[ 9], p[10], p[11],
+ p[12], p[13], p[14], p[15]
+ );
+ gCombinerUpdated = false;
+ }
+
+ *(gDisplayListHead++) = sDjuiCombineMode;
+ } else switch (mode) {
+ case CS_COLOR: gDPSetCombineMode(gDisplayListHead++, G_CC_FADE, G_CC_PASS2); break;
+ case CS_TEXTURE: gDPSetCombineMode(gDisplayListHead++, G_CC_FADEA, G_CC_PASS2); break;
+ case CS_TEXT: gDPSetCombineMode(gDisplayListHead++, G_CC_FADEA, G_CC_MODULATERGBA_PRIM2); cycleType = G_CYC_2CYCLE; break;
+ default: break;
+ }
+
+ if (sCombinerCycleType != cycleType) {
+ gDPSetCycleType(gDisplayListHead++, cycleType);
+ sCombinerCycleType = cycleType;
+ }
}
static const Vtx vertex_djui_menu_rect[] = {
- {{{ 0, -1, 0 }, 0, { 0, 0 }, { 0x96, 0x96, 0x96, 0xff }}},
- {{{ 1, -1, 0 }, 0, { 0, 0 }, { 0x96, 0x96, 0x96, 0xff }}},
- {{{ 1, 0, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
- {{{ 0, 0, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
+ {{{ 0, 1, 0 }, 0, { 0, 0 }, { 0x96, 0x96, 0x96, 0xff }}},
+ {{{ 1, 1, 0 }, 0, { 0, 0 }, { 0x96, 0x96, 0x96, 0xff }}},
+ {{{ 1, 0, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
+ {{{ 0, 0, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
};
static const Vtx vertex_djui_simple_rect[] = {
- {{{ 0, -1, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
- {{{ 1, -1, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
- {{{ 1, 0, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
- {{{ 0, 0, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
+ {{{ 0, 1, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
+ {{{ 1, 1, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
+ {{{ 1, 0, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
+ {{{ 0, 0, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
};
const Gfx dl_djui_menu_rect[] = {
gsDPPipeSync(),
- gsSPClearGeometryMode(G_LIGHTING),
- gsDPSetCombineMode(G_CC_FADE, G_CC_FADE),
+ gsSPClearGeometryMode(G_LIGHTING | G_CULL_BOTH),
gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2),
gsSPVertexNonGlobal(vertex_djui_menu_rect, 4, 0),
gsSP2Triangles(0, 1, 2, 0x0, 0, 2, 3, 0x0),
+ gsSPSetGeometryMode(G_LIGHTING | G_CULL_BACK),
gsSPEndDisplayList(),
};
const Gfx dl_djui_simple_rect[] = {
gsDPPipeSync(),
- gsSPClearGeometryMode(G_LIGHTING),
- gsDPSetCombineMode(G_CC_FADE, G_CC_FADE),
+ gsSPClearGeometryMode(G_LIGHTING | G_CULL_BOTH),
gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2),
gsSPVertexNonGlobal(vertex_djui_simple_rect, 4, 0),
gsSP2Triangles(0, 1, 2, 0x0, 0, 2, 3, 0x0),
+ gsSPSetGeometryMode(G_LIGHTING | G_CULL_BACK),
gsSPEndDisplayList(),
};
@@ -86,16 +172,15 @@ f32 djui_gfx_get_scale(void) {
/////////////////////////////////////////////
static const Vtx vertex_djui_image[] = {
- {{{ 0, -1, 0 }, 0, { 0, 2048 }, { 0xff, 0xff, 0xff, 0xff }}},
- {{{ 1, -1, 0 }, 0, { 2048, 2048 }, { 0xff, 0xff, 0xff, 0xff }}},
- {{{ 1, 0, 0 }, 0, { 2048, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
- {{{ 0, 0, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
+ {{{ 0, 1, 0 }, 0, { 0, 2048 }, { 0xff, 0xff, 0xff, 0xff }}},
+ {{{ 1, 1, 0 }, 0, { 2048, 2048 }, { 0xff, 0xff, 0xff, 0xff }}},
+ {{{ 1, 0, 0 }, 0, { 2048, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
+ {{{ 0, 0, 0 }, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
};
const Gfx dl_djui_image[] = {
gsDPPipeSync(),
gsSPClearGeometryMode(G_LIGHTING | G_CULL_BOTH),
- gsDPSetCombineMode(G_CC_FADEA, G_CC_FADEA),
gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
gsDPLoadTextureBlock(NULL, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 0, 0, 0, 0),
@@ -104,7 +189,7 @@ const Gfx dl_djui_image[] = {
// gsSPExecuteDjui(G_TEXCLIP_DJUI),
gsSP2Triangles(0, 1, 2, 0x0, 0, 2, 3, 0x0),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
- gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),
+ gsDPSetCombineMode(G_CC_SHADE, G_CC_PASS2),
gsSPSetGeometryMode(G_LIGHTING | G_CULL_BACK),
gsSPEndDisplayList(),
};
@@ -114,6 +199,7 @@ inline static u8 djui_gfx_power_of_two(u32 value) {
}
void djui_gfx_render_texture(const Texture* texture, u32 w, u32 h, u8 fmt, u8 siz, bool filter) {
+ djui_gfx_update_combine_mode(CS_TEXTURE);
gDPSetTextureFilter(gDisplayListHead++, filter ? G_TF_BILERP : G_TF_POINT);
gDPSetTextureOverrideDjui(gDisplayListHead++, texture, djui_gfx_power_of_two(w), djui_gfx_power_of_two(h), fmt, siz);
gSPDisplayList(gDisplayListHead++, dl_djui_image);
@@ -138,13 +224,13 @@ void djui_gfx_render_texture_tile(const Texture* texture, u32 w, u32 h, u8 fmt,
f32 aspect = tileH ? ((f32)tileW / (f32)tileH) : 1;
- vtx[0] = (Vtx) {{{ 0, -1, 0 }, 0, { ( tileX * 2048.0f) / (f32)w + 1, ((tileY + tileH) * 2048.0f) / (f32)h + 1 }, { 0xff, 0xff, 0xff, 0xff }}};
- vtx[2] = (Vtx) {{{ 1 * aspect, 0, 0 }, 0, { ((tileX + tileW) * 2048.0f) / (f32)w + 1, ( tileY * 2048.0f) / (f32)h + 1 }, { 0xff, 0xff, 0xff, 0xff }}};
- vtx[1] = (Vtx) {{{ 1 * aspect, -1, 0 }, 0, { ((tileX + tileW) * 2048.0f) / (f32)w + 1, ((tileY + tileH) * 2048.0f) / (f32)h + 1 }, { 0xff, 0xff, 0xff, 0xff }}};
- vtx[3] = (Vtx) {{{ 0, 0, 0 }, 0, { ( tileX * 2048.0f) / (f32)w + 1, ( tileY * 2048.0f) / (f32)h + 1 }, { 0xff, 0xff, 0xff, 0xff }}};
+ vtx[0] = (Vtx) {{{ 0, 1, 0 }, 0, { ( tileX * 2048.0f) / (f32)w + 1, ((tileY + tileH) * 2048.0f) / (f32)h + 1 }, { 0xff, 0xff, 0xff, 0xff }}};
+ vtx[2] = (Vtx) {{{ 1 * aspect, 0, 0 }, 0, { ((tileX + tileW) * 2048.0f) / (f32)w + 1, ( tileY * 2048.0f) / (f32)h + 1 }, { 0xff, 0xff, 0xff, 0xff }}};
+ vtx[1] = (Vtx) {{{ 1 * aspect, 1, 0 }, 0, { ((tileX + tileW) * 2048.0f) / (f32)w + 1, ((tileY + tileH) * 2048.0f) / (f32)h + 1 }, { 0xff, 0xff, 0xff, 0xff }}};
+ vtx[3] = (Vtx) {{{ 0, 0, 0 }, 0, { ( tileX * 2048.0f) / (f32)w + 1, ( tileY * 2048.0f) / (f32)h + 1 }, { 0xff, 0xff, 0xff, 0xff }}};
gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING | G_CULL_BOTH);
- gDPSetCombineMode(gDisplayListHead++, G_CC_FADEA, G_CC_FADEA);
+ djui_gfx_update_combine_mode(CS_TEXTURE);
gDPSetRenderMode(gDisplayListHead++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
gDPSetTextureFilter(gDisplayListHead++, filter ? G_TF_BILERP : G_TF_POINT);
@@ -160,14 +246,13 @@ void djui_gfx_render_texture_tile(const Texture* texture, u32 w, u32 h, u8 fmt,
gSP2TrianglesDjui(gDisplayListHead++, 0, 1, 2, 0x0, 0, 2, 3, 0x0);
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF);
- gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE);
+ gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_PASS2);
gSPSetGeometryMode(gDisplayListHead++, G_LIGHTING | G_CULL_BACK);
}
void djui_gfx_render_texture_font_begin() {
gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING | G_CULL_BOTH);
- gDPSetCombineMode(gDisplayListHead++, G_CC_FADEA, G_CC_MODULATERGBA_PRIM2);
- gDPSetCycleType(gDisplayListHead++, G_CYC_2CYCLE);
+ djui_gfx_update_combine_mode(CS_TEXT);
gDPSetRenderMode(gDisplayListHead++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
gDPSetTextureFilter(gDisplayListHead++, djui_hud_get_filter() ? G_TF_BILERP : G_TF_POINT);
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
@@ -193,15 +278,13 @@ void djui_gfx_render_texture_font(const Texture* texture, u32 w, u32 h, u8 fmt,
void djui_gfx_render_texture_font_end() {
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF);
- gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE);
- gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE);
+ gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_PASS2);
gSPSetGeometryMode(gDisplayListHead++, G_LIGHTING | G_CULL_BACK);
}
void djui_gfx_render_texture_tile_font_begin() {
gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING | G_CULL_BOTH);
- gDPSetCombineMode(gDisplayListHead++, G_CC_FADEA, G_CC_MODULATERGBA_PRIM2);
- gDPSetCycleType(gDisplayListHead++, G_CYC_2CYCLE);
+ djui_gfx_update_combine_mode(CS_TEXT);
gDPSetRenderMode(gDisplayListHead++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
gDPSetTextureFilter(gDisplayListHead++, G_TF_POINT);
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
@@ -231,10 +314,10 @@ void djui_gfx_render_texture_tile_font(const Texture* texture, u32 w, u32 h, u8
// this should be tested carefully. it definitely fixes some stuff, but what does it break?
f32 offsetX = (-1024.0f / (f32)w) + 1;
f32 offsetY = (-1024.0f / (f32)h) + 1;
- vtx[0] = (Vtx) {{{ 0, -1, 0 }, 0, { ( tileX * 2048.0f) / (f32)w + offsetX, ((tileY + tileH) * 2048.0f) / (f32)h + offsetY }, { 0xff, 0xff, 0xff, 0xff }}};
- vtx[2] = (Vtx) {{{ 1 * aspect, 0, 0 }, 0, { ((tileX + tileW) * 2048.0f) / (f32)w + offsetX, ( tileY * 2048.0f) / (f32)h + offsetY }, { 0xff, 0xff, 0xff, 0xff }}};
- vtx[1] = (Vtx) {{{ 1 * aspect, -1, 0 }, 0, { ((tileX + tileW) * 2048.0f) / (f32)w + offsetX, ((tileY + tileH) * 2048.0f) / (f32)h + offsetY }, { 0xff, 0xff, 0xff, 0xff }}};
- vtx[3] = (Vtx) {{{ 0, 0, 0 }, 0, { ( tileX * 2048.0f) / (f32)w + offsetX, ( tileY * 2048.0f) / (f32)h + offsetY }, { 0xff, 0xff, 0xff, 0xff }}};
+ vtx[0] = (Vtx) {{{ 0, 1, 0 }, 0, { ( tileX * 2048.0f) / (f32)w + offsetX, ((tileY + tileH) * 2048.0f) / (f32)h + offsetY }, { 0xff, 0xff, 0xff, 0xff }}};
+ vtx[2] = (Vtx) {{{ 1 * aspect, 0, 0 }, 0, { ((tileX + tileW) * 2048.0f) / (f32)w + offsetX, ( tileY * 2048.0f) / (f32)h + offsetY }, { 0xff, 0xff, 0xff, 0xff }}};
+ vtx[1] = (Vtx) {{{ 1 * aspect, 1, 0 }, 0, { ((tileX + tileW) * 2048.0f) / (f32)w + offsetX, ((tileY + tileH) * 2048.0f) / (f32)h + offsetY }, { 0xff, 0xff, 0xff, 0xff }}};
+ vtx[3] = (Vtx) {{{ 0, 0, 0 }, 0, { ( tileX * 2048.0f) / (f32)w + offsetX, ( tileY * 2048.0f) / (f32)h + offsetY }, { 0xff, 0xff, 0xff, 0xff }}};
gDPSetTextureOverrideDjui(gDisplayListHead++, texture, djui_gfx_power_of_two(w), djui_gfx_power_of_two(h), fmt, siz);
*(gDisplayListHead++) = (Gfx) gsSPExecuteDjui(G_TEXOVERRIDE_DJUI);
@@ -245,33 +328,33 @@ void djui_gfx_render_texture_tile_font(const Texture* texture, u32 w, u32 h, u8
void djui_gfx_render_texture_tile_font_end() {
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF);
- gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE);
- gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE);
+ gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_PASS2);
gSPSetGeometryMode(gDisplayListHead++, G_LIGHTING | G_CULL_BACK);
}
/////////////////////////////////////////////
-void djui_gfx_position_translate(f32* x, f32* y) {
+void djui_gfx_dimension_translate(f32* x, f32* y) {
u32 windowWidth, windowHeight;
gfx_get_dimensions(&windowWidth, &windowHeight);
- *x = GFX_DIMENSIONS_FROM_LEFT_EDGE(0) + *x * ((f32)SCREEN_HEIGHT / (f32)windowHeight) * djui_gfx_get_scale();
- *y = SCREEN_HEIGHT - *y * ((f32)SCREEN_HEIGHT / (f32)windowHeight) * djui_gfx_get_scale();
+
+ *x *= ((f32)SCREEN_HEIGHT / (f32)windowHeight) * djui_gfx_get_scale();
+ *y *= ((f32)SCREEN_HEIGHT / (f32)windowHeight) * djui_gfx_get_scale();
}
void djui_gfx_scale_translate(f32* width, f32* height) {
u32 windowWidth, windowHeight;
gfx_get_dimensions(&windowWidth, &windowHeight);
- *width = *width * ((f32)SCREEN_HEIGHT / (f32)windowHeight) * djui_gfx_get_scale();
- *height = *height * ((f32)SCREEN_HEIGHT / (f32)windowHeight) * djui_gfx_get_scale();
+ *width *= ((f32)SCREEN_HEIGHT / (f32)windowHeight) * djui_gfx_get_scale();
+ *height *= ((f32)SCREEN_HEIGHT / (f32)windowHeight) * djui_gfx_get_scale();
}
void djui_gfx_size_translate(f32* size) {
u32 windowWidth, windowHeight;
gfx_get_dimensions(&windowWidth, &windowHeight);
- *size = *size * ((f32)SCREEN_HEIGHT / (f32)windowHeight) * djui_gfx_get_scale();
+ *size *= ((f32)SCREEN_HEIGHT / (f32)windowHeight) * djui_gfx_get_scale();
}
bool djui_gfx_add_clipping_specific(struct DjuiBase* base, f32 dX, f32 dY, f32 dW, f32 dH) {
diff --git a/src/pc/djui/djui_gfx.h b/src/pc/djui/djui_gfx.h
index 2df6786e9..2db320c9b 100644
--- a/src/pc/djui/djui_gfx.h
+++ b/src/pc/djui/djui_gfx.h
@@ -13,6 +13,37 @@ extern const Gfx dl_djui_img_end[];
void djui_gfx_displaylist_begin(void);
void djui_gfx_displaylist_end(void);
+enum CombinerSource {
+ CS_KEEP = -1,
+ CS_0,
+ CS_1,
+ CS_TEXTURE, // TEXEL0
+ CS_COLOR, // ENVIRONMENT
+ CS_TEXT, // PRIMITIVE
+ CS_COMBINED, // COMBINED
+ CS_NOISE, // NOISE
+ CS_TEXTURE_ALPHA, // TEXEL0_ALPHA
+ CS_COLOR_ALPHA, // ENV_ALPHA
+ CS_TEXT_ALPHA, // PRIMITIVE_ALPHA
+ CS_COMBINED_ALPHA, // COMBINED_ALPHA
+};
+
+struct CombinerPart {
+ enum CombinerSource a, b, c, d;
+};
+
+typedef enum CombinerSource CombinerCycle[2][4];
+
+struct CombinerState {
+ CombinerCycle cycle[2];
+ u8 cycles;
+};
+
+extern struct CombinerState gCombinerState;
+extern bool gCombinerUpdated;
+extern bool gCombinerOverride;
+void djui_gfx_update_combine_mode(enum CombinerSource mode);
+
/* |description|Gets the current visual scaling factor of DJUI|descriptionEnd| */
f32 djui_gfx_get_scale(void);
@@ -29,7 +60,7 @@ void djui_gfx_render_texture_tile_font_end();
void gfx_get_dimensions(u32* width, u32* height);
-void djui_gfx_position_translate(f32* x, f32* y);
+void djui_gfx_dimension_translate(f32* x, f32* y);
void djui_gfx_scale_translate(f32* width, f32* height);
void djui_gfx_size_translate(f32* size);
diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c
index b29bf3b3a..a0d582e38 100644
--- a/src/pc/djui/djui_hud_utils.c
+++ b/src/pc/djui/djui_hud_utils.c
@@ -25,11 +25,20 @@
#include "engine/math_util.h"
#define INTERP_INIT(v) {v, v}
+#define INTERP_SET(field, p, c) field.prev = p; field.curr = c;
+#define INTERP_RESET(field, c) field.prev = field.curr = c;
+#define INTERP_MUL(field, m) field.prev *= m.prev; field.curr *= m.curr;
+#define IS_INTERP_VAL(field, v) (field.prev == v && field.curr == v)
+#define IS_INTERP_SAME(field) (field.prev == field.curr)
typedef struct {
f32 prev, curr;
} InterpFieldF32;
+typedef struct {
+ s16 prev, curr;
+} InterpFieldS16;
+
struct HudUtilsState {
enum HudUtilsResolution resolution;
enum HudUtilsFilter filter;
@@ -37,7 +46,7 @@ struct HudUtilsState {
struct DjuiColor color;
struct DjuiColor textColor;
struct {
- InterpFieldF32 degrees;
+ InterpFieldS16 units;
InterpFieldF32 pivotX;
InterpFieldF32 pivotY;
} rotation;
@@ -54,7 +63,7 @@ static struct HudUtilsState sHudUtilsState = {
.color = { 255, 255, 255, 255 },
.textColor = { 255, 255, 255, 255 },
.rotation = {
- .degrees = INTERP_INIT(0),
+ .units = INTERP_INIT(0),
.pivotX = INTERP_INIT(ROTATION_PIVOT_X_LEFT),
.pivotY = INTERP_INIT(ROTATION_PIVOT_Y_TOP),
},
@@ -67,7 +76,6 @@ 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;
extern ALIGNED8 const u8 texture_hud_char_camera[];
@@ -110,12 +118,9 @@ static inline bool djui_hud_text_font_is_legacy() {
return sHudUtilsState.font < 0;
}
-static void djui_hud_position_translate(f32* x, f32* y) {
+static void djui_hud_dimension_translate(f32* x, f32* y) {
if (sHudUtilsState.resolution == RESOLUTION_DJUI) {
- djui_gfx_position_translate(x, y);
- } else {
- *x = GFX_DIMENSIONS_FROM_LEFT_EDGE(0) + *x;
- *y = SCREEN_HEIGHT - *y;
+ djui_gfx_dimension_translate(x, y);
}
}
@@ -128,9 +133,7 @@ static void djui_hud_size_translate(f32* size) {
// Translates position and scale to N64 resolution
static void djui_hud_translate_positions(f32 *outX, f32 *outY, f32 *outW, f32 *outH) {
// translate position
- djui_hud_position_translate(outX, outY);
- *outX -= GFX_DIMENSIONS_FROM_LEFT_EDGE(0);
- *outY -= SCREEN_HEIGHT;
+ djui_hud_dimension_translate(outX, outY);
// translate scale
if (sHudUtilsState.resolution == RESOLUTION_DJUI) {
@@ -154,6 +157,7 @@ enum InterpHudType {
INTERP_HUD_HALIGN,
INTERP_HUD_VALIGN,
INTERP_HUD_NEW_LINE,
+ INTERP_HUD_COLOR,
};
typedef struct {
@@ -163,14 +167,41 @@ typedef struct {
} InterpHudGfx;
struct InterpHud {
- f32 z;
- InterpFieldF32 posX, posY;
- InterpFieldF32 scaleX, scaleY;
+ bool noMtx;
+ union {
+ struct {
+ InterpFieldF32 posX, posY;
+ InterpFieldF32 scaleX, scaleY;
+ };
+ struct {
+ InterpFieldF32 r, g, b, a;
+ };
+ };
f32 width, height;
struct HudUtilsState state;
struct GrowingArray *gfx;
};
+static bool sDjuiHudMtxPushed = false;
+static inline void djui_hud_setup_matrix() {
+ sDjuiHudMtxPushed = false;
+}
+
+static s8 djui_hud_pass_matrix() {
+ if (sDjuiHudMtxPushed) {
+ return DJUI_MTX_NOPUSH;
+ } else {
+ sDjuiHudMtxPushed = true;
+ return DJUI_MTX_PUSH;
+ }
+}
+
+static inline void djui_hud_pop_matrix(struct InterpHud *interp) {
+ if (sDjuiHudMtxPushed) {
+ gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
+ } else if (interp) { gSPNoOp(gDisplayListHead++); }
+}
+
static struct GrowingArray *sInterpHuds = NULL;
static u32 sInterpHudCount = 0;
@@ -187,7 +218,6 @@ void patch_djui_hud_before(void) {
}
void patch_djui_hud(f32 delta) {
- f32 savedZ = gDjuiHudUtilsZ;
Gfx* savedHeadPos = gDisplayListHead;
struct HudUtilsState savedState = sHudUtilsState;
@@ -199,7 +229,7 @@ void patch_djui_hud(f32 delta) {
f32 scaleW = delta_interpolate_f32(interp->scaleX.prev, interp->scaleX.curr, delta);
f32 scaleH = delta_interpolate_f32(interp->scaleY.prev, interp->scaleY.curr, delta);
sHudUtilsState = interp->state;
- gDjuiHudUtilsZ = interp->z;
+ djui_hud_setup_matrix();
for (u32 j = 0; j != interp->gfx->count; ++j) {
const InterpHudGfx *gfx = interp->gfx->buffer[j];
@@ -207,38 +237,30 @@ void patch_djui_hud(f32 delta) {
switch (gfx->type) {
case INTERP_HUD_TRANSLATION: {
- f32 translatedX = x;
- f32 translatedY = y;
- djui_hud_position_translate(&translatedX, &translatedY);
- create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, gDjuiHudUtilsZ);
+ djui_hud_dimension_translate(&x, &y);
+ create_dl_translation_matrix(djui_hud_pass_matrix(), x, y, 0);
} break;
case INTERP_HUD_ROTATION: {
- if (sHudUtilsState.rotation.degrees.prev != 0 || sHudUtilsState.rotation.degrees.curr != 0) {
- f32 translatedW = scaleW;
- f32 translatedH = scaleH;
- djui_hud_size_translate(&translatedW);
- djui_hud_size_translate(&translatedH);
- s16 rotPrev = degrees_to_sm64(sHudUtilsState.rotation.degrees.prev);
- s16 rotCurr = degrees_to_sm64(sHudUtilsState.rotation.degrees.curr);
- s32 normalizedDiff = (((s32) rotCurr - (s32) rotPrev + 0x8000) & 0xFFFF) - 0x8000; // Fix modular overflow/underflow
- s32 rotation = delta_interpolate_s32(rotCurr - normalizedDiff, rotCurr, delta);
- f32 pivotX = delta_interpolate_f32(sHudUtilsState.rotation.pivotX.prev, sHudUtilsState.rotation.pivotX.curr, delta);
- f32 pivotY = delta_interpolate_f32(sHudUtilsState.rotation.pivotY.prev, sHudUtilsState.rotation.pivotY.curr, delta);
- f32 pivotTranslationX = interp->width * translatedW * pivotX;
- f32 pivotTranslationY = interp->height * translatedH * pivotY;
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, +pivotTranslationX, -pivotTranslationY, 0);
- create_dl_rotation_matrix(DJUI_MTX_NOPUSH, sm64_to_degrees(rotation), 0, 0, 1);
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, -pivotTranslationX, +pivotTranslationY, 0);
- }
+ f32 translatedW = scaleW, translatedH = scaleH;
+ djui_hud_dimension_translate(&translatedW, &translatedH);
+ s16 rotPrev = sHudUtilsState.rotation.units.prev;
+ s16 rotCurr = sHudUtilsState.rotation.units.curr;
+ s32 normalizedDiff = (((s32) rotCurr - (s32) rotPrev + 0x8000) & 0xFFFF) - 0x8000; // Fix modular overflow/underflow
+ s32 rotation = delta_interpolate_s32(rotCurr - normalizedDiff, rotCurr, delta);
+ f32 pivotX = delta_interpolate_f32(sHudUtilsState.rotation.pivotX.prev, sHudUtilsState.rotation.pivotX.curr, delta);
+ f32 pivotY = delta_interpolate_f32(sHudUtilsState.rotation.pivotY.prev, sHudUtilsState.rotation.pivotY.curr, delta);
+ f32 pivotTranslationX = interp->width * translatedW * pivotX;
+ f32 pivotTranslationY = interp->height * translatedH * pivotY;
+ create_dl_translation_matrix(djui_hud_pass_matrix(), +pivotTranslationX, +pivotTranslationY, 0);
+ create_dl_rotation_matrix(DJUI_MTX_NOPUSH, sm64_to_degrees(rotation), 0, 0, -1);
+ create_dl_translation_matrix(DJUI_MTX_NOPUSH, -pivotTranslationX, -pivotTranslationY, 0);
} break;
case INTERP_HUD_SCALE: {
- f32 translatedW = scaleW;
- f32 translatedH = scaleH;
- djui_hud_size_translate(&translatedW);
- djui_hud_size_translate(&translatedH);
- create_dl_scale_matrix(DJUI_MTX_NOPUSH, interp->width * translatedW, interp->height * translatedH, 1.0f);
+ f32 translatedW = scaleW, translatedH = scaleH;
+ djui_hud_dimension_translate(&translatedW, &translatedH);
+ create_dl_scale_matrix(djui_hud_pass_matrix(), interp->width * translatedW, interp->height * translatedH, 1.0f);
} break;
case INTERP_HUD_HALIGN: {
@@ -250,22 +272,27 @@ void patch_djui_hud(f32 delta) {
case INTERP_HUD_VALIGN: {
f32 textVAlign = delta_interpolate_f32(sHudUtilsState.textAlignment.v.prev, sHudUtilsState.textAlignment.v.curr, delta);
f32 textHeight = gfx->params[0];
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, 0, textHeight * textVAlign, 0);
+ create_dl_translation_matrix(DJUI_MTX_NOPUSH, 0, -textHeight * textVAlign, 0);
} break;
case INTERP_HUD_NEW_LINE: {
const struct DjuiFont *font = djui_hud_get_text_font();
f32 textHAlign = delta_interpolate_f32(sHudUtilsState.textAlignment.h.prev, sHudUtilsState.textAlignment.h.curr, delta);
f32 lineWidth = gfx->params[0];
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, -lineWidth * (1.f - textHAlign), -font->lineHeight, 0);
+ create_dl_translation_matrix(DJUI_MTX_NOPUSH, -lineWidth * (1.f - textHAlign), font->lineHeight, 0);
+ } break;
+
+ case INTERP_HUD_COLOR: {
+ gDPSetEnvColor(gDisplayListHead++, x, y, scaleW, scaleH);
} break;
}
}
+
+ if (!interp->noMtx) { djui_hud_pop_matrix(interp); }
}
sHudUtilsState = savedState;
gDisplayListHead = savedHeadPos;
- gDjuiHudUtilsZ = savedZ;
}
static struct InterpHud *djui_hud_create_interp() {
@@ -276,7 +303,6 @@ static struct InterpHud *djui_hud_create_interp() {
);
if (interp) {
- interp->z = gDjuiHudUtilsZ;
interp->state = sHudUtilsState;
if (!interp->gfx) {
interp->gfx = growing_array_init(NULL, 8, malloc, free);
@@ -303,6 +329,51 @@ void djui_hud_clear_interp_data() {
sInterpHudCount = 0;
}
+static inline void djui_hud_do_translation(struct InterpHud *interp, f32 x, f32 y) {
+ bool doInterp = interp && !(IS_INTERP_SAME(interp->posX) && IS_INTERP_SAME(interp->posY));
+ if (doInterp || !(x == 0 && y == 0)) {
+ if (doInterp) { djui_hud_create_interp_gfx(interp, INTERP_HUD_TRANSLATION); }
+
+ djui_hud_dimension_translate(&x, &y);
+ create_dl_translation_matrix(djui_hud_pass_matrix(), x, y, 0);
+ }
+}
+
+static inline void djui_hud_do_rotation(struct InterpHud *interp, f32 width, f32 height) {
+ if (IS_INTERP_VAL(sHudUtilsState.rotation.units, 0)) { return; }
+
+ bool doInterp = interp && !(
+ IS_INTERP_SAME(sHudUtilsState.rotation.units)
+ && IS_INTERP_SAME(sHudUtilsState.rotation.pivotX)
+ && IS_INTERP_SAME(sHudUtilsState.rotation.pivotY)
+ );
+
+ djui_hud_dimension_translate(&width, &height);
+
+ if (doInterp) { djui_hud_create_interp_gfx(interp, INTERP_HUD_ROTATION); }
+
+ f32 pivotTranslationX = width * sHudUtilsState.rotation.pivotX.curr;
+ f32 pivotTranslationY = height * sHudUtilsState.rotation.pivotY.curr;
+
+ create_dl_translation_matrix(djui_hud_pass_matrix(), +pivotTranslationX, +pivotTranslationY, 0);
+ create_dl_rotation_matrix(DJUI_MTX_NOPUSH, sm64_to_degrees(sHudUtilsState.rotation.units.curr), 0, 0, -1);
+ create_dl_translation_matrix(DJUI_MTX_NOPUSH, -pivotTranslationX, -pivotTranslationY, 0);
+}
+
+static inline void djui_hud_do_scale(struct InterpHud *interp, f32 scaleX, f32 scaleY) {
+ bool doInterp = interp && !(
+ IS_INTERP_SAME(interp->scaleX)
+ && IS_INTERP_SAME(interp->scaleY)
+ );
+
+ if (doInterp || !(scaleX == 1 && scaleY == 1)) {
+ if (doInterp) { djui_hud_create_interp_gfx(interp, INTERP_HUD_SCALE); }
+
+ djui_hud_dimension_translate(&scaleX, &scaleY);
+ create_dl_scale_matrix(djui_hud_pass_matrix(), scaleX, scaleY, 1.0f);
+ }
+}
+
////////////
// others //
////////////
@@ -350,6 +421,21 @@ void djui_hud_set_color(u8 r, u8 g, u8 b, u8 a) {
gDPSetEnvColor(gDisplayListHead++, r, g, b, a);
}
+void djui_hud_set_color_interpolated(u8 prevR, u8 prevG, u8 prevB, u8 prevA, u8 r, u8 g, u8 b, u8 a) {
+ struct InterpHud *interp = djui_hud_create_interp();
+ if (interp) {
+ INTERP_SET(interp->r, prevR, r);
+ INTERP_SET(interp->g, prevG, g);
+ INTERP_SET(interp->b, prevB, b);
+ INTERP_SET(interp->a, prevA, a);
+ interp->noMtx = true;
+
+ djui_hud_create_interp_gfx(interp, INTERP_HUD_COLOR);
+ }
+
+ djui_hud_set_color(r, g, b, a);
+}
+
void djui_hud_reset_color(void) {
sHudUtilsState.color.r = 255;
sHudUtilsState.color.g = 255;
@@ -380,25 +466,45 @@ void djui_hud_reset_text_color(void) {
sHudUtilsState.textColor.a = 255;
}
+void djui_hud_set_combiner_cycles(u8 cycles) {
+ gCombinerState.cycles = cycles != 2 ? 1 : 2;
+}
+
+void djui_hud_set_combiner(u8 cycle, bool alpha,
+ OPTIONAL enum CombinerSource a, OPTIONAL enum CombinerSource b, OPTIONAL enum CombinerSource c, OPTIONAL enum CombinerSource d) {
+ if (--cycle > 1) { return; }
+
+ struct CombinerPart *part = (struct CombinerPart*) gCombinerState.cycle[cycle][alpha];
+ if (a > CS_KEEP) { part->a = a; }
+ if (b > CS_KEEP) { part->b = b; }
+ if (c > CS_KEEP) { part->c = c; }
+ if (d > CS_KEEP) { part->d = d; }
+
+ gCombinerUpdated = true;
+ gCombinerOverride = true;
+}
+
+void djui_hud_reset_combiner() {
+ gCombinerState.cycles = 1;
+ gCombinerOverride = false;
+}
+
void djui_hud_get_rotation(RET s16 *rotation, RET f32 *pivotX, RET f32 *pivotY) {
- *rotation = degrees_to_sm64(sHudUtilsState.rotation.degrees.curr);
+ *rotation = sHudUtilsState.rotation.units.curr;
*pivotX = sHudUtilsState.rotation.pivotX.curr;
*pivotY = sHudUtilsState.rotation.pivotY.curr;
}
-void djui_hud_set_rotation(s16 rotation, f32 pivotX, f32 pivotY) {
- sHudUtilsState.rotation.degrees.prev = sHudUtilsState.rotation.degrees.curr = sm64_to_degrees(rotation);
- sHudUtilsState.rotation.pivotX.prev = sHudUtilsState.rotation.pivotX.curr = pivotX;
- sHudUtilsState.rotation.pivotY.prev = sHudUtilsState.rotation.pivotY.curr = pivotY;
+void djui_hud_set_rotation(s16 rotation, OPTIONAL f32 pivotX, OPTIONAL f32 pivotY) {
+ INTERP_RESET(sHudUtilsState.rotation.units, rotation);
+ INTERP_RESET(sHudUtilsState.rotation.pivotX, pivotX);
+ INTERP_RESET(sHudUtilsState.rotation.pivotY, pivotY);
}
void djui_hud_set_rotation_interpolated(s16 prevRotation, f32 prevPivotX, f32 prevPivotY, s16 rotation, f32 pivotX, f32 pivotY) {
- sHudUtilsState.rotation.degrees.prev = sm64_to_degrees(prevRotation);
- sHudUtilsState.rotation.degrees.curr = sm64_to_degrees(rotation);
- sHudUtilsState.rotation.pivotX.prev = prevPivotX;
- sHudUtilsState.rotation.pivotX.curr = pivotX;
- sHudUtilsState.rotation.pivotY.prev = prevPivotY;
- sHudUtilsState.rotation.pivotY.curr = pivotY;
+ INTERP_SET(sHudUtilsState.rotation.units, prevRotation, rotation);
+ INTERP_SET(sHudUtilsState.rotation.pivotX, prevPivotX, pivotX);
+ INTERP_SET(sHudUtilsState.rotation.pivotY, prevPivotY, pivotY);
}
void djui_hud_get_text_alignment(RET f32 *textHAlign, RET f32 *textVAlign) {
@@ -407,33 +513,33 @@ void djui_hud_get_text_alignment(RET f32 *textHAlign, RET f32 *textVAlign) {
}
void djui_hud_set_text_alignment(f32 textHAlign, f32 textVAlign) {
- sHudUtilsState.textAlignment.h.prev = sHudUtilsState.textAlignment.h.curr = textHAlign;
- sHudUtilsState.textAlignment.v.prev = sHudUtilsState.textAlignment.v.curr = textVAlign;
+ INTERP_RESET(sHudUtilsState.textAlignment.h, textHAlign);
+ INTERP_RESET(sHudUtilsState.textAlignment.v, textVAlign);
}
void djui_hud_set_text_alignment_interpolated(f32 prevTextHAlign, f32 prevTextVAlign, f32 textHAlign, f32 textVAlign) {
- sHudUtilsState.textAlignment.h.prev = prevTextHAlign;
- sHudUtilsState.textAlignment.h.curr = textHAlign;
- sHudUtilsState.textAlignment.v.prev = prevTextVAlign;
- sHudUtilsState.textAlignment.v.curr = textVAlign;
+ INTERP_SET(sHudUtilsState.textAlignment.h, prevTextHAlign, textHAlign);
+ INTERP_SET(sHudUtilsState.textAlignment.v, prevTextVAlign, textVAlign);
}
u32 djui_hud_get_screen_width(void) {
- u32 windowWidth, windowHeight;
- gfx_get_dimensions(&windowWidth, &windowHeight);
-
- return (sHudUtilsState.resolution == RESOLUTION_N64)
- ? GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_HEIGHT
- : (windowWidth / djui_gfx_get_scale());
+ if (sHudUtilsState.resolution == RESOLUTION_N64) {
+ return SCREEN_HEIGHT * GFX_DIMENSIONS_ASPECT_RATIO;
+ } else {
+ u32 windowWidth, windowHeight;
+ gfx_get_dimensions(&windowWidth, &windowHeight);
+ return windowWidth / djui_gfx_get_scale();
+ }
}
u32 djui_hud_get_screen_height(void) {
- u32 windowWidth, windowHeight;
- gfx_get_dimensions(&windowWidth, &windowHeight);
-
- return (sHudUtilsState.resolution == RESOLUTION_N64)
- ? SCREEN_HEIGHT
- : (windowHeight / djui_gfx_get_scale());
+ if (sHudUtilsState.resolution == RESOLUTION_N64) {
+ return SCREEN_HEIGHT;
+ } else {
+ u32 windowWidth, windowHeight;
+ gfx_get_dimensions(&windowWidth, &windowHeight);
+ return windowHeight / djui_gfx_get_scale();
+ }
}
f32 djui_hud_get_mouse_x(void) {
@@ -484,8 +590,7 @@ f32 djui_hud_get_mouse_scroll_y(void) {
void djui_hud_set_viewport(f32 x, f32 y, f32 width, f32 height) {
// translate position and scale
- f32 translatedX = x, translatedY = y, translatedW = width, translatedH = height;
- djui_hud_translate_positions(&translatedX, &translatedY, &translatedW, &translatedH);
+ djui_hud_translate_positions(&x, &y, &width, &height);
// convert to viewport structure
static Vp vp = {{
@@ -493,10 +598,10 @@ void djui_hud_set_viewport(f32 x, f32 y, f32 width, f32 height) {
{ 640, 480, 511, 0 },
}};
Vp_t *viewport = &vp.vp;
- viewport->vscale[0] = translatedW * 2.0f;
- viewport->vscale[1] = translatedH * 2.0f;
- viewport->vtrans[0] = (translatedW + translatedX) * 2.0f;
- viewport->vtrans[1] = (translatedH + translatedY) * 2.0f;
+ viewport->vscale[0] = width * 2.0f;
+ viewport->vscale[1] = height * 2.0f;
+ viewport->vtrans[0] = (width + x) * 2.0f;
+ viewport->vtrans[1] = (height + y) * 2.0f;
gSPViewport(gDisplayListHead++, &vp);
}
@@ -508,17 +613,76 @@ void djui_hud_reset_viewport(void) {
void djui_hud_set_scissor(f32 x, f32 y, f32 width, f32 height) {
// translate position and scale
- f32 translatedX = x, translatedY = y, translatedW = width, translatedH = height;
- djui_hud_translate_positions(&translatedX, &translatedY, &translatedW, &translatedH);
+ djui_hud_translate_positions(&x, &y, &width, &height);
// apply the scissor
- gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, translatedX, translatedY, translatedW, translatedH);
+ gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, x, y, width, height);
}
void djui_hud_reset_scissor(void) {
gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, BORDER_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - BORDER_HEIGHT);
}
+static u8 sTransformDepth = 0;
+
+static void djui_hud_transform_internal(f32 x, f32 y, f32 scaleX, f32 scaleY, struct InterpHud *interp) {
+ if (sTransformDepth == MAX_MATRIX_STACK_SIZE - 3) { return; }
+ djui_hud_setup_matrix();
+
+ // translate
+ djui_hud_do_translation(interp, x, y);
+
+ // rotate
+ enum HudUtilsResolution origResolution = sHudUtilsState.resolution;
+ sHudUtilsState.resolution = RESOLUTION_N64;
+ djui_hud_do_rotation(interp,
+ SCREEN_HEIGHT * GFX_DIMENSIONS_ASPECT_RATIO * scaleX,
+ SCREEN_HEIGHT * scaleY);
+ sHudUtilsState.resolution = origResolution;
+
+ // scale
+ djui_hud_do_scale(interp, scaleX, scaleY);
+
+ if (sDjuiHudMtxPushed) { sTransformDepth++; }
+}
+
+void djui_hud_transform(f32 x, f32 y, f32 scaleX, f32 scaleY) {
+ djui_hud_transform_internal(x, y, scaleX, scaleY, NULL);
+}
+
+void djui_hud_transform_interpolated(f32 prevX, f32 prevY, f32 prevScaleX, f32 prevScaleY, f32 x, f32 y, f32 scaleX, f32 scaleY) {
+ struct InterpHud *interp = djui_hud_create_interp();
+ if (interp) {
+ interp->noMtx = true;
+ INTERP_SET(interp->posX, prevX, x);
+ INTERP_SET(interp->posY, prevY, y);
+ INTERP_SET(interp->scaleX, prevScaleX, scaleX);
+ INTERP_SET(interp->scaleY, prevScaleY, scaleY);
+ INTERP_MUL(interp->state.rotation.pivotX, interp->scaleX);
+ INTERP_MUL(interp->state.rotation.pivotY, interp->scaleY);
+ interp->state.resolution = RESOLUTION_N64;
+ interp->width = SCREEN_HEIGHT * GFX_DIMENSIONS_ASPECT_RATIO;
+ interp->height = SCREEN_HEIGHT;
+ }
+
+ djui_hud_transform_internal(prevX, prevY, prevScaleX, prevScaleY, interp);
+}
+
+void djui_hud_close_transform(void) {
+ if (sTransformDepth) {
+ gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
+ sTransformDepth--;
+ }
+}
+
+void djui_hud_reset_transform(void) {
+ if (sTransformDepth > 0) { printf("\n%i: %i", gGlobalTimer, sTransformDepth); }
+ while (sTransformDepth) {
+ gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
+ sTransformDepth--;
+ }
+}
+
void djui_hud_measure_text(const char* message, RET f32 *width, RET f32 *height) {
if (message == NULL) { return; }
const struct DjuiFont* font = djui_hud_get_text_font();
@@ -575,7 +739,6 @@ static Mtx *allocate_dl_translation_matrix() {
static void djui_hud_print_text_internal(const char* message, f32 x, f32 y, f32 scaleX, f32 scaleY, struct InterpHud *interp) {
if (message == NULL) { return; }
- gDjuiHudUtilsZ += 0.001f;
const struct DjuiFont* font = djui_hud_get_text_font();
f32 fontScaleX = font->defaultFontScale * scaleX;
@@ -586,30 +749,23 @@ static void djui_hud_print_text_internal(const char* message, f32 x, f32 y, f32
gSPDisplayList(gDisplayListHead++, font->textBeginDisplayList);
}
- // translate position
- djui_hud_create_interp_gfx(interp, INTERP_HUD_TRANSLATION);
- f32 translatedX = x + (font->xOffset * scaleX);
- f32 translatedY = y + (font->yOffset * scaleY);
- djui_hud_position_translate(&translatedX, &translatedY);
- create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, gDjuiHudUtilsZ);
+ djui_hud_setup_matrix();
+
+ // translate
+ x += (font->xOffset * scaleX); y += (font->yOffset * scaleY);
+ djui_hud_do_translation(interp, x, y);
// rotate
- f32 translatedFontSizeX = fontScaleX;
- f32 translatedFontSizeY = fontScaleY;
- djui_hud_size_translate(&translatedFontSizeX);
- djui_hud_size_translate(&translatedFontSizeY);
- if (sHudUtilsState.rotation.degrees.prev != 0 || sHudUtilsState.rotation.degrees.curr != 0) {
- djui_hud_create_interp_gfx(interp, INTERP_HUD_ROTATION);
- f32 pivotTranslationX = font->defaultFontScale * translatedFontSizeX * sHudUtilsState.rotation.pivotX.curr;
- f32 pivotTranslationY = font->defaultFontScale * translatedFontSizeY * sHudUtilsState.rotation.pivotY.curr;
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, +pivotTranslationX, -pivotTranslationY, 0);
- create_dl_rotation_matrix(DJUI_MTX_NOPUSH, sHudUtilsState.rotation.degrees.curr, 0, 0, 1);
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, -pivotTranslationX, +pivotTranslationY, 0);
+ f32 width, height;
+ djui_hud_measure_text(message, &width, &height);
+ if (interp) {
+ interp->width = width;
+ interp->height = height;
}
+ djui_hud_do_rotation(interp, width * scaleX, height * scaleY);
// compute font size
- djui_hud_create_interp_gfx(interp, INTERP_HUD_SCALE);
- create_dl_scale_matrix(DJUI_MTX_NOPUSH, translatedFontSizeX, translatedFontSizeY, 1.0f);
+ djui_hud_do_scale(interp, fontScaleX, fontScaleY);
// allocate the translation matrix for the vertical alignment
InterpHudGfx *valignGfx = djui_hud_create_interp_gfx(interp, INTERP_HUD_VALIGN);
@@ -707,8 +863,7 @@ static void djui_hud_print_text_internal(const char* message, f32 x, f32 y, f32
guTranslate(valignMatrix, 0, textHeight * sHudUtilsState.textAlignment.v.curr, 0);
if (valignGfx) { valignGfx->params[0] = textHeight; }
- // pop
- gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
+ djui_hud_pop_matrix(interp);
}
void djui_hud_print_text(const char* message, f32 x, f32 y, f32 scaleX, f32 scaleY) {
@@ -734,17 +889,10 @@ void djui_hud_print_text_interpolated(const char* message, f32 prevX, f32 prevY,
struct InterpHud *interp = djui_hud_create_interp();
if (interp) {
- const struct DjuiFont* font = djui_hud_get_text_font();
- interp->posX.prev = prevX;
- interp->posY.prev = prevY;
- interp->posX.curr = x;
- interp->posY.curr = y;
- interp->scaleX.prev = prevScaleX;
- interp->scaleY.prev = prevScaleY;
- interp->scaleX.curr = scaleX;
- interp->scaleY.curr = scaleY;
- interp->width = font->defaultFontScale;
- interp->height = font->defaultFontScale;
+ INTERP_SET(interp->posX, prevX, x);
+ INTERP_SET(interp->posY, prevY, y);
+ INTERP_SET(interp->scaleX, prevScaleX, scaleX);
+ INTERP_SET(interp->scaleY, prevScaleY, scaleY);
}
djui_hud_print_text_internal(message, x, y, scaleX, scaleY, interp);
@@ -762,78 +910,46 @@ static void djui_hud_render_texture_raw(const Texture* texture, u32 width, u32 h
if (!texture) { return; }
- gDjuiHudUtilsZ += 0.001f;
+ djui_hud_setup_matrix();
- // translate position
- djui_hud_create_interp_gfx(interp, INTERP_HUD_TRANSLATION);
- f32 translatedX = x;
- f32 translatedY = y;
- djui_hud_position_translate(&translatedX, &translatedY);
- create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, gDjuiHudUtilsZ);
+ // translate
+ djui_hud_do_translation(interp, x, y);
// rotate
- f32 translatedW = scaleW;
- f32 translatedH = scaleH;
- djui_hud_size_translate(&translatedW);
- djui_hud_size_translate(&translatedH);
- if (sHudUtilsState.rotation.degrees.prev != 0 || sHudUtilsState.rotation.degrees.curr != 0) {
- djui_hud_create_interp_gfx(interp, INTERP_HUD_ROTATION);
- f32 pivotTranslationX = width * translatedW * sHudUtilsState.rotation.pivotX.curr;
- f32 pivotTranslationY = height * translatedH * sHudUtilsState.rotation.pivotY.curr;
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, +pivotTranslationX, -pivotTranslationY, 0);
- create_dl_rotation_matrix(DJUI_MTX_NOPUSH, sHudUtilsState.rotation.degrees.curr, 0, 0, 1);
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, -pivotTranslationX, +pivotTranslationY, 0);
- }
+ djui_hud_do_rotation(interp, width * scaleW, height * scaleH);
- // translate scale
- djui_hud_create_interp_gfx(interp, INTERP_HUD_SCALE);
- create_dl_scale_matrix(DJUI_MTX_NOPUSH, width * translatedW, height * translatedH, 1.0f);
+ // scale
+ djui_hud_do_scale(interp, width * scaleW, height * scaleH);
// render
djui_gfx_render_texture(texture, width, height, fmt, siz, sHudUtilsState.filter);
// pop
- gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
+ djui_hud_pop_matrix(interp);
}
static void djui_hud_render_texture_tile_raw(const Texture* texture, u32 width, u32 height, u8 fmt, u8 siz, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH, struct InterpHud *interp) {
if (!texture) { return; }
- gDjuiHudUtilsZ += 0.001f;
+ djui_hud_setup_matrix();
if (width != 0) { scaleW *= (f32) tileW / (f32) width; }
if (height != 0) { scaleH *= (f32) tileH / (f32) height; }
- // translate position
- djui_hud_create_interp_gfx(interp, INTERP_HUD_TRANSLATION);
- f32 translatedX = x;
- f32 translatedY = y;
- djui_hud_position_translate(&translatedX, &translatedY);
- create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, gDjuiHudUtilsZ);
+ // translate
+ djui_hud_do_translation(interp, x, y);
// rotate
- f32 translatedW = scaleW;
- f32 translatedH = scaleH;
- djui_hud_size_translate(&translatedW);
- djui_hud_size_translate(&translatedH);
- if (sHudUtilsState.rotation.degrees.prev != 0 || sHudUtilsState.rotation.degrees.curr != 0) {
- djui_hud_create_interp_gfx(interp, INTERP_HUD_ROTATION);
- f32 aspect = tileH ? ((f32) tileW / (f32) tileH) : 1.f;
- f32 pivotTranslationX = width * translatedW * aspect * sHudUtilsState.rotation.pivotX.curr;
- f32 pivotTranslationY = height * translatedH * sHudUtilsState.rotation.pivotY.curr;
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, +pivotTranslationX, -pivotTranslationY, 0);
- create_dl_rotation_matrix(DJUI_MTX_NOPUSH, sHudUtilsState.rotation.degrees.curr, 0, 0, 1);
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, -pivotTranslationX, +pivotTranslationY, 0);
- }
+ f32 aspect = tileH ? ((f32) tileW / (f32) tileH) : 1.f;
+ djui_hud_do_rotation(interp, width * scaleW * aspect, height * scaleH);
- // translate scale
- djui_hud_create_interp_gfx(interp, INTERP_HUD_SCALE);
- create_dl_scale_matrix(DJUI_MTX_NOPUSH, width * translatedW, height * translatedH, 1.0f);
+ // scale
+ djui_hud_do_scale(interp, width * scaleW, height * scaleH);
// render
djui_gfx_render_texture_tile(texture, width, height, fmt, siz, tileX, tileY, tileW, tileH, sHudUtilsState.filter);
// pop
- gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
+ djui_hud_pop_matrix(interp);
}
void djui_hud_render_texture(struct TextureInfo* texInfo, f32 x, f32 y, f32 scaleW, f32 scaleH) {
@@ -851,14 +967,10 @@ void djui_hud_render_texture_interpolated(struct TextureInfo* texInfo, f32 prevX
struct InterpHud *interp = djui_hud_create_interp();
if (interp) {
- interp->posX.prev = prevX;
- interp->posY.prev = prevY;
- interp->posX.curr = x;
- interp->posY.curr = y;
- interp->scaleX.prev = prevScaleW;
- interp->scaleY.prev = prevScaleH;
- interp->scaleX.curr = scaleW;
- interp->scaleY.curr = scaleH;
+ INTERP_SET(interp->posX, prevX, x);
+ INTERP_SET(interp->posY, prevY, y);
+ INTERP_SET(interp->scaleX, prevScaleW, scaleW);
+ INTERP_SET(interp->scaleY, prevScaleH, scaleH);
interp->width = texInfo->width;
interp->height = texInfo->height;
}
@@ -881,14 +993,10 @@ void djui_hud_render_texture_tile_interpolated(struct TextureInfo* texInfo, f32
struct InterpHud *interp = djui_hud_create_interp();
if (interp) {
- interp->posX.prev = prevX;
- interp->posY.prev = prevY;
- interp->posX.curr = x;
- interp->posY.curr = y;
- interp->scaleX.prev = prevScaleW;
- interp->scaleY.prev = prevScaleH;
- interp->scaleX.curr = scaleW;
- interp->scaleY.curr = scaleH;
+ INTERP_SET(interp->posX, prevX, x);
+ INTERP_SET(interp->posY, prevY, y);
+ INTERP_SET(interp->scaleX, prevScaleW, scaleW);
+ INTERP_SET(interp->scaleY, prevScaleH, scaleH);
interp->width = texInfo->width;
interp->height = texInfo->height;
}
@@ -897,38 +1005,23 @@ void djui_hud_render_texture_tile_interpolated(struct TextureInfo* texInfo, f32
}
static void djui_hud_render_rect_internal(f32 x, f32 y, f32 width, f32 height, struct InterpHud *interp) {
- gDjuiHudUtilsZ += 0.001f;
+ djui_hud_setup_matrix();
- // translate position
- djui_hud_create_interp_gfx(interp, INTERP_HUD_TRANSLATION);
- f32 translatedX = x;
- f32 translatedY = y;
- djui_hud_position_translate(&translatedX, &translatedY);
- create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, gDjuiHudUtilsZ);
+ // translate
+ djui_hud_do_translation(interp, x, y);
// rotate
- f32 translatedW = width;
- f32 translatedH = height;
- djui_hud_size_translate(&translatedW);
- djui_hud_size_translate(&translatedH);
- if (sHudUtilsState.rotation.degrees.prev != 0 || sHudUtilsState.rotation.degrees.curr != 0) {
- djui_hud_create_interp_gfx(interp, INTERP_HUD_ROTATION);
- f32 pivotTranslationX = translatedW * sHudUtilsState.rotation.pivotX.curr;
- f32 pivotTranslationY = translatedH * sHudUtilsState.rotation.pivotY.curr;
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, +pivotTranslationX, -pivotTranslationY, 0);
- create_dl_rotation_matrix(DJUI_MTX_NOPUSH, sHudUtilsState.rotation.degrees.curr, 0, 0, 1);
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, -pivotTranslationX, +pivotTranslationY, 0);
- }
+ djui_hud_do_rotation(interp, width, height);
- // translate scale
- djui_hud_create_interp_gfx(interp, INTERP_HUD_SCALE);
- create_dl_scale_matrix(DJUI_MTX_NOPUSH, translatedW, translatedH, 1.0f);
+ // scale
+ djui_hud_do_scale(interp, width, height);
// render
+ djui_gfx_update_combine_mode(CS_COLOR);
gSPDisplayList(gDisplayListHead++, dl_djui_simple_rect);
// pop
- gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
+ djui_hud_pop_matrix(interp);
}
void djui_hud_render_rect(f32 x, f32 y, f32 width, f32 height) {
@@ -938,14 +1031,10 @@ void djui_hud_render_rect(f32 x, f32 y, f32 width, f32 height) {
void djui_hud_render_rect_interpolated(f32 prevX, f32 prevY, f32 prevWidth, f32 prevHeight, f32 x, f32 y, f32 width, f32 height) {
struct InterpHud *interp = djui_hud_create_interp();
if (interp) {
- interp->posX.prev = prevX;
- interp->posY.prev = prevY;
- interp->posX.curr = x;
- interp->posY.curr = y;
- interp->scaleX.prev = prevWidth;
- interp->scaleY.prev = prevHeight;
- interp->scaleX.curr = width;
- interp->scaleY.curr = height;
+ INTERP_SET(interp->posX, prevX, x);
+ INTERP_SET(interp->posY, prevY, y);
+ INTERP_SET(interp->scaleX, prevWidth, width);
+ INTERP_SET(interp->scaleY, prevHeight, height);
interp->width = 1;
interp->height = 1;
}
@@ -995,7 +1084,7 @@ bool djui_hud_world_pos_to_screen_pos(Vec3f pos, VEC_OUT Vec3f out) {
f32 screenWidth, screenHeight;
if (sHudUtilsState.resolution == RESOLUTION_N64) {
- screenWidth = GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_HEIGHT;
+ screenWidth = SCREEN_HEIGHT * GFX_DIMENSIONS_ASPECT_RATIO;
screenHeight = SCREEN_HEIGHT;
} else {
u32 windowWidth, windowHeight;
diff --git a/src/pc/djui/djui_hud_utils.h b/src/pc/djui/djui_hud_utils.h
index 56ea5a698..ba1a0dd3a 100644
--- a/src/pc/djui/djui_hud_utils.h
+++ b/src/pc/djui/djui_hud_utils.h
@@ -1,6 +1,8 @@
#ifndef DJUI_HUD_UTILS_H
#define DJUI_HUD_UTILS_H
+#include "pc/lua/smlua.h"
+
// Common pivot values for rotation
#define ROTATION_PIVOT_X_LEFT 0.0
#define ROTATION_PIVOT_X_CENTER 0.5
@@ -59,7 +61,6 @@ struct GlobalTextures {
};
extern struct GlobalTextures gGlobalTextures;
-extern f32 gDjuiHudUtilsZ;
extern bool gDjuiHudLockMouse;
void djui_hud_clear_interp_data();
@@ -80,6 +81,8 @@ void djui_hud_set_font(s8 fontType);
struct DjuiColor* djui_hud_get_color(void);
/* |description|Sets the current DJUI HUD global color|descriptionEnd| */
void djui_hud_set_color(u8 r, u8 g, u8 b, u8 a);
+/* |description|Sets the current DJUI HUD global color interpolated|descriptionEnd| */
+void djui_hud_set_color_interpolated(u8 prevR, u8 prevG, u8 prevB, u8 prevA, u8 r, u8 g, u8 b, u8 a);
/* |description|Resets the current DJUI HUD global color|descriptionEnd| */
void djui_hud_reset_color(void);
/* |description|Gets the current DJUI HUD text default color. This color is overridden by color codes|descriptionEnd| */
@@ -88,10 +91,20 @@ struct DjuiColor* djui_hud_get_text_color(void);
void djui_hud_set_text_color(u8 r, u8 g, u8 b, u8 a);
/* |description|Resets the current DJUI HUD text default color. This color is overridden by color codes|descriptionEnd| */
void djui_hud_reset_text_color(void);
+/* |description|Sets the number of cycles used by the combiner|descriptionEnd| */
+void djui_hud_set_combiner_cycles(u8 cycles);
+/* |description|
+Sets the current DJUI HUD combiner.
+Each part uses the following equation: `P = (A - B) * C + D`.
+Cycle 2 may be used to extend the equation, with the result of the previous cycle accessible through CS_COMBINED
+|descriptionEnd| */
+void djui_hud_set_combiner(u8 cycle, bool alpha, OPTIONAL enum CombinerSource a, OPTIONAL enum CombinerSource b, OPTIONAL enum CombinerSource c, OPTIONAL enum CombinerSource d);
+/* |description|Resets the current DJUI HUD combiner|descriptionEnd| */
+void djui_hud_reset_combiner();
/* |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| */
-void djui_hud_set_rotation(s16 rotation, f32 pivotX, f32 pivotY);
+void djui_hud_set_rotation(s16 rotation, OPTIONAL f32 pivotX, OPTIONAL f32 pivotY);
/* |description|Sets the current DJUI HUD rotation interpolated|descriptionEnd| */
void djui_hud_set_rotation_interpolated(s16 prevRotation, f32 prevPivotX, f32 prevPivotY, s16 rotation, f32 pivotX, f32 pivotY);
/* |description|Gets the current DJUI HUD text alignment|descriptionEnd| */
@@ -136,6 +149,14 @@ void djui_hud_reset_viewport(void);
void djui_hud_set_scissor(f32 x, f32 y, f32 width, f32 height);
/* |description|Resets the scissor rectangle to a fullscreen state|descriptionEnd| */
void djui_hud_reset_scissor(void);
+/* |description|Applies a transformation (translate, rotate, scale) to subsequent DJUI HUD elements until closed|descriptionEnd| */
+void djui_hud_transform(f32 x, f32 y, f32 scaleX, f32 scaleY);
+/* |description|Applies an interpolated transformation (translate, rotate, scale) to subsequent DJUI HUD elements until closed|descriptionEnd| */
+void djui_hud_transform_interpolated(f32 prevX, f32 prevY, f32 prevScaleX, f32 prevScaleY, f32 x, f32 y, f32 scaleX, f32 scaleY);
+/* |description|Closes the previous transformation|descriptionEnd| */
+void djui_hud_close_transform(void);
+/* |description|Resets the transformation to a fullscreen state|descriptionEnd| */
+void djui_hud_reset_transform(void);
/* |description|Measures the width and height of `message` in the current font|descriptionEnd| */
void djui_hud_measure_text(const char* message, RET f32 *width, RET f32 *height);
diff --git a/src/pc/djui/djui_image.c b/src/pc/djui/djui_image.c
index d082b06cd..10b17c1c7 100644
--- a/src/pc/djui/djui_image.c
+++ b/src/pc/djui/djui_image.c
@@ -13,7 +13,7 @@ static bool djui_image_render(struct DjuiBase* base) {
// translate position
f32 translatedX = comp->x;
f32 translatedY = comp->y;
- djui_gfx_position_translate(&translatedX, &translatedY);
+ djui_gfx_dimension_translate(&translatedX, &translatedY);
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
// translate size
diff --git a/src/pc/djui/djui_inputbox.c b/src/pc/djui/djui_inputbox.c
index d5c4bde44..c97fb738c 100644
--- a/src/pc/djui/djui_inputbox.c
+++ b/src/pc/djui/djui_inputbox.c
@@ -493,6 +493,8 @@ static void djui_inputbox_render_selection(struct DjuiInputbox* inputbox) {
}
}
+ djui_gfx_update_combine_mode(CS_COLOR);
+
// render only cursor when there is no selection width
if (selection[0] == selection[1]) {
if (sCursorBlink < DJUI_INPUTBOX_MID_BLINK && djui_interactable_is_input_focus(&inputbox->base)) {
@@ -573,7 +575,7 @@ static bool djui_inputbox_render(struct DjuiBase* base) {
// translate position
f32 translatedX = comp->x + inputbox->viewX;
f32 translatedY = comp->y + inputbox->yOffset;
- djui_gfx_position_translate(&translatedX, &translatedY);
+ djui_gfx_dimension_translate(&translatedX, &translatedY);
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
// compute font size
diff --git a/src/pc/djui/djui_rect.c b/src/pc/djui/djui_rect.c
index 97383c65a..a5630bb10 100644
--- a/src/pc/djui/djui_rect.c
+++ b/src/pc/djui/djui_rect.c
@@ -10,7 +10,7 @@ bool djui_rect_render(struct DjuiBase* base) {
// translate position
f32 translatedX = clip->x;
f32 translatedY = clip->y;
- djui_gfx_position_translate(&translatedX, &translatedY);
+ djui_gfx_dimension_translate(&translatedX, &translatedY);
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
// translate size
@@ -20,6 +20,7 @@ bool djui_rect_render(struct DjuiBase* base) {
create_dl_scale_matrix(DJUI_MTX_NOPUSH, translatedWidth, translatedHeight, 1.0f);
// render
+ djui_gfx_update_combine_mode(CS_COLOR);
gDPSetEnvColor(gDisplayListHead++, base->color.r, base->color.g, base->color.b, base->color.a);
gSPDisplayList(gDisplayListHead++, base->gradient ? dl_djui_menu_rect : dl_djui_simple_rect);
diff --git a/src/pc/djui/djui_text.c b/src/pc/djui/djui_text.c
index a67f1d4fd..577e3cdbb 100644
--- a/src/pc/djui/djui_text.c
+++ b/src/pc/djui/djui_text.c
@@ -252,7 +252,7 @@ static void djui_text_render_single_char(struct DjuiText* text, char* c) {
return;
}
- create_dl_translation_matrix(DJUI_MTX_NOPUSH, sTextRenderX - sTextRenderLastX, (sTextRenderY - sTextRenderLastY) * -1.0f, 0);
+ create_dl_translation_matrix(DJUI_MTX_NOPUSH, sTextRenderX - sTextRenderLastX, sTextRenderY - sTextRenderLastY, 0);
text->font->render_char(c);
sTextRenderLastX = sTextRenderX;
@@ -474,7 +474,7 @@ static bool djui_text_render(struct DjuiBase* base) {
// translate position
f32 translatedX = comp->x;
f32 translatedY = comp->y;
- djui_gfx_position_translate(&translatedX, &translatedY);
+ djui_gfx_dimension_translate(&translatedX, &translatedY);
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
// compute size
diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c
index ec2922c1b..750b30737 100644
--- a/src/pc/lua/smlua_constants_autogen.c
+++ b/src/pc/lua/smlua_constants_autogen.c
@@ -1461,6 +1461,18 @@ const char gSmluaConstants[] = ""
"CONSOLE_MESSAGE_INFO=0\n"
"CONSOLE_MESSAGE_WARNING=1\n"
"CONSOLE_MESSAGE_ERROR=2\n"
+"CS_KEEP=-1\n"
+"CS_0=0\n"
+"CS_1=1\n"
+"CS_TEXTURE=2\n"
+"CS_COLOR=3\n"
+"CS_TEXT=4\n"
+"CS_COMBINED=5\n"
+"CS_NOISE=6\n"
+"CS_TEXTURE_ALPHA=7\n"
+"CS_COLOR_ALPHA=8\n"
+"CS_TEXT_ALPHA=9\n"
+"CS_COMBINED_ALPHA=10\n"
"ROTATION_PIVOT_X_LEFT=0.0\n"
"ROTATION_PIVOT_X_CENTER=0.5\n"
"ROTATION_PIVOT_X_RIGHT=1.0\n"
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index 2b05d1a9c..55001f963 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -12369,6 +12369,37 @@ int smlua_func_djui_hud_set_color(lua_State* L) {
return 1;
}
+int smlua_func_djui_hud_set_color_interpolated(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 8) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "djui_hud_set_color_interpolated", 8, top);
+ return 0;
+ }
+
+ u8 prevR = smlua_to_integer(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "djui_hud_set_color_interpolated"); return 0; }
+ u8 prevG = smlua_to_integer(L, 2);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "djui_hud_set_color_interpolated"); return 0; }
+ u8 prevB = smlua_to_integer(L, 3);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "djui_hud_set_color_interpolated"); return 0; }
+ u8 prevA = smlua_to_integer(L, 4);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "djui_hud_set_color_interpolated"); return 0; }
+ u8 r = smlua_to_integer(L, 5);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 5, "djui_hud_set_color_interpolated"); return 0; }
+ u8 g = smlua_to_integer(L, 6);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 6, "djui_hud_set_color_interpolated"); return 0; }
+ u8 b = smlua_to_integer(L, 7);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 7, "djui_hud_set_color_interpolated"); return 0; }
+ u8 a = smlua_to_integer(L, 8);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 8, "djui_hud_set_color_interpolated"); return 0; }
+
+ djui_hud_set_color_interpolated(prevR, prevG, prevB, prevA, r, g, b, a);
+
+ return 1;
+}
+
int smlua_func_djui_hud_reset_color(lua_State* L) {
if (L == NULL) { return 0; }
@@ -12437,6 +12468,77 @@ int smlua_func_djui_hud_reset_text_color(lua_State* L) {
return 1;
}
+int smlua_func_djui_hud_set_combiner_cycles(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", "djui_hud_set_combiner_cycles", 1, top);
+ return 0;
+ }
+
+ u8 cycles = smlua_to_integer(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "djui_hud_set_combiner_cycles"); return 0; }
+
+ djui_hud_set_combiner_cycles(cycles);
+
+ return 1;
+}
+
+int smlua_func_djui_hud_set_combiner(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top < 2 || top > 6) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected between %u and %u, Received %u", "djui_hud_set_combiner", 2, 6, top);
+ return 0;
+ }
+
+ u8 cycle = smlua_to_integer(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "djui_hud_set_combiner"); return 0; }
+ bool alpha = smlua_to_boolean(L, 2);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "djui_hud_set_combiner"); return 0; }
+ enum CombinerSource a = (enum CombinerSource) 0;
+ if (top >= 3) {
+ a = smlua_to_integer(L, 3);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "djui_hud_set_combiner"); return 0; }
+ }
+ enum CombinerSource b = (enum CombinerSource) 0;
+ if (top >= 4) {
+ b = smlua_to_integer(L, 4);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "djui_hud_set_combiner"); return 0; }
+ }
+ enum CombinerSource c = (enum CombinerSource) 0;
+ if (top >= 5) {
+ c = smlua_to_integer(L, 5);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 5, "djui_hud_set_combiner"); return 0; }
+ }
+ enum CombinerSource d = (enum CombinerSource) 0;
+ if (top >= 6) {
+ d = smlua_to_integer(L, 6);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 6, "djui_hud_set_combiner"); return 0; }
+ }
+
+ djui_hud_set_combiner(cycle, alpha, a, b, c, d);
+
+ return 1;
+}
+
+int smlua_func_djui_hud_reset_combiner(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_combiner", 0, top);
+ return 0;
+ }
+
+
+ djui_hud_reset_combiner();
+
+ return 1;
+}
+
int smlua_func_djui_hud_get_rotation(lua_State* L) {
if (L == NULL) { return 0; }
@@ -12464,17 +12566,23 @@ int smlua_func_djui_hud_set_rotation(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
- if (top != 3) {
- LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "djui_hud_set_rotation", 3, top);
+ if (top < 1 || top > 3) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected between %u and %u, Received %u", "djui_hud_set_rotation", 1, 3, top);
return 0;
}
s16 rotation = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "djui_hud_set_rotation"); return 0; }
- f32 pivotX = smlua_to_number(L, 2);
- if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "djui_hud_set_rotation"); return 0; }
- f32 pivotY = smlua_to_number(L, 3);
- if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "djui_hud_set_rotation"); return 0; }
+ f32 pivotX = (f32) 0;
+ if (top >= 2) {
+ pivotX = smlua_to_number(L, 2);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "djui_hud_set_rotation"); return 0; }
+ }
+ f32 pivotY = (f32) 0;
+ if (top >= 3) {
+ pivotY = smlua_to_number(L, 3);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "djui_hud_set_rotation"); return 0; }
+ }
djui_hud_set_rotation(rotation, pivotX, pivotY);
@@ -12844,6 +12952,90 @@ int smlua_func_djui_hud_reset_scissor(lua_State* L) {
return 1;
}
+int smlua_func_djui_hud_transform(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_transform", 4, top);
+ return 0;
+ }
+
+ f32 x = smlua_to_number(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "djui_hud_transform"); return 0; }
+ f32 y = smlua_to_number(L, 2);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "djui_hud_transform"); return 0; }
+ f32 scaleX = smlua_to_number(L, 3);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "djui_hud_transform"); return 0; }
+ f32 scaleY = smlua_to_number(L, 4);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "djui_hud_transform"); return 0; }
+
+ djui_hud_transform(x, y, scaleX, scaleY);
+
+ return 1;
+}
+
+int smlua_func_djui_hud_transform_interpolated(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 8) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "djui_hud_transform_interpolated", 8, top);
+ return 0;
+ }
+
+ f32 prevX = smlua_to_number(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "djui_hud_transform_interpolated"); return 0; }
+ f32 prevY = smlua_to_number(L, 2);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "djui_hud_transform_interpolated"); return 0; }
+ f32 prevScaleX = smlua_to_number(L, 3);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "djui_hud_transform_interpolated"); return 0; }
+ f32 prevScaleY = smlua_to_number(L, 4);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "djui_hud_transform_interpolated"); return 0; }
+ f32 x = smlua_to_number(L, 5);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 5, "djui_hud_transform_interpolated"); return 0; }
+ f32 y = smlua_to_number(L, 6);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 6, "djui_hud_transform_interpolated"); return 0; }
+ f32 scaleX = smlua_to_number(L, 7);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 7, "djui_hud_transform_interpolated"); return 0; }
+ f32 scaleY = smlua_to_number(L, 8);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 8, "djui_hud_transform_interpolated"); return 0; }
+
+ djui_hud_transform_interpolated(prevX, prevY, prevScaleX, prevScaleY, x, y, scaleX, scaleY);
+
+ return 1;
+}
+
+int smlua_func_djui_hud_close_transform(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_close_transform", 0, top);
+ return 0;
+ }
+
+
+ djui_hud_close_transform();
+
+ return 1;
+}
+
+int smlua_func_djui_hud_reset_transform(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_transform", 0, top);
+ return 0;
+ }
+
+
+ djui_hud_reset_transform();
+
+ return 1;
+}
+
int smlua_func_djui_hud_measure_text(lua_State* L) {
if (L == NULL) { return 0; }
@@ -38003,10 +38195,14 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "djui_hud_set_font", smlua_func_djui_hud_set_font);
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_set_color_interpolated", smlua_func_djui_hud_set_color_interpolated);
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_set_combiner_cycles", smlua_func_djui_hud_set_combiner_cycles);
+ smlua_bind_function(L, "djui_hud_set_combiner", smlua_func_djui_hud_set_combiner);
+ smlua_bind_function(L, "djui_hud_reset_combiner", smlua_func_djui_hud_reset_combiner);
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);
@@ -38030,6 +38226,10 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "djui_hud_reset_viewport", smlua_func_djui_hud_reset_viewport);
smlua_bind_function(L, "djui_hud_set_scissor", smlua_func_djui_hud_set_scissor);
smlua_bind_function(L, "djui_hud_reset_scissor", smlua_func_djui_hud_reset_scissor);
+ smlua_bind_function(L, "djui_hud_transform", smlua_func_djui_hud_transform);
+ smlua_bind_function(L, "djui_hud_transform_interpolated", smlua_func_djui_hud_transform_interpolated);
+ smlua_bind_function(L, "djui_hud_close_transform", smlua_func_djui_hud_close_transform);
+ smlua_bind_function(L, "djui_hud_reset_transform", smlua_func_djui_hud_reset_transform);
smlua_bind_function(L, "djui_hud_measure_text", smlua_func_djui_hud_measure_text);
smlua_bind_function(L, "djui_hud_render_texture", smlua_func_djui_hud_render_texture);
smlua_bind_function(L, "djui_hud_render_texture_tile", smlua_func_djui_hud_render_texture_tile);