Added text rendering to Lua API

This commit is contained in:
MysterD 2022-02-15 22:08:01 -08:00
parent a8b0f9db68
commit 7dd18aaa2a
9 changed files with 501 additions and 1 deletions

View File

@ -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()
main()

View File

@ -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]

View File

@ -26,6 +26,17 @@
<br />
- 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)
<br />
- djui_popup.h
- [djui_popup_create](#djui_popup_create)
@ -611,6 +622,154 @@
<br />
---
# functions from djui_gfx_utils.h
<br />
## [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:](#)
<br />
## [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:](#)
<br />
## [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:](#)
<br />
## [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:](#)
<br />
## [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:](#)
<br />
## [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:](#)
<br />
## [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:](#)
<br />
---
# functions from djui_popup.h

View File

@ -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();

View File

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

View File

@ -0,0 +1,140 @@
#include <stdio.h>
#include <PR/ultratypes.h>
#include <PR/gbi.h>
#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);
}*/
}

View File

@ -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

View File

@ -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);

View File

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