Asset refactor

This commit is contained in:
YourWishes committed 2026-04-03 12:56:04 -05:00
1 parent 0885da8d44
commit da1a5a3f1b
59 files changed
+1032 -726

No files matched your search

@@ -10,6 +10,4 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
assettileset.c
assetlanguage.c
assetscript.c
assetmap.c
assetmapchunk.c
)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1 -1
View File
@@ -75,4 +75,4 @@ else
print("Unknown platform, no default input bindings set.")
end
sceneSet('scene/minesweeper.lua')
sceneSet('scene/main_menu/main_menu.lua')
Binary file not shown.
+44
View File
@@ -0,0 +1,44 @@
module('spritebatch')
module('camera')
module('color')
module('ui')
module('screen')
module('time')
module('text')
module('tileset')
module('texture')
module('input')
module('shader')
module('locale')
screenSetBackground(colorCornflowerBlue())
camera = cameraCreate(CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC)
function sceneDispose()
end
function sceneUpdate()
end
function sceneRender()
-- Update camera
camera.top = screenGetHeight()
camera.right = screenGetWidth()
shaderBind(SHADER_UNLIT)
proj = cameraGetProjectionMatrix(camera)
shaderSetMatrix(SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj)
view = cameraGetViewMatrix(camera)
shaderSetMatrix(SHADER_UNLIT, SHADER_UNLIT_VIEW, view)
-- shaderSetTexture(SHADER_UNLIT, SHADER_UNLIT_TEXTURE, nil)
-- spriteBatchPush(
-- 32, 32,
-- 64, 64,
-- colorWhite()
-- )
-- spriteBatchFlush()
textDraw(10, 10, "Hello World\nHow are you?", colorRed())
spriteBatchFlush()
end
-264
View File
@@ -1,264 +0,0 @@
module('spritebatch')
module('camera')
module('color')
module('ui')
module('screen')
module('time')
module('glm')
module('text')
module('tileset')
module('texture')
module('input')
module('shader')
CELL_STATE_DEFAULT = 0
CELL_STATE_HOVER = 1
CELL_STATE_DOWN = 2
CELL_STATE_DISABLED = 3
screenSetBackground(colorCornflowerBlue())
camera = cameraCreate(CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC)
-- tilesetUi = tilesetGetByName("ui")
-- textureUi = textureLoad(tilesetUi.texture)
-- tilesetBorder = tilesetGetByName("border")
-- textureBorder = textureLoad(tilesetBorder.texture)
-- textureGrid = textureLoad("minesweeper/grid_bg.dpi")
-- tilesetCell = tilesetGetByName("cell")
-- textureCell = textureLoad(tilesetCell.texture)
-- cellSliceDefault = tilesetPositionGetUV(tilesetCell, 3, 5)
-- cellSliceHover = tilesetPositionGetUV(tilesetCell, 3, 4)
-- cellSliceDown = tilesetPositionGetUV(tilesetCell, 3, 6)
-- cellSliceDisabled = tilesetPositionGetUV(tilesetCell, 3, 7)
-- sweepwerCols = 10
-- sweeperRows = 14
-- mouseX = -1
-- mouseY = -1
-- centerX = 0
-- centerY = 0
-- boardWidth = sweepwerCols * tilesetCell.tileWidth
-- boardHeight = sweeperRows * tilesetCell.tileHeight
-- i = 0
-- cells = {}
-- for y = 1, sweeperRows do
-- for x = 1, sweepwerCols do
-- cells[i] = CELL_STATE_DEFAULT
-- i = i + 1
-- end
-- end
function cellDraw(x, y, type)
local slice = cellSliceDefault
if type == CELL_STATE_HOVER then
slice = cellSliceHover
elseif type == CELL_STATE_DOWN then
slice = cellSliceDown
elseif type == CELL_STATE_DISABLED then
slice = cellSliceDisabled
end
spriteBatchPush(
x, y,
x + tilesetCell.tileWidth, y + tilesetCell.tileHeight,
colorWhite(),
slice.u0, slice.v0,
slice.u1, slice.v1
)
end
function backgroundDraw()
local t = (TIME.time / 40) % 1
local scaleX = screenGetWidth() / textureGrid.width
local scaleY = screenGetHeight() / textureGrid.height
local u0 = t * scaleX
local v0 = t * scaleY
local u1 = scaleX + u0
local v1 = scaleY + v0
spriteBatchPush(textureGrid,
0, 0,
screenGetWidth(), screenGetHeight(),
colorWhite(),
u0, v0,
u1, v1
)
end
function borderDraw(x, y, innerWidth, innerHeight)
-- Top Left
local uv = tilesetPositionGetUV(tilesetBorder, 0, 0)
spriteBatchPush(textureBorder,
x - tilesetBorder.tileWidth, y - tilesetBorder.tileWidth,
x, y,
colorWhite(),
uv.u0, uv.v0,
uv.u1, uv.v1
)
-- Top Right
uv = tilesetPositionGetUV(tilesetBorder, 10, 0)
spriteBatchPush(textureBorder,
x + innerWidth, y - tilesetBorder.tileHeight,
x + innerWidth + tilesetBorder.tileWidth, y,
colorWhite(),
uv.u0, uv.v0,
uv.u1, uv.v1
)
-- Bottom Left
uv = tilesetPositionGetUV(tilesetBorder, 0, 10)
spriteBatchPush(textureBorder,
x - tilesetBorder.tileWidth, y + innerHeight,
x, y + innerHeight + tilesetBorder.tileHeight,
colorWhite(),
uv.u0, uv.v0,
uv.u1, uv.v1
)
-- Bottom Right
uv = tilesetPositionGetUV(tilesetBorder, 10, 10)
spriteBatchPush(textureBorder,
x + innerWidth, y + innerHeight,
x + innerWidth + tilesetBorder.tileWidth, y + innerHeight + tilesetBorder.tileHeight,
colorWhite(),
uv.u0, uv.v0,
uv.u1, uv.v1
)
-- Top
uv = tilesetPositionGetUV(tilesetBorder, 1, 0)
spriteBatchPush(textureBorder,
x, y - tilesetBorder.tileHeight,
x + innerWidth, y,
colorWhite(),
uv.u0, uv.v0,
uv.u1, uv.v1
)
-- Bottom
uv = tilesetPositionGetUV(tilesetBorder, 1, 10)
spriteBatchPush(textureBorder,
x, y + innerHeight,
x + innerWidth, y + innerHeight + tilesetBorder.tileHeight,
colorWhite(),
uv.u0, uv.v0,
uv.u1, uv.v1
)
-- Left
uv = tilesetPositionGetUV(tilesetBorder, 0, 1)
spriteBatchPush(textureBorder,
x - tilesetBorder.tileWidth, y,
x, y + innerHeight,
colorWhite(),
uv.u0, uv.v0,
uv.u1, uv.v1
)
-- Right
uv = tilesetPositionGetUV(tilesetBorder, 10, 1)
spriteBatchPush(textureBorder,
x + innerWidth, y,
x + innerWidth + tilesetBorder.tileWidth, y + innerHeight,
colorWhite(),
uv.u0, uv.v0,
uv.u1, uv.v1
)
end
x = 0
y = 0
function sceneDispose()
end
function sceneUpdate()
x = x + inputAxis(INPUT_ACTION_LEFT, INPUT_ACTION_RIGHT)
y = y + inputAxis(INPUT_ACTION_UP, INPUT_ACTION_DOWN)
end
function sceneRender()
-- Update camera
camera.bottom = 0
camera.top = screenGetHeight()
camera.right = screenGetWidth()
shaderBind(SHADER_UNLIT)
proj = cameraGetProjectionMatrix(camera)
shaderSetMatrix(SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj)
view = cameraGetViewMatrix(camera)
shaderSetMatrix(SHADER_UNLIT, SHADER_UNLIT_VIEW, view)
shaderSetTexture(SHADER_UNLIT, SHADER_UNLIT_TEXTURE, nil)
spriteBatchPush(
x, y,
x + 32, y + 32,
colorWhite()
)
spriteBatchFlush()
textDraw(10, 10, "Hello World\nHow are you?", colorRed())
spriteBatchFlush()
-- Update mouse position
-- if INPUT_POINTER then
-- mouseX = inputGetValue(INPUT_ACTION_POINTERX) * screenGetWidth()
-- mouseY = inputGetValue(INPUT_ACTION_POINTERY) * screenGetHeight()
-- -- Draw cursor
-- spriteBatchPush(
-- nil,
-- mouseX - 2, mouseY - 2,
-- mouseX + 2, mouseY + 2,
-- colorRed(),
-- 0, 0,
-- 1, 1
-- )
-- end
-- textDraw(10, 10, "Hello World")
-- centerX = math.floor(screenGetWidth() / 2)
-- centerY = math.floor(screenGetHeight() / 2)
-- Draw elements
-- backgroundDraw()
-- borderDraw(
-- centerX - (boardWidth / 2), centerY - (boardHeight / 2),
-- boardWidth, boardHeight
-- )
-- i = 0
-- -- Foreach cell
-- local offX = centerX - (boardWidth / 2)
-- local offY = centerY - (boardHeight / 2)
-- for y = 0, sweeperRows - 1 do
-- for x = 0, sweepwerCols - 1 do
-- i = y * sweepwerCols + x
-- -- Hovered
-- if
-- cells[i] == CELL_STATE_DEFAULT and
-- mouseX >= x * tilesetCell.tileWidth + offX and mouseX < (x + 1) * tilesetCell.tileWidth + offX and
-- mouseY >= y * tilesetCell.tileHeight + offY and mouseY < (y + 1) * tilesetCell.tileHeight + offY
-- then
-- cells[i] = CELL_STATE_HOVER
-- else
-- cells[i] = CELL_STATE_DEFAULT
-- end
-- cellDraw(
-- x * tilesetCell.tileWidth + offX,
-- y * tilesetCell.tileHeight + offY,
-- cells[i]
-- )
-- end
-- end
end
+19
View File
@@ -0,0 +1,19 @@
{
"name": "Dominic",
"age": 31,
"likes": [
"thing1",
"thing2"
],
"options": {
"someParam": true,
"someSubObject": {
"someSubSubParam": 52
},
"someArray": [
1,
2,
3
]
}
}
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

+31
View File
@@ -0,0 +1,31 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
include(FetchContent)
FetchContent_Declare(
stb
GIT_REPOSITORY https://github.com/nothings/stb.git
)
# Fetch stb if not already done
FetchContent_MakeAvailable(stb)
# Find the stb_image.h header
set(STB_INCLUDE_DIR "${stb_SOURCE_DIR}")
set(STB_IMAGE_HEADER "${stb_SOURCE_DIR}/stb_image.h")
if(EXISTS "${STB_IMAGE_HEADER}")
add_library(stb_image INTERFACE)
target_include_directories(stb_image INTERFACE "${STB_INCLUDE_DIR}")
set(STB_IMAGE_FOUND TRUE)
else()
set(STB_IMAGE_FOUND FALSE)
endif()
# Standard CMake variables
set(STB_IMAGE_INCLUDE_DIRS "${STB_INCLUDE_DIR}")
set(STB_IMAGE_LIBRARIES stb_image)
mark_as_advanced(STB_IMAGE_INCLUDE_DIRS STB_IMAGE_LIBRARIES STB_IMAGE_FOUND)
+18
View File
@@ -0,0 +1,18 @@
include(FetchContent)
if(NOT TARGET yyjson)
FetchContent_Declare(
yyjson
GIT_REPOSITORY https://github.com/ibireme/yyjson.git
GIT_TAG 0.12.0
)
FetchContent_MakeAvailable(yyjson)
endif()
# Provide an imported target if not already available
if(NOT TARGET yyjson::yyjson)
add_library(yyjson::yyjson ALIAS yyjson)
endif()
# Mark yyjson as found for find_package compatibility
set(yyjson_FOUND TRUE)
+2 -1
View File
@@ -4,7 +4,8 @@
# https://opensource.org/licenses/MIT
add_subdirectory(dusk)
add_subdirectory(duskrpg)
# add_subdirectory(duskrpg)
add_subdirectory(dusktrivia)
if(DUSK_TARGET_SYSTEM STREQUAL "linux" OR DUSK_TARGET_SYSTEM STREQUAL "knulli")
add_subdirectory(dusklinux)
+18
View File
@@ -14,6 +14,24 @@ if(NOT libzip_FOUND)
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC zip)
endif()
if(NOT stb_image_FOUND)
find_package(stb REQUIRED)
if(STB_IMAGE_FOUND)
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC stb_image)
else()
message(FATAL_ERROR "stb_image not found. Please ensure stb is correctly fetched.")
endif()
endif()
if(NOT yyjson_FOUND)
find_package(yyjson REQUIRED)
if(yyjson_FOUND)
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC yyjson::yyjson)
else()
message(FATAL_ERROR "yyjson not found. Please ensure yyjson is correctly fetched.")
endif()
endif()
if(NOT Lua_FOUND)
find_package(Lua REQUIRED)
if(Lua_FOUND AND NOT TARGET Lua::Lua)
+2 -1
View File
@@ -7,7 +7,8 @@
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
asset.c
assetfile.c
)
# Subdirs
add_subdirectory(type)
add_subdirectory(loader)
+21 -90
View File
@@ -9,7 +9,6 @@
#include "util/memory.h"
#include "util/string.h"
#include "assert/assert.h"
#include "asset/assettype.h"
#include "engine/engine.h"
#include "util/string.h"
@@ -33,106 +32,38 @@ bool_t assetFileExists(const char_t *filename) {
return true;
}
errorret_t assetLoad(const char_t *filename, void *output) {
errorret_t assetLoad(
const char_t *filename,
assetfileloader_t loader,
void *params,
void *output
) {
assertStrLenMax(filename, FILENAME_MAX, "Filename too long.");
assertNotNull(output, "Output pointer cannot be NULL.");
// Determine the asset type by reading the extension
const assettypedef_t *def = NULL;
for(uint_fast8_t i = 0; i < ASSET_TYPE_COUNT; i++) {
const assettypedef_t *cmp = &ASSET_TYPE_DEFINITIONS[i];
assertNotNull(cmp, "Asset type definition cannot be NULL.");
if(cmp->extension == NULL) continue;
if(!stringEndsWithCaseInsensitive(filename, cmp->extension)) continue;
def = cmp;
break;
}
if(def == NULL) {
errorThrow("Unknown asset type for file: %s", filename);
}
assertNotNull(loader, "Asset file loader cannot be NULL.");
assetfile_t file = {
.filename = filename,
.params = params,
.output = output,
.zipFile = NULL,
.size = 0
};
// Get file size of the asset.
zip_stat_t st;
zip_stat_init(&st);
if(!zip_stat(ASSET.zip, filename, 0, &st) == 0) {
zip_stat_init(&file.stat);
if(!zip_stat(ASSET.zip, filename, 0, &file.stat) == 0) {
errorThrow("Failed to stat asset file: %s", filename);
}
// Minimum file size.
zip_int64_t fileSize = (zip_int64_t)st.size;
if(fileSize <= 0) {
file.size = (zip_int64_t)file.stat.size;
if(file.size <= 0) {
errorThrow("Asset file is empty: %s", filename);
}
// Try to open the file
zip_file_t *file = zip_fopen(ASSET.zip, filename, 0);
if(file == NULL) {
errorThrow("Failed to open asset file: %s", filename);
}
// Load the asset data
switch(def->loadStrategy) {
case ASSET_LOAD_STRAT_ENTIRE:
assertNotNull(def->entire, "Asset load function cannot be NULL.");
// Must have more to read
if(fileSize <= 0) {
zip_fclose(file);
errorThrow("No data remaining to read for asset: %s", filename);
}
if(fileSize > def->dataSize) {
zip_fclose(file);
errorThrow(
"Asset file has too much data remaining after header: %s",
filename
);
}
// Create space to read the entire asset data
void *data = memoryAllocate(fileSize);
if(!data) {
zip_fclose(file);
errorThrow(
"Failed to allocate memory for asset data of file: %s", filename
);
}
// Read in the asset data.
zip_int64_t bytesRead = zip_fread(file, data, fileSize);
if(bytesRead == 0 || bytesRead > fileSize) {
memoryFree(data);
zip_fclose(file);
errorThrow("Failed to read asset data for file: %s", filename);
}
fileSize -= bytesRead;
// Close the file now we have the data
zip_fclose(file);
// Pass to the asset type loader
assetentire_t entire = {
.data = data,
.output = output
};
errorret_t ret = def->entire(entire);
memoryFree(data);
errorChain(ret);
break;
case ASSET_LOAD_STRAT_CUSTOM:
assertNotNull(def->custom, "Asset load function cannot be NULL.");
assetcustom_t customData = {
.zipFile = file,
.output = output
};
errorChain(def->custom(customData));
break;
default:
assertUnreachable("Unknown asset load strategy.");
}
errorChain(loader(&file));
assertNull(file.zipFile, "Asset file loader did not close the file.");
errorOk();
}
+11 -4
View File
@@ -7,8 +7,8 @@
#pragma once
#include "error/error.h"
#include "assettype.h"
#include "asset/assetplatform.h"
#include "assetfile.h"
#ifndef assetInitPlatform
#error "Platform must define assetInitPlatform function."
@@ -20,7 +20,7 @@
#define ASSET_FILE_NAME "dusk.dsk"
#define ASSET_HEADER_SIZE 3
typedef struct {
typedef struct asset_s {
zip_t *zip;
assetplatform_t platform;
} asset_t;
@@ -41,13 +41,20 @@ errorret_t assetInit(void);
bool_t assetFileExists(const char_t *filename);
/**
* Loads an asset by its filename, the output type depends on the asset type.
* Loads an asset by its filename,
*
* @param filename The filename of the asset to retrieve.
* @param loader Loader to use for loading the asset file.
* @param params Parameters to pass to the loader.
* @param output The output pointer to store the loaded asset data.
* @return An error code if the asset could not be loaded.
*/
errorret_t assetLoad(const char_t *filename, void *output);
errorret_t assetLoad(
const char_t *filename,
assetfileloader_t loader,
void *params,
void *output
);
/**
* Disposes/cleans up the asset system.
+53
View File
@@ -0,0 +1,53 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "asset/asset.h"
#include "assert/assert.h"
errorret_t assetFileOpen(assetfile_t *file) {
assertNotNull(file, "Asset file cannot be NULL.");
assertNotNull(file->filename, "Asset file filename cannot be NULL.");
assertNotNull(ASSET.zip, "Asset zip cannot be NULL.");
assertNull(file->zipFile, "Asset file already open.");
file->zipFile = zip_fopen(ASSET.zip, file->filename, 0);
if(file->zipFile == NULL) {
errorThrow("Failed to open asset file: %s", file->filename);
}
file->position = 0;
errorOk();
}
errorret_t assetFileRead(
assetfile_t *file,
void *buffer,
const size_t bufferSize
) {
assertNotNull(file, "Asset file cannot be NULL.");
assertNotNull(file->zipFile, "Asset file must be opened before reading.");
// I assume zip_fread takes buffer NULL for skipping?
zip_int64_t bytesRead = zip_fread(file->zipFile, buffer, bufferSize);
if(bytesRead < 0) {
errorThrow("Failed to read from asset file: %s", file->filename);
}
file->position += bytesRead;
file->lastRead = bytesRead;
errorOk();
}
errorret_t assetFileClose(assetfile_t *file) {
assertNotNull(file, "Asset file cannot be NULL.");
assertNotNull(file->zipFile, "Asset file must be opened before closing.");
if(zip_fclose(file->zipFile) != 0) {
errorThrow("Failed to close asset file: %s", file->filename);
}
file->zipFile = NULL;
file->position = 0;
errorOk();
}
+57
View File
@@ -0,0 +1,57 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
#include <zip.h>
typedef struct assetfile_s assetfile_t;
typedef errorret_t (*assetfileloader_t)(assetfile_t *file);
typedef struct assetfile_s {
const char_t *filename;
void *params;
void *output;
zip_stat_t stat;
zip_int64_t size;
zip_int64_t position;
zip_int64_t lastRead;
zip_file_t *zipFile;
} assetfile_t;
/**
* Opens the asset file for reading. After opening the loader is responsible
* for closing the file.
*
* @param file The asset file to open.
* @return An error code if the file could not be opened.
*/
errorret_t assetFileOpen(assetfile_t *file);
/**
* Read bytes from the asset file. Assumes the file has already been opened
* prior to trying to read anything.
*
* @param file File to read from.
* @param buffer Buffer to read the file data into., or NULL to skip bytes.
* @param size Size of the buffer to read into.
*/
errorret_t assetFileRead(
assetfile_t *file,
void *buffer,
const size_t bufferSize
);
/**
* Closes the asset file and releases any resources associated with it.
*
* @param file The asset file to close.
* @return An error code if the file could not be closed properly.
*/
errorret_t assetFileClose(assetfile_t *file);
-84
View File
@@ -1,84 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "type/assettexture.h"
// #include "type/assetpalette.h"
#include "type/assettileset.h"
#include "type/assetlanguage.h"
#include "type/assetscript.h"
#include "type/assetmap.h"
#include "type/assetmapchunk.h"
#include <zip.h>
typedef enum {
ASSET_TYPE_NULL,
ASSET_TYPE_TEXTURE,
ASSET_TYPE_TILESET,
ASSET_TYPE_LANGUAGE,
ASSET_TYPE_SCRIPT,
ASSET_TYPE_COUNT,
} assettype_t;
typedef enum {
ASSET_LOAD_STRAT_ENTIRE,
ASSET_LOAD_STRAT_CUSTOM
} assetloadstrat_t;
typedef struct assetentire_s {
void *data;
void *output;
} assetentire_t;
typedef struct assetcustom_s {
zip_file_t *zipFile;
void *output;
} assetcustom_t;
typedef struct {
const char_t *extension;
const size_t dataSize;
const assetloadstrat_t loadStrategy;
union {
errorret_t (*entire)(assetentire_t entire);
errorret_t (*custom)(assetcustom_t custom);
};
} assettypedef_t;
static const assettypedef_t ASSET_TYPE_DEFINITIONS[ASSET_TYPE_COUNT] = {
[ASSET_TYPE_NULL] = {
0
},
[ASSET_TYPE_TEXTURE] = {
.extension = "DTX",
.loadStrategy = ASSET_LOAD_STRAT_ENTIRE,
.dataSize = sizeof(assettexture_t),
.entire = assetTextureLoad
},
[ASSET_TYPE_TILESET] = {
.extension = "DTF",
.loadStrategy = ASSET_LOAD_STRAT_ENTIRE,
.dataSize = sizeof(assettileset_t),
.entire = assetTilesetLoad
},
[ASSET_TYPE_LANGUAGE] = {
.extension = "DLF",
.loadStrategy = ASSET_LOAD_STRAT_CUSTOM,
.custom = assetLanguageHandler
},
[ASSET_TYPE_SCRIPT] = {
.extension = "lua",
.loadStrategy = ASSET_LOAD_STRAT_CUSTOM,
.custom = assetScriptHandler
},
};
+12
View File
@@ -0,0 +1,12 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
# Subdirs
add_subdirectory(display)
add_subdirectory(locale)
add_subdirectory(script)
add_subdirectory(json)
@@ -0,0 +1,11 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
assettextureloader.c
assettilesetloader.c
)
@@ -0,0 +1,115 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assettextureloader.h"
#include "assert/assert.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "log/log.h"
#include "util/endian.h"
stbi_io_callbacks ASSET_TEXTURE_STB_CALLBACKS = {
.read = assetTextureReader,
.skip = assetTextureSkipper,
.eof = assetTextureEOF
};
int assetTextureReader(void *user, char *data, int size) {
assertNotNull(data, "Data buffer for stb_image callbacks cannot be NULL.");
assetfile_t *file = (assetfile_t*)user;
assertNotNull(file, "Asset file in stb_image callbacks cannot be NULL.");
errorret_t ret = assetFileRead(file, data, (size_t)size);
if(ret.code != ERROR_OK) {
errorCatch(errorPrint(ret));
return -1;
}
return file->lastRead;
}
void assetTextureSkipper(void *user, int n) {
assetfile_t *file = (assetfile_t*)user;
assertNotNull(file, "Asset file in stb_image callbacks cannot be NULL.");
errorret_t ret = assetFileRead(file, NULL, (size_t)n);
if(ret.code != ERROR_OK) {
errorCatch(errorPrint(ret));
}
}
int assetTextureEOF(void *user) {
assetfile_t *file = (assetfile_t*)user;
assertNotNull(file, "Asset file in stb_image callbacks cannot be NULL.");
return file->position >= file->size;
}
errorret_t assetTextureLoader(assetfile_t *file) {
assertNotNull(file, "Asset file cannot be NULL.");
assertNotNull(file->params, "Asset file parameters cannot be NULL.");
assertNotNull(file->output, "Asset file output cannot be NULL.");
assettextureloaderparams_t *p = (assettextureloaderparams_t*)file->params;
assertNotNull(p, "Asset texture loader parameters cannot be NULL.");
int channelsDesired;
switch(p->format) {
case TEXTURE_FORMAT_RGBA:
channelsDesired = 4;
break;
default:
errorThrow("Bad texture format.");
}
int width, height, channels;
errorChain(assetFileOpen(file));
uint8_t *data = stbi_load_from_callbacks(
&ASSET_TEXTURE_STB_CALLBACKS,
file,
&width,
&height,
&channels,
channelsDesired
);
errorChain(assetFileClose(file));
if(data == NULL) {
const char_t *errorStr = stbi_failure_reason();
errorThrow("Failed to load texture from file %s.", errorStr);
}
// Fixes a specific bug probably with Dolphin but for now just assuming endian
if(!isHostLittleEndian()) {
stbi__vertical_flip(data, width, height, channelsDesired);
}
errorChain(textureInit(
(texture_t*)file->output,
(int32_t)width, (int32_t)height,
p->format,
(texturedata_t){
.rgbaColors = (color_t*)data
}
));
stbi_image_free(data);
errorOk();
}
errorret_t assetTextureLoad(
const char_t *path,
texture_t *out,
const textureformat_t format
) {
assettextureloaderparams_t params = {
.format = format
};
return assetLoad(path, assetTextureLoader, &params, out);
}
@@ -0,0 +1,50 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "asset/asset.h"
#include "display/texture/texture.h"
typedef struct {
textureformat_t format;
} assettextureloaderparams_t;
/**
* STB image read callback for asset files.
*
* @param user User data passed to the callback, should be an assetfile_t*.
* @param data Buffer to read the file data into.
* @param size Size of the buffer to read into.
* @return Number of bytes read, or -1 on error.
*/
int assetTextureReader(void *user, char *data, int size);
void assetTextureSkipper(void *user, int n);
int assetTextureEOF(void *user);
/**
* Handler for texture assets.
*
* @param file Asset file to load the texture from.
* @return Any error that occurs during loading.
*/
errorret_t assetTextureLoader(assetfile_t *file);
/**
* Loads a texture from the specified path.
*
* @param path Path to the texture asset.
* @param out Output texture to load into.
* @param format Format of the texture to load.
* @return Any error that occurs during loading.
*/
errorret_t assetTextureLoad(
const char_t *path,
texture_t *out,
const textureformat_t format
);
@@ -0,0 +1,80 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assettilesetloader.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "util/endian.h"
errorret_t assetTilesetLoader(assetfile_t *file) {
assertNotNull(file, "Asset file pointer for tileset loader is null.");
tileset_t *out = (tileset_t *)file->output;
assertNotNull(out, "Output pointer for tileset loader is null.");
uint8_t *entire = memoryAllocate(file->size);
errorChain(assetFileOpen(file));
errorChain(assetFileRead(file, entire, file->size));
errorChain(assetFileClose(file));
assertTrue(file->lastRead == file->size, "Failed to read entire file.");
if(
entire[0] != 'D' ||
entire[1] != 'T' ||
entire[2] != 'F'
) {
errorThrow("Invalid tileset header");
}
if(entire[3] != 0x00) {
errorThrow("Unsupported tileset version");
}
// Fix endianness
out->tileWidth = endianLittleToHost16(*(uint16_t *)(entire + 4));
out->tileHeight = endianLittleToHost16(*(uint16_t *)(entire + 6));
out->columns = endianLittleToHost16(*(uint16_t *)(entire + 8));
out->rows = endianLittleToHost16(*(uint16_t *)(entire + 10));
// out->right = endianLittleToHost16(*(uint16_t *)(entire + 12));
// out->bottom = endianLittleToHost16(*(uint16_t *)(entire + 14));
if(out->tileWidth == 0) {
errorThrow("Tile width cannot be 0");
}
if(out->tileHeight == 0) {
errorThrow("Tile height cannot be 0");
}
if(out->columns == 0) {
errorThrow("Column count cannot be 0");
}
if(out->rows == 0) {
errorThrow("Row count cannot be 0");
}
out->uv[0] = endianLittleToHostFloat(*(float *)(entire + 16));
out->uv[1] = endianLittleToHostFloat(*(float *)(entire + 20));
if(out->uv[1] < 0.0f || out->uv[1] > 1.0f) {
errorThrow("Invalid v0 value in tileset");
}
// Setup tileset
out->tileCount = out->columns * out->rows;
memoryFree(entire);
errorOk();
}
errorret_t assetTilesetLoad(
const char_t *path,
tileset_t *out
) {
return assetLoad(path, assetTilesetLoader, NULL, out);
}
@@ -0,0 +1,30 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "asset/asset.h"
#include "display/texture/tileset.h"
/**
* Handler for tileset assets.
*
* @param file Asset file to load the tileset from.
* @return Any error that occurs during loading.
*/
errorret_t assetTilesetLoader(assetfile_t *file);
/**
* Loads a tileset from the specified path.
*
* @param path Path to the tileset asset.
* @param out Output tileset to load into.
* @return Any error that occurs during loading.
*/
errorret_t assetTilesetLoad(
const char_t *path,
tileset_t *out
);
+10
View File
@@ -0,0 +1,10 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
assetjsonloader.c
)
@@ -0,0 +1,53 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assetjsonloader.h"
#include "util/memory.h"
#include "assert/assert.h"
errorret_t assetJsonLoadFileToDoc(assetfile_t *file, yyjson_doc **outDoc) {
assertNotNull(file, "Asset file pointer for JSON loader is null.");
assertNotNull(outDoc, "Output pointer for JSON loader is null.");
if(file->size > ASSET_JSON_FILE_SIZE_MAX) {
errorThrow("JSON exceeds maximum allowed size");
}
// Create buffer
uint8_t *buffer = memoryAllocate(file->size);
errorChain(assetFileOpen(file));
// Read entire file
errorChain(assetFileRead(file, buffer, file->size));
assertTrue(file->lastRead == file->size, "Failed to read entire JSON file.");
errorChain(assetFileClose(file));
*outDoc = yyjson_read(
buffer,
file->size,
YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_TRAILING_COMMAS
);
memoryFree(buffer);
if(!*outDoc) errorThrow("Failed to parse JSON");
errorOk();
}
errorret_t assetJsonLoader(assetfile_t *file) {
yyjson_doc **outDoc = (yyjson_doc **)file->output;
assertNotNull(outDoc, "Output pointer for JSON loader is null.");
return assetJsonLoadFileToDoc(file, outDoc);
}
errorret_t assetJsonLoad(
const char_t *path,
yyjson_doc **outDoc
) {
return assetLoad(path, assetJsonLoader, NULL, outDoc);
}
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "asset/asset.h"
#include "yyjson.h"
#define ASSET_JSON_FILE_SIZE_MAX 1024*256
typedef struct {
void *nothing;
} assetjsonloaderparams_t;
/**
* Loads a JSON document from the specified asset file.
*
* @param file Asset file to load the JSON document from.
* @param outDoc Pointer to store the loaded JSON document.
* @return Any error that occurs during loading.
*/
errorret_t assetJsonLoadFileToDoc(assetfile_t *file, yyjson_doc **outDoc);
/**
* Handler for locale assets.
*
* @param file Asset file to load the locale from.
* @return Any error that occurs during loading.
*/
errorret_t assetJsonLoader(assetfile_t *file);
/**
* Loads a locale from the specified path.
*
* @param path Path to the locale asset.
* @param outDoc Pointer to store the loaded JSON document.
* @return Any error that occurs during loading.
*/
errorret_t assetJsonLoad(
const char_t *path,
yyjson_doc **outDoc
);
@@ -0,0 +1,10 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
assetlocaleloader.c
)
@@ -0,0 +1,19 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assetlocaleloader.h"
errorret_t assetLocaleLoader(assetfile_t *file) {
errorThrow("Locale asset loading is not yet implemented.");
}
errorret_t assetLocaleLoad(
const char_t *path,
void *nothing
) {
errorThrow("Locale asset loading is not yet implemented.");
}
@@ -0,0 +1,34 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "asset/asset.h"
#include "locale/localemanager.h"
typedef struct {
void *nothing;
} assetlocaleloaderparams_t;
/**
* Handler for locale assets.
*
* @param file Asset file to load the locale from.
* @return Any error that occurs during loading.
*/
errorret_t assetLocaleLoader(assetfile_t *file);
/**
* Loads a locale from the specified path.
*
* @param path Path to the locale asset.
* @param nothing Nothing yet.
* @return Any error that occurs during loading.
*/
errorret_t assetLocaleLoad(
const char_t *path,
void *nothing
);
@@ -0,0 +1,10 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
assetscriptloader.c
)
@@ -0,0 +1,82 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assetscriptloader.h"
#include "assert/assert.h"
errorret_t assetScriptLoader(assetfile_t *file) {
assertNotNull(file, "Asset file cannot be NULL");
assertNull(file->zipFile, "Asset file zip handle must be NULL");
assertNotNull(file->output, "Asset file output cannot be NULL");
assetscript_t *script = (assetscript_t *)file->output;
// Open the asset for buffering
errorChain(assetFileOpen(file));
// Request loading
if(!lua_load(
script->ctx->luaState,
assetScriptReader,
file,
file->filename,
NULL
) == LUA_OK) {
const char_t *strErr = lua_tostring(script->ctx->luaState, -1);
lua_pop(script->ctx->luaState, 1);
errorThrow("Failed to load Lua script: %s", strErr);
}
// Now loaded, exec
if(lua_pcall(script->ctx->luaState, 0, LUA_MULTRET, 0) != LUA_OK) {
const char_t *strErr = lua_tostring(script->ctx->luaState, -1);
lua_pop(script->ctx->luaState, 1);
errorThrow("Failed to execute Lua script: %s", strErr);
}
// Close the file
return assetFileClose(file);
}
errorret_t assetScriptLoad(const char_t *path, scriptcontext_t *ctx) {
assertNotNull(path, "Script path cannot be NULL");
assertNotNull(ctx, "Script context cannot be NULL");
assetscript_t script;
script.ctx = ctx;
return assetLoad(
path,
assetScriptLoader,
NULL,
&script
);
}
const char_t * assetScriptReader(lua_State* L, void* data, size_t* size) {
assetfile_t *file = (assetfile_t*)data;
assertNotNull(file, "Script asset file cannot be NULL");
assertNotNull(file->zipFile, "Script asset zip handle cannot be NULL");
assertNotNull(file->output, "Script asset output cannot be NULL");
assetscript_t *script = (assetscript_t *)file->output;
assertNotNull(script, "Script asset output cannot be NULL");
zip_int64_t read = zip_fread(
file->zipFile,
script->buffer,
sizeof(script->buffer)
);
if(read < 0) {
*size = 0;
return NULL;
}
*size = (size_t)read;
return script->buffer;
}
@@ -0,0 +1,48 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "asset/asset.h"
#include "script/scriptcontext.h"
#define ASSET_SCRIPT_BUFFER_SIZE 1024
typedef struct {
void *nothing;
} assetscriptloaderparams_t;
typedef struct {
scriptcontext_t *ctx;
char_t buffer[ASSET_SCRIPT_BUFFER_SIZE];
} assetscript_t;
/**
* Handler for script assets.
*
* @param file Asset file to load the script from.
* @return Any error that occurs during loading.
*/
errorret_t assetScriptLoader(assetfile_t *file);
/**
* Loads a script from the specified path.
*
* @param path Path to the script asset.
* @param ctx Script context to load the script into.
* @return Any error that occurs during loading.
*/
errorret_t assetScriptLoad(const char_t *path, scriptcontext_t *ctx);
/**
* Reader function for Lua to read script data from the asset.
*
* @param L Lua state.
* @param data Pointer to the scriptcontext_t structure.
* @param size Pointer to store the size of the read data.
* @return Pointer to the read data buffer.
*/
const char_t * assetScriptReader(lua_State* L, void* data, size_t* size);
-15
View File
@@ -1,15 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "asset/asset.h"
#include "assert/assert.h"
#include "util/memory.h"
errorret_t assetMapHandler(assetcustom_t custom) {
printf("Map Loaded from asset!\n");
errorOk();
}
-20
View File
@@ -1,20 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
typedef struct assetcustom_s assetcustom_t;
/**
* Loads a map asset from the given data pointer into the output map structure.
*
* @param data Pointer to the raw assetmap_t data.
* @param output Pointer to the map_t to load the map into.
* @return An error code.
*/
errorret_t assetMapHandler(assetcustom_t custom);
-185
View File
@@ -1,185 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "asset/asset.h"
#include "assert/assert.h"
#include "map/mapchunk.h"
#include "util/endian.h"
#pragma pack(push, 1)
typedef struct {
uint32_t tileCount;
uint8_t modelCount;
uint8_t entityCount;
} assetchunkheader_t;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct {
maptile_t tile;
} assetchunktiledata_t;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct {
uint32_t vertexCount;
} assetchunkmodelheader_t;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct {
uint8_t entityType;
uint8_t localX;
uint8_t localY;
uint8_t localZ;
} assetchunkentityheader_t;
#pragma pack(pop)
errorret_t assetMapChunkHandler(assetcustom_t custom) {
assertNotNull(custom.output, "Output pointer cannot be NULL");
assertNotNull(custom.zipFile, "Zip file pointer cannot be NULL");
mapchunk_t *chunk = (mapchunk_t *)custom.output;
assertTrue(chunk->meshCount == 0, "Chunk is not in a good state");
// Read header
assetchunkheader_t header;
size_t bytesRead = zip_fread(
custom.zipFile, &header, sizeof(assetchunkheader_t)
);
if(bytesRead != sizeof(assetchunkheader_t)) {
zip_fclose(custom.zipFile);
errorThrow("Failed to read chunk asset header.");
}
// Fix endianess if necessary
header.tileCount = endianLittleToHost32(header.tileCount);
if(header.tileCount != CHUNK_TILE_COUNT) {
zip_fclose(custom.zipFile);
errorThrow(
"Chunk asset has invalid tile count: %d (expected %d).",
header.tileCount,
CHUNK_TILE_COUNT
);
}
if(header.modelCount > CHUNK_MESH_COUNT_MAX) {
zip_fclose(custom.zipFile);
errorThrow(
"Chunk asset has too many models: %d (max %d).",
header.modelCount,
CHUNK_MESH_COUNT_MAX
);
}
if(header.entityCount > CHUNK_ENTITY_COUNT_MAX) {
zip_fclose(custom.zipFile);
errorThrow(
"Chunk asset has too many entities: %d (max %d).",
header.entityCount,
CHUNK_ENTITY_COUNT_MAX
);
}
chunk->meshCount = header.modelCount;
// Read tile data
bytesRead = zip_fread(
custom.zipFile,
chunk->tiles,
sizeof(assetchunktiledata_t) * header.tileCount
);
if(bytesRead != sizeof(assetchunktiledata_t) * header.tileCount) {
zip_fclose(custom.zipFile);
errorThrow("Failed to read chunk tile data.");
}
// For each model...
uint32_t vertexIndex = 0;
for(uint8_t i = 0; i < header.modelCount; i++) {
assetchunkmodelheader_t modelHeader;
bytesRead = zip_fread(
custom.zipFile, &modelHeader, sizeof(assetchunkmodelheader_t)
);
if(bytesRead != sizeof(assetchunkmodelheader_t)) {
zip_fclose(custom.zipFile);
errorThrow("Failed to read chunk model header.");
}
// Fix endianess if necessary
modelHeader.vertexCount = endianLittleToHost32(modelHeader.vertexCount);
if(
vertexIndex + modelHeader.vertexCount >
CHUNK_VERTEX_COUNT_MAX
) {
zip_fclose(custom.zipFile);
errorThrow("Chunk model vertex count exceeds maximum.");
}
// Read vertex data.
bytesRead = zip_fread(
custom.zipFile,
&chunk->vertices[vertexIndex],
sizeof(meshvertex_t) * modelHeader.vertexCount
);
if(bytesRead != sizeof(meshvertex_t) * modelHeader.vertexCount) {
zip_fclose(custom.zipFile);
errorThrow("Failed to read chunk model vertex data.");
}
// Init the mesh
if(modelHeader.vertexCount > 0) {
mesh_t *mesh = &chunk->meshes[i];
meshInit(
mesh,
MESH_PRIMITIVE_TYPE_TRIANGLES,
modelHeader.vertexCount,
&chunk->vertices[vertexIndex]
);
vertexIndex += modelHeader.vertexCount;
} else {
// chunk->meshes[i].vertexCount = 0;
}
}
// Read entity data
// for(uint8_t i = 0; i < header.entityCount; i++) {
// assetchunkentityheader_t entityHeader;
// bytesRead = zip_fread(
// custom.zipFile, &entityHeader, sizeof(assetchunkentityheader_t)
// );
// if(bytesRead != sizeof(assetchunkentityheader_t)) {
// zip_fclose(custom.zipFile);
// errorThrow("Failed to read chunk entity header.");
// }
// uint8_t entityIndex = entityGetAvailable();
// if(entityIndex == 0xFF) {
// zip_fclose(custom.zipFile);
// errorThrow("No available entity slots.");
// }
// entity_t *entity = &ENTITIES[entityIndex];
// entityInit(entity, (entitytype_t)entityHeader.entityType);
// entity->position.x = (
// (chunk->position.x * CHUNK_WIDTH) + entityHeader.localX
// );
// entity->position.y = (
// (chunk->position.y * CHUNK_HEIGHT) + entityHeader.localY
// );
// entity->position.z = (
// (chunk->position.z * CHUNK_DEPTH) + entityHeader.localZ
// );
// chunk->entities[i] = entityIndex;
// }
errorOk();
}
-19
View File
@@ -1,19 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
typedef struct assetcustom_s assetcustom_t;
/**
* Handles loading of map chunk data from a map chunk asset file.
*
* @param custom The custom asset loading parameters.
* @return An error code.
*/
errorret_t assetMapChunkHandler(assetcustom_t custom);
+2 -2
View File
@@ -35,8 +35,8 @@ void cameraInitOrthographic(camera_t *camera) {
camera->projType = CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC;
camera->orthographic.left = 0.0f;
camera->orthographic.right = SCREEN.width;
camera->orthographic.top = 0.0f;
camera->orthographic.bottom = SCREEN.height;
camera->orthographic.top = SCREEN.height;
camera->orthographic.bottom = 0.0f;
camera->nearClip = 0.1f;
camera->farClip = 1.0f;
+15 -4
View File
@@ -9,16 +9,18 @@
#include "assert/assert.h"
#include "util/memory.h"
#include "display/spritebatch/spritebatch.h"
#include "asset/asset.h"
#include "asset/loader/display/assettextureloader.h"
#include "asset/loader/display/assettilesetloader.h"
#include "display/shader/shaderunlit.h"
texture_t DEFAULT_FONT_TEXTURE;
tileset_t DEFAULT_FONT_TILESET;
errorret_t textInit(void) {
errorChain(assetLoad("ui/minogram.dtx", &DEFAULT_FONT_TEXTURE));
errorChain(assetLoad("ui/minogram.dtf", &DEFAULT_FONT_TILESET));
errorChain(assetTextureLoad(
"ui/minogram.png", &DEFAULT_FONT_TEXTURE, TEXTURE_FORMAT_RGBA
));
errorChain(assetTilesetLoad("ui/minogram.dtf", &DEFAULT_FONT_TILESET));
errorOk();
}
@@ -75,6 +77,15 @@ errorret_t textDraw(
errorChain(shaderSetTexture(&SHADER_UNLIT, SHADER_UNLIT_TEXTURE, texture));
// errorChain(spriteBatchPush(
// // texture,
// posX, posY,
// posX + texture->width * 1, posY + texture->height * 1,
// color,
// 0.0f, 0.0f, 1.0f, 1.0f
// ));
// errorOk();
char_t c;
int32_t i = 0;
while((c = text[i++]) != '\0') {
+20 -6
View File
@@ -14,10 +14,11 @@
#include "scene/scene.h"
#include "asset/asset.h"
#include "ui/ui.h"
#include "map/map.h"
#include "script/scriptmanager.h"
#include "item/backpack.h"
#include "assert/assert.h"
#include "game/game.h"
#include "asset/loader/json/assetjsonloader.h"
engine_t ENGINE;
@@ -35,9 +36,22 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
errorChain(scriptManagerInit());
errorChain(displayInit());
errorChain(uiInit());
errorChain(mapInit());
errorChain(sceneInit());
backpackInit();
errorChain(gameInit());
// JSON test.
yyjson_doc *doc;
assetJsonLoad("test.json", &doc);
yyjson_val *root = yyjson_doc_get_root(doc);
assertTrue(root, "JSON root is null.");
yyjson_val *name = yyjson_obj_get(root, "name");
assertTrue(name && yyjson_is_str(name), "JSON 'name' field is missing or not a string.");
const char *nameStr = yyjson_get_str(name);
printf("Name: %s\n", nameStr);
yyjson_doc_free(doc);
// Run the initial script.
scriptcontext_t ctx;
@@ -54,7 +68,7 @@ errorret_t engineUpdate(void) {
uiUpdate();
errorChain(sceneUpdate());
mapUpdate();
errorChain(gameUpdate());
errorChain(displayUpdate());
if(inputPressed(INPUT_ACTION_RAGEQUIT)) ENGINE.running = false;
@@ -68,7 +82,7 @@ void engineExit(void) {
errorret_t engineDispose(void) {
sceneDispose();
mapDispose();
errorChain(gameDispose());
localeManagerDispose();
uiDispose();
errorChain(displayDispose());
-3
View File
@@ -7,8 +7,6 @@
#include "localemanager.h"
#include "util/memory.h"
#include "asset/asset.h"
#include "assert/assert.h"
localemanager_t LOCALE;
@@ -34,5 +32,4 @@ errorret_t localeManagerSetLocale(const dusklocale_t locale) {
}
void localeManagerDispose() {
assetLanguageDispose(&LOCALE.language);
}
+2 -2
View File
@@ -6,13 +6,13 @@
*/
#pragma once
#include "asset/asset.h"
#include "error/error.h"
#include "localemanager.h"
#include "locale/locale.h"
typedef struct {
dusklocale_t locale;
assetlanguage_t language;
// assetlanguage_t language;
} localemanager_t;
extern localemanager_t LOCALE;
+10 -3
View File
@@ -6,9 +6,9 @@
*/
#include "moduletexture.h"
#include "asset/asset.h"
#include "display/texture/texture.h"
#include "assert/assert.h"
#include "display/texture/texture.h"
#include "asset/loader/display/assettextureloader.h"
#include "util/memory.h"
#include "util/string.h"
@@ -83,6 +83,11 @@ int moduleTextureLoad(lua_State *l) {
luaL_error(l, "First argument must be a string filename.");
return 0;
}
if(!lua_isnumber(l, 2)) {
luaL_error(l, "Second argument must be a number format.");
return 0;
}
const char_t *filename = lua_tostring(l, 1);
assertNotNull(filename, "Filename cannot be NULL.");
@@ -92,7 +97,9 @@ int moduleTextureLoad(lua_State *l) {
texture_t *tex = (texture_t *)lua_newuserdata(l, sizeof(texture_t));
memoryZero(tex, sizeof(texture_t));
errorret_t ret = assetLoad(filename, tex);
textureformat_t format = (textureformat_t)lua_tonumber(l, 2);
errorret_t ret = assetTextureLoad(filename, tex, format);
if(ret.code != ERROR_OK) {
errorCatch(errorPrint(ret));
luaL_error(l, "Failed to load texture asset: %s", filename);
+2 -20
View File
@@ -11,6 +11,7 @@
#include "util/memory.h"
#include "script/scriptmodule.h"
#include "event/event.h"
#include "asset/loader/script/assetscriptloader.h"
errorret_t scriptContextInit(scriptcontext_t *context) {
assertNotNull(context, "Script context cannot be NULL");
@@ -53,26 +54,7 @@ errorret_t scriptContextExec(scriptcontext_t *context, const char_t *script) {
errorret_t scriptContextExecFile(scriptcontext_t *ctx, const char_t *fname) {
assertNotNull(ctx, "Script context cannot be NULL");
assertNotNull(fname, "Filename cannot be NULL");
assetscript_t script;
errorChain(assetLoad(fname, &script));
if(lua_load(
ctx->luaState, assetScriptReader, &script, fname, NULL
) != LUA_OK) {
const char_t *strErr = lua_tostring(ctx->luaState, -1);
lua_pop(ctx->luaState, 1);
errorThrow("Failed to load Lua script: %s", strErr);
}
if(lua_pcall(ctx->luaState, 0, LUA_MULTRET, 0) != LUA_OK) {
const char_t *strErr = lua_tostring(ctx->luaState, -1);
lua_pop(ctx->luaState, 1);
errorThrow("Failed to execute Lua script: %s", strErr);
}
errorChain(assetScriptDispose(&script));
errorOk();
return assetScriptLoad(fname, ctx);
}
void scriptContextDispose(scriptcontext_t *context) {
+14
View File
@@ -0,0 +1,14 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Includes
target_include_directories(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
# Subdirs
add_subdirectory(game)
add_subdirectory(script)
+10
View File
@@ -0,0 +1,10 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
game.c
)
+20
View File
@@ -0,0 +1,20 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "game.h"
errorret_t gameInit(void) {
errorOk();
}
errorret_t gameUpdate(void) {
errorOk();
}
errorret_t gameDispose(void) {
errorOk();
}
+30
View File
@@ -0,0 +1,30 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
/**
* Initializes the game.
*
* @return An error code indicating success or failure.
*/
errorret_t gameInit(void);
/**
* Updates the game state. Should be called every frame.
*
* @return An error code indicating success or failure.
*/
errorret_t gameUpdate(void);
/**
* Disposes of game resources. Should be called when the game is shutting down.
*
* @return An error code indicating success or failure.
*/
errorret_t gameDispose(void);
+7
View File
@@ -0,0 +1,7 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Subdirs
add_subdirectory(module)
@@ -0,0 +1,6 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Subdirectories
+8
View File
@@ -0,0 +1,8 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once