From bdb8f11eab8b49a61b142aede4a39c9bdd53e87b Mon Sep 17 00:00:00 2001 From: Agent X <44549182+Agent-11@users.noreply.github.com> Date: Sun, 17 Dec 2023 21:36:24 -0500 Subject: [PATCH] Bring back base FONT_NORMAL as FONT_ALIASED FONT_NORMAL is the same as FONT_TINY, except with a different scale to match mods that use FONT_NORMAL --- autogen/lua_definitions/constants.lua | 5 ++- bin/custom_font.c | 23 ++++++++++++ docs/lua/constants.md | 3 +- src/pc/djui/djui_font.c | 33 ++++++++++++++++++ src/pc/djui/djui_hud_utils.h | 1 + src/pc/lua/smlua_constants_autogen.c | 3 +- .../custom_font_aliased.rgba32.png | Bin 0 -> 11256 bytes 7 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 textures/custom_font/custom_font_aliased.rgba32.png diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index d5399647..46d64ef7 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -3465,7 +3465,10 @@ FONT_HUD = 2 FONT_TINY = 3 --- @type DjuiFontType -FONT_COUNT = 4 +FONT_ALIASED = 4 + +--- @type DjuiFontType +FONT_COUNT = 5 --- @class HudUtilsFilter diff --git a/bin/custom_font.c b/bin/custom_font.c index 120af938..f4e2afce 100644 --- a/bin/custom_font.c +++ b/bin/custom_font.c @@ -49,3 +49,26 @@ const f32 font_title_widths[] = { }; ////////////////////////////////////////////////////////// + +ALIGNED8 const u8 texture_font_aliased[] = { +#include "textures/custom_font/custom_font_aliased.rgba32.inc.c" +}; + +const f32 font_aliased_widths[] = { +/* ! " # $ % & ' ( ) * + , - . / */ + 7, 12, 14, 12, 14, 16, 8, 10, 10, 12, 14, 8, 12, 8, 10, +/* 0 1 2 3 4 5 6 7 8 9 */ + 14, 12, 13, 14, 14, 14, 14, 13, 14, 14, +/* : ; < = > ? @ */ + 6, 8, 10, 12, 10, 11, 18, +/* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */ + 12, 12, 12, 12, 11, 10, 12, 12, 9, 12, 12, 10, 16, 16, 12, 11, 12, 12, 12, 10, 12, 10, 16, 14, 12, 12, +/* [ \ ] ^ _ ` */ + 10, 10, 10, 12, 12, 8, +/* a b c d e f g h i j k l m n o p q r s t u v w x y z */ + 10, 10, 10, 10, 9, 8, 12, 10, 7, 9, 10, 4, 13, 10, 9, 9, 10, 9, 10, 9, 10, 9, 14, 12, 10, 10, +/* { | } ~ DEL */ + 10, 8, 10, 16, 10, +}; + +////////////////////////////////////////////////////////// diff --git a/docs/lua/constants.md b/docs/lua/constants.md index e5406a27..09b377ff 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -1170,7 +1170,8 @@ | FONT_MENU | 1 | | FONT_HUD | 2 | | FONT_TINY | 3 | -| FONT_COUNT | 4 | +| FONT_ALIASED | 4 | +| FONT_COUNT | 5 | ### [enum HudUtilsFilter](#HudUtilsFilter) | Identifier | Value | diff --git a/src/pc/djui/djui_font.c b/src/pc/djui/djui_font.c index 6b75896c..18000524 100644 --- a/src/pc/djui/djui_font.c +++ b/src/pc/djui/djui_font.c @@ -147,6 +147,38 @@ static const struct DjuiFont sDjuiFontTiny = { .char_width = djui_font_normal_char_width, }; + //////////////////////////////// + // font 5 (DJ's aliased font) // +//////////////////////////////// + +static void djui_font_aliased_render_char(char* c) { + // replace undisplayable characters + if (*c == ' ') { return; } + + u32 index = djui_unicode_get_sprite_index(c); + u32 tx = index % 32; + u32 ty = index / 32; + + extern ALIGNED8 const u8 texture_font_aliased[]; + djui_gfx_render_texture_tile(texture_font_aliased, 512, 256, 32, tx * 16, ty * 32, 16, 32, false); +} + +static f32 djui_font_aliased_char_width(char* c) { + if (*c == ' ') { return 6 / 32.0f; } + extern const f32 font_aliased_widths[]; + return djui_unicode_get_sprite_width(c, font_aliased_widths) / 32.0f; +} + +static const struct DjuiFont sDjuiFontAliased = { + .charWidth = 0.5f, + .charHeight = 1.0f, + .lineHeight = 0.8125f, + .defaultFontScale = 32.0f, + .textBeginDisplayList = NULL, + .render_char = djui_font_aliased_render_char, + .char_width = djui_font_aliased_char_width, +}; + /////////////// // font list // /////////////// @@ -156,4 +188,5 @@ const struct DjuiFont* gDjuiFonts[] = { &sDjuiFontTitle, &sDjuiFontHud, &sDjuiFontTiny, + &sDjuiFontAliased }; \ No newline at end of file diff --git a/src/pc/djui/djui_hud_utils.h b/src/pc/djui/djui_hud_utils.h index e81ddce4..60403e00 100644 --- a/src/pc/djui/djui_hud_utils.h +++ b/src/pc/djui/djui_hud_utils.h @@ -18,6 +18,7 @@ enum DjuiFontType { FONT_MENU, FONT_HUD, FONT_TINY, + FONT_ALIASED, FONT_COUNT, }; diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index 1e29b1c4..902e3d83 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -1372,7 +1372,8 @@ char gSmluaConstants[] = "" "FONT_MENU = 1\n" "FONT_HUD = 2\n" "FONT_TINY = 3\n" -"FONT_COUNT = 4\n" +"FONT_ALIASED = 4\n" +"FONT_COUNT = 5\n" "ENVFX_MODE_NONE = 0\n" "ENVFX_SNOW_NORMAL = 1\n" "ENVFX_SNOW_WATER = 2\n" diff --git a/textures/custom_font/custom_font_aliased.rgba32.png b/textures/custom_font/custom_font_aliased.rgba32.png new file mode 100644 index 0000000000000000000000000000000000000000..fa02a747ebb1e31c1f4665a3d10be42194988507 GIT binary patch literal 11256 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