Render text working.

This commit is contained in:
2025-09-02 22:47:07 -05:00
parent 87f18d0e13
commit 1af2b8f47b
19 changed files with 340 additions and 157 deletions

View File

@@ -10,8 +10,8 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
if(NOT DEFINED DUSK_TARGET_SYSTEM) if(NOT DEFINED DUSK_TARGET_SYSTEM)
# set(DUSK_TARGET_SYSTEM "linux") set(DUSK_TARGET_SYSTEM "linux")
set(DUSK_TARGET_SYSTEM "psp") # set(DUSK_TARGET_SYSTEM "psp")
endif() endif()
# Prep cache # Prep cache

View File

@@ -4,7 +4,7 @@
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
add_asset(PALETTE first.palette.png) add_asset(PALETTE first.palette.png)
add_asset(IMAGE minogram_6x10.png type=ALPHA) add_asset(IMAGE font_minogram.png type=ALPHA)
add_asset(IMAGE entities.png type=PALETTIZED) add_asset(IMAGE entities.png type=PALETTIZED)
# add_asset(TILESET entities.tsx) # add_asset(TILESET entities.tsx)

BIN
assets/font_minogram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -12,7 +12,12 @@
#include "console/console.h" #include "console/console.h"
assetdef_t ASSET_DEFINITIONS[ASSET_TYPE_COUNT] = { assetdef_t ASSET_DEFINITIONS[ASSET_TYPE_COUNT] = {
[ASSET_TYPE_PALETTE_IMAGE] = { "DPI", assetPaletteImageLoad }, [ASSET_TYPE_PALETTE_IMAGE] = {
"DPI", assetPaletteImageLoad, assetPaletteImageDispose
},
[ASSET_TYPE_ALPHA_IMAGE] = {
"DAI", assetAlphaImageLoad, assetAlphaImageDispose
},
}; };
errorret_t assetInit(asset_t *asset, const char_t *filename) { errorret_t assetInit(asset_t *asset, const char_t *filename) {
@@ -50,7 +55,6 @@ ref_t assetLock(asset_t *asset) {
void assetUnlock(asset_t *asset, const ref_t ref) { void assetUnlock(asset_t *asset, const ref_t ref) {
assertNotNull(asset, "Asset cannot be NULL."); assertNotNull(asset, "Asset cannot be NULL.");
assertTrue(ref > 0, "Reference must be greater than 0.");
// Just unlock the reference in the reference list. // Just unlock the reference in the reference list.
refListUnlock(&asset->refList, ref); refListUnlock(&asset->refList, ref);
@@ -121,9 +125,16 @@ errorret_t assetLoad(asset_t *asset) {
errorOk(); errorOk();
} }
void assetDispose(asset_t *asset) { errorret_t assetDispose(asset_t *asset) {
assertNotNull(asset, "Asset cannot be NULL."); assertNotNull(asset, "Asset cannot be NULL.");
if(asset->state == ASSET_STATE_LOADED) {
// Dispose of the asset based on its type.
assetdef_t *def = &ASSET_DEFINITIONS[asset->type];
if(def->dispose) errorChain(def->dispose(asset));
asset->state = ASSET_STATE_NOT_LOADED;
}
if(asset->file) { if(asset->file) {
zip_fclose(asset->file); zip_fclose(asset->file);
asset->file = NULL; asset->file = NULL;

View File

@@ -11,6 +11,7 @@
#include <zip.h> #include <zip.h>
#include "asset/type/assetpaletteimage.h" #include "asset/type/assetpaletteimage.h"
#include "asset/type/assetalphaimage.h"
#define ASSET_HEADER_SIZE 3 #define ASSET_HEADER_SIZE 3
#define ASSET_REFERENCE_COUNT_MAX 8 #define ASSET_REFERENCE_COUNT_MAX 8
@@ -29,6 +30,7 @@ typedef enum {
typedef enum { typedef enum {
ASSET_TYPE_UNKNOWN, ASSET_TYPE_UNKNOWN,
ASSET_TYPE_PALETTE_IMAGE, ASSET_TYPE_PALETTE_IMAGE,
ASSET_TYPE_ALPHA_IMAGE,
ASSET_TYPE_COUNT ASSET_TYPE_COUNT
} assettype_t; } assettype_t;
@@ -43,12 +45,14 @@ typedef struct asset_s {
union { union {
assetpaletteimage_t paletteImage; assetpaletteimage_t paletteImage;
assetalphaimager_t alphaImage;
}; };
} asset_t; } asset_t;
typedef struct { typedef struct {
const char_t header[ASSET_HEADER_SIZE + 1]; const char_t header[ASSET_HEADER_SIZE + 1];
errorret_t (*load)(asset_t *asset); errorret_t (*load)(asset_t *asset);
errorret_t (*dispose)(asset_t *asset);
} assetdef_t; } assetdef_t;
extern assetdef_t ASSET_DEFINITIONS[ASSET_TYPE_COUNT]; extern assetdef_t ASSET_DEFINITIONS[ASSET_TYPE_COUNT];
@@ -97,4 +101,4 @@ errorret_t assetLoad(asset_t *asset);
* *
* @param asset The asset to dispose of. * @param asset The asset to dispose of.
*/ */
void assetDispose(asset_t *asset); errorret_t assetDispose(asset_t *asset);

View File

@@ -87,7 +87,26 @@ errorret_t assetManagerGetAsset(const char_t *filename, asset_t **outAsset) {
errorOk(); errorOk();
} }
errorret_t assetManagerLoadAsset(
const char_t *filename,
asset_t **outAsset,
ref_t *outRef
) {
assertNotNull(outRef, "Output reference pointer cannot be null.");
errorChain(assetManagerGetAsset(filename, outAsset));
ref_t ref = assetLock(*outAsset);
errorChain(assetLoad(*outAsset));
*outRef = ref;
errorOk();
}
void assetManagerDispose(void) { void assetManagerDispose(void) {
asset_t *asset = ASSET_MANAGER.assets;
while(asset < &ASSET_MANAGER.assets[ASSET_MANAGER.assetCount]) {
assetDispose(asset);
++asset;
}
if(ASSET_MANAGER.zip != NULL) { if(ASSET_MANAGER.zip != NULL) {
zip_close(ASSET_MANAGER.zip); zip_close(ASSET_MANAGER.zip);
ASSET_MANAGER.zip = NULL; ASSET_MANAGER.zip = NULL;

View File

@@ -6,7 +6,6 @@
*/ */
#pragma once #pragma once
#include "display/texture/texture.h"
#include "asset.h" #include "asset.h"
#define ASSET_MANAGER_ASSET_COUNT_MAX 256 #define ASSET_MANAGER_ASSET_COUNT_MAX 256
@@ -59,6 +58,21 @@ void assetManagerUpdate(void);
*/ */
errorret_t assetManagerGetAsset(const char_t *filename, asset_t **outAsset); errorret_t assetManagerGetAsset(const char_t *filename, asset_t **outAsset);
/**
* Gets, locks and loads an asset. This is all blocking so only use if you
* really need to.
*
* @param filename The filename of the asset to get.
* @param outAsset The output asset pointer.
* @param outRef The output asset reference pointer.
* @return An error code if something goes wrong.
*/
errorret_t assetManagerLoadAsset(
const char_t *filename,
asset_t **outAsset,
ref_t *outRef
);
/** /**
* Disposes/cleans up the asset system. * Disposes/cleans up the asset system.
*/ */

View File

@@ -6,5 +6,6 @@
# Sources # Sources
target_sources(${DUSK_TARGET_NAME} target_sources(${DUSK_TARGET_NAME}
PRIVATE PRIVATE
assetalphaimage.c
assetpaletteimage.c assetpaletteimage.c
) )

View File

@@ -0,0 +1,55 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "asset/asset.h"
errorret_t assetAlphaImageLoad(asset_t *asset) {
// Read entire alpha image.
assetalphaimageraw_t raw;
zip_int64_t bytesRead = zip_fread(asset->file, &raw, sizeof(raw));
if(bytesRead < sizeof(raw.width) + sizeof(raw.height)) {
errorThrow("Failed to read alpha image dimensions.");
}
if(raw.width <= 0 || raw.width > ASSET_ALPHA_IMAGE_WIDTH_MAX) {
errorThrow("Invalid alpha image width.");
}
if(raw.height <= 0 || raw.height > ASSET_ALPHA_IMAGE_HEIGHT_MAX) {
errorThrow("Invalid alpha image height.");
}
printf("Alpha image dimensions: %ux%u\n", raw.width, raw.height);
zip_int64_t expecting = (
sizeof(raw.width) +
sizeof(raw.height) +
(raw.width * raw.height * sizeof(uint8_t))
);
if(bytesRead != expecting) {
errorThrow("Incorrect alpha filesize.");
}
textureInit(
&asset->alphaImage.texture,
(int32_t)raw.width,
(int32_t)raw.height,
TEXTURE_FORMAT_ALPHA,
(texturedata_t){
.alpha = {
.data = raw.pixels
}
}
);
errorOk();
}
errorret_t assetAlphaImageDispose(asset_t *asset) {
textureDispose(&asset->alphaImage.texture);
errorOk();
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
#include "display/texture/texture.h"
#define ASSET_ALPHA_IMAGE_WIDTH_MAX 256
#define ASSET_ALPHA_IMAGE_HEIGHT_MAX 256
#define ASSET_ALPHA_IMAGE_SIZE_MAX ( \
ASSET_ALPHA_IMAGE_WIDTH_MAX * ASSET_ALPHA_IMAGE_HEIGHT_MAX \
)
typedef struct asset_s asset_t;
#pragma pack(push, 1)
typedef struct {
uint32_t width;
uint32_t height;
uint8_t pixels[ASSET_ALPHA_IMAGE_SIZE_MAX];
} assetalphaimageraw_t;
#pragma pack(pop)
typedef struct {
texture_t texture;
} assetalphaimager_t;
/**
* Loads an alpha image asset from the given asset structure. The asset must
* be of type ASSET_TYPE_ALPHA_IMAGE and must be loaded.
*
* @param asset The asset to load the alpha image from.
* @return An error code.
*/
errorret_t assetAlphaImageLoad(asset_t *asset);
/**
* Disposes of an alpha image asset, freeing any allocated resources.
*
* @param asset The asset to dispose of.
* @return An error code.
*/
errorret_t assetAlphaImageDispose(asset_t *asset);

View File

@@ -53,5 +53,10 @@ errorret_t assetPaletteImageLoad(asset_t *asset) {
} }
); );
errorOk();
}
errorret_t assetPaletteImageDispose(asset_t *asset) {
textureDispose(&asset->paletteImage.texture);
errorOk(); errorOk();
} }

View File

@@ -37,4 +37,12 @@ typedef struct {
* @param asset The asset to load the palette image from. * @param asset The asset to load the palette image from.
* @return An error code. * @return An error code.
*/ */
errorret_t assetPaletteImageLoad(asset_t *asset); errorret_t assetPaletteImageLoad(asset_t *asset);
/**
* Disposes of a palette image asset, freeing any allocated resources.
*
* @param asset The asset to dispose of.
* @return An error code.
*/
errorret_t assetPaletteImageDispose(asset_t *asset);

View File

@@ -10,7 +10,7 @@
#include "display/framebuffer/framebuffer.h" #include "display/framebuffer/framebuffer.h"
#include "display/scene/scenemanager.h" #include "display/scene/scenemanager.h"
#include "display/spritebatch/spritebatch.h" #include "display/spritebatch/spritebatch.h"
#include "display/ui/rendertext.h"
#include "display/mesh/quad.h" #include "display/mesh/quad.h"
display_t DISPLAY; display_t DISPLAY;
@@ -62,6 +62,7 @@ errorret_t displayInit(void) {
quadInit(); quadInit();
frameBufferInitBackbuffer(); frameBufferInitBackbuffer();
spriteBatchInit(); spriteBatchInit();
errorChain(renderTextInit());
sceneManagerInit(); sceneManagerInit();
errorOk(); errorOk();
@@ -117,6 +118,7 @@ errorret_t displayUpdate(void) {
errorret_t displayDispose(void) { errorret_t displayDispose(void) {
sceneManagerDispose(); sceneManagerDispose();
renderTextDispose();
spriteBatchDispose(); spriteBatchDispose();
#if DISPLAY_SDL2 #if DISPLAY_SDL2

View File

@@ -12,13 +12,25 @@
#include "display/scene/scenemanager.h" #include "display/scene/scenemanager.h"
#include "display/mesh/quad.h" #include "display/mesh/quad.h"
#include "asset/assetmanager.h" #include "asset/assetmanager.h"
#include "display/ui/rendertext.h"
camera_t SCENE_OVERWORLD_CAMERA; camera_t SCENE_OVERWORLD_CAMERA;
asset_t *testAsset; asset_t *testAsset;
void sceneOverworldInit(void) { void sceneOverworldInit(void) {
cameraInit(&SCENE_OVERWORLD_CAMERA); cameraInit(&SCENE_OVERWORLD_CAMERA);
glm_vec3_copy((vec3){32.0f, 32.0f, 32.0f}, SCENE_OVERWORLD_CAMERA.lookat.position); // glm_vec3_copy((vec3){32.0f, 32.0f, 32.0f}, SCENE_OVERWORLD_CAMERA.lookat.position);
SCENE_OVERWORLD_CAMERA.projType = CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC;
SCENE_OVERWORLD_CAMERA.orthographic.left = 0.0f;
SCENE_OVERWORLD_CAMERA.orthographic.right = 128.0f;
SCENE_OVERWORLD_CAMERA.orthographic.top = 0.0f;
SCENE_OVERWORLD_CAMERA.orthographic.bottom = 72.0f;
SCENE_OVERWORLD_CAMERA.nearClip = -1.0f;
SCENE_OVERWORLD_CAMERA.farClip = 1000.0f;
SCENE_OVERWORLD_CAMERA.viewType = CAMERA_VIEW_TYPE_MATRIX;
glm_mat4_identity(SCENE_OVERWORLD_CAMERA.view);
scene_t *scene = &SCENE_MANAGER_SCENES[SCENE_TYPE_OVERWORLD]; scene_t *scene = &SCENE_MANAGER_SCENES[SCENE_TYPE_OVERWORLD];
scene->flags |= SCENE_FLAG_ACTIVE | SCENE_FLAG_VISIBLE; scene->flags |= SCENE_FLAG_ACTIVE | SCENE_FLAG_VISIBLE;
@@ -39,13 +51,14 @@ void sceneOverworldRender(void) {
// Draw entities // Draw entities
// Draw overlay layer. // Draw overlay layer.
renderTextDraw(0.0f, 0.0f, "Hello World", 0xFF, 0xFF, 0xFF);
spriteBatchPush( // spriteBatchPush(
&testAsset->paletteImage.texture, // &testAsset->paletteImage.texture,
0.0f, 0.0f, 12.0f, 12.0f, // 0.0f, 0.0f, 12.0f, 12.0f,
0xFF, 0xFF, 0xFF, 0xFF, // 0xFF, 0xFF, 0xFF, 0xFF,
0.0f, 0.0f, 1.0f, 1.0f // 0.0f, 0.0f, 1.0f, 1.0f
); // );
spriteBatchFlush(); spriteBatchFlush();
cameraPopMatrix(); cameraPopMatrix();

View File

@@ -5,156 +5,126 @@
// * https://opensource.org/licenses/MIT // * https://opensource.org/licenses/MIT
// */ // */
// #include "rendertext.h" #include "rendertext.h"
#include "asset/assetmanager.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "display/spritebatch/spritebatch.h"
// #include "display/display.h" // #include "display/display.h"
// #include "assert/assert.h"
// #include "display/spritebatch/spritebatch.h"
// #include "util/memory.h"
// #include "util/math.h" // #include "util/math.h"
// texture_t RENDER_TEXT_TEXTURE; rendertext_t RENDER_TEXT;
// static mesh_t RENDER_TEXT_QUAD_MESH; errorret_t renderTextInit(void) {
memoryZero(&RENDER_TEXT, sizeof(rendertext_t));
// void renderTextInit(void) { errorChain(assetManagerLoadAsset(
// const int32_t cols = FONT_COLUMN_COUNT; "font_minogram.dai", &RENDER_TEXT.asset, &RENDER_TEXT.assetRef
// const int32_t rows = (FONT_TILE_COUNT + cols - 1) / cols; ));
// const int32_t inputFontWidth = cols * FONT_TILE_WIDTH; errorOk();
// const int32_t inputFontHeight = rows * FONT_TILE_HEIGHT; }
// int32_t outputFontWidth = inputFontWidth; void renderTextDispose(void) {
// int32_t outputFontHeight = inputFontHeight; if(RENDER_TEXT.asset) {
assetUnlock(RENDER_TEXT.asset, RENDER_TEXT.assetRef);
}
}
// // // Round up to nearest power of 2 void renderTextDrawChar(
// // #if PSP const float_t x,
// // outputFontWidth = mathNextPowTwo(inputFontWidth); const float_t y,
// // outputFontHeight = mathNextPowTwo(inputFontHeight); const char_t c,
// // #endif const uint8_t r,
const uint8_t g,
const uint8_t b
) {
int32_t tileIndex = (int32_t)(c) - RENDER_TEXT_CHAR_START;
assertTrue(
tileIndex >= 0 && tileIndex <= RENDER_TEXT_TILE_COUNT,
"Character is out of bounds for font tiles"
);
// uint8_t *pixels = (uint8_t *)memoryAllocate( const float_t w = (float)RENDER_TEXT.asset->alphaImage.texture.width;
// outputFontWidth * outputFontHeight * const float_t h = (float)RENDER_TEXT.asset->alphaImage.texture.height;
// sizeof(uint8_t) const int32_t tileX = (tileIndex % RENDER_TEXT_COLUMN_COUNT);
// ); const int32_t tileY = (tileIndex / RENDER_TEXT_COLUMN_COUNT);
// // Buffer the pixels. spriteBatchPush(
// for(int tileIndex = 0; tileIndex < FONT_TILE_COUNT; ++tileIndex) { &RENDER_TEXT.asset->alphaImage.texture,
// const int32_t tileX = (tileIndex % FONT_COLUMN_COUNT) * FONT_TILE_WIDTH; x, y,
// const int32_t tileY = (tileIndex / FONT_COLUMN_COUNT) * FONT_TILE_HEIGHT; x + RENDER_TEXT_TILE_WIDTH, y + RENDER_TEXT_TILE_HEIGHT,
// const uint8_t* tile = TILE_PIXEL_DATA[tileIndex]; r, g, b, 0xFF,
(tileX * RENDER_TEXT_TILE_WIDTH) / w,
(tileY * RENDER_TEXT_TILE_HEIGHT) / h,
((tileX + 1) * RENDER_TEXT_TILE_WIDTH) / w,
((tileY + 1) * RENDER_TEXT_TILE_HEIGHT) / h
);
}
// for (int y = 0; y < FONT_TILE_HEIGHT; ++y) { void renderTextDraw(
// for (int x = 0; x < FONT_TILE_WIDTH; ++x) { const float_t x,
// const int32_t pixel = (tileY + y) * outputFontWidth + (tileX + x); const float_t y,
// const int32_t pixelOffset = pixel; const char_t *text,
// uint8_t value = tile[y * FONT_TILE_WIDTH + x]; const uint8_t r,
// pixels[pixel] = value ? 0xFF : 0x00; // Alpha channel const uint8_t g,
// } const uint8_t b
// } ) {
// } assertNotNull(text, "Text cannot be NULL");
// textureInit( float_t posX = x;
// &RENDER_TEXT_TEXTURE, float_t posY = y;
// outputFontWidth, outputFontHeight,
// TEXTURE_FORMAT_ALPHA, pixels
// );
// memoryFree(pixels);
// }
// void renderTextDrawChar( char_t c;
// const float_t x, int32_t i = 0;
// const float_t y, while((c = text[i++]) != '\0') {
// const char_t c, if(c == '\n') {
// const uint8_t r, posX = x;
// const uint8_t g, posY += RENDER_TEXT_TILE_HEIGHT;
// const uint8_t b continue;
// ) { }
// int32_t tileIndex = (int32_t)(c) - FONT_CHAR_START;
// assertTrue(
// tileIndex >= 0 && tileIndex < FONT_TILE_COUNT,
// "Character is out of bounds for font tiles"
// );
// const float_t w = (float)RENDER_TEXT_TEXTURE.width; if(c == ' ') {
// const float_t h = (float)RENDER_TEXT_TEXTURE.height; posX += RENDER_TEXT_TILE_WIDTH;
// const int32_t tileX = (tileIndex % FONT_COLUMN_COUNT); continue;
// const int32_t tileY = (tileIndex / FONT_COLUMN_COUNT); }
// spriteBatchPush( renderTextDrawChar(posX, posY, c, r, g, b);
// &RENDER_TEXT_TEXTURE, posX += RENDER_TEXT_TILE_WIDTH;
// x, y, }
// x + FONT_TILE_WIDTH, y + FONT_TILE_HEIGHT, }
// r, g, b, 0xFF,
// (tileX * FONT_TILE_WIDTH) / w,
// (tileY * FONT_TILE_HEIGHT) / h,
// ((tileX + 1) * FONT_TILE_WIDTH) / w,
// ((tileY + 1) * FONT_TILE_HEIGHT) / h
// );
// }
// void renderTextDraw( void renderTextMeasure(
// const float_t x, const char_t *text,
// const float_t y, int32_t *outWidth,
// const char_t *text, int32_t *outHeight
// const uint8_t r, ) {
// const uint8_t g, assertNotNull(text, "Text cannot be NULL");
// const uint8_t b assertNotNull(outWidth, "Output width pointer cannot be NULL");
// ) { assertNotNull(outHeight, "Output height pointer cannot be NULL");
// assertNotNull(text, "Text cannot be NULL");
// float_t posX = x; int32_t width = 0;
// float_t posY = y; int32_t height = RENDER_TEXT_TILE_HEIGHT;
int32_t lineWidth = 0;
// char_t c; char_t c;
// int32_t i = 0; int32_t i = 0;
// while((c = text[i++]) != '\0') { while((c = text[i++]) != '\0') {
// if(c == '\n') { if(c == '\n') {
// posX = x; if(lineWidth > width) {
// posY += FONT_TILE_HEIGHT; width = lineWidth;
// continue; }
// } lineWidth = 0;
height += RENDER_TEXT_TILE_HEIGHT;
continue;
}
// renderTextDrawChar(posX, posY, c, r, g, b); lineWidth += RENDER_TEXT_TILE_WIDTH;
// posX += FONT_TILE_WIDTH; }
// }
// }
// void renderTextMeasure( if(lineWidth > width) {
// const char_t *text, width = lineWidth;
// int32_t *outWidth, }
// int32_t *outHeight
// ) {
// assertNotNull(text, "Text cannot be NULL");
// assertNotNull(outWidth, "Output width pointer cannot be NULL");
// assertNotNull(outHeight, "Output height pointer cannot be NULL");
// int32_t width = 0; *outWidth = width;
// int32_t height = FONT_TILE_HEIGHT; *outHeight = height;
// int32_t lineWidth = 0; }
// char_t c;
// int32_t i = 0;
// while((c = text[i++]) != '\0') {
// if(c == '\n') {
// if(lineWidth > width) {
// width = lineWidth;
// }
// lineWidth = 0;
// height += FONT_TILE_HEIGHT;
// continue;
// }
// lineWidth += FONT_TILE_WIDTH;
// }
// if(lineWidth > width) {
// width = lineWidth;
// }
// *outWidth = width;
// *outHeight = height;
// }
// lineWidth += FONT_TILE_WIDTH;
// void renderTextDispose(void) {
// textureDispose(&RENDER_TEXT_TEXTURE);
// }

View File

@@ -6,14 +6,28 @@
*/ */
#pragma once #pragma once
#include "display/texture/texture.h" #include "asset/assetmanager.h"
extern texture_t RENDER_TEXT_TEXTURE; #define RENDER_TEXT_CHAR_START '@'
#define RENDER_TEXT_COLUMN_COUNT 16
#define RENDER_TEXT_ROW_COUNT 6
#define RENDER_TEXT_TILE_COUNT (RENDER_TEXT_COLUMN_COUNT*RENDER_TEXT_ROW_COUNT)
#define RENDER_TEXT_TILE_WIDTH 6.0f
#define RENDER_TEXT_TILE_HEIGHT 10.0f
typedef struct {
ref_t assetRef;
asset_t *asset;
} rendertext_t;
extern rendertext_t RENDER_TEXT;
/** /**
* Initializes the text rendering system. * Initializes the text rendering system.
*/ */
void renderTextInit(void); errorret_t renderTextInit(void);
/** /**
* Draws a single character at the specified position. * Draws a single character at the specified position.

View File

@@ -56,10 +56,13 @@ void refListUnlock(reflist_t *list, const ref_t ref) {
} while(slot < end); } while(slot < end);
assertTrue(slot < end, "Reference not found in list"); assertTrue(slot < end, "Reference not found in list");
memoryMove(slot, slot + 1, (end - slot - 1) * sizeof(ref_t)); // Can't move if list only has one ref
if(list->count > 1) {
memoryMove(slot, slot + 1, (end - slot - 1) * sizeof(ref_t));
}
list->count--; list->count--;
if(list->onRemove) list->onRemove(list, ref); if(list->onRemove) list->onRemove(list, ref);
if(list->onEmpty && refListIsEmpty(list)) list->onEmpty(list); if(list->onEmpty && refListIsEmpty(list)) list->onEmpty(list);
} }

View File

@@ -72,7 +72,24 @@ def processAlphaImage(asset):
assetPath = asset['path'] assetPath = asset['path']
print(f"Processing alpha image: {assetPath}") print(f"Processing alpha image: {assetPath}")
data = bytearray()
data.extend(b"DAI") # Dusk Alpha Image
image = Image.open(assetPath).convert("RGBA")
data.extend(image.width.to_bytes(4, 'little')) # Width
data.extend(image.height.to_bytes(4, 'little')) # Height
for pixel in list(image.getdata()):
# Only write alpha channel
data.append(pixel[3].to_bytes(1, 'little')[0]) # Pixel alpha
relative = getAssetRelativePath(assetPath)
fileNameWithoutExt = os.path.splitext(os.path.basename(assetPath))[0]
outputFileRelative = os.path.join(os.path.dirname(relative), f"{fileNameWithoutExt}.dai")
outputFilePath = os.path.join(args.output_assets, outputFileRelative)
os.makedirs(os.path.dirname(outputFilePath), exist_ok=True)
with open(outputFilePath, "wb") as f:
f.write(data)
outImage = { outImage = {
"files": [] "files": [ outputFilePath ]
} }
return outImage return outImage