This commit is contained in:
2025-10-01 13:20:34 -05:00
parent 28174b8dc8
commit 22e2f703db
229 changed files with 272 additions and 8941 deletions

View File

@@ -28,10 +28,10 @@ void frameBufferInitBackbuffer() {
) {
#if DISPLAY_SDL2 == 1
assertNotNull(framebuffer, "Framebuffer cannot be NULL");
assertTrue(width > 0 && height > 0, "Width & height must be greater than 0");
assertTrue(width > 0 && height > 0, "W/H must be greater than 0");
memoryZero(framebuffer, sizeof(framebuffer_t));
textureInit(&framebuffer->texture, width, height, GL_RGBA, (texturedata_t){
textureInit(&framebuffer->texture, width, height, GL_RGBA,(texturedata_t){
.rgba = { .colors = NULL }
});

View File

@@ -9,6 +9,4 @@ target_sources(${DUSK_TARGET_NAME}
scenemanager.c
)
# Subdirs
add_subdirectory(overworld)
add_subdirectory(test)
# Subdirs

View File

@@ -1,10 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
sceneoverworld.c
)

View File

@@ -1,146 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "sceneoverworld.h"
#include "rpg/entity/entity.h"
#include "display/spritebatch/spritebatch.h"
#include "display/framebuffer/framebuffer.h"
#include "display/scene/scenemanager.h"
#include "display/mesh/quad.h"
#include "asset/assetmanager.h"
#include "assert/assert.h"
#include "display/tileset/tileset_entities.h"
sceneoverworld_t SCENE_OVERWORLD;
asset_t *testAsset;
ref_t testAssetRef;
errorret_t sceneOverworldInit(void) {
cameraInit(&SCENE_OVERWORLD.camera);
glm_vec3_copy((vec3){ 0.0f, 1.0f, 0.0f }, SCENE_OVERWORLD.camera.lookat.up);
SCENE_OVERWORLD.camera.perspective.fov = 45;
SCENE_OVERWORLD.camera.farClip = 10000.0f;
scene_t *scene = &SCENE_MANAGER_SCENES[SCENE_TYPE_OVERWORLD];
scene->flags |= SCENE_FLAG_ACTIVE | SCENE_FLAG_VISIBLE;
errorChain(assetManagerLoadAsset(
TILESET_ENTITIES.image, &testAsset, &testAssetRef
));
errorOk();
}
void sceneOverworldUpdate(void) {
if(RPG.map == NULL) return;
// Move camera to player.
const entity_t *start = &RPG.map->entities[0];
const entity_t *end = &RPG.map->entities[RPG.map->entityCount];
while(start < end) {
if(start->type == ENTITY_TYPE_PLAYER) {
SCENE_OVERWORLD.camera.lookat.target[0] = start->position[0];
SCENE_OVERWORLD.camera.lookat.target[1] = start->position[1];
break;
}
start++;
}
}
void sceneOverworldRender(void) {
const float_t camOffset = 12.0f;
const float_t fbWidth = frameBufferGetWidth(FRAMEBUFFER_BOUND);
const float_t fbHeight = frameBufferGetHeight(FRAMEBUFFER_BOUND);
const float_t aspect = fbWidth / fbHeight;
const float_t pixelPerfectOffset = tanf(
(glm_rad(180) - SCENE_OVERWORLD.camera.perspective.fov) / 2.0f
) * (fbHeight/ 2.0f);
// glm_vec3_copy((vec3){
// -100.0f, -100.0f, 0.0f
// }, SCENE_OVERWORLD.camera.lookat.target);
glm_vec3_copy((vec3){
SCENE_OVERWORLD.camera.lookat.target[0],
SCENE_OVERWORLD.camera.lookat.target[1] + camOffset,
SCENE_OVERWORLD.camera.lookat.target[2] + pixelPerfectOffset
}, SCENE_OVERWORLD.camera.lookat.position);
cameraPushMatrix(&SCENE_OVERWORLD.camera);
if(RPG.map != NULL) sceneOverworldRenderMap(RPG.map);
spriteBatchFlush();
cameraPopMatrix();
}
void sceneOverworldRenderMap(const map_t *map) {
assertNotNull(map, "Map pointer cannot be NULL");
// Draw base layer
sceneOverworldRenderMapLayer(map, &map->base);
// Draw entities
const entity_t *start = &map->entities[0];
const entity_t *end = &map->entities[map->entityCount];
while(start < end) {
// Render entity here.
sceneOverworldRenderEntity(start);
start++;
}
spriteBatchFlush();
// Draw overlay layer.
sceneOverworldRenderMapLayer(map, &map->overlay);
}
void sceneOverworldRenderEntity(const entity_t *entity) {
assertNotNull(entity, "Entity pointer cannot be NULL");
assertTrue(entity->type < ENTITY_TYPE_COUNT, "Invalid entity type");
assertTrue(entity->type != ENTITY_TYPE_NULL, "Cannot have NULL entity type");
vec4 uv;
tilesetPositionGetUV(&TILESET_ENTITIES, entity->direction, 0, uv);
// For now, just draw a placeholder quad.
spriteBatchPush(
&testAsset->paletteImage.texture,
entity->position[0], entity->position[1],
entity->position[0] + TILESET_ENTITIES.tileWidth,
entity->position[1] + TILESET_ENTITIES.tileHeight,
COLOR_WHITE,
uv[0], uv[1], uv[2], uv[3]
);
}
void sceneOverworldRenderMapLayer(const map_t *map, const maplayer_t *layer) {
assertNotNull(layer, "Map layer pointer cannot be NULL");
for(uint32_t y = 0; y < map->height; y++) {
for(uint32_t x = 0; x < map->width; x++) {
const tile_t *tile = &layer->tiles[y * map->width + x];
if(tile->id == 0) continue;
spriteBatchPush(
NULL,
x * TILESET_ENTITIES.tileWidth,
y * TILESET_ENTITIES.tileHeight,
(x + 1) * TILESET_ENTITIES.tileWidth,
(y + 1) * TILESET_ENTITIES.tileHeight,
COLOR_RED,
0, 0, 1, 1
);
}
}
spriteBatchFlush();
}
void sceneOverworldDispose(void) {
// Dispose of the overworld scene.
if(testAsset) assetUnlock(testAsset, testAssetRef);
}

View File

@@ -1,59 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "display/camera.h"
#include "rpg/rpg.h"
#include "error/error.h"
typedef struct {
camera_t camera;
} sceneoverworld_t;
extern sceneoverworld_t SCENE_OVERWORLD;
/**
* Initialize the overworld scene.
*/
errorret_t sceneOverworldInit(void);
/**
* Update the overworld scene.
*/
void sceneOverworldUpdate(void);
/**
* Render the overworld scene.
*/
void sceneOverworldRender(void);
/**
* Render a map in the overworld scene.
*
* @param map Pointer to the map to render.
*/
void sceneOverworldRenderMap(const map_t *map);
/**
* Render an entity in the overworld scene.
*
* @param entity Pointer to the entity to render.
*/
void sceneOverworldRenderEntity(const entity_t *entity);
/**
* Render a map layer in the overworld scene.
*
* @param map Pointer to the map the layer belongs to.
* @param layer Pointer to the map layer to render.
*/
void sceneOverworldRenderMapLayer(const map_t *map, const maplayer_t *layer);
/**
* Dispose of the overworld scene.
*/
void sceneOverworldDispose(void);

View File

@@ -21,14 +21,4 @@ typedef struct {
void (*sleep)(void);
uint8_t flags;
} scene_t;
typedef enum {
SCENE_TYPE_LOGO,
SCENE_TYPE_TEST,
SCENE_TYPE_OVERWORLD,
SCENE_TYPE_COUNT
} scenetype_t;
#define SCENE_TYPE_INITIAL SCENE_TYPE_OVERWORLD
} scene_t;

View File

@@ -7,55 +7,52 @@
#include "scenemanager.h"
#include "display/scene/overworld/sceneoverworld.h"
#include "display/scene/test/scenetest.h"
scenemanager_t SCENE_MANAGER;
scene_t SCENE_MANAGER_SCENES[SCENE_TYPE_COUNT] = {
[SCENE_TYPE_LOGO] = { 0 },
// scene_t SCENE_MANAGER_SCENES[SCENE_TYPE_COUNT] = {
// [SCENE_TYPE_LOGO] = { 0 },
[SCENE_TYPE_TEST] = {
.init = sceneTestInit,
.update = sceneTestUpdate,
.render = sceneTestRender,
.dispose = sceneTestDispose
},
// [SCENE_TYPE_TEST] = {
// .init = sceneTestInit,
// .update = sceneTestUpdate,
// .render = sceneTestRender,
// .dispose = sceneTestDispose
// },
[SCENE_TYPE_OVERWORLD] = {
.init = sceneOverworldInit,
.update = sceneOverworldUpdate,
.render = sceneOverworldRender,
.dispose = sceneOverworldDispose
}
};
// [SCENE_TYPE_OVERWORLD] = {
// .init = sceneOverworldInit,
// .update = sceneOverworldUpdate,
// .render = sceneOverworldRender,
// .dispose = sceneOverworldDispose
// }
// };
errorret_t sceneManagerInit(void) {
scene_t *initial = &SCENE_MANAGER_SCENES[SCENE_TYPE_INITIAL];
if(initial->init != NULL) errorChain(initial->init());
// scene_t *initial = &SCENE_MANAGER_SCENES[SCENE_TYPE_INITIAL];
// if(initial->init != NULL) errorChain(initial->init());
errorOk();
}
void sceneManagerUpdate(void) {
// For each scene.
for(uint8_t i = 0; i < SCENE_TYPE_COUNT; i++) {
scene_t *scene = &SCENE_MANAGER_SCENES[i];
if((scene->flags & SCENE_FLAG_ACTIVE) == 0) continue;
if(scene->update != NULL) scene->update();
}
// for(uint8_t i = 0; i < SCENE_TYPE_COUNT; i++) {
// scene_t *scene = &SCENE_MANAGER_SCENES[i];
// if((scene->flags & SCENE_FLAG_ACTIVE) == 0) continue;
// if(scene->update != NULL) scene->update();
// }
}
void sceneManagerRender(void) {
for(uint8_t i = 0; i < SCENE_TYPE_COUNT; i++) {
scene_t *scene = &SCENE_MANAGER_SCENES[i];
if((scene->flags & SCENE_FLAG_VISIBLE) == 0) continue;
if(scene->render != NULL) scene->render();
}
// for(uint8_t i = 0; i < SCENE_TYPE_COUNT; i++) {
// scene_t *scene = &SCENE_MANAGER_SCENES[i];
// if((scene->flags & SCENE_FLAG_VISIBLE) == 0) continue;
// if(scene->render != NULL) scene->render();
// }
}
void sceneManagerDispose(void) {
for(uint8_t i = 0; i < SCENE_TYPE_COUNT; i++) {
scene_t *scene = &SCENE_MANAGER_SCENES[i];
if(scene->dispose != NULL) scene->dispose();
}
// for(uint8_t i = 0; i < SCENE_TYPE_COUNT; i++) {
// scene_t *scene = &SCENE_MANAGER_SCENES[i];
// if(scene->dispose != NULL) scene->dispose();
// }
}

View File

@@ -13,7 +13,7 @@ typedef struct {
} scenemanager_t;
extern scenemanager_t SCENE_MANAGER;
extern scene_t SCENE_MANAGER_SCENES[SCENE_TYPE_COUNT];
// extern scene_t SCENE_MANAGER_SCENES[SCENE_TYPE_COUNT];
/**
* Initializes the scene manager and the initial scene.

View File

@@ -1,10 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
scenetest.c
)

View File

@@ -1,48 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "scenetest.h"
#include "display/scene/scenemanager.h"
#include "display/spritebatch/spritebatch.h"
scenetest_t SCENE_TEST;
errorret_t sceneTestInit(void) {
cameraInit(&SCENE_TEST.camera);
SCENE_TEST.camera.projType = CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC;
SCENE_TEST.camera.nearClip = -1.0f;
SCENE_TEST.camera.farClip = 2.0f;
SCENE_TEST.camera.viewType = CAMERA_VIEW_TYPE_2D;
SCENE_TEST.camera._2d.zoom = 2.0f;
SCENE_TEST.camera._2d.position[0] = -150.0f;
SCENE_TEST.camera._2d.position[1] = -50.0f;
scene_t *scene = &SCENE_MANAGER_SCENES[SCENE_TYPE_TEST];
scene->flags |= SCENE_FLAG_ACTIVE | SCENE_FLAG_VISIBLE;
errorOk();
}
void sceneTestUpdate(void) {
}
void sceneTestRender(void) {
SCENE_TEST.camera.orthographic.left = 0.0f;
SCENE_TEST.camera.orthographic.right = frameBufferGetWidth(FRAMEBUFFER_BOUND);
SCENE_TEST.camera.orthographic.top = frameBufferGetHeight(FRAMEBUFFER_BOUND);
SCENE_TEST.camera.orthographic.bottom = 0.0f;
cameraPushMatrix(&SCENE_TEST.camera);
spriteBatchClear();
spriteBatchFlush();
cameraPopMatrix();
}
void sceneTestDispose(void) {
}

View File

@@ -1,36 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "display/camera.h"
#include "error/error.h"
typedef struct {
camera_t camera;
} scenetest_t;
extern scenetest_t SCENE_TEST;
/**
* Initialize the test scene.
*/
errorret_t sceneTestInit(void);
/**
* Update the test scene.
*/
void sceneTestUpdate(void);
/**
* Render the test scene.
*/
void sceneTestRender(void);
/**
* Dispose of the test scene.
*/
void sceneTestDispose(void);

View File

@@ -13,12 +13,22 @@
#include "uifps.h"
#include "util/memory.h"
#include "display/tileset/tileset_minogram.h"
ui_t UI;
errorret_t uiInit(void) {
memoryZero(&UI, sizeof(ui_t));
errorChain(uiTextInit());
// Load debug font.
UI.debugFontTileset = &TILESET_MINOGRAM;
errorChain(assetManagerLoadAsset(
UI.debugFontTileset->image,
&UI.debugFontAsset,
&UI.debugFontRef
));
// Setup UI Camera.
cameraInit(&UI.camera);
UI.camera.projType = CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC;
@@ -28,12 +38,12 @@ errorret_t uiInit(void) {
UI.camera.orthographic.bottom = frameBufferGetHeight(&FRAMEBUFFER_BACKBUFFER);
UI.camera.nearClip = -1.0f;
UI.camera.farClip = 1.0f;
UI.camera.viewType = CAMERA_VIEW_TYPE_MATRIX;
glm_mat4_identity(UI.camera.view);
UI.scale = 1.0f;
// Setup FPS element.
uiFPSInit();
errorOk();
@@ -61,5 +71,5 @@ void uiRender(void) {
}
void uiDispose(void) {
uiTextDispose();
}

View File

@@ -8,10 +8,17 @@
#pragma once
#include "error/error.h"
#include "display/camera.h"
#include "display/texture/texture.h"
#include "display/tileset.h"
#include "asset/asset.h"
typedef struct {
camera_t camera;
float_t scale;
const tileset_t *debugFontTileset;
asset_t *debugFontAsset;
ref_t debugFontRef;
} ui_t;
extern ui_t UI;

View File

@@ -8,6 +8,7 @@
#include "uiconsole.h"
#include "uitext.h"
#include "console/console.h"
#include "ui.h"
void uiConsoleRender(void) {
if(!CONSOLE.visible) return;
@@ -21,7 +22,11 @@ void uiConsoleRender(void) {
i--;
continue;
}
uiTextDraw(0, i * TILESET_MINOGRAM.tileHeight, line, COLOR_WHITE);
uiTextDraw(
0, i * TILESET_MINOGRAM.tileHeight,
line, COLOR_WHITE,
UI.debugFontTileset, &UI.debugFontAsset->alphaImage.texture
);
i--;
} while(i > 0);
}

View File

@@ -10,6 +10,7 @@
#include "time/time.h"
#include "console/console.h"
#include "util/string.h"
#include "ui.h"
void uiFPSInit(void) {
consoleRegVar("fps", "0", NULL);
@@ -36,5 +37,9 @@ void uiFPSRender(void) {
COLOR_RED
);
uiTextDraw(0, 0, buffer, color);
uiTextDraw(
0, 0,
buffer, color,
UI.debugFontTileset, &UI.debugFontAsset->alphaImage.texture
);
}

View File

@@ -11,47 +11,32 @@
#include "util/memory.h"
#include "display/spritebatch/spritebatch.h"
uitext_t UI_TEXT;
errorret_t uiTextInit(void) {
memoryZero(&UI_TEXT, sizeof(uitext_t));
errorChain(assetManagerLoadAsset(
TILESET_MINOGRAM.image, &UI_TEXT.asset, &UI_TEXT.assetRef
));
errorOk();
}
void uiTextDispose(void) {
if(UI_TEXT.asset) {
assetUnlock(UI_TEXT.asset, UI_TEXT.assetRef);
}
}
void uiTextDrawChar(
const float_t x,
const float_t y,
const char_t c,
const color_t color
const color_t color,
const tileset_t *tileset,
texture_t *texture
) {
int32_t tileIndex = (int32_t)(c) - UI_TEXT_CHAR_START;
if(tileIndex < 0 || tileIndex >= TILESET_MINOGRAM.tileCount) {
if(tileIndex < 0 || tileIndex >= tileset->tileCount) {
tileIndex = ((int32_t)'@') - UI_TEXT_CHAR_START;
}
assertTrue(
tileIndex >= 0 && tileIndex <= TILESET_MINOGRAM.tileCount,
tileIndex >= 0 && tileIndex <= tileset->tileCount,
"Character is out of bounds for font tiles"
);
vec4 uv;
tilesetTileGetUV(&TILESET_MINOGRAM, tileIndex, uv);
tilesetTileGetUV(tileset, tileIndex, uv);
spriteBatchPush(
&UI_TEXT.asset->alphaImage.texture,
texture,
x, y,
x + TILESET_MINOGRAM.tileWidth,
y + TILESET_MINOGRAM.tileHeight,
x + tileset->tileWidth,
y + tileset->tileHeight,
color,
uv[0], uv[1], uv[2], uv[3]
);
@@ -61,7 +46,9 @@ void uiTextDraw(
const float_t x,
const float_t y,
const char_t *text,
const color_t color
const color_t color,
const tileset_t *tileset,
texture_t *texture
) {
assertNotNull(text, "Text cannot be NULL");
@@ -73,22 +60,23 @@ void uiTextDraw(
while((c = text[i++]) != '\0') {
if(c == '\n') {
posX = x;
posY += TILESET_MINOGRAM.tileHeight;
posY += tileset->tileHeight;
continue;
}
if(c == ' ') {
posX += TILESET_MINOGRAM.tileWidth;
posX += tileset->tileWidth;
continue;
}
uiTextDrawChar(posX, posY, c, color);
posX += TILESET_MINOGRAM.tileWidth;
uiTextDrawChar(posX, posY, c, color, tileset, texture);
posX += tileset->tileWidth;
}
}
void uiTextMeasure(
const char_t *text,
const tileset_t *tileset,
int32_t *outWidth,
int32_t *outHeight
) {
@@ -97,7 +85,7 @@ void uiTextMeasure(
assertNotNull(outHeight, "Output height pointer cannot be NULL");
int32_t width = 0;
int32_t height = TILESET_MINOGRAM.tileHeight;
int32_t height = tileset->tileHeight;
int32_t lineWidth = 0;
char_t c;
@@ -108,11 +96,11 @@ void uiTextMeasure(
width = lineWidth;
}
lineWidth = 0;
height += TILESET_MINOGRAM.tileHeight;
height += tileset->tileHeight;
continue;
}
lineWidth += TILESET_MINOGRAM.tileWidth;
lineWidth += tileset->tileWidth;
}
if(lineWidth > width) {

View File

@@ -11,18 +11,6 @@
#define UI_TEXT_CHAR_START '!'
typedef struct {
ref_t assetRef;
asset_t *asset;
} uitext_t;
extern uitext_t UI_TEXT;
/**
* Initializes the text rendering system.
*/
errorret_t uiTextInit(void);
/**
* Draws a single character at the specified position.
*
@@ -30,12 +18,16 @@ errorret_t uiTextInit(void);
* @param y The y-coordinate to draw the character at.
* @param c The character to draw.
* @param color The color to draw the character in.
* @param tileset Font tileset to use for rendering.
* @param texture Texture containing the font tileset image.
*/
void uiTextDrawChar(
const float_t x,
const float_t y,
const char_t c,
const color_t color
const color_t color,
const tileset_t *tileset,
texture_t *texture
);
/**
@@ -45,28 +37,29 @@ void uiTextDrawChar(
* @param y The y-coordinate to draw the text at.
* @param text The null-terminated string of text to draw.
* @param color The color to draw the text in.
* @param tileset Font tileset to use for rendering.
* @param texture Texture containing the font tileset image.
*/
void uiTextDraw(
const float_t x,
const float_t y,
const char_t *text,
const color_t color
const color_t color,
const tileset_t *tileset,
texture_t *texture
);
/**
* Measures the width and height of the given text string when rendered.
*
* @param text The null-terminated string of text to measure.
* @param tileset Font tileset to use for measurement.
* @param outWidth Pointer to store the measured width in pixels.
* @param outHeight Pointer to store the measured height in pixels.
*/
void uiTextMeasure(
const char_t *text,
const tileset_t *tileset,
int32_t *outWidth,
int32_t *outHeight
);
/**
* Disposes of the text rendering system, freeing any allocated resources.
*/
void uiTextDispose(void);
);