Add asset loading support.
This commit is contained in:
@ -19,9 +19,9 @@ endif()
|
|||||||
set(DAWN_ROOT_DIR "${CMAKE_SOURCE_DIR}")
|
set(DAWN_ROOT_DIR "${CMAKE_SOURCE_DIR}")
|
||||||
set(DAWN_BUILD_DIR "${CMAKE_BINARY_DIR}")
|
set(DAWN_BUILD_DIR "${CMAKE_BINARY_DIR}")
|
||||||
set(DAWN_SOURCES_DIR "${DAWN_ROOT_DIR}/src")
|
set(DAWN_SOURCES_DIR "${DAWN_ROOT_DIR}/src")
|
||||||
# set(DAWN_TOOLS_DIR "${DAWN_ROOT_DIR}/tools")
|
set(DAWN_TOOLS_DIR "${DAWN_ROOT_DIR}/tools")
|
||||||
# set(DAWN_ASSETS_SOURCE_DIR "${DAWN_ROOT_DIR}/assets")
|
set(DAWN_ASSETS_SOURCE_DIR "${DAWN_ROOT_DIR}/assets")
|
||||||
# set(DAWN_ASSETS_BUILD_DIR "${DAWN_BUILD_DIR}/assets")
|
set(DAWN_ASSETS_BUILD_DIR "${DAWN_BUILD_DIR}/assets")
|
||||||
set(DAWN_GENERATED_DIR "${DAWN_BUILD_DIR}/generated")
|
set(DAWN_GENERATED_DIR "${DAWN_BUILD_DIR}/generated")
|
||||||
set(DAWN_TEMP_DIR "${DAWN_BUILD_DIR}/temp")
|
set(DAWN_TEMP_DIR "${DAWN_BUILD_DIR}/temp")
|
||||||
|
|
||||||
@ -32,7 +32,10 @@ project(Dawn
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Add tools
|
# Add tools
|
||||||
# add_subdirectory(tools)
|
add_subdirectory(tools)
|
||||||
|
|
||||||
|
# Add assets
|
||||||
|
add_subdirectory(assets)
|
||||||
|
|
||||||
# Add Libraries
|
# Add Libraries
|
||||||
add_subdirectory(lib)
|
add_subdirectory(lib)
|
||||||
|
10
assets/CMakeLists.txt
Normal file
10
assets/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Copyright (c) 2024 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
tool_copy(
|
||||||
|
testmap
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/testmap.json
|
||||||
|
testmap.json
|
||||||
|
)
|
@ -21,3 +21,11 @@ FetchContent_Declare(
|
|||||||
GIT_TAG 1796cc5ce298235b615dc7a4750b8c3ba56a05dd
|
GIT_TAG 1796cc5ce298235b615dc7a4750b8c3ba56a05dd
|
||||||
)
|
)
|
||||||
FetchContent_MakeAvailable(cglm)
|
FetchContent_MakeAvailable(cglm)
|
||||||
|
|
||||||
|
#LibArchive
|
||||||
|
FetchContent_Declare(
|
||||||
|
libarchive
|
||||||
|
GIT_REPOSITORY https://github.com/libarchive/libarchive
|
||||||
|
GIT_TAG v3.7.6
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(libarchive)
|
@ -6,6 +6,7 @@
|
|||||||
# Libraries
|
# Libraries
|
||||||
target_link_libraries(${DAWN_TARGET_NAME}
|
target_link_libraries(${DAWN_TARGET_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
|
archive_static
|
||||||
)
|
)
|
||||||
|
|
||||||
# Includes
|
# Includes
|
||||||
@ -16,6 +17,7 @@ target_include_directories(${DAWN_TARGET_NAME}
|
|||||||
|
|
||||||
# Subdirs
|
# Subdirs
|
||||||
add_subdirectory(assert)
|
add_subdirectory(assert)
|
||||||
|
add_subdirectory(asset)
|
||||||
add_subdirectory(display)
|
add_subdirectory(display)
|
||||||
add_subdirectory(game)
|
add_subdirectory(game)
|
||||||
add_subdirectory(rpg)
|
add_subdirectory(rpg)
|
||||||
@ -25,4 +27,7 @@ add_subdirectory(ui)
|
|||||||
target_sources(${DAWN_TARGET_NAME}
|
target_sources(${DAWN_TARGET_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
input.c
|
input.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Assets
|
||||||
|
add_dependencies(${DAWN_TARGET_NAME} dawnassets)
|
11
src/dawn/asset/CMakeLists.txt
Normal file
11
src/dawn/asset/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Copyright (c) 2024 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https:#opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DAWN_TARGET_NAME}
|
||||||
|
PRIVATE
|
||||||
|
asset.c
|
||||||
|
assetarchive.c
|
||||||
|
)
|
158
src/dawn/asset/asset.c
Normal file
158
src/dawn/asset/asset.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "asset.h"
|
||||||
|
#include "assetarchive.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "util/math.h"
|
||||||
|
|
||||||
|
void assetInit() {
|
||||||
|
// TODO: Works on Windows? path sep probs wrong.
|
||||||
|
// const char_t *assetFilename = "dawn.tar";
|
||||||
|
// char_t *assetPath = malloc(sizeof(char_t) * (
|
||||||
|
// strlen(SYSTEM.executableDirectory) + strlen(assetFilename) + 1
|
||||||
|
// ));
|
||||||
|
// sprintf(assetPath, "%s/%s", SYSTEM.executableDirectory, assetFilename);
|
||||||
|
char_t *assetPath = "/home/yourwishes/htdocs/Dawn/build/dawn.tar";
|
||||||
|
ASSET_FILE = fopen(assetPath, "rb");
|
||||||
|
// free(assetPath);
|
||||||
|
assertNotNull(ASSET_FILE, "assetInit: Failed to open asset file!");
|
||||||
|
|
||||||
|
ASSET_ARCHIVE = NULL;
|
||||||
|
ASSET_ENTRY = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t assetReadUntil(uint8_t *buffer, const char_t c, const size_t maxLength) {
|
||||||
|
if(buffer == NULL) {
|
||||||
|
assertTrue(
|
||||||
|
maxLength == -1, "If no buffer is provided, maxLength must be -1."
|
||||||
|
);
|
||||||
|
uint8_t tBuffer[1];
|
||||||
|
size_t read = 0;
|
||||||
|
while(assetRead(tBuffer, 1) == 1 && (char_t)tBuffer[0] != c) read++;
|
||||||
|
return read;
|
||||||
|
} else {
|
||||||
|
size_t read = 0;
|
||||||
|
while(read < maxLength) {
|
||||||
|
// TODO: Read more than 1 char at a time.
|
||||||
|
read += assetRead(buffer + read, 1);
|
||||||
|
if((char_t)buffer[read-1] == c) return read - 1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assetOpen(const char_t *path) {
|
||||||
|
assertNull(ASSET_ARCHIVE, "assetOpenFile: Archive is not NULL!");
|
||||||
|
assertNull(ASSET_ENTRY, "assetOpenFile: Entry is not NULL!");
|
||||||
|
assertStringValid(path, 1024, "assetOpenFile: Path is not valid!");
|
||||||
|
|
||||||
|
// Store path
|
||||||
|
strcpy(ASSET_PATH_CURRENT, path);
|
||||||
|
|
||||||
|
// Prepare data
|
||||||
|
ASSET_ARCHIVE = archive_read_new();
|
||||||
|
assertNotNull(ASSET_ARCHIVE, "assetOpenFile: Failed to create archive!");
|
||||||
|
|
||||||
|
// Set up the reader
|
||||||
|
// archive_read_support_filter_bzip2(ASSET_ARCHIVE);
|
||||||
|
archive_read_support_format_tar(ASSET_ARCHIVE);
|
||||||
|
|
||||||
|
// Open reader
|
||||||
|
archive_read_set_open_callback(ASSET_ARCHIVE, &assetArchiveOpen);
|
||||||
|
archive_read_set_read_callback(ASSET_ARCHIVE, &assetArchiveRead);
|
||||||
|
archive_read_set_seek_callback(ASSET_ARCHIVE, &assetArchiveSeek);
|
||||||
|
archive_read_set_close_callback(ASSET_ARCHIVE, &assetArchiveOpen);
|
||||||
|
archive_read_set_callback_data(ASSET_ARCHIVE, ASSET_ARCHIVE_BUFFER);
|
||||||
|
|
||||||
|
int32_t ret = archive_read_open1(ASSET_ARCHIVE);
|
||||||
|
assertTrue(ret == ARCHIVE_OK, "assetOpenFile: Failed to open archive!");
|
||||||
|
|
||||||
|
// Iterate over each file.
|
||||||
|
while(archive_read_next_header(ASSET_ARCHIVE, &ASSET_ENTRY) == ARCHIVE_OK) {
|
||||||
|
const char_t *headerFile = (char_t*)archive_entry_pathname(ASSET_ENTRY);
|
||||||
|
if(strcmp(headerFile, ASSET_PATH_CURRENT) == 0) return;
|
||||||
|
int32_t ret = archive_read_data_skip(ASSET_ARCHIVE);
|
||||||
|
assertTrue(ret == ARCHIVE_OK, "assetOpenFile: Failed to skip data!");
|
||||||
|
}
|
||||||
|
|
||||||
|
assertUnreachable("assetOpenFile: Failed to find file!");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t assetGetSize() {
|
||||||
|
assertNotNull(ASSET_ARCHIVE, "assetGetSize: Archive is NULL!");
|
||||||
|
assertNotNull(ASSET_ENTRY, "assetGetSize: Entry is NULL!");
|
||||||
|
assertTrue(
|
||||||
|
archive_entry_size_is_set(ASSET_ENTRY),
|
||||||
|
"assetGetSize: Entry size is not set!"
|
||||||
|
);
|
||||||
|
|
||||||
|
size_t n = archive_entry_size(ASSET_ENTRY);
|
||||||
|
|
||||||
|
char_t path[2048];
|
||||||
|
sprintf(
|
||||||
|
path, "/home/yourwishes/htdocs/dusk/build/assets/%s", ASSET_PATH_CURRENT
|
||||||
|
);
|
||||||
|
FILE *temp = fopen(path, "rb");
|
||||||
|
assertNotNull(temp, "assetGetSize: Failed to open temp file!");
|
||||||
|
fseek(temp, 0, SEEK_END);
|
||||||
|
size_t size = ftell(temp);
|
||||||
|
assertTrue(size == n, "assetGetSize: Size is not equal!");
|
||||||
|
fclose(temp);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t assetRead(uint8_t *buffer, size_t bufferSize) {
|
||||||
|
assertNotNull(ASSET_ARCHIVE, "assetRead: Archive is NULL!");
|
||||||
|
assertNotNull(ASSET_ENTRY, "assetRead: Entry is NULL!");
|
||||||
|
assertNotNull(buffer, "assetRead: Buffer is NULL!");
|
||||||
|
assertTrue(bufferSize > 0, "assetRead: Buffer size must be greater than 0!");
|
||||||
|
ssize_t read = archive_read_data(ASSET_ARCHIVE, buffer, bufferSize);
|
||||||
|
|
||||||
|
if(read == ARCHIVE_FATAL) {
|
||||||
|
assertUnreachable(archive_error_string(ASSET_ARCHIVE));
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(read != ARCHIVE_RETRY, "assetRead: Failed to read data (RETRY)!");
|
||||||
|
assertTrue(read != ARCHIVE_WARN, "assetRead: Failed to read data (WARN)!");
|
||||||
|
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
void assetSkip(const size_t length) {
|
||||||
|
assertNotNull(ASSET_ARCHIVE, "assetSkip: Archive is NULL!");
|
||||||
|
assertNotNull(ASSET_ENTRY, "assetSkip: Entry is NULL!");
|
||||||
|
assertTrue(length > 0, "assetSkip: Length must be greater than 0!");
|
||||||
|
|
||||||
|
// Asset archive does not support skipping, so we have to read and discard.
|
||||||
|
uint8_t buffer[1024];
|
||||||
|
size_t remaining = length;
|
||||||
|
do {
|
||||||
|
size_t toRead = mathMin(remaining, 1024);
|
||||||
|
size_t read = assetRead(buffer, toRead);
|
||||||
|
assertTrue(read == toRead, "assetSkip: Failed to skip data! (overskip?)");
|
||||||
|
remaining -= read;
|
||||||
|
} while(remaining > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assetClose() {
|
||||||
|
assertNotNull(ASSET_ARCHIVE, "assetClose: Archive is NULL!");
|
||||||
|
assertNotNull(ASSET_ENTRY, "assetClose: Entry is NULL!");
|
||||||
|
int32_t ret = archive_read_free(ASSET_ARCHIVE);
|
||||||
|
assertTrue(ret == ARCHIVE_OK, "assetClose: Failed to close archive!");
|
||||||
|
ASSET_ARCHIVE = NULL;
|
||||||
|
ASSET_ENTRY = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void assetDispose() {
|
||||||
|
assertNull(ASSET_ARCHIVE, "assetDestroy: Archive is not NULL!");
|
||||||
|
assertNull(ASSET_ENTRY, "assetDestroy: Entry is not NULL!");
|
||||||
|
|
||||||
|
int32_t result = fclose(ASSET_FILE);
|
||||||
|
assertTrue(result == 0, "assetDestroy: Failed to close asset file!");
|
||||||
|
}
|
73
src/dawn/asset/asset.h
Normal file
73
src/dawn/asset/asset.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2023 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dawn.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the asset manager.
|
||||||
|
*/
|
||||||
|
void assetInit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens an asset by its filename (within the asset archive). Asset paths should
|
||||||
|
* always use the unix forward slash '/' as a path separator.
|
||||||
|
*
|
||||||
|
* @param path The path to the asset within the archive.
|
||||||
|
*/
|
||||||
|
void assetOpen(const char_t *path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of the asset.
|
||||||
|
*
|
||||||
|
* @return The size of the asset.
|
||||||
|
*/
|
||||||
|
size_t assetGetSize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the asset into the buffer.
|
||||||
|
*
|
||||||
|
* @param buffer The buffer to read the asset into.
|
||||||
|
* @param bufferSize The size of the buffer.
|
||||||
|
* @return The amount of data read.
|
||||||
|
*/
|
||||||
|
size_t assetRead(uint8_t *buffer, size_t bufferSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads ahead in the buffer until either the end of the buffer, or the
|
||||||
|
* specified character is found. Return value will be -1 if the character was
|
||||||
|
* not found.
|
||||||
|
*
|
||||||
|
* Buffer can be NULL if you just want to skip ahead.
|
||||||
|
*
|
||||||
|
* Returned value will be either the amount of data read into the buffer, which
|
||||||
|
* excludes the extra 1 character that was read from the asset. If the character
|
||||||
|
* was not found, -1 will be returned.
|
||||||
|
*
|
||||||
|
* @param buffer Buffer to read into.
|
||||||
|
* @param c Character to read until.
|
||||||
|
* @param maxLength Maximum length to read.
|
||||||
|
* @return -1 if the character was not found, otherwise the amount of data read.
|
||||||
|
*/
|
||||||
|
size_t assetReadUntil(uint8_t *buffer, const char_t c, const size_t maxLength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skips ahead in the buffer by the specified length.
|
||||||
|
*
|
||||||
|
* @param length The length to skip ahead by.
|
||||||
|
*/
|
||||||
|
void assetSkip(const size_t length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the asset.
|
||||||
|
*/
|
||||||
|
void assetClose();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys and cleans up the asset manager.
|
||||||
|
*/
|
||||||
|
void assetDispose();
|
55
src/dawn/asset/assetarchive.c
Normal file
55
src/dawn/asset/assetarchive.c
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2023 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "asset/assetarchive.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "util/math.h"
|
||||||
|
|
||||||
|
FILE *ASSET_FILE;
|
||||||
|
struct archive *ASSET_ARCHIVE;
|
||||||
|
struct archive_entry *ASSET_ENTRY;
|
||||||
|
uint8_t ASSET_ARCHIVE_BUFFER[ASSET_BUFFER_SIZE];
|
||||||
|
char_t ASSET_PATH_CURRENT[ASSET_PATH_MAX];
|
||||||
|
|
||||||
|
ssize_t assetArchiveRead(
|
||||||
|
struct archive *archive,
|
||||||
|
void *data,
|
||||||
|
const void **buffer
|
||||||
|
) {
|
||||||
|
assertNotNull(archive, "assetArchiveRead: Archive is NULL!");
|
||||||
|
assertNotNull(data, "assetArchiveRead: Data is NULL!");
|
||||||
|
assertNotNull(buffer, "assetArchiveRead: Buffer is NULL!");
|
||||||
|
|
||||||
|
*buffer = data;
|
||||||
|
size_t read = fread(data, 1, ASSET_BUFFER_SIZE, ASSET_FILE);
|
||||||
|
if(ferror(ASSET_FILE)) return ARCHIVE_FATAL;
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t assetArchiveSeek(
|
||||||
|
struct archive *archive,
|
||||||
|
void *data,
|
||||||
|
int64_t offset,
|
||||||
|
int32_t whence
|
||||||
|
) {
|
||||||
|
assertNotNull(archive, "assetArchiveSeek: Archive is NULL!");
|
||||||
|
assertNotNull(data, "assetArchiveSeek: Data is NULL!");
|
||||||
|
assertTrue(offset > 0, "assetArchiveSeek: Offset must be greater than 0!");
|
||||||
|
int32_t ret = fseek(ASSET_FILE, offset, whence);
|
||||||
|
assertTrue(ret == 0, "assetArchiveSeek: Failed to seek!");
|
||||||
|
return ftell(ASSET_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t assetArchiveOpen(struct archive *a, void *data) {
|
||||||
|
int32_t ret = fseek(ASSET_FILE, 0, SEEK_SET);
|
||||||
|
assertTrue(ret == 0, "assetArchiveOpen: Failed to seek to start of file!");
|
||||||
|
return ARCHIVE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t assetArchiveClose(struct archive *a, void *data) {
|
||||||
|
return assetArchiveOpen(a, data);
|
||||||
|
}
|
68
src/dawn/asset/assetarchive.h
Normal file
68
src/dawn/asset/assetarchive.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2023 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "asset/asset.h"
|
||||||
|
#include <archive.h>
|
||||||
|
#include <archive_entry.h>
|
||||||
|
|
||||||
|
#define ASSET_BUFFER_SIZE 32768
|
||||||
|
#define ASSET_PATH_MAX 1024
|
||||||
|
|
||||||
|
extern FILE *ASSET_FILE;
|
||||||
|
extern struct archive *ASSET_ARCHIVE;
|
||||||
|
extern struct archive_entry *ASSET_ENTRY;
|
||||||
|
extern uint8_t ASSET_ARCHIVE_BUFFER[ASSET_BUFFER_SIZE];
|
||||||
|
extern char_t ASSET_PATH_CURRENT[ASSET_PATH_MAX];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal read method provided to libarchive api.
|
||||||
|
*
|
||||||
|
* @param archive The archive to read from.
|
||||||
|
* @param data The data to read into.
|
||||||
|
* @param buffer The buffer to read from.
|
||||||
|
* @return The amount of data read.
|
||||||
|
*/
|
||||||
|
ssize_t assetArchiveRead(
|
||||||
|
struct archive *archive,
|
||||||
|
void *data,
|
||||||
|
const void **buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal seek method provided to libarchive api.
|
||||||
|
*
|
||||||
|
* @param archive The archive to seek in.
|
||||||
|
* @param data The data to seek in.
|
||||||
|
* @param offset Offset bytes to seek.
|
||||||
|
* @param whence Relative to whence to seek.
|
||||||
|
* @return The new position.
|
||||||
|
*/
|
||||||
|
int64_t assetArchiveSeek(
|
||||||
|
struct archive *archive,
|
||||||
|
void *data,
|
||||||
|
int64_t offset,
|
||||||
|
int32_t whence
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal open method provided to libarchive api.
|
||||||
|
*
|
||||||
|
* @param archive The archive to open.
|
||||||
|
* @param data The data to open.
|
||||||
|
* @return The result of the open.
|
||||||
|
*/
|
||||||
|
int32_t assetArchiveOpen(struct archive *a, void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal close method provided to libarchive api.
|
||||||
|
*
|
||||||
|
* @param archive The archive to close.
|
||||||
|
* @param data The data to close.
|
||||||
|
* @return The result of the close.
|
||||||
|
*/
|
||||||
|
int32_t assetArchiveClose(struct archive *a, void *data);
|
@ -11,6 +11,7 @@
|
|||||||
#include "display/display.h"
|
#include "display/display.h"
|
||||||
#include "rpg/world/maps/testmap.h"
|
#include "rpg/world/maps/testmap.h"
|
||||||
#include "ui/textbox.h"
|
#include "ui/textbox.h"
|
||||||
|
#include "asset/asset.h"
|
||||||
|
|
||||||
map_t MAP;
|
map_t MAP;
|
||||||
game_t GAME;
|
game_t GAME;
|
||||||
@ -21,6 +22,7 @@ void gameInit() {
|
|||||||
timeInit();
|
timeInit();
|
||||||
inputInit();
|
inputInit();
|
||||||
displayInit();
|
displayInit();
|
||||||
|
assetInit();
|
||||||
textboxInit();
|
textboxInit();
|
||||||
|
|
||||||
testMapInit(&MAP);
|
testMapInit(&MAP);
|
||||||
@ -62,5 +64,6 @@ void gameSetMap(map_t *map) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void gameDispose() {
|
void gameDispose() {
|
||||||
|
assetDispose();
|
||||||
displayDispose();
|
displayDispose();
|
||||||
}
|
}
|
14
tools/CMakeLists.txt
Normal file
14
tools/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Copyright (c) 2023 Dominic Msters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Tool Level Values
|
||||||
|
set(
|
||||||
|
DAWN_TOOL_GENERATED_DEPENDENCIES
|
||||||
|
CACHE INTERNAL ${DAWN_CACHE_TARGET}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Tools
|
||||||
|
add_subdirectory(assetstool)
|
||||||
|
add_subdirectory(copytool)
|
17
tools/assetstool/CMakeLists.txt
Normal file
17
tools/assetstool/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (c) 2023 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
find_package(Python3 REQUIRED COMPONENTS Interpreter)
|
||||||
|
|
||||||
|
add_custom_target(dawnassets
|
||||||
|
COMMAND
|
||||||
|
${Python3_EXECUTABLE}
|
||||||
|
${DAWN_TOOLS_DIR}/assetstool/assetstool.py
|
||||||
|
--input=${DAWN_ASSETS_BUILD_DIR}
|
||||||
|
--output=${DAWN_BUILD_DIR}/dawn.tar
|
||||||
|
COMMENT "Bundling assets..."
|
||||||
|
USES_TERMINAL
|
||||||
|
DEPENDS ${DAWN_ASSETS}
|
||||||
|
)
|
62
tools/assetstool/assetstool.py
Executable file
62
tools/assetstool/assetstool.py
Executable file
@ -0,0 +1,62 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# Copyright (c) 2023 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tarfile
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
# Args
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Bundles all assets into the internal archive format.'
|
||||||
|
)
|
||||||
|
parser.add_argument('-i', '--input');
|
||||||
|
parser.add_argument('-o', '--output');
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Ensure the directory for the output path exists
|
||||||
|
if not os.path.exists(os.path.dirname(args.output)):
|
||||||
|
os.makedirs(os.path.dirname(args.output))
|
||||||
|
|
||||||
|
# Create a ZIP archive and add the specified directory
|
||||||
|
# archive = tarfile.open(args.output, 'w:bz2') # BZ2 Compression
|
||||||
|
|
||||||
|
# Does the archive already exist?
|
||||||
|
filesInArchive = []
|
||||||
|
|
||||||
|
if os.path.exists(args.output):
|
||||||
|
# Yes, open it
|
||||||
|
archive = tarfile.open(args.output, 'r:')
|
||||||
|
|
||||||
|
# Get all the files in the archive
|
||||||
|
for member in archive.getmembers():
|
||||||
|
filesInArchive.append(member.name)
|
||||||
|
|
||||||
|
archive.close()
|
||||||
|
|
||||||
|
# Open archive for appending.
|
||||||
|
archive = tarfile.open(args.output, 'a:')
|
||||||
|
else:
|
||||||
|
# No, create it
|
||||||
|
archive = tarfile.open(args.output, 'w:')
|
||||||
|
|
||||||
|
# Add all files in the input directory
|
||||||
|
for foldername, subfolders, filenames in os.walk(args.input):
|
||||||
|
for filename in filenames:
|
||||||
|
|
||||||
|
# Is the file already in the archive?
|
||||||
|
absolute_path = os.path.join(foldername, filename)
|
||||||
|
relative_path = os.path.relpath(absolute_path, args.input)
|
||||||
|
|
||||||
|
if relative_path in filesInArchive:
|
||||||
|
# Yes, skip it
|
||||||
|
continue
|
||||||
|
|
||||||
|
# No, add it
|
||||||
|
print(f"Archiving asset {filename}...")
|
||||||
|
archive.add(absolute_path, arcname=relative_path)
|
||||||
|
|
||||||
|
# Close the archive
|
||||||
|
archive.close()
|
11
tools/copytool/CMakeLists.txt
Normal file
11
tools/copytool/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Copyright (c) 2023 Dominic Msters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
function(tool_copy target input output)
|
||||||
|
add_custom_target(${target}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${input} ${output}
|
||||||
|
)
|
||||||
|
add_dependencies(dawnassets ${target})
|
||||||
|
endfunction()
|
Reference in New Issue
Block a user