From 6e1dca996cc9bbbadc6435558b570988dfe514aa Mon Sep 17 00:00:00 2001 From: jonko0493 Date: Tue, 20 May 2025 12:43:36 -0700 Subject: [PATCH] rich text: Allow the number of fonts to be specified dynamically --- examples/text/font_from_nitrofs/source/main.c | 28 +++++----- examples/text/font_from_ram/source/main.c | 28 +++++----- include/NERichText.h | 13 ++++- source/NERichText.c | 53 ++++++++++++++----- 4 files changed, 76 insertions(+), 46 deletions(-) diff --git a/examples/text/font_from_nitrofs/source/main.c b/examples/text/font_from_nitrofs/source/main.c index 1bab517..b211bb3 100644 --- a/examples/text/font_from_nitrofs/source/main.c +++ b/examples/text/font_from_nitrofs/source/main.c @@ -20,9 +20,9 @@ void Draw3DScene1(void *arg) NE_2DViewInit(); - NE_RichTextRender3D(3, "VAWATa\ntajl", 0, 0); + NE_RichTextRender3D(1, "VAWATa\ntajl", 0, 0); - NE_RichTextRender3DAlpha(2, "Text with alpha", 10, 80, + NE_RichTextRender3DAlpha(0, "Text with alpha", 10, 80, POLY_ALPHA(20) | POLY_CULL_BACK, 30); } @@ -70,28 +70,28 @@ int main(int argc, char *argv[]) // Load a 16-color font to be used for rendering text as quads - NE_RichTextInit(2); - NE_RichTextMetadataLoadFAT(2, "fonts/font.fnt"); - NE_RichTextMaterialLoadGRF(2, "fonts/font_16_png.grf"); + NE_RichTextInit(0); + NE_RichTextMetadataLoadFAT(0, "fonts/font.fnt"); + NE_RichTextMaterialLoadGRF(0, "fonts/font_16_png.grf"); // Load a 256-color font to be used for rendering text as quads - NE_RichTextInit(3); - NE_RichTextMetadataLoadFAT(3, "fonts/font.fnt"); - NE_RichTextMaterialLoadGRF(3, "fonts/font_256_png.grf"); + NE_RichTextInit(1); + NE_RichTextMetadataLoadFAT(1, "fonts/font.fnt"); + NE_RichTextMaterialLoadGRF(1, "fonts/font_256_png.grf"); // Load a 16-color font to be used for rendering text to textures. - NE_RichTextInit(5); - NE_RichTextMetadataLoadFAT(5, "fonts/font.fnt"); - NE_RichTextBitmapLoadGRF(5, "fonts/font_16_png.grf"); + NE_RichTextInit(2); + NE_RichTextMetadataLoadFAT(2, "fonts/font.fnt"); + NE_RichTextBitmapLoadGRF(2, "fonts/font_16_png.grf"); // Render text to a texture using the last font we've loaded // We don't care about managing the palette. Passing NULL will tell Nitro // Engine to delete the palete automatically when the material is deleted. NE_Material *Material = NULL; - NE_RichTextRenderMaterial(5, + NE_RichTextRenderMaterial(2, "Sample: AWAV.\nÿ_ßðñÑü(o´Áá)|\nInvalid char: ŋ", &Material, NULL); @@ -114,9 +114,7 @@ int main(int argc, char *argv[]) NE_SpriteDelete(Scene.TextSprite); NE_MaterialDelete(Material); - NE_RichTextEnd(2); - NE_RichTextEnd(3); - NE_RichTextEnd(5); + NE_RichTextResetSystem(); return 0; } diff --git a/examples/text/font_from_ram/source/main.c b/examples/text/font_from_ram/source/main.c index 26df444..39e41f4 100644 --- a/examples/text/font_from_ram/source/main.c +++ b/examples/text/font_from_ram/source/main.c @@ -23,9 +23,9 @@ void Draw3DScene(void *arg) NE_2DViewInit(); - NE_RichTextRender3D(3, "VAWATa\ntajl", 0, 0); + NE_RichTextRender3D(1, "VAWATa\ntajl", 0, 0); - NE_RichTextRender3DAlpha(2, "Text with alpha", 10, 80, + NE_RichTextRender3DAlpha(0, "Text with alpha", 10, 80, POLY_ALPHA(20) | POLY_CULL_BACK, 30); } @@ -55,8 +55,8 @@ int main(int argc, char *argv[]) // Load a 16-color font to be used for rendering text as quads - NE_RichTextInit(2); - NE_RichTextMetadataLoadMemory(2, font_fnt_bin, font_fnt_bin_size); + NE_RichTextInit(0); + NE_RichTextMetadataLoadMemory(0, font_fnt_bin, font_fnt_bin_size); { NE_Material *Font16 = NE_MaterialCreate(); @@ -71,13 +71,13 @@ int main(int argc, char *argv[]) // The material and palette will be deleted when the rich text font is // deleted. - NE_RichTextMaterialSet(2, Font16, Pal16); + NE_RichTextMaterialSet(0, Font16, Pal16); } // Load a 256-color font to be used for rendering text as quads - NE_RichTextInit(3); - NE_RichTextMetadataLoadMemory(3, font_fnt_bin, font_fnt_bin_size); + NE_RichTextInit(1); + NE_RichTextMetadataLoadMemory(1, font_fnt_bin, font_fnt_bin_size); { NE_Material *Font256 = NE_MaterialCreate(); @@ -92,14 +92,14 @@ int main(int argc, char *argv[]) // The material and palette will be deleted when the rich text font is // deleted. - NE_RichTextMaterialSet(3, Font256, Pal256); + NE_RichTextMaterialSet(1, Font256, Pal256); } // Load a 16-color font to be used for rendering text to textures. - NE_RichTextInit(5); - NE_RichTextMetadataLoadMemory(5, font_fnt_bin, font_fnt_bin_size); - NE_RichTextBitmapSet(5, font_16Bitmap, 256, 256, NE_PAL16, + NE_RichTextInit(2); + NE_RichTextMetadataLoadMemory(2, font_fnt_bin, font_fnt_bin_size); + NE_RichTextBitmapSet(2, font_16Bitmap, 256, 256, NE_PAL16, font_16Pal, font_16PalLen); // Render text to a texture using the last font we've loaded @@ -107,7 +107,7 @@ int main(int argc, char *argv[]) // We don't care about managing the palette. Passing NULL will tell Nitro // Engine to delete the palete automatically when the material is deleted. NE_Material *Material = NULL; - NE_RichTextRenderMaterial(5, + NE_RichTextRenderMaterial(2, "Sample: AWAV.\nÿ_ßðñÑü(o´Áá)|\nInvalid char: ŋ", &Material, NULL); @@ -130,9 +130,7 @@ int main(int argc, char *argv[]) NE_SpriteDelete(Scene.TextSprite); NE_MaterialDelete(Material); - NE_RichTextEnd(2); - NE_RichTextEnd(3); - NE_RichTextEnd(5); + NE_RichTextResetSystem(); return 0; } diff --git a/include/NERichText.h b/include/NERichText.h index fde0b2a..b08b54b 100644 --- a/include/NERichText.h +++ b/include/NERichText.h @@ -34,7 +34,8 @@ /// /// @{ -#define NE_MAX_RICH_TEXT_FONTS 8 ///< Default max number of rich text fonts +#define NE_DEFAULT_RICH_TEXT_FONTS 8 ///< Default max number of rich text fonts +#define NE_MAX_RICH_TEXT_FONTS NE_DEFAULT_RICH_TEXT_FONTS ///< Deprecated and unused, left for compatibility /// Change the priority of rich text drawn after this function call. /// @@ -44,12 +45,20 @@ void NE_RichTextPrioritySet(int priority); /// Set to 0 the priority of rich text drawn after this function call. void NE_RichTextPriorityReset(void); +/// Initializes the rich text system with the specified number of slots. +/// +/// This must be called before initializing any rich text slots. +/// +/// @param numSlots The number of rich text slots to allocate. +/// @return Returns 1 on success, 0 on failure. +int NE_RichTextStartSystem(u32 numSlots); + /// Clears all rich text font slots. void NE_RichTextResetSystem(void); /// Initialize a rich text slot. /// -/// @param slot The slot to initialize (from 0 to NE_MAX_RICH_TEXT_FONTS). +/// @param slot The slot to initialize (from 0 to the number of slots specified in NE_RichTextSystemStart). void NE_RichTextInit(u32 slot); /// End a rich text slot and free all the resources used by it. diff --git a/source/NERichText.c b/source/NERichText.c index 3ff33b6..54e6420 100644 --- a/source/NERichText.c +++ b/source/NERichText.c @@ -29,7 +29,9 @@ typedef struct { bool active; } ne_rich_textinfo_t; -static ne_rich_textinfo_t NE_RichTextInfo[NE_MAX_RICH_TEXT_FONTS]; +static u32 NE_NumRichTextSlots = 0; + +static ne_rich_textinfo_t *NE_RichTextInfo; static int NE_RICH_TEXT_PRIORITY = 0; @@ -45,8 +47,17 @@ void NE_RichTextPriorityReset(void) void NE_RichTextInit(u32 slot) { - if (slot >= NE_MAX_RICH_TEXT_FONTS) + // Compatibility mode -- if someone tries to allocate a slot + // without having called start system, we allocate the old maximum + // number of slots for safety + if (NE_NumRichTextSlots == 0) + NE_RichTextStartSystem(NE_DEFAULT_RICH_TEXT_FONTS); + + if (slot >= NE_NumRichTextSlots) + { + NE_DebugPrint("Attempted to initialize a slot greater than the number of slots allocated; skipping"); return; + } ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; if (info->active) @@ -60,7 +71,7 @@ void NE_RichTextInit(u32 slot) int NE_RichTextEnd(u32 slot) { - if (slot >= NE_MAX_RICH_TEXT_FONTS) + if (slot >= NE_NumRichTextSlots) return 0; ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; @@ -97,17 +108,31 @@ int NE_RichTextEnd(u32 slot) return 1; } +int NE_RichTextStartSystem(u32 numSlots) +{ + NE_NumRichTextSlots = numSlots; + NE_RichTextInfo = calloc(sizeof(ne_rich_textinfo_t), NE_NumRichTextSlots); + if (NE_RichTextInfo == NULL) + { + NE_DebugPrint("Failed to allocate array for NE_RichTextInfo"); + return 0; + } + return 1; +} + void NE_RichTextResetSystem(void) { - for (int i = 0; i < NE_MAX_RICH_TEXT_FONTS; i++) + for (int i = 0; i < NE_NumRichTextSlots; i++) NE_RichTextEnd(i); + free(NE_RichTextInfo); + NE_NumRichTextSlots = 0; } int NE_RichTextMetadataLoadFAT(u32 slot, const char *path) { NE_AssertPointer(path, "NULL path pointer"); - if (slot >= NE_MAX_RICH_TEXT_FONTS) + if (slot >= NE_NumRichTextSlots) return 0; ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; @@ -131,7 +156,7 @@ int NE_RichTextMetadataLoadMemory(u32 slot, const void *data, size_t data_size) { NE_AssertPointer(data, "NULL data pointer"); - if (slot >= NE_MAX_RICH_TEXT_FONTS) + if (slot >= NE_NumRichTextSlots) return 0; ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; @@ -155,7 +180,7 @@ int NE_RichTextMaterialLoadGRF(u32 slot, const char *path) { NE_AssertPointer(path, "NULL path pointer"); - if (slot >= NE_MAX_RICH_TEXT_FONTS) + if (slot >= NE_NumRichTextSlots) return 0; ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; @@ -181,7 +206,7 @@ int NE_RichTextMaterialSet(u32 slot, NE_Material *mat, NE_Palette *pal) { NE_AssertPointer(mat, "NULL material pointer"); - if (slot >= NE_MAX_RICH_TEXT_FONTS) + if (slot >= NE_NumRichTextSlots) return 0; ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; @@ -204,7 +229,7 @@ int NE_RichTextBitmapLoadGRF(u32 slot, const char *path) #else // NE_BLOCKSDS NE_AssertPointer(path, "NULL path pointer"); - if (slot >= NE_MAX_RICH_TEXT_FONTS) + if (slot >= NE_NumRichTextSlots) return 0; ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; @@ -307,7 +332,7 @@ int NE_RichTextBitmapSet(u32 slot, const void *texture_buffer, NE_AssertPointer(texture_buffer, "NULL texture pointer"); NE_AssertPointer(palette_buffer, "NULL palette pointer"); - if (slot >= NE_MAX_RICH_TEXT_FONTS) + if (slot >= NE_NumRichTextSlots) return 0; ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; @@ -341,7 +366,7 @@ int NE_RichTextRenderDryRun(u32 slot, const char *str, NE_AssertPointer(size_x, "NULL size X pointer"); NE_AssertPointer(size_y, "NULL size Y pointer"); - if (slot >= NE_MAX_RICH_TEXT_FONTS) + if (slot >= NE_NumRichTextSlots) return 0; ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; @@ -360,7 +385,7 @@ int NE_RichTextRender3D(u32 slot, const char *str, s32 x, s32 y) { NE_AssertPointer(str, "NULL str pointer"); - if (slot >= NE_MAX_RICH_TEXT_FONTS) + if (slot >= NE_NumRichTextSlots) return 0; ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; @@ -382,7 +407,7 @@ int NE_RichTextRender3DAlpha(u32 slot, const char *str, s32 x, s32 y, { NE_AssertPointer(str, "NULL str pointer"); - if (slot >= NE_MAX_RICH_TEXT_FONTS) + if (slot >= NE_NumRichTextSlots) return 0; ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; @@ -407,7 +432,7 @@ int NE_RichTextRenderMaterial(u32 slot, const char *str, NE_Material **mat, NE_AssertPointer(mat, "NULL mat pointer"); NE_AssertPointer(pal, "NULL pal pointer"); - if (slot >= NE_MAX_RICH_TEXT_FONTS) + if (slot >= NE_NumRichTextSlots) return 0; ne_rich_textinfo_t *info = &NE_RichTextInfo[slot];