Build libpakrd with cmake instead of using it as prebuilt library
This commit is contained in:
1 parent
c5dd826c66
commit
2de3e9b4df
12 files changed
+442
-15
No files matched your search
+1
-9
@@ -52,10 +52,6 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
|
|||||||
SDL2_ttf
|
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
|
install(FILES
|
||||||
include/aliases.h
|
include/aliases.h
|
||||||
include/constants.h
|
include/constants.h
|
||||||
@@ -71,11 +67,6 @@ install(FILES
|
|||||||
CONFIGURATIONS Release
|
CONFIGURATIONS Release
|
||||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||||
)
|
)
|
||||||
install(FILES
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/intern/pakrd/libpakrd.so
|
|
||||||
CONFIGURATIONS Release
|
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
)
|
|
||||||
install(TARGETS ${PROJECT_NAME}
|
install(TARGETS ${PROJECT_NAME}
|
||||||
CONFIGURATIONS Release
|
CONFIGURATIONS Release
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
@@ -85,3 +76,4 @@ install(TARGETS ${PROJECT_NAME}
|
|||||||
|
|
||||||
# SUB-DIRECTORIES
|
# SUB-DIRECTORIES
|
||||||
add_subdirectory(extern)
|
add_subdirectory(extern)
|
||||||
|
add_subdirectory(intern)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
|
add_subdirectory(pakrd)
|
||||||
@@ -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}
|
||||||
|
)
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef D_ARR_H
|
||||||
|
#define D_ARR_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#include "aliases.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#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
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef IO_H
|
||||||
|
#define IO_H
|
||||||
|
|
||||||
|
#include "SDL_rwops.h"
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#include "aliases.h"
|
||||||
|
#include <linux/limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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
|
||||||
@@ -30,11 +30,6 @@ typedef struct {
|
|||||||
u64 patch;
|
u64 patch;
|
||||||
} pak_ver_t;
|
} pak_ver_t;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u64 size;
|
|
||||||
u8 data[];
|
|
||||||
} pak_entry_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u64 magic;
|
u64 magic;
|
||||||
pak_ver_t version;
|
pak_ver_t version;
|
||||||
@@ -43,7 +38,6 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct asset_pack asset_pack_t;
|
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);
|
asset_pack_t *load_asset_pack(const char *filepath);
|
||||||
buf_t *read_file_from_pack(asset_pack_t *pack, const char *filename);
|
buf_t *read_file_from_pack(asset_pack_t *pack, const char *filename);
|
||||||
void close_pack_file(buf_t **buf);
|
void close_pack_file(buf_t **buf);
|
||||||
Binary file not shown.
@@ -0,0 +1,78 @@
|
|||||||
|
#include "cpath.h"
|
||||||
|
#include "aliases.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#include "darr.h"
|
||||||
|
#include "aliases.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#include "io.h"
|
||||||
|
#include "SDL_rwops.h"
|
||||||
|
#include "aliases.h"
|
||||||
|
#include "cpath.h"
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <linux/limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
#include "pak.h"
|
||||||
|
#include "SDL_rwops.h"
|
||||||
|
#include "aliases.h"
|
||||||
|
#include "darr.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include <linux/limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user