diff --git a/autogen/convert_constants.py b/autogen/convert_constants.py
index f036c9b2..b92b0b6d 100644
--- a/autogen/convert_constants.py
+++ b/autogen/convert_constants.py
@@ -17,6 +17,7 @@ in_files = [
"src/pc/network/network_player.h",
"include/PR/os_cont.h",
"src/game/interaction.c",
+ "src/pc/djui/djui_gfx_utils.h",
]
exclude_constants = [
@@ -286,4 +287,4 @@ def main():
global totalConstants
print("Total constants: " + str(totalConstants))
-main()
\ No newline at end of file
+main()
diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py
index 14f5464d..6e83bd7b 100644
--- a/autogen/convert_functions.py
+++ b/autogen/convert_functions.py
@@ -33,6 +33,7 @@ in_files = [
"src/game/level_info.h",
"src/game/save_file.h",
"src/game/sound_init.h",
+ "src/pc/djui/djui_gfx_utils.h",
]
override_allowed_functions = {
@@ -84,6 +85,7 @@ template = """/* THIS FILE IS AUTOGENERATED */
#include "src/game/level_info.h"
#include "src/game/save_file.h"
#include "src/game/sound_init.h"
+#include "src/pc/djui/djui_gfx_utils.h"
$[FUNCTIONS]
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index 0cfc3eb8..fd58d577 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -26,6 +26,17 @@
+- djui_gfx_utils.h
+ - [djui_gfx_get_screen_height](#djui_gfx_get_screen_height)
+ - [djui_gfx_get_screen_width](#djui_gfx_get_screen_width)
+ - [djui_gfx_measure_text](#djui_gfx_measure_text)
+ - [djui_gfx_print_text](#djui_gfx_print_text)
+ - [djui_gfx_set_color](#djui_gfx_set_color)
+ - [djui_gfx_set_font](#djui_gfx_set_font)
+ - [djui_gfx_set_resolution](#djui_gfx_set_resolution)
+
+
+
- djui_popup.h
- [djui_popup_create](#djui_popup_create)
@@ -611,6 +622,154 @@
+---
+# functions from djui_gfx_utils.h
+
+
+
+
+## [djui_gfx_get_screen_height](#djui_gfx_get_screen_height)
+
+### Lua Example
+`local integerValue = djui_gfx_get_screen_height()`
+
+### Parameters
+- None
+
+### Returns
+- integer
+
+### C Prototype
+`u32 djui_gfx_get_screen_height(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_gfx_get_screen_width](#djui_gfx_get_screen_width)
+
+### Lua Example
+`local integerValue = djui_gfx_get_screen_width()`
+
+### Parameters
+- None
+
+### Returns
+- integer
+
+### C Prototype
+`u32 djui_gfx_get_screen_width(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_gfx_measure_text](#djui_gfx_measure_text)
+
+### Lua Example
+`local numberValue = djui_gfx_measure_text(message)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| message | string |
+
+### Returns
+- number
+
+### C Prototype
+`f32 djui_gfx_measure_text(const char* message);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_gfx_print_text](#djui_gfx_print_text)
+
+### Lua Example
+`djui_gfx_print_text(message, x, y, scale)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| message | string |
+| x | float |
+| y | float |
+| scale | float |
+
+### Returns
+- None
+
+### C Prototype
+`void djui_gfx_print_text(const char* message, float x, float y, float scale);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_gfx_set_color](#djui_gfx_set_color)
+
+### Lua Example
+`djui_gfx_set_color(r, g, b, a)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| r | integer |
+| g | integer |
+| b | integer |
+| a | integer |
+
+### Returns
+- None
+
+### C Prototype
+`void djui_gfx_set_color(u8 r, u8 g, u8 b, u8 a);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_gfx_set_font](#djui_gfx_set_font)
+
+### Lua Example
+`djui_gfx_set_font(fontType)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| fontType | integer |
+
+### Returns
+- None
+
+### C Prototype
+`void djui_gfx_set_font(enum DjuiFontType fontType);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_gfx_set_resolution](#djui_gfx_set_resolution)
+
+### Lua Example
+`djui_gfx_set_resolution(resolutionType)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| resolutionType | integer |
+
+### Returns
+- None
+
+### C Prototype
+`void djui_gfx_set_resolution(enum GfxUtilsResolution resolutionType);`
+
+[:arrow_up_small:](#)
+
+
+
---
# functions from djui_popup.h
diff --git a/src/pc/djui/djui.c b/src/pc/djui/djui.c
index 15ed389c..79dcb5a1 100644
--- a/src/pc/djui/djui.c
+++ b/src/pc/djui/djui.c
@@ -2,7 +2,9 @@
#include "../debuglog.h"
#include "pc/cliopts.h"
#include "game/level_update.h"
+#include "pc/lua/smlua_hooks.h"
#include "djui_panel_playerlist.h"
+#include "djui_gfx_utils.h"
static Gfx* sSavedDisplayListHead = NULL;
@@ -53,6 +55,8 @@ void djui_render(void) {
sSavedDisplayListHead = gDisplayListHead;
create_dl_ortho_matrix();
+ smlua_call_event_hooks(HOOK_ON_HUD_RENDER);
+
djui_panel_update();
djui_popup_update();
diff --git a/src/pc/djui/djui_font.c b/src/pc/djui/djui_font.c
index cbeab3b0..b0bbb68c 100644
--- a/src/pc/djui/djui_font.c
+++ b/src/pc/djui/djui_font.c
@@ -92,6 +92,71 @@ static const struct DjuiFont sDjuiFontTitle = {
.char_width = djui_font_title_char_width,
};
+ ///////////////////////
+ // font 3 (hud font) //
+///////////////////////
+
+/*
+ texture_hud_char_0, texture_hud_char_1, texture_hud_char_2, texture_hud_char_3,
+ texture_hud_char_4, texture_hud_char_5, texture_hud_char_6, texture_hud_char_7,
+ texture_hud_char_8, texture_hud_char_9, texture_hud_char_A, texture_hud_char_B,
+ texture_hud_char_C, texture_hud_char_D, texture_hud_char_E, texture_hud_char_F,
+ texture_hud_char_G, texture_hud_char_H, texture_hud_char_I, texture_hud_char_J,
+ texture_hud_char_K, texture_hud_char_L, texture_hud_char_M, texture_hud_char_N,
+ texture_hud_char_O, texture_hud_char_P, 0x0, texture_hud_char_R,
+ texture_hud_char_S, texture_hud_char_T, texture_hud_char_U, 0x0,
+ texture_hud_char_W, 0x0, texture_hud_char_Y, texture_hud_char_waluigi_head,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, texture_hud_char_multiply, texture_hud_char_coin,
+ texture_hud_char_mario_head, texture_hud_char_star, texture_hud_char_luigi_head, texture_hud_char_toad_head,
+ texture_hud_char_apostrophe, texture_hud_char_double_quote,
+*/
+
+static u8 djui_font_hud_index(char c) {
+ if (c == 'q' || c == 'Q') { return 50; }
+ if (c == 'v' || c == 'V') { return 50; }
+ if (c == 'x' || c == 'X') { return 50; }
+ if (c == 'z' || c == 'Z') { return 50; }
+
+ switch (c) {
+ case '$': return 51;
+ case '*': return 53;
+ case '\'': return 56;
+ case '"': return 57;
+ }
+
+ if (c >= '0' && c <= '9') { return 0 + c - '0'; }
+ if (c >= 'a' && c <= 'z') { return 10 + c - 'a'; }
+ if (c >= 'A' && c <= 'Z') { return 10 + c - 'A'; }
+
+ if (c >= 58) { return 50; }
+ if (main_hud_lut[(int)c] == NULL) { return 50; }
+
+ return c;
+}
+
+static void djui_font_hud_render_char(char c) {
+ u8 index = djui_font_hud_index(c);
+ djui_gfx_render_texture(main_hud_lut[index], 16, 16, 16);
+}
+
+static f32 djui_font_hud_char_width(UNUSED char c) {
+ return 0.75f;
+}
+
+static const struct DjuiFont sDjuiFontHud = {
+ .charWidth = 1.0f,
+ .charHeight = 0.9f,
+ .lineHeight = 0.7f,
+ .defaultFontScale = 16.0f,
+ .rotatedUV = false,
+ .textBeginDisplayList = NULL,
+ .render_char = djui_font_hud_render_char,
+ .char_width = djui_font_hud_char_width,
+};
+
///////////////
// font list //
///////////////
@@ -99,4 +164,5 @@ static const struct DjuiFont sDjuiFontTitle = {
const struct DjuiFont* gDjuiFonts[] = {
&sDjuiFontNormal,
&sDjuiFontTitle,
+ &sDjuiFontHud,
};
\ No newline at end of file
diff --git a/src/pc/djui/djui_gfx_utils.c b/src/pc/djui/djui_gfx_utils.c
new file mode 100644
index 00000000..f3a3b6f6
--- /dev/null
+++ b/src/pc/djui/djui_gfx_utils.c
@@ -0,0 +1,140 @@
+#include
+#include
+#include
+
+#include "pc/gfx/gfx_pc.h"
+#include "pc/gfx/gfx_window_manager_api.h"
+#include "pc/pc_main.h"
+
+#include "gfx_dimensions.h"
+#include "config.h"
+#include "djui.h"
+#include "djui_gfx_utils.h"
+
+static enum GfxUtilsResolution sResolution = RESOLUTION_DJUI;
+static enum DjuiFontType sFont = FONT_NORMAL;
+
+void djui_gfx_set_resolution(enum GfxUtilsResolution resolutionType) {
+ if (resolutionType >= RESOLUTION_COUNT) { return; }
+ sResolution = resolutionType;
+}
+
+void djui_gfx_set_font(enum DjuiFontType fontType) {
+ if (fontType >= FONT_COUNT) { return; }
+ sFont = fontType;
+}
+
+void djui_gfx_set_color(u8 r, u8 g, u8 b, u8 a) {
+ gDPSetEnvColor(gDisplayListHead++, r, g, b, a);
+}
+
+u32 djui_gfx_get_screen_width(void) {
+ u32 windowWidth, windowHeight;
+ wm_api->get_dimensions(&windowWidth, &windowHeight);
+
+ return (sResolution == RESOLUTION_N64)
+ ? (GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_HEIGHT)
+ : (windowWidth / djui_gfx_get_scale());
+}
+
+u32 djui_gfx_get_screen_height(void) {
+ u32 windowWidth, windowHeight;
+ wm_api->get_dimensions(&windowWidth, &windowHeight);
+
+ return (sResolution == RESOLUTION_N64)
+ ? SCREEN_HEIGHT
+ : (windowHeight / djui_gfx_get_scale());
+}
+
+f32 djui_gfx_measure_text(const char* message) {
+ if (message == NULL) { return 0; }
+ const struct DjuiFont* font = gDjuiFonts[sFont];
+ f32 width = 0;
+ const char* c = message;
+ while(*c != '\0') {
+ width += font->char_width(*c);
+ c++;
+ }
+ return width * font->defaultFontScale;
+}
+
+void djui_gfx_print_text(const char* message, float x, float y, float scale) {
+ if (message == NULL) { return; }
+ const struct DjuiFont* font = gDjuiFonts[sFont];
+ f32 fontScale = font->defaultFontScale * scale;
+
+ // setup display list
+ if (font->textBeginDisplayList != NULL) {
+ gSPDisplayList(gDisplayListHead++, font->textBeginDisplayList);
+ }
+
+ // translate position
+ f32 translatedX = x;
+ f32 translatedY = y;
+ if (sResolution == RESOLUTION_DJUI) {
+ djui_gfx_position_translate(&translatedX, &translatedY);
+ } else if (sResolution == RESOLUTION_N64) {
+ translatedX = GFX_DIMENSIONS_FROM_LEFT_EDGE(0) + x;
+ translatedY = SCREEN_HEIGHT - y;
+ }
+ create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
+
+ // compute font size
+ f32 translatedFontSize = fontScale;
+ if (sResolution == RESOLUTION_DJUI) {
+ djui_gfx_size_translate(&translatedFontSize);
+ }
+ create_dl_scale_matrix(DJUI_MTX_NOPUSH, translatedFontSize, translatedFontSize, 1.0f);
+
+ // render the line
+ f32 addX = 0;
+ size_t length = strlen(message);
+ for (size_t i = 0; i < length; i++) {
+ char c = message[i];
+ f32 charWidth = font->char_width(c);
+
+ if (c == '\n' && c == ' ') {
+ addX += charWidth;
+ continue;
+ }
+
+ // render
+ font->render_char(c);
+ create_dl_translation_matrix(DJUI_MTX_NOPUSH, charWidth + addX, 0, 0);
+ addX = 0;
+ }
+
+ // pop
+ gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
+}
+
+void djui_gfx_utils_render(void) {
+ //struct DjuiColor fore = { .r = 255, .g = 255, .b = 255, .a = 255 };
+ //struct DjuiColor back = { .r = 0, .g = 0, .b = 0, .a = 255 };
+ //const struct DjuiFont* font = gDjuiFonts[2];
+ //djui_gfx_print_text(font, "abcdefghijklmnopqrstuvwxyz:1234567890", 2, 2, 2, back);
+ //djui_gfx_print_text(font, "1234567890:abcdefghijklmnopqrstuvwxyz", 0, 0, 2, fore);
+ //float scale = 240.0f / gfx_current_dimensions.height;
+
+ /*{
+ f32 screenWidth = djui_gfx_get_screen_width(RESOLUTION_N64);
+ f32 width = djui_gfx_measure_text(font, "PAUSE", RESOLUTION_N64);
+
+ f32 screenHeight = djui_gfx_get_screen_height(RESOLUTION_N64);
+ f32 height = 16;
+
+ djui_gfx_print_text(font, "PAUSE", screenWidth - width, screenHeight - height - 32, 1.0f, fore, RESOLUTION_N64);
+ djui_gfx_print_text(font, "PAUSE", screenWidth - width * 2, screenHeight - height, 1.0f, fore, RESOLUTION_N64);
+ }*/
+
+ /*{
+ f32 screenWidth = djui_gfx_get_screen_width(RESOLUTION_DJUI);
+ f32 width = djui_gfx_measure_text(font, "PAUSE", RESOLUTION_DJUI);
+
+ f32 screenHeight = djui_gfx_get_screen_height(RESOLUTION_DJUI);
+ f32 height = 16;
+
+ djui_gfx_print_text(FONT_NORMAL, "PAUSE", screenWidth - width, screenHeight - height - 32, 1.0f, fore, RESOLUTION_DJUI);
+ djui_gfx_print_text(FONT_NORMAL, "PAUSE", screenWidth - width * 2, screenHeight - height, 1.0f, fore, RESOLUTION_DJUI);
+ }*/
+}
\ No newline at end of file
diff --git a/src/pc/djui/djui_gfx_utils.h b/src/pc/djui/djui_gfx_utils.h
new file mode 100644
index 00000000..56e8cefc
--- /dev/null
+++ b/src/pc/djui/djui_gfx_utils.h
@@ -0,0 +1,27 @@
+#ifndef DJUI_GFX_UTILS_H
+#define DJUI_GFX_UTILS_H
+
+enum GfxUtilsResolution {
+ RESOLUTION_DJUI,
+ RESOLUTION_N64,
+ RESOLUTION_COUNT,
+};
+
+enum DjuiFontType {
+ FONT_NORMAL,
+ FONT_MENU,
+ FONT_HUD,
+ FONT_COUNT,
+};
+
+void djui_gfx_set_resolution(enum GfxUtilsResolution resolutionType);
+void djui_gfx_set_font(enum DjuiFontType fontType);
+void djui_gfx_set_color(u8 r, u8 g, u8 b, u8 a);
+
+u32 djui_gfx_get_screen_width(void);
+u32 djui_gfx_get_screen_height(void);
+
+f32 djui_gfx_measure_text(const char* message);
+void djui_gfx_print_text(const char* message, float x, float y, float scale);
+
+#endif
\ No newline at end of file
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index 4c9d439f..031877ea 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -19,6 +19,7 @@
#include "src/game/level_info.h"
#include "src/game/save_file.h"
#include "src/game/sound_init.h"
+#include "src/pc/djui/djui_gfx_utils.h"
//////////////
// camera.h //
@@ -203,6 +204,95 @@ int smlua_func_djui_chat_message_create(lua_State* L) {
return 1;
}
+ //////////////////////
+ // djui_gfx_utils.h //
+//////////////////////
+
+int smlua_func_djui_gfx_get_screen_height(UNUSED lua_State* L) {
+ if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
+
+
+ lua_pushinteger(L, djui_gfx_get_screen_height());
+
+ return 1;
+}
+
+int smlua_func_djui_gfx_get_screen_width(UNUSED lua_State* L) {
+ if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
+
+
+ lua_pushinteger(L, djui_gfx_get_screen_width());
+
+ return 1;
+}
+
+int smlua_func_djui_gfx_measure_text(lua_State* L) {
+ if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
+
+ const char* message = smlua_to_string(L, 1);
+ if (!gSmLuaConvertSuccess) { return 0; }
+
+ lua_pushnumber(L, djui_gfx_measure_text(message));
+
+ return 1;
+}
+
+int smlua_func_djui_gfx_print_text(lua_State* L) {
+ if(!smlua_functions_valid_param_count(L, 4)) { return 0; }
+
+ const char* message = smlua_to_string(L, 1);
+ if (!gSmLuaConvertSuccess) { return 0; }
+ float x = smlua_to_number(L, 2);
+ if (!gSmLuaConvertSuccess) { return 0; }
+ float y = smlua_to_number(L, 3);
+ if (!gSmLuaConvertSuccess) { return 0; }
+ float scale = smlua_to_number(L, 4);
+ if (!gSmLuaConvertSuccess) { return 0; }
+
+ djui_gfx_print_text(message, x, y, scale);
+
+ return 1;
+}
+
+int smlua_func_djui_gfx_set_color(lua_State* L) {
+ if(!smlua_functions_valid_param_count(L, 4)) { return 0; }
+
+ u8 r = smlua_to_integer(L, 1);
+ if (!gSmLuaConvertSuccess) { return 0; }
+ u8 g = smlua_to_integer(L, 2);
+ if (!gSmLuaConvertSuccess) { return 0; }
+ u8 b = smlua_to_integer(L, 3);
+ if (!gSmLuaConvertSuccess) { return 0; }
+ u8 a = smlua_to_integer(L, 4);
+ if (!gSmLuaConvertSuccess) { return 0; }
+
+ djui_gfx_set_color(r, g, b, a);
+
+ return 1;
+}
+
+int smlua_func_djui_gfx_set_font(lua_State* L) {
+ if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
+
+ int fontType = smlua_to_integer(L, 1);
+ if (!gSmLuaConvertSuccess) { return 0; }
+
+ djui_gfx_set_font(fontType);
+
+ return 1;
+}
+
+int smlua_func_djui_gfx_set_resolution(lua_State* L) {
+ if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
+
+ int resolutionType = smlua_to_integer(L, 1);
+ if (!gSmLuaConvertSuccess) { return 0; }
+
+ djui_gfx_set_resolution(resolutionType);
+
+ return 1;
+}
+
//////////////////
// djui_popup.h //
//////////////////
@@ -3406,6 +3496,15 @@ void smlua_bind_functions_autogen(void) {
// djui_chat_message.h
smlua_bind_function(L, "djui_chat_message_create", smlua_func_djui_chat_message_create);
+ // djui_gfx_utils.h
+ smlua_bind_function(L, "djui_gfx_get_screen_height", smlua_func_djui_gfx_get_screen_height);
+ smlua_bind_function(L, "djui_gfx_get_screen_width", smlua_func_djui_gfx_get_screen_width);
+ smlua_bind_function(L, "djui_gfx_measure_text", smlua_func_djui_gfx_measure_text);
+ smlua_bind_function(L, "djui_gfx_print_text", smlua_func_djui_gfx_print_text);
+ smlua_bind_function(L, "djui_gfx_set_color", smlua_func_djui_gfx_set_color);
+ smlua_bind_function(L, "djui_gfx_set_font", smlua_func_djui_gfx_set_font);
+ smlua_bind_function(L, "djui_gfx_set_resolution", smlua_func_djui_gfx_set_resolution);
+
// djui_popup.h
smlua_bind_function(L, "djui_popup_create", smlua_func_djui_popup_create);
diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h
index 87824e79..33f01543 100644
--- a/src/pc/lua/smlua_hooks.h
+++ b/src/pc/lua/smlua_hooks.h
@@ -12,6 +12,7 @@ enum LuaHookedEventType {
HOOK_ON_PVP_ATTACK,
HOOK_ON_PLAYER_CONNECTED,
HOOK_ON_PLAYER_DISCONNECTED,
+ HOOK_ON_HUD_RENDER,
HOOK_MAX,
};
@@ -24,6 +25,7 @@ static char* LuaHookedEventTypeName[] = {
"HOOK_ON_PVP_ATTACK",
"HOOK_ON_PLAYER_CONNECTED",
"HOOK_ON_PLAYER_DISCONNECTED",
+ "HOOK_ON_HUD_RENDER",
"HOOK_MAX"
};