From 2de3e9b4dfe11b62fc3af0cae858ac5eee827efd Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 5 Nov 2023 19:15:56 +0000 Subject: [PATCH] Build libpakrd with cmake instead of using it as prebuilt library --- CMakeLists.txt | 10 +-- intern/CMakeLists.txt | 3 + intern/pakrd/CMakeLists.txt | 46 ++++++++++ intern/pakrd/include/cpath.h | 18 ++++ intern/pakrd/include/darr.h | 24 +++++ intern/pakrd/include/io.h | 25 ++++++ intern/pakrd/{ => include}/pak.h | 6 -- intern/pakrd/libpakrd.so | Bin 21216 -> 0 bytes intern/pakrd/src/cpath.c | 78 ++++++++++++++++ intern/pakrd/src/darr.c | 62 +++++++++++++ intern/pakrd/src/io.c | 37 ++++++++ intern/pakrd/src/pak.c | 148 +++++++++++++++++++++++++++++++ 12 files changed, 442 insertions(+), 15 deletions(-) create mode 100644 intern/CMakeLists.txt create mode 100644 intern/pakrd/CMakeLists.txt create mode 100644 intern/pakrd/include/cpath.h create mode 100644 intern/pakrd/include/darr.h create mode 100644 intern/pakrd/include/io.h rename intern/pakrd/{ => include}/pak.h (86%) delete mode 100755 intern/pakrd/libpakrd.so create mode 100644 intern/pakrd/src/cpath.c create mode 100644 intern/pakrd/src/darr.c create mode 100644 intern/pakrd/src/io.c create mode 100644 intern/pakrd/src/pak.c diff --git a/CMakeLists.txt b/CMakeLists.txt index f4b95a9..48c7751 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,10 +52,6 @@ target_link_libraries(${PROJECT_NAME} PUBLIC SDL2_ttf ) -add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/intern/pakrd/libpakrd.so ${OUTPUT_BASE_DIR}/${CMAKE_BUILD_TYPE}/lib -) - install(FILES include/aliases.h include/constants.h @@ -71,11 +67,6 @@ install(FILES CONFIGURATIONS Release DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) -install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/intern/pakrd/libpakrd.so - CONFIGURATIONS Release - DESTINATION ${CMAKE_INSTALL_LIBDIR} -) install(TARGETS ${PROJECT_NAME} CONFIGURATIONS Release RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} @@ -85,3 +76,4 @@ install(TARGETS ${PROJECT_NAME} # SUB-DIRECTORIES add_subdirectory(extern) +add_subdirectory(intern) diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt new file mode 100644 index 0000000..0612444 --- /dev/null +++ b/intern/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.10) + +add_subdirectory(pakrd) diff --git a/intern/pakrd/CMakeLists.txt b/intern/pakrd/CMakeLists.txt new file mode 100644 index 0000000..779c51c --- /dev/null +++ b/intern/pakrd/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.17) + +project(pakrd) + +# VARIABLES +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +set(BUILD_SHARED_LIBS ON) + +if(CMAKE_HOST_WIN32) + # Export both *.lib and *.dll on Windows + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) +endif() + +set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/../lib") + +# TARGETS +add_library(${PROJECT_NAME} SHARED + src/cpath.c + src/darr.c + src/io.c + src/pak.c +) + +target_include_directories(${PROJECT_NAME} PUBLIC + ${CMAKE_CURRENT_BINARY_DIR} + include + ../../include/ +) + +target_link_libraries(${PROJECT_NAME} PUBLIC SDL2) + +install(FILES + include/cpath.h + include/darr.h + include/io.h + include/pak.h + CONFIGURATIONS Release + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) +install(TARGETS ${PROJECT_NAME} + CONFIGURATIONS Release + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +) diff --git a/intern/pakrd/include/cpath.h b/intern/pakrd/include/cpath.h new file mode 100644 index 0000000..06f7018 --- /dev/null +++ b/intern/pakrd/include/cpath.h @@ -0,0 +1,18 @@ +#ifndef PATH_UTILS_H +#define PATH_UTILS_H + +#include "aliases.h" + +#define NUMPARTS(...) \ + (sizeof((const char *[]){"", __VA_ARGS__}) / sizeof(const char *) - 1) + +#define JOIN_PATH(DST, ...) join_path(DST, NUMPARTS(__VA_ARGS__), __VA_ARGS__) + +void join_path(char *dst, u64 count, ...); + +#define DIRNAME(DST, PATH) dirup(DST, 1, PATH) +#define DIRUP(DST, COUNT, PATH) dirup(DST, COUNT, PATH) + +void dirup(char *dst, u64 levels, const char *path); + +#endif // !PATH_UTILS_H diff --git a/intern/pakrd/include/darr.h b/intern/pakrd/include/darr.h new file mode 100644 index 0000000..ad47b37 --- /dev/null +++ b/intern/pakrd/include/darr.h @@ -0,0 +1,24 @@ +#ifndef D_ARR_H +#define D_ARR_H + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#include "aliases.h" +#include + +#define INVALID_IDX -1 + +typedef struct darr darr_t; + +bool darr_init(darr_t **darr); +i64 darr_add(darr_t **darr, void *item); +void **darr_get_items(darr_t *darr); +void darr_free(darr_t **darr); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // !D_ARR_H diff --git a/intern/pakrd/include/io.h b/intern/pakrd/include/io.h new file mode 100644 index 0000000..29b8bc0 --- /dev/null +++ b/intern/pakrd/include/io.h @@ -0,0 +1,25 @@ +#ifndef IO_H +#define IO_H + +#include "SDL_rwops.h" +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#include "aliases.h" +#include +#include +#include +#include + +#define STREQ(S1, S2) (strcmp(S1, S2) == 0) +#define STRNEQ(S1, S2, COUNT) (strncmp(S1, S2, COUNT) == 0) + +u64 get_file_length(SDL_RWops *io); +void read_entire_file(void *dst, SDL_RWops *io); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // !IO_H diff --git a/intern/pakrd/pak.h b/intern/pakrd/include/pak.h similarity index 86% rename from intern/pakrd/pak.h rename to intern/pakrd/include/pak.h index ed1db7b..c906810 100644 --- a/intern/pakrd/pak.h +++ b/intern/pakrd/include/pak.h @@ -30,11 +30,6 @@ typedef struct { u64 patch; } pak_ver_t; -typedef struct { - u64 size; - u8 data[]; -} pak_entry_t; - typedef struct { u64 magic; pak_ver_t version; @@ -43,7 +38,6 @@ typedef struct { typedef struct asset_pack asset_pack_t; -bool create_asset_pack(const char *dirpath, const char *output); asset_pack_t *load_asset_pack(const char *filepath); buf_t *read_file_from_pack(asset_pack_t *pack, const char *filename); void close_pack_file(buf_t **buf); diff --git a/intern/pakrd/libpakrd.so b/intern/pakrd/libpakrd.so deleted file mode 100755 index 5ef0b612de9cc4700b54eea851f4b18b66f9e134..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21216 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 +#include +#include + +#if defined(__unix__) || defined(__APPLE__) || defined(__ANDROID__) +INTERNAL char path_sep = '/'; +#elif defined(_WIN32) || defined(_WIN64) +INTERNAL char path_sep = '\\'; +#endif + +void join_root_and_leaf(const char *root, const char *leaf, char *dst); + +void join_path(char *dst, u64 count, ...) { + va_list args; + + va_start(args, count); + + for (u64 i = 0; i < count; ++i) { + join_root_and_leaf(dst, va_arg(args, const char *), dst); + } + + va_end(args); +} + +void dirup(char *dst, u64 levels, const char *path) { + if (levels < 1) { + return; + } + + u64 end_index = 0; + u64 sep_count = 0; + + u64 length = strlen(path); + if (path[length - 1] == path_sep) { + --length; + } + + for (u64 i = length - 1; i >= 0; --i) { + if (path[i] == path_sep) { + ++sep_count; + end_index = i; + + if (sep_count == levels) { + break; + } + } + } + + if (sep_count < levels) { + end_index = 0; + } + + strncpy(dst, path, end_index); +} + +void join_root_and_leaf(const char *root, const char *leaf, char *dst) { + u64 root_length = strlen(root); + u64 root_end = root_length - 1; + + u64 leaf_length = strlen(leaf); + u64 leaf_start = 0; + + if (root[root_end] == path_sep) { + --root_end; + } + + if (leaf[leaf_start] == path_sep) { + ++leaf_start; + } + + memcpy(dst, root, ++root_end); + + dst[root_end] = path_sep; + + memcpy(&(dst[++root_end]), &(leaf[leaf_start]), leaf_length - leaf_start); +} diff --git a/intern/pakrd/src/darr.c b/intern/pakrd/src/darr.c new file mode 100644 index 0000000..9d45212 --- /dev/null +++ b/intern/pakrd/src/darr.c @@ -0,0 +1,62 @@ +#include "darr.h" +#include "aliases.h" +#include +#include + +#define BASE_CAPACITY 2048 + +struct darr { + u64 count; + u64 capacity; + void *items[]; +}; + +bool darr_init(darr_t **darr) { + u64 size = sizeof(darr_t) + sizeof(void *) * BASE_CAPACITY; + + *darr = malloc(size); + if (!(*darr)) { + return false; + } + + memset((void *)(*darr), 0, size); + + (*darr)->capacity = BASE_CAPACITY; + + return true; +} + +i64 darr_add(darr_t **darr, void *item) { + if ((*darr)->count == (*darr)->capacity) { + u64 new_size = + sizeof(darr_t) + sizeof(void *) * ((*darr)->capacity + BASE_CAPACITY); + + darr_t *orig = *darr; + + *darr = realloc(*darr, new_size); + if (!(*darr)) { + *darr = orig; + + return INVALID_IDX; + } + + (*darr)->capacity += BASE_CAPACITY; + } + + u64 index = (*darr)->count; + + (*darr)->items[((*darr)->count)++] = item; + + return index; +} + +void **darr_get_items(darr_t *darr) { return darr->items; } + +void darr_free(darr_t **darr) { + if (!(*darr)) { + return; + } + + free(*darr); + *darr = NULL; +} diff --git a/intern/pakrd/src/io.c b/intern/pakrd/src/io.c new file mode 100644 index 0000000..3c74b0a --- /dev/null +++ b/intern/pakrd/src/io.c @@ -0,0 +1,37 @@ +#include "io.h" +#include "SDL_rwops.h" +#include "aliases.h" +#include "cpath.h" +#include +#include +#include +#include +#include +#include + +#define MAX_DIR_DEPTH PATH_MAX + +u64 get_file_length(SDL_RWops *io) { + u64 current = SDL_RWtell(io); + + SDL_RWseek(io, 0, SEEK_END); + + u64 length = SDL_RWtell(io); + + // Restore the cursor position to where it was + SDL_RWseek(io, current, SEEK_SET); + + return length; +} + +void read_entire_file(void *dst, SDL_RWops *io) { + u64 length = get_file_length(io); + + u64 current = SDL_RWtell(io); + + SDL_RWseek(io, 0, SEEK_SET); + + SDL_RWread(io, dst, length, 1); + + SDL_RWseek(io, current, SEEK_SET); +} diff --git a/intern/pakrd/src/pak.c b/intern/pakrd/src/pak.c new file mode 100644 index 0000000..9c0a305 --- /dev/null +++ b/intern/pakrd/src/pak.c @@ -0,0 +1,148 @@ +#include "pak.h" +#include "SDL_rwops.h" +#include "aliases.h" +#include "darr.h" +#include "io.h" +#include +#include +#include +#include + +#define PAK_MAGIC 0x4B41502054535341 +#define PAK_MAJOR 1 +#define PAK_MINOR 0 +#define PAK_PATCH 0 +#define PAK_EXT ".pak" + +struct asset_pack { + pak_t header; + SDL_RWops *io; + u8 *toc; + toc_entry_t **toc_entries; + u64 assets_length; + u64 assets_offset; +}; + +asset_pack_t *load_asset_pack(const char *filepath) { + char full_path[PATH_MAX] = {0}; + +#ifdef __ANDROID__ + strcpy(full_path, filepath); +#else + realpath(filepath, full_path); +#endif /* ifdef __ANDROID__ */ + + asset_pack_t *pack = (asset_pack_t *)malloc(sizeof(asset_pack_t)); + if (!pack) { + return NULL; + } + + memset((void *)pack, 0, sizeof(asset_pack_t)); + + pack->io = SDL_RWFromFile(full_path, "rb"); + if (!(pack->io)) { + close_asset_pack(&pack); + + return NULL; + } + + u64 file_size = get_file_length(pack->io); + + SDL_RWread(pack->io, (void *)(&(pack->header)), sizeof(pak_t), 1); + + u64 toc_size = pack->header.toc.size; + + pack->toc = (u8 *)malloc(toc_size); + if (!(pack->toc)) { + close_asset_pack(&pack); + + return NULL; + } + + SDL_RWread(pack->io, (void *)(pack->toc), toc_size, 1); + + u64 entries_size = sizeof(toc_entry_t *) * pack->header.toc.count; + + pack->toc_entries = (toc_entry_t **)malloc(entries_size); + if (!(pack->toc_entries)) { + close_asset_pack(&pack); + + return NULL; + } + + toc_entry_t *next = (toc_entry_t *)pack->toc; + + for (u64 i = 0; i < pack->header.toc.count; ++i) { + pack->toc_entries[i] = next; + + next = (toc_entry_t *)((u8 *)next + sizeof(toc_entry_t) + next->length); + } + + pack->assets_offset = SDL_RWtell(pack->io); + + pack->assets_length = file_size - pack->assets_offset; + + return pack; +} + +buf_t *read_file_from_pack(asset_pack_t *pack, const char *filename) { + toc_entry_t *entry = NULL; + buf_t *output = NULL; + + for (u64 i = 0; i < pack->header.toc.count; ++i) { + entry = pack->toc_entries[i]; + + if (STRNEQ(filename, entry->name, entry->length)) { + SDL_RWseek(pack->io, pack->assets_offset + entry->offset, SEEK_SET); + + u64 size = 0; + SDL_RWread(pack->io, &size, sizeof(u64), 1); + + output = (buf_t *)malloc(sizeof(buf_t) + size); + if (!output) { + break; + } + + output->size = size; + + SDL_RWread(pack->io, &(output->data), size, 1); + + break; + } + } + + return output; +} + +void close_pack_file(buf_t **buf) { + buf_t *b = *buf; + + if (!b || b->size == 0) { + return; + } + + free(*buf); + *buf = NULL; +} + +void close_asset_pack(asset_pack_t **pack) { + if (!(*pack)) { + return; + } + + if ((*pack)->toc_entries) { + free((*pack)->toc_entries); + } + + if ((*pack)->toc) { + free((*pack)->toc); + } + + if ((*pack)->io) { + SDL_RWclose((*pack)->io); + } + + free(*pack); + + *pack = NULL; +}