From d48d92720215f56a7369f5453e09f235adfdc136 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Sun, 17 Aug 2025 17:58:53 -0500 Subject: [PATCH] textbox renders. --- archive/fixed.c | 257 ---------------- archive/fixed.h | 379 ------------------------ src/dusk/entity/npc.c | 1 - src/dusksdl2/display/ui/CMakeLists.txt | 1 + src/dusksdl2/display/ui/rendertextbox.c | 70 +++++ src/dusksdl2/display/ui/rendertextbox.h | 4 +- src/dusksdl2/display/ui/renderui.c | 6 + src/dusksdl2/dusksdl2input.h | 1 + 8 files changed, 81 insertions(+), 638 deletions(-) delete mode 100644 archive/fixed.c delete mode 100644 archive/fixed.h create mode 100644 src/dusksdl2/display/ui/rendertextbox.c diff --git a/archive/fixed.c b/archive/fixed.c deleted file mode 100644 index 4b5fd75..0000000 --- a/archive/fixed.c +++ /dev/null @@ -1,257 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "fixed.h" -#include "assert/assert.h" - -float_t fx248Fromi32(const int32_t b) { - return (float_t)b << FIXED248_FRACTION_BITS; -} - -float_t fx248Fromu32(const uint32_t b) { - return (float_t)((int32_t)b << FIXED248_FRACTION_BITS); -} - -float_t fx248Fromf32(const float_t b) { - return (float_t)(b * (1 << FIXED248_FRACTION_BITS)); -} - -float_t fx248Fromu16(const uint16_t b) { - return (float_t)((int32_t)b << FIXED248_FRACTION_BITS); -} - -float_t fx248Fromu8(const uint8_t b) { - return (float_t)((int32_t)b << FIXED248_FRACTION_BITS); -} - - - -int32_t fx248Toi32(const float_t a) { - return a >> FIXED248_FRACTION_BITS; -} - -uint32_t fx248Tou32(const float_t a) { - return (uint32_t)(a >> FIXED248_FRACTION_BITS); -} - -float_t fx248Tof32(const float_t a) { - return (float_t)a / (1 << FIXED248_FRACTION_BITS); -} - -uint16_t fx248Tou16(const float_t a) { - return (uint16_t)(a >> FIXED248_FRACTION_BITS); -} - -uint8_t fx248Tou8(const float_t a) { - return (uint8_t)(a >> FIXED248_FRACTION_BITS); -} - - - -float_t fx248Addfx248(const float_t a, const float_t b) { - return a + b; -} - -float_t fx248Addi32(const float_t a, const int32_t b) { - return fx248Addfx248(a, fx248Fromi32(b)); -} - -float_t fx248Addu32(const float_t a, const uint32_t b) { - return fx248Addfx248(a, fx248Fromu32(b)); -} - -float_t fx248Addf32(const float_t a, const float_t b) { - return fx248Addfx248(a, fx248Fromf32(b)); -} - - - -float_t fx248Subfx248(const float_t a, const float_t b) { - return a - b; -} - -float_t fx248Subi32(const float_t a, const int32_t b) { - return fx248Subfx248(a, fx248Fromi32(b)); -} - -float_t fx248Subu32(const float_t a, const uint32_t b) { - return fx248Subfx248(a, fx248Fromu32(b)); -} - -float_t fx248Subf32(const float_t a, const float_t b) { - return fx248Subfx248(a, fx248Fromf32(b)); -} - - - -float_t fx248Mulfx248(const float_t a, const float_t b) { - return (float_t)(((int64_t)a * (int64_t)b) >> FIXED248_FRACTION_BITS); -} - -float_t fx248Muli32(const float_t a, const int32_t b) { - return (float_t)(((int64_t)a * (int64_t)b) >> FIXED248_FRACTION_BITS); -} - -float_t fx248Mulu32(const float_t a, const uint32_t b) { - return (float_t)( - ((int64_t)a * (int64_t)(int32_t)b - ) >> FIXED248_FRACTION_BITS); -} - -float_t fx248Mulf32(const float_t a, const float_t b) { - return (float_t)(( - (int64_t)a * (int64_t)(b * (1 << FIXED248_FRACTION_BITS)) - ) >> FIXED248_FRACTION_BITS); -} - - - -float_t fx248Divfx248(const float_t a, const float_t b) { - assertFalse(b == 0, "Division by zero in fx248Divfx248"); - return (float_t)(((int64_t)a << FIXED248_FRACTION_BITS) / (int64_t)b); -} - -float_t fx248Divi32(const float_t a, const int32_t b) { - assertFalse(b == 0, "Division by zero in fx248Divi32"); - return (float_t)(((int64_t)a << FIXED248_FRACTION_BITS) / (int64_t)b); -} - -float_t fx248Divu32(const float_t a, const uint32_t b) { - assertFalse(b == 0, "Division by zero in fx248Divu32"); - return (float_t)( - ((int64_t)a << FIXED248_FRACTION_BITS - ) / (int64_t)(int32_t)b); -} - -float_t fx248Divf32(const float_t a, const float_t b) { - assertFalse(b == 0, "Division by zero in fx248Divf32"); - return (float_t)(( - (int64_t)a << FIXED248_FRACTION_BITS - ) / (int64_t)(b * (1 << FIXED248_FRACTION_BITS))); -} - - - -float_t fx248Floor(const float_t a) { - return a & ~((1 << FIXED248_FRACTION_BITS) - 1); -} - -float_t fx248Ceil(const float_t a) { - if(a & ((1 << FIXED248_FRACTION_BITS) - 1)) { - return (a & ~((1 << FIXED248_FRACTION_BITS) - 1)) + (1 << FIXED248_FRACTION_BITS); - } - return a; -} - -float_t fx248Round(const float_t a) { - if(a & ((1 << (FIXED248_FRACTION_BITS - 1)) - 1)) { - return (a & ~((1 << FIXED248_FRACTION_BITS) - 1)) + (1 << FIXED248_FRACTION_BITS); - } - return a & ~((1 << FIXED248_FRACTION_BITS) - 1); -} - - - -uint32_t fx248Flooru32(const float_t a) { - return (uint32_t)((a >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); -} - -uint32_t fx248Ceilu32(const float_t a) { - return (uint32_t)(((a + ((1 << FIXED248_FRACTION_BITS) - 1)) >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); -} - -uint32_t fx248Roundu32(const float_t a) { - return (uint32_t)(((a + (1 << (FIXED248_FRACTION_BITS - 1))) >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); -} - -float_t fx248Sqrt(const float_t a) { - if(a == 0) return 0; - - float_t y = a > FIXED248(1, 0) ? a : FIXED248(1, 0); - float_t last = 0; - int max_iter = 16; - while(y != last && max_iter-- > 0) { - last = y; - int32_t div = (int32_t)(((int64_t)a << FIXED248_FRACTION_BITS) / y); - y = (y + div) >> 1; - } - return y; -} - - - -float_t fx248Max(const float_t a, const float_t b) { - return (a > b) ? a : b; -} - -float_t fx248Min(const float_t a, const float_t b) { - return (a < b) ? a : b; -} - -float_t fx248Clamp( - const float_t a, - const float_t min, - const float_t max -) { - return (a < min) ? min : (a > max) ? max : a; -} - -float_t fx248Abs(const float_t a) { - return (a < 0) ? -a : a; -} - - - -float_t fx248Atan2( - const float_t y, - const float_t x -) { - // Handle special cases - if (x == 0) { - if (y > 0) return FX248_HALF_PI; - if (y < 0) return -FX248_HALF_PI; - return 0; - } - - // Use absolute values for quadrant correction - float_t abs_y = y; - if (abs_y < 0) abs_y = -abs_y; - - float_t angle; - if (abs_y < fx248Abs(x)) { - float_t z = fx248Divfx248(y, x); - float_t z2 = fx248Mulfx248(z, z); - float_t z3 = fx248Mulfx248(z2, z); - float_t z5 = fx248Mulfx248(z3, z2); - angle = fx248Subfx248( - fx248Addfx248(z, fx248Divfx248(z5, fx248Fromi32(5))), - fx248Divfx248(z3, fx248Fromi32(3)) - ); - if (x < 0) { - if (y < 0) { - angle -= FX248_PI; - } else { - angle += FX248_PI; - } - } - } else { - float_t z = fx248Divfx248(x, y); - float_t z2 = fx248Mulfx248(z, z); - float_t z3 = fx248Mulfx248(z2, z); - float_t z5 = fx248Mulfx248(z3, z2); - angle = fx248Subfx248( - fx248Addfx248(z, fx248Divfx248(z5, fx248Fromi32(5))), - fx248Divfx248(z3, fx248Fromi32(3)) - ); - if (y > 0) { - angle = FX248_HALF_PI - angle; - } else { - angle = -FX248_HALF_PI - angle; - } - } - return angle; -} \ No newline at end of file diff --git a/archive/fixed.h b/archive/fixed.h deleted file mode 100644 index 335a149..0000000 --- a/archive/fixed.h +++ /dev/null @@ -1,379 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" - -typedef int32_t float_t; - -#define FIXED248_FRACTION_BITS 8 -#define FIXED248_HIGH_MULTIPLIER (1 << FIXED248_FRACTION_BITS) -#define FIXED248_MIN INT32_MIN -#define FIXED248_MAX INT32_MAX -#define FIXED248(i, f) ((float_t)( \ - ((i) << FIXED248_FRACTION_BITS) + \ - (((f) * FIXED248_HIGH_MULTIPLIER) / 100) \ -)) -#define FIXED248_ONE (FIXED248(1, 0)) -#define FIXED248_ZERO (FIXED248(0, 0)) -#define FX248_PI 804 -#define FX248_HALF_PI 402 -#define FX248_3PI_4 603 -#define FX248_NEG_PI -804 - -/** - * Convert an int32_t value to a float_t value. - * - * @param b The int32_t value to convert. - * @return The converted float_t value. - */ -float_t fx248Fromi32(const int32_t b); - -/** - * Convert a uint32_t value to a float_t value. - * - * @param b The uint32_t value to convert. - * @return The converted float_t value. - */ -float_t fx248Fromu32(const uint32_t b); - -/** - * Convert a float_t value to a float_t value. - * - * @param b The float_t value to convert. - * @return The converted float_t value. - */ -float_t fx248Fromf32(const float_t b); - -/** - * Convert a uint16_t value to a float_t value. - * - * @param b The uint16_t value to convert. - * @return The converted float_t value. - */ -float_t fx248Fromu16(const uint16_t b); - -/** - * Convert a uint8_t value to a float_t value. - * - * @param b The uint8_t value to convert. - * @return The converted float_t value. - */ -float_t fx248Fromu8(const uint8_t b); - - - -/** - * Convert a float_t value to an int32_t value. - * - * @param a The float_t value to convert. - * @return The converted int32_t value. - */ -int32_t fx248Toi32(const float_t a); - -/** - * Convert a float_t value to a uint32_t value. - * - * @param a The float_t value to convert. - * @return The converted uint32_t value. - */ -uint32_t fx248Tou32(const float_t a); - -/** - * Convert a float_t value to a float_t value. - * - * @param a The float_t value to convert. - * @return The converted float_t value. - */ -float_t fx248Tof32(const float_t a); - -/** - * Convert a float_t value to a uint16_t value. - * - * @param a The float_t value to convert. - * @return The converted uint16_t value. - */ -uint16_t fx248Tou16(const float_t a); - -/** - * Convert a float_t value to an uint8_t value. - * - * @param a The float_t value to convert. - * @return The converted uint8_t value. - */ -uint8_t fx248Tou8(const float_t a); - - - -/** - * Add a float_t value to another float_t value. - * - * @param a First float_t value. - * @param b Second float_t value to add to the first value. - * @return The result of the addition as a float_t value. - */ -float_t fx248Addfx248(const float_t a, const float_t b); - -/** - * Add an int32_t value to a float_t value. - * - * @param a The float_t value to which the int32_t will be added. - * @param b The int32_t value to add to the float_t value. - * @return The result of the addition as a float_t value. - */ -float_t fx248Addi32(const float_t a, const int32_t b); - -/** - * Add a uint32_t value to a float_t value. - * - * @param a The float_t value to which the uint32_t will be added. - * @param b The uint32_t value to add to the float_t value. - * @return The result of the addition as a float_t value. - */ -float_t fx248Addu32(const float_t a, const uint32_t b); - -/** - * Add a float_t value to a float_t value. - * - * @param a Pointer to the float_t value (will be modified). - * @param b The float_t value to add to the float_t value. - * @return The result of the addition as a float_t value. - */ -float_t fx248Addf32(const float_t a, const float_t b); - - - -/** - * Subtract a float_t value from another float_t value. - * - * @param a First float_t value. - * @param b The float_t value to subtract from the first value. - * @return The result of the subtraction as a float_t value. - */ -float_t fx248Subfx248(const float_t a, const float_t b); - -/** - * Subtract an int32_t value from a float_t value. - * - * @param a The float_t value from which the int32_t will be subtracted. - * @param b The int32_t value to subtract from the float_t value. - * @return The result of the subtraction as a float_t value. - */ -float_t fx248Subi32(const float_t a, const int32_t b); - -/** - * Subtract a uint32_t value from a float_t value. - * - * @param a The float_t value from which the uint32_t will be subtracted. - * @param b The uint32_t value to subtract from the float_t value. - * @return The result of the subtraction as a float_t value. - */ -float_t fx248Subu32(const float_t a, const uint32_t b); - -/** - * Subtract a float_t value from a float_t value. - * - * @param a The float_t value from which the float_t will be subtracted. - * @param b The float_t value to subtract from the float_t value. - * @return The result of the subtraction as a float_t value. - */ -float_t fx248Subf32(const float_t a, const float_t b); - - - -/** - * Multiply two float_t values. - * - * @param a First float_t value. - * @param b Second float_t value to multiply with the first value. - * @return The result of the multiplication as a float_t value. - */ -float_t fx248Mulfx248(const float_t a, const float_t b); - -/** - * Multiply a float_t value by an int32_t value. - * - * @param a The float_t value to multiply. - * @param b The int32_t value to multiply with the float_t value. - * @return The result of the multiplication as a float_t value. - */ -float_t fx248Muli32(const float_t a, const int32_t b); - -/** - * Multiply a float_t value by a uint32_t value. - * - * @param a The float_t value to multiply. - * @param b The uint32_t value to multiply with the float_t value. - * @return The result of the multiplication as a float_t value. - */ -float_t fx248Mulu32(const float_t a, const uint32_t b); - -/** - * Multiply a float_t value by a float_t value. - * - * @param a The float_t value to multiply. - * @param b The float_t value to multiply with the float_t value. - * @return The result of the multiplication as a float_t value. - */ -float_t fx248Mulf32(const float_t a, const float_t b); - - - -/** - * Divide two float_t values. - * - * @param a The float_t value to be divided. - * @param b The float_t value to divide by. - * @return The result of the division as a float_t value. - */ -float_t fx248Divfx248(const float_t a, const float_t b); - -/** - * Divide a float_t value by an int32_t value. - * - * @param a The float_t value to be divided. - * @param b The int32_t value to divide by. - * @return The result of the division as a float_t value. - */ -float_t fx248Divi32(const float_t a, const int32_t b); - -/** - * Divide a float_t value by a uint32_t value. - * - * @param a The float_t value to be divided. - * @param b The uint32_t value to divide by. - * @return The result of the division as a float_t value. - */ -float_t fx248Divu32(const float_t a, const uint32_t b); - -/** - * Divide a float_t value by a float_t value. - * - * @param a The float_t value to be divided. - * @param b The float_t value to divide by. - * @return The result of the division as a float_t value. - */ -float_t fx248Divf32(const float_t a, const float_t b); - - - -/** - * Convert a float_t value to an int32_t value, rounding towards zero. - * - * @param a The float_t value to convert. - * @return The converted int32_t value. - */ -float_t fx248Floor(const float_t a); - -/** - * Convert a float_t value to an int32_t value, rounding towards positive - * infinity. - * - * @param a The float_t value to convert. - * @return The converted int32_t value. - */ -float_t fx248Ceil(const float_t a); - -/** - * Convert a float_t value to an int32_t value, rounding to the nearest - * integer. - * - * @param a The float_t value to convert. - * @return The converted int32_t value. - */ -float_t fx248Round(const float_t a); - - - -/** - * Convert a float_t value to a uint32_t value, rounding towards zero. - * - * @param a The float_t value to convert. - * @return The converted uint32_t value. - */ -uint32_t fx248Flooru32(const float_t a); - -/** - * Convert a float_t value to a uint32_t value, rounding towards positive - * infinity. - * - * @param a The float_t value to convert. - * @return The converted uint32_t value. - */ -uint32_t fx248Ceilu32(const float_t a); - -/** - * Convert a float_t value to a uint32_t value, rounding to the nearest - * integer. - * - * @param a The float_t value to convert. - * @return The converted uint32_t value. - */ -uint32_t fx248Roundu32(const float_t a); - -/** - * Returns the square root of a float_t value. - * - * @param a The float_t value to calculate the square root of. - */ -float_t fx248Sqrt(const float_t a); - - - -/** - * Returns the maximum of two float_t values. - * - * @param a First float_t value. - * @param b Second float_t value. - * @return The maximum of the two values. - */ -float_t fx248Max(const float_t a, const float_t b); - -/** - * Returns the minimum of two float_t values. - * - * @param a First float_t value. - * @param b Second float_t value. - * @return The minimum of the two values. - */ -float_t fx248Min(const float_t a, const float_t b); - -/** - * Clamp a float_t value between a minimum and maximum value. - * - * @param a The float_t value to clamp. - * @param min The minimum value to clamp to. - * @param max The maximum value to clamp to. - * @return The clamped float_t value. - */ -float_t fx248Clamp( - const float_t a, - const float_t min, - const float_t max -); - -/** - * Returns the absolute value of a float_t value. - * - * @param a The float_t value to calculate the absolute value of. - * @return The absolute value as a float_t value. - */ -float_t fx248Abs(const float_t a); - - - -/** - * Calculate the arctangent of a float_t value. - * - * @param y Y coordinate value. - * @param x X coordinate value. - * @return The arctangent of the value as a float_t value. - */ -float_t fx248Atan2( - const float_t y, - const float_t x -); \ No newline at end of file diff --git a/src/dusk/entity/npc.c b/src/dusk/entity/npc.c index 3065f8b..67408c4 100644 --- a/src/dusk/entity/npc.c +++ b/src/dusk/entity/npc.c @@ -19,7 +19,6 @@ void npcLoad(entity_t *entity, const entity_t *source) { } void npcUpdate(entity_t *entity) { - } void npcInteract(entity_t *player, entity_t *self) { diff --git a/src/dusksdl2/display/ui/CMakeLists.txt b/src/dusksdl2/display/ui/CMakeLists.txt index 54dddc7..2ca6934 100644 --- a/src/dusksdl2/display/ui/CMakeLists.txt +++ b/src/dusksdl2/display/ui/CMakeLists.txt @@ -10,4 +10,5 @@ target_sources(${DUSK_TARGET_NAME} renderfps.c rendertext.c renderui.c + rendertextbox.c ) \ No newline at end of file diff --git a/src/dusksdl2/display/ui/rendertextbox.c b/src/dusksdl2/display/ui/rendertextbox.c new file mode 100644 index 0000000..a6684fd --- /dev/null +++ b/src/dusksdl2/display/ui/rendertextbox.c @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "rendertextbox.h" +#include "ui/uitextbox.h" +#include "display/ui/rendertext.h" +#include "display/spritebatch/spritebatch.h" +#include "assert/assert.h" + +void renderTextboxDraw(void) { + if(!UI_TEXTBOX.visible) return; + + // Background + spriteBatchPush( + NULL, + 0, RENDER_HEIGHT - UI_TEXTBOX_HEIGHT, + RENDER_WIDTH, RENDER_HEIGHT, + 0x00, 0x00, 0x00, 0xFF, + 0.0f, 0.0f, 1.0f, 1.0f + ); + + uint32_t x = 0; + uint32_t y = RENDER_HEIGHT - UI_TEXTBOX_HEIGHT; + + if(UI_TEXTBOX.charsRevealed > 0) { + uint8_t charsRendered = 0; + + // For each line + for(uint8_t i = 0; i < UI_TEXTBOX_LINES_PER_PAGE; i++) { + // Get count of chars in the line + uint8_t lineLength = UI_TEXTBOX.lineLengths[ + i + (UI_TEXTBOX.page * UI_TEXTBOX_LINES_PER_PAGE) + ]; + if(lineLength == 0) continue; + + // Determine how many chars left to render + uint8_t lineChars = UI_TEXTBOX.charsRevealed - charsRendered; + + // Don't render more than in line + if(lineChars > lineLength) lineChars = lineLength; + assertTrue(lineChars > 0, "Line chars must be greater than 0"); + + // Update how many rendered + charsRendered += lineChars; + + for(uint8_t j = 0; j < lineChars; j++) { + renderTextDrawChar( + x + UI_TEXTBOX_PADDING_X + UI_TEXTBOX_BORDER_WIDTH + ( + j * FONT_TILE_WIDTH + ), + y + UI_TEXTBOX_PADDING_Y + UI_TEXTBOX_BORDER_HEIGHT + ( + i * FONT_TILE_HEIGHT + ), + UI_TEXTBOX.text[ + (i * UI_TEXTBOX_CHARS_PER_LINE) + j + + (UI_TEXTBOX.page * UI_TEXTBOX_CHARS_PER_PAGE) + ], + 0xFF, 0xFF, 0xFF + ); + } + + // Check if we're done rendering text + if(UI_TEXTBOX.charsRevealed - charsRendered == 0) break; + } + } +} \ No newline at end of file diff --git a/src/dusksdl2/display/ui/rendertextbox.h b/src/dusksdl2/display/ui/rendertextbox.h index f0a9ce0..ce657b9 100644 --- a/src/dusksdl2/display/ui/rendertextbox.h +++ b/src/dusksdl2/display/ui/rendertextbox.h @@ -5,4 +5,6 @@ * https://opensource.org/licenses/MIT */ -#pragma once \ No newline at end of file +#pragma once + +void renderTextboxDraw(void); \ No newline at end of file diff --git a/src/dusksdl2/display/ui/renderui.c b/src/dusksdl2/display/ui/renderui.c index 50571f9..238118c 100644 --- a/src/dusksdl2/display/ui/renderui.c +++ b/src/dusksdl2/display/ui/renderui.c @@ -9,6 +9,7 @@ #include "display/ui/rendertext.h" #include "display/ui/renderconsole.h" #include "display/ui/renderfps.h" +#include "display/ui/rendertextbox.h" #include "display/spritebatch/spritebatch.h" #include "display/camera/camera.h" @@ -18,6 +19,10 @@ renderuicallback_t RENDER_UI_CALLBACKS[] = { .dispose = renderTextDispose }, + { + .draw = renderTextboxDraw, + }, + { .draw = renderConsoleDraw, }, @@ -46,6 +51,7 @@ void renderUIDraw(void) { RENDER_UI_CALLBACKS[i].draw(); } + spriteBatchFlush(); cameraUIPop(); } diff --git a/src/dusksdl2/dusksdl2input.h b/src/dusksdl2/dusksdl2input.h index e6160d2..2a095e7 100644 --- a/src/dusksdl2/dusksdl2input.h +++ b/src/dusksdl2/dusksdl2input.h @@ -52,6 +52,7 @@ { SDL_SCANCODE_DOWN, INPUT_BIND_DOWN }, { SDL_SCANCODE_RETURN, INPUT_BIND_ACTION }, { SDL_SCANCODE_SPACE, INPUT_BIND_ACTION }, + { SDL_SCANCODE_E, INPUT_BIND_ACTION }, { SDL_SCANCODE_ESCAPE, INPUT_BIND_CANCEL }, { SDL_SCANCODE_BACKSPACE, INPUT_BIND_CANCEL }, { SDL_SCANCODE_TAB, INPUT_BIND_CONSOLE },