Custom font rendering.
This commit is contained in:
@ -7,13 +7,3 @@
|
||||
|
||||
#pragma once
|
||||
#include "ui/fontdata.h"
|
||||
|
||||
#define FONT_HEIGHT 8
|
||||
#define FONT_WIDTH FONT_HEIGHT
|
||||
#define FONT_LINE_SPACING 1
|
||||
|
||||
#define FONT_LINE_HEIGHT ( \
|
||||
FONT_HEIGHT + FONT_LINE_SPACING \
|
||||
)
|
||||
|
||||
//
|
@ -20,21 +20,17 @@ void uiTextboxUpdate() {
|
||||
if(UI_TEXTBOX.visible == false) return;
|
||||
|
||||
if(UI_TEXTBOX.charsRevealed < UI_TEXTBOX.pageChars[UI_TEXTBOX.page]) {
|
||||
if((RENDER_FRAME % 4) == 0) {
|
||||
UI_TEXTBOX.charsRevealed++;
|
||||
} else if(inputIsDown(INPUT_BIND_ACTION)) {
|
||||
UI_TEXTBOX.charsRevealed++;
|
||||
if(inputIsDown(INPUT_BIND_ACTION)) {
|
||||
UI_TEXTBOX.charsRevealed++;
|
||||
}
|
||||
|
||||
} else {
|
||||
if(inputPressed(INPUT_BIND_ACTION)) {
|
||||
if(UI_TEXTBOX.page < UI_TEXTBOX.pageCount - 1) {
|
||||
uitextbox_t *textbox = &UI_TEXTBOX;
|
||||
printf("next page?\n");
|
||||
UI_TEXTBOX.page++;
|
||||
UI_TEXTBOX.charsRevealed = 0;
|
||||
} else {
|
||||
printf("Closing textbox\n");
|
||||
// Close the textbox
|
||||
UI_TEXTBOX.visible = false;
|
||||
UI_TEXTBOX.page = 0;
|
||||
@ -45,8 +41,6 @@ void uiTextboxUpdate() {
|
||||
}
|
||||
|
||||
void uiTextboxSetText(const char_t *text) {
|
||||
uitextbox_t *textbox = &UI_TEXTBOX;
|
||||
|
||||
assertNotNull(text, "Text pointer cannot be NULL, call uiTextboxClose()");
|
||||
|
||||
memoryZero(UI_TEXTBOX.text, sizeof(UI_TEXTBOX.text));
|
||||
|
@ -12,13 +12,13 @@
|
||||
#define UI_TEXTBOX_LINES_PER_PAGE 4
|
||||
#define UI_TEXTBOX_WIDTH RENDER_WIDTH
|
||||
#define UI_TEXTBOX_HEIGHT_INNER ( \
|
||||
FONT_LINE_HEIGHT * UI_TEXTBOX_LINES_PER_PAGE \
|
||||
FONT_TILE_HEIGHT * UI_TEXTBOX_LINES_PER_PAGE \
|
||||
)
|
||||
|
||||
#define UI_TEXTBOX_BORDER_WIDTH 4
|
||||
#define UI_TEXTBOX_BORDER_HEIGHT 4
|
||||
#define UI_TEXTBOX_PADDING_X 4
|
||||
#define UI_TEXTBOX_PADDING_Y 4
|
||||
#define UI_TEXTBOX_BORDER_HEIGHT UI_TEXTBOX_BORDER_WIDTH
|
||||
#define UI_TEXTBOX_PADDING_X 2
|
||||
#define UI_TEXTBOX_PADDING_Y UI_TEXTBOX_PADDING_X
|
||||
#define UI_TEXTBOX_WIDTH_INNER ( \
|
||||
UI_TEXTBOX_WIDTH - (UI_TEXTBOX_BORDER_WIDTH * 2) - \
|
||||
(UI_TEXTBOX_PADDING_X * 2) \
|
||||
@ -28,7 +28,7 @@
|
||||
(UI_TEXTBOX_PADDING_Y * 2) \
|
||||
)
|
||||
|
||||
#define UI_TEXTBOX_CHARS_PER_LINE (UI_TEXTBOX_WIDTH_INNER / FONT_WIDTH)
|
||||
#define UI_TEXTBOX_CHARS_PER_LINE (UI_TEXTBOX_WIDTH_INNER / FONT_TILE_WIDTH)
|
||||
#define UI_TEXTBOX_CHARS_PER_PAGE ( \
|
||||
UI_TEXTBOX_CHARS_PER_LINE * UI_TEXTBOX_LINES_PER_PAGE \
|
||||
)
|
||||
@ -40,6 +40,8 @@
|
||||
UI_TEXTBOX_CHARS_PER_PAGE * UI_TEXTBOX_PAGE_COUNT_MAX \
|
||||
)
|
||||
|
||||
#define UI_TEXTBOX_REVEAL_RATE 2
|
||||
|
||||
typedef struct {
|
||||
char_t text[UI_TEXTBOX_CHARS_MAX];
|
||||
uint8_t lineLengths[UI_TEXTBOX_LINE_COUNT];
|
||||
@ -65,6 +67,11 @@ void uiTextboxInit(void);
|
||||
*/
|
||||
void uiTextboxUpdate(void);
|
||||
|
||||
/**
|
||||
* Sets the text for the UI textbox.
|
||||
*
|
||||
* @param text The text to display in the textbox.
|
||||
*/
|
||||
void uiTextboxSetText(
|
||||
const char_t *text
|
||||
);
|
@ -9,6 +9,7 @@
|
||||
#include "ui/uitextbox.h"
|
||||
#include "util/memory.h"
|
||||
#include "assert/assert.h"
|
||||
#include "display/render.h"
|
||||
|
||||
void drawUIInit(void) {
|
||||
}
|
||||
@ -20,22 +21,21 @@ void drawUI() {
|
||||
void drawUITextbox() {
|
||||
if(!UI_TEXTBOX.visible) return;
|
||||
|
||||
uitextbox_t *textbox = &UI_TEXTBOX;
|
||||
|
||||
// Semi-transparent dark blue
|
||||
Color background = (Color){ 0, 0, 128, 128 };
|
||||
|
||||
uint32_t x = 0;
|
||||
uint32_t y = RENDER_HEIGHT - UI_TEXTBOX_HEIGHT;
|
||||
|
||||
DrawRectangle(
|
||||
0, RENDER_HEIGHT - UI_TEXTBOX_HEIGHT,
|
||||
x, y,
|
||||
UI_TEXTBOX_WIDTH, UI_TEXTBOX_HEIGHT,
|
||||
background
|
||||
);
|
||||
|
||||
BeginBlendMode(BLEND_ALPHA);
|
||||
|
||||
if(UI_TEXTBOX.charsRevealed > 0) {
|
||||
char_t buffer[UI_TEXTBOX_CHARS_PER_LINE + 1];// +1 for null term
|
||||
uint8_t charsRendered = 0;
|
||||
uitextbox_t *textbox = &UI_TEXTBOX;
|
||||
|
||||
// For each line
|
||||
for(uint8_t i = 0; i < UI_TEXTBOX_LINES_PER_PAGE; i++) {
|
||||
@ -55,33 +55,66 @@ void drawUITextbox() {
|
||||
// Update how many rendered
|
||||
charsRendered += lineChars;
|
||||
|
||||
// Copy string from VN Textbox...
|
||||
memoryCopy(
|
||||
buffer,
|
||||
UI_TEXTBOX.text + (UI_TEXTBOX.page * UI_TEXTBOX_CHARS_PER_PAGE) +
|
||||
(i * UI_TEXTBOX_CHARS_PER_LINE),
|
||||
lineChars
|
||||
);
|
||||
// Null term string
|
||||
buffer[lineChars] = '\0'; // Null-terminate the string
|
||||
|
||||
// Render the text
|
||||
DrawText(
|
||||
buffer,
|
||||
UI_TEXTBOX_PADDING_X + UI_TEXTBOX_BORDER_WIDTH,
|
||||
(
|
||||
(RENDER_HEIGHT - UI_TEXTBOX_HEIGHT) +
|
||||
UI_TEXTBOX_PADDING_Y + UI_TEXTBOX_BORDER_HEIGHT +
|
||||
(i * FONT_LINE_HEIGHT)
|
||||
),
|
||||
FONT_HEIGHT,
|
||||
WHITE
|
||||
);
|
||||
for(uint8_t j = 0; j < lineChars; j++) {
|
||||
drawUIChar(
|
||||
UI_TEXTBOX.text[
|
||||
(i * UI_TEXTBOX_CHARS_PER_LINE) + j +
|
||||
(UI_TEXTBOX.page * UI_TEXTBOX_CHARS_PER_PAGE)
|
||||
],
|
||||
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
|
||||
),
|
||||
WHITE
|
||||
);
|
||||
}
|
||||
|
||||
// Check if we're done rendering text
|
||||
if(UI_TEXTBOX.charsRevealed - charsRendered == 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
EndBlendMode();
|
||||
}
|
||||
|
||||
void drawUIText(
|
||||
const uint8_t *text,
|
||||
const uint16_t length,
|
||||
const int32_t x,
|
||||
const int32_t y,
|
||||
const Color color
|
||||
) {
|
||||
assertNotNull(text, "Text to draw cannot be NULL");
|
||||
if(length == 0) return;
|
||||
|
||||
for(uint16_t i = 0; i < length; i++) {
|
||||
drawUIChar(text[i], x + (i * FONT_TILE_WIDTH), y, color);
|
||||
}
|
||||
}
|
||||
|
||||
void drawUIChar(
|
||||
const char_t c,
|
||||
const int32_t x,
|
||||
const int32_t y,
|
||||
const Color color
|
||||
) {
|
||||
if(c < ' ' || c > '~') return; // Only print printable ASCII characters
|
||||
|
||||
int32_t charIndex = TILE_INDEXES[c - FONT_CHAR_START];
|
||||
int32_t charX = (charIndex % FONT_COLUMN_COUNT) * FONT_TILE_WIDTH;
|
||||
int32_t charY = (charIndex / FONT_COLUMN_COUNT) * FONT_TILE_HEIGHT;
|
||||
|
||||
// FLip Y coordinate for raylib texture coordinates
|
||||
DrawTextureRec(
|
||||
RENDER_FONT_TEXTURE,
|
||||
(Rectangle) {
|
||||
(float) charX,
|
||||
(float) charY, // Flip Y by adding height
|
||||
(float) FONT_TILE_WIDTH,
|
||||
(float) FONT_TILE_HEIGHT // Negative height to flip the texture
|
||||
},
|
||||
(Vector2) { x, y }, // Add FONT_HEIGHT to flip Y
|
||||
color
|
||||
);
|
||||
}
|
@ -22,3 +22,35 @@ void drawUI(void);
|
||||
* Draws the UI textbox to the screen.
|
||||
*/
|
||||
void drawUITextbox(void);
|
||||
|
||||
/**
|
||||
* Draws text to the screen at the specified position with the given color.
|
||||
*
|
||||
* @param text The text to draw.
|
||||
* @param length The length of the text to draw.
|
||||
* @param x The x-coordinate to draw the text at.
|
||||
* @param y The y-coordinate to draw the text at.
|
||||
* @param color The color of the text.
|
||||
*/
|
||||
void drawUIText(
|
||||
const uint8_t *text,
|
||||
const uint16_t length,
|
||||
const int32_t x,
|
||||
const int32_t y,
|
||||
const Color color
|
||||
);
|
||||
|
||||
/**
|
||||
* Draws a single character to the screen at the specified position with the given color.
|
||||
*
|
||||
* @param c The character to draw.
|
||||
* @param x The x-coordinate to draw the character at.
|
||||
* @param y The y-coordinate to draw the character at.
|
||||
* @param color The color of the character.
|
||||
*/
|
||||
void drawUIChar(
|
||||
const char_t c,
|
||||
const int32_t x,
|
||||
const int32_t y,
|
||||
const Color color
|
||||
);
|
@ -14,6 +14,7 @@
|
||||
RenderTexture2D RENDER_SCREEN_TEXTURE;
|
||||
Texture2D RENDER_TILEMAP_TEXTURE;
|
||||
Texture2D RENDER_ENTITIES_TEXTURE;
|
||||
Texture2D RENDER_FONT_TEXTURE;
|
||||
|
||||
void renderInit(void) {
|
||||
InitWindow(
|
||||
@ -31,6 +32,7 @@ void renderInit(void) {
|
||||
RENDER_SCREEN_TEXTURE = LoadRenderTexture(RENDER_WIDTH, RENDER_HEIGHT);
|
||||
RENDER_TILEMAP_TEXTURE = LoadTexture("../data/tilemap.png");
|
||||
RENDER_ENTITIES_TEXTURE = LoadTexture("../data/entities.png");
|
||||
RENDER_FONT_TEXTURE = LoadTexture("../data/minogram_6x10.png");
|
||||
|
||||
drawOverworldInit();
|
||||
drawUIInit();
|
||||
|
@ -12,3 +12,4 @@
|
||||
extern RenderTexture2D RENDER_SCREEN_TEXTURE;
|
||||
extern Texture2D RENDER_TILEMAP_TEXTURE;
|
||||
extern Texture2D RENDER_ENTITIES_TEXTURE;
|
||||
extern Texture2D RENDER_FONT_TEXTURE;
|
@ -119,7 +119,17 @@ with open(outputFile, 'w') as f:
|
||||
f.write(f"#define FONT_TILE_HEIGHT {root.attrib['tileheight']}\n")
|
||||
f.write(f"#define FONT_TILE_COUNT {len(outputTileIndexes)}\n")
|
||||
f.write(f"#define FONT_CHAR_START {CHAR_START}\n")
|
||||
f.write(f"#define FONT_CHAR_END {CHAR_END}\n\n")
|
||||
f.write(f"#define FONT_CHAR_END {CHAR_END}\n")
|
||||
f.write(f"#define FONT_CHAR_COUNT {CHARS_TOTAL}\n")
|
||||
f.write(f"#define FONT_COLUMN_COUNT {img.width // int(root.attrib['tilewidth'])}\n")
|
||||
f.write(f"#define FONT_ROW_COUNT {img.height // int(root.attrib['tileheight'])}\n\n")
|
||||
|
||||
f.write("static const uint8_t TILE_INDEXES[FONT_CHAR_COUNT] = {\n")
|
||||
f.write(" ")
|
||||
for i in range(len(outputTileIndexes)):
|
||||
tileIndex = outputTileIndexes[i]
|
||||
f.write(f"{tileIndex}, ")
|
||||
f.write("\n};\n\n")
|
||||
|
||||
f.write("static const uint8_t TILE_PIXEL_DATA[FONT_TILE_COUNT][FONT_TILE_WIDTH * FONT_TILE_HEIGHT] = {\n")
|
||||
for i in range(len(outputTileIndexes)):
|
||||
@ -137,6 +147,7 @@ with open(outputFile, 'w') as f:
|
||||
for x in range(int(root.attrib['tilewidth'])):
|
||||
pixel = tile.getpixel((x, y))
|
||||
f.write(f"0x{1 if pixel[3] > 0 else 0:02X}, ")
|
||||
f.write("},\n\n")
|
||||
|
||||
|
||||
f.write("},\n")
|
||||
f.write("};\n\n")
|
Reference in New Issue
Block a user