diff --git a/include/NERichText.h b/include/NERichText.h index b08b54b..ad04cc2 100644 --- a/include/NERichText.h +++ b/include/NERichText.h @@ -166,6 +166,19 @@ int NE_RichTextBitmapSet(u32 slot, const void *texture_buffer, NE_TextureFormat texture_fmt, const void *palette_buffer, size_t palette_size); +/// Calculates the final size and cursor position of rendering the provided string. +///More actions +/// @param slot The slot to use. +/// @param str The string to render. +/// @param size_x Pointer to store the width of the resulting image. +/// @param size_y Pointer to store the height of the resulting image. +/// @param final_x Pointer to store the final X position of the cursor. +/// @param final_y Pointer to store the final Y position of the cursor. +/// @return Returns 1 on success, 0 on failure. +int NE_RichTextRenderDryRunWithPos(u32 slot, const char *str, + size_t *size_x, size_t *size_y, + size_t *final_x, size_t *final_y); + /// Calculates the final size of rendering the provided string. /// /// @param slot The slot to use. @@ -176,6 +189,19 @@ int NE_RichTextBitmapSet(u32 slot, const void *texture_buffer, int NE_RichTextRenderDryRun(u32 slot, const char *str, size_t *size_x, size_t *size_y); +/// Render a string by rendering one 3D quad per codepoint. +/// +/// This preserves the polygon format that is currently active. +/// +/// @param slot The slot to use. +/// @param str The string to render. +/// @param x The left coordinate of the text. +/// @param y The top coordinate of the text. +/// @param xIndent The horizontal indentation to apply to the first line of text. +/// @return Returns 1 on success, 0 on failure. +int NE_RichTextRender3DWithIndent(u32 slot, const char *str, s32 x, s32 y, + s32 xIndent); + /// Render a string by rendering one 3D quad per codepoint. /// /// This preserves the polygon format that is currently active. @@ -187,6 +213,48 @@ int NE_RichTextRenderDryRun(u32 slot, const char *str, /// @return Returns 1 on success, 0 on failure. int NE_RichTextRender3D(u32 slot, const char *str, s32 x, s32 y); +/// Render a string by rendering one 3D quad per codepoint.More actions +/// +/// This preserves the polygon format that is currently active. +/// +/// @param slot The slot to use. +/// @param str The string to render. +/// @param x The left coordinate of the text. +/// @param y The top coordinate of the text. +/// @param xIndent The horizontal indentation to apply to the first line of text. +/// @return Returns 1 on success, 0 on failure. +int NE_RichTextRender3DWithIndent(u32 slot, const char *str, s32 x, s32 y, + s32 xIndent); + +/// Render a string by rendering one 3D quad per codepoint. +/// +/// This preserves the polygon format that is currently active. +/// @return Returns 1 on success, 0 on failure. +int NE_RichTextRender3D(u32 slot, const char *str, s32 x, s32 y); + +/// Render a string by rendering one 3D quad per codepoint with alternating +/// polygon IDs. +/// +/// This function will alternate between polygon IDs so that alpha blending +/// works between multiple polygons when they overlap. This is a requirement of +/// the NDS 3D hardware. +/// +/// It is required to pass the base polygon format as a parameter because the +/// polygon format data is write-only. Whenever the polygon ID needs to be +/// changed, the rest of the polygon format flags need to be set as well. +/// +/// @param slot The slot to use. +/// @param str The string to render. +/// @param x The left coordinate of the text. +/// @param y The top coordinate of the text. +/// @param poly_fmt The polygon format values to be used for the quads. +/// @param poly_id_base The base polygon ID to use for the quads. +/// @param xIndent The horizontal indentation to apply to the first line of text. +/// @return Returns 1 on success, 0 on failure. +int NE_RichTextRender3DAlphaWithIndent(u32 slot, const char *str, s32 x, s32 y, + uint32_t poly_fmt, int poly_id_base, + s32 xIndent); + /// Render a string by rendering one 3D quad per codepoint with alternating /// polygon IDs. /// diff --git a/source/NERichText.c b/source/NERichText.c index 54e6420..5a1a79b 100644 --- a/source/NERichText.c +++ b/source/NERichText.c @@ -359,12 +359,15 @@ int NE_RichTextBitmapSet(u32 slot, const void *texture_buffer, return 1; } -int NE_RichTextRenderDryRun(u32 slot, const char *str, - size_t *size_x, size_t *size_y) +int NE_RichTextRenderDryRunWithPos(u32 slot, const char *str, + size_t *size_x, size_t *size_y, + size_t *final_x, size_t *final_y) { NE_AssertPointer(str, "NULL str pointer"); NE_AssertPointer(size_x, "NULL size X pointer"); NE_AssertPointer(size_y, "NULL size Y pointer"); + NE_AssertPointer(final_x, "NULL final X pointer"); + NE_AssertPointer(final_y, "NULL final Y pointer"); if (slot >= NE_NumRichTextSlots) return 0; @@ -373,15 +376,24 @@ int NE_RichTextRenderDryRun(u32 slot, const char *str, if (!info->active) return 0; - dsf_error err = DSF_StringRenderDryRun(info->handle, str, - size_x, size_y); + dsf_error err = DSF_StringRenderDryRunWithCursor(info->handle, str, + size_x, size_y, + final_x, final_y); if (err != DSF_NO_ERROR) return 0; return 1; } -int NE_RichTextRender3D(u32 slot, const char *str, s32 x, s32 y) +int NE_RichTextRenderDryRun(u32 slot, const char *str, + size_t *size_x, size_t *size_y) +{ + size_t final_x, final_y; + return NE_RichTextRenderDryRunWithPos(slot, str, size_x, size_y, &final_x, &final_y); +} + +int NE_RichTextRender3DWithIndent(u32 slot, const char *str, s32 x, s32 y, + s32 xIndent) { NE_AssertPointer(str, "NULL str pointer"); @@ -394,8 +406,37 @@ int NE_RichTextRender3D(u32 slot, const char *str, s32 x, s32 y) NE_MaterialUse(info->material); - dsf_error err = DSF_StringRender3D(info->handle, str, x, y, - NE_RICH_TEXT_PRIORITY); + dsf_error err = DSF_StringRender3DWithIndent(info->handle, str, x, y, + NE_RICH_TEXT_PRIORITY, xIndent); + if (err != DSF_NO_ERROR) + return 0; + + return 1; +} + +int NE_RichTextRender3D(u32 slot, const char *str, s32 x, s32 y) +{ + return NE_RichTextRender3DWithIndent(slot, str, x, y, 0); +} + +int NE_RichTextRender3DAlphaWithIndent(u32 slot, const char *str, s32 x, s32 y, + uint32_t poly_fmt, int poly_id_base, + s32 xIndent) +{ + NE_AssertPointer(str, "NULL str pointer"); + + if (slot >= NE_NumRichTextSlots) + return 0; + + ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; + if (!info->active) + return 0; + + NE_MaterialUse(info->material); + + dsf_error err = DSF_StringRender3DAlphaWithIndent(info->handle, str, x, y, + NE_RICH_TEXT_PRIORITY, + poly_fmt, poly_id_base, xIndent); if (err != DSF_NO_ERROR) return 0; @@ -405,24 +446,7 @@ int NE_RichTextRender3D(u32 slot, const char *str, s32 x, s32 y) int NE_RichTextRender3DAlpha(u32 slot, const char *str, s32 x, s32 y, uint32_t poly_fmt, int poly_id_base) { - NE_AssertPointer(str, "NULL str pointer"); - - if (slot >= NE_NumRichTextSlots) - return 0; - - ne_rich_textinfo_t *info = &NE_RichTextInfo[slot]; - if (!info->active) - return 0; - - NE_MaterialUse(info->material); - - dsf_error err = DSF_StringRender3DAlpha(info->handle, str, x, y, - NE_RICH_TEXT_PRIORITY, - poly_fmt, poly_id_base); - if (err != DSF_NO_ERROR) - return 0; - - return 1; + return NE_RichTextRender3DAlphaWithIndent(slot, str, x, y, poly_fmt, poly_id_base, 0); } int NE_RichTextRenderMaterial(u32 slot, const char *str, NE_Material **mat, diff --git a/source/libdsf/dsf.c b/source/libdsf/dsf.c index a21efd6..7dc06dc 100644 --- a/source/libdsf/dsf.c +++ b/source/libdsf/dsf.c @@ -537,23 +537,27 @@ static dsf_error DSF_CodepointRender3D(dsf_handle handle, uint32_t codepoint, return DSF_NO_ERROR; } -dsf_error DSF_StringRenderDryRun(dsf_handle handle, const char *str, - size_t *size_x, size_t *size_y) +dsf_error DSF_StringRenderDryRunWithCursor(dsf_handle handle, const char *str, + size_t *size_x, size_t *size_y, + size_t *final_x, size_t *final_y) { - if ((handle == 0) || (str == NULL) || (size_x == NULL) || (size_y == NULL)) + if ((handle == 0) || (str == NULL) || (size_x == NULL) || (size_y == NULL) || + (final_x == NULL) || (final_y == NULL)) return DSF_INVALID_ARGUMENT; + dsf_font_internal_state *font = (dsf_font_internal_state *)handle; + if (strlen(str) == 0) { *size_x = 0; *size_y = 0; + *final_x = font->pointer_x; + *final_y = font->pointer_y; return DSF_NO_ERROR; } dsf_error ret = DSF_NO_ERROR; - dsf_font_internal_state *font = (dsf_font_internal_state *)handle; - font->pointer_x = 0; font->pointer_y = 0; font->box_left = 0; @@ -587,8 +591,16 @@ dsf_error DSF_StringRenderDryRun(dsf_handle handle, const char *str, return ret; } -dsf_error DSF_StringRender3D(dsf_handle handle, const char *str, - int32_t x, int32_t y, int32_t z) +dsf_error DSF_StringRenderDryRun(dsf_handle handle, const char *str, + size_t *size_x, size_t *size_y) +{ + size_t final_x, final_y; + return DSF_StringRenderDryRunWithCursor(handle, str, size_x, size_y, &final_x, &final_y); +} + +dsf_error DSF_StringRender3DWithIndent(dsf_handle handle, const char *str, + int32_t x, int32_t y, int32_t z, + int32_t xStart) { if ((handle == 0) || (str == NULL)) return DSF_INVALID_ARGUMENT; @@ -597,7 +609,7 @@ dsf_error DSF_StringRender3D(dsf_handle handle, const char *str, dsf_font_internal_state *font = (dsf_font_internal_state *)handle; - font->pointer_x = x; + font->pointer_x = x + xStart; font->pointer_y = y; font->box_left = x; font->box_top = y; @@ -623,9 +635,16 @@ dsf_error DSF_StringRender3D(dsf_handle handle, const char *str, return ret; } -dsf_error DSF_StringRender3DAlpha(dsf_handle handle, const char *str, - int32_t x, int32_t y, int32_t z, - uint32_t poly_fmt, int poly_id_base) +dsf_error DSF_StringRender3D(dsf_handle handle, const char *str, + int32_t x, int32_t y, int32_t z) +{ + return DSF_StringRender3DWithIndent(handle, str, x, y, z, 0); +} + +dsf_error DSF_StringRender3DAlphaWithIndent(dsf_handle handle, const char *str, + int32_t x, int32_t y, int32_t z, + uint32_t poly_fmt, int poly_id_base, + int32_t xStart) { if ((handle == 0) || (str == NULL)) return DSF_INVALID_ARGUMENT; @@ -634,7 +653,7 @@ dsf_error DSF_StringRender3DAlpha(dsf_handle handle, const char *str, dsf_font_internal_state *font = (dsf_font_internal_state *)handle; - font->pointer_x = x; + font->pointer_x = x + xStart; font->pointer_y = y; font->box_left = x; font->box_top = y; @@ -663,6 +682,13 @@ dsf_error DSF_StringRender3DAlpha(dsf_handle handle, const char *str, return ret; } +dsf_error DSF_StringRender3DAlpha(dsf_handle handle, const char *str, + int32_t x, int32_t y, int32_t z, + uint32_t poly_fmt, int poly_id_base) +{ + return DSF_StringRender3DAlphaWithIndent(handle, str, x, y, z, poly_fmt, poly_id_base, 0); +} + static dsf_error DSF_CodepointRenderBuffer(dsf_handle handle, uint32_t codepoint, unsigned int texture_fmt, const void *font_texture, size_t font_width, size_t font_height, diff --git a/source/libdsf/dsf.h b/source/libdsf/dsf.h index 3a97696..2f6d0f5 100644 --- a/source/libdsf/dsf.h +++ b/source/libdsf/dsf.h @@ -93,16 +93,42 @@ dsf_error DSF_FreeFont(dsf_handle *handle); /// @defgroup libdsf_render Functions to draw text strings. /// @{ +/// @param handle Handler of the font to use. +/// @param str String to print. +/// @param size_x Pointer to a variable to store the size. +/// @param size_y Pointer to a variable to store the size. +/// @param final_x Pointer to a variable to store the final X cursor position. +/// @param final_y Pointer to a variable to store the final Y cursor position. +/// +/// @return An error code or DSF_NO_ERROR on success. +dsf_error DSF_StringRenderDryRunWithCursor(dsf_handle handle, const char *str, + size_t *size_x, size_t *size_y, + size_t *final_x, size_t *final_y); + /// Pretend to render a string to calculate its final size once rendered. /// -/// @param handle Handler of the font to use. -/// @param str String to print. -/// @param size_x Pointer to a variable to store the size. -/// @param size_y Pointer to a variable to store the size. +/// @param handle Handler of the font to use. +/// @param str String to print. +/// @param size_x Pointer to a variable to store the size. +/// @param size_y Pointer to a variable to store the size. /// /// @return An error code or DSF_NO_ERROR on success. dsf_error DSF_StringRenderDryRun(dsf_handle handle, const char *str, size_t *size_x, size_t *size_y); + +/// Render a string by rendering one 3D quad per codepoint. +/// +/// @param handle Handler of the font to use. +/// @param str String to print. +/// @param x Top x coordinate (0 to 255, but you can go outside of that). +/// @param y Left y coordinate (0 to 191, but you can go outside of that). +/// @param z Z coordinate (depth). +/// @param xStart The horizontal component of the cursor's starting offset (reset to x on line break) +/// +/// @return An error code or DSF_NO_ERROR on success. +dsf_error DSF_StringRender3DWithIndent(dsf_handle handle, const char *str, + int32_t x, int32_t y, int32_t z, + int32_t xStart); /// Render a string by rendering one 3D quad per codepoint. /// @@ -116,6 +142,32 @@ dsf_error DSF_StringRenderDryRun(dsf_handle handle, const char *str, dsf_error DSF_StringRender3D(dsf_handle handle, const char *str, int32_t x, int32_t y, int32_t z); +/// Render a string by rendering one 3D quad per codepoint with alternating +/// polygon IDs. +/// +/// This function will alternate between polygon IDs so that alpha blending +/// works between multiple polygons when they overlap. This is a requirement of +/// the NDS 3D hardware. +/// +/// It is required to pass the base polygon format as a parameter because the +/// polygon format data is write-only. Whenever the polygon ID needs to be +/// changed, the rest of the polygon format flags need to be set as well. +/// +/// @param handle Handler of the font to use. +/// @param str String to print. +/// @param x Top x coordinate (0 to 255, but you can go outside of that). +/// @param y Left y coordinate (0 to 191, but you can go outside of that). +/// @param z Z coordinate (depth). +/// @param poly_fmt Polygon formats to apply to the characters. +/// @param poly_id_base poly_id_base and poly_id_base + 1 will be used. +/// @param xStart The horizontal component of the cursor's starting offset (reset to x on line break) +/// +/// @return An error code or DSF_NO_ERROR on success. +dsf_error DSF_StringRender3DAlphaWithIndent(dsf_handle handle, const char *str, + int32_t x, int32_t y, int32_t z, + uint32_t poly_fmt, int poly_id_base, + int32_t xStart); + /// Render a string by rendering one 3D quad per codepoint with alternating /// polygon IDs. ///