Compare commits
40 Commits
e162e078c5
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 90b5acd002 | |||
| e8fbe275f7 | |||
| ae61eef10a | |||
| fb1d1697f1 | |||
| 2f3d8106ea | |||
| 1f423b1d9b | |||
| 07a223f250 | |||
| b2dc73148e | |||
| 1be318c239 | |||
| 7b472cac4b | |||
| db4df86756 | |||
| f8f08c7473 | |||
| ca55dc2549 | |||
| ce4be85d14 | |||
| 3ec25758ef | |||
| f3ae1aef64 | |||
| c04e8bd4a3 | |||
| c5c447d5c5 | |||
| 490ccfc3c6 | |||
| 041167d26f | |||
| 7beac7e475 | |||
| 31d78bfcd3 | |||
| 07daa2ca19 | |||
| 7fd7bc4dfa | |||
| 9fa96f9712 | |||
| ce5b943416 | |||
| 69d4462833 | |||
| 2a8ddcfbd0 | |||
| 276867f76a | |||
| c0d9858b97 | |||
| 7e08071e45 | |||
| 42f5489a36 | |||
| f035650038 | |||
| 0c7d3adc3f | |||
| 8275d3fa75 | |||
| cb9b6fd4dc | |||
| 05e5a9ca21 | |||
| 04dc7cc3f4 | |||
| 9451c7d4db | |||
| 945bb3ff51 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
.cache
|
.cache
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
pckr
|
pckr
|
||||||
|
libpakrd.so
|
||||||
|
dist
|
||||||
|
|||||||
8
.gitmodules
vendored
Normal file
8
.gitmodules
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[submodule "intern/c-cpp-aliases"]
|
||||||
|
path = intern/c-cpp-aliases
|
||||||
|
url = https://git.thewizardapprentice.com/abdelrahman/c-cpp-aliases.git
|
||||||
|
branch = main
|
||||||
|
[submodule "intern/cpath"]
|
||||||
|
path = intern/cpath
|
||||||
|
url = https://git.thewizardapprentice.com/abdelrahman/cpath.git
|
||||||
|
branch = main
|
||||||
83
.vscode/launch.json
vendored
Normal file
83
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "(gdb) Debug pckr",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/pckr",
|
||||||
|
"args": [
|
||||||
|
"${workspaceFolder}/test_assets",
|
||||||
|
"${workspaceFolder}/assets"
|
||||||
|
],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Set Disassembly Flavor to Intel",
|
||||||
|
"text": "-gdb-set disassembly-flavor intel",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "(gdb) Debug pckr_test",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/pckr_test",
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Set Disassembly Flavor to Intel",
|
||||||
|
"text": "-gdb-set disassembly-flavor intel",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "(gdb) Debug pakrd_test",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/pakrd_test",
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Set Disassembly Flavor to Intel",
|
||||||
|
"text": "-gdb-set disassembly-flavor intel",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
# Asset packer
|
# pckr (Asset packer)
|
||||||
|
|
||||||
Simple asset packer and pack reader for my game
|
Simple asset packer and pack reader for my game
|
||||||
|
|||||||
118
compile
Executable file
118
compile
Executable file
@@ -0,0 +1,118 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
CC=gcc
|
||||||
|
CFLAGS="-Wall -Werror -pedantic -Iinclude -Iintern/c-cpp-aliases -Iintern/cpath/include "
|
||||||
|
|
||||||
|
PCKR_SRC="\
|
||||||
|
intern/cpath/src/cpath.c \
|
||||||
|
src/argparse.c \
|
||||||
|
src/io.c \
|
||||||
|
src/darr.c \
|
||||||
|
src/pak.c \
|
||||||
|
src/pckr.c \
|
||||||
|
src/main.c"
|
||||||
|
|
||||||
|
PAKRD_SRC="\
|
||||||
|
intern/cpath/src/cpath.c \
|
||||||
|
src/io.c \
|
||||||
|
src/darr.c \
|
||||||
|
src/pak.c"
|
||||||
|
PAKRD_FLAGS="-fPIC -rdynamic -shared "
|
||||||
|
|
||||||
|
PCKR_TEST_SRC="\
|
||||||
|
intern/cpath/src/cpath.c \
|
||||||
|
src/io.c \
|
||||||
|
src/pckr_test.c"
|
||||||
|
PCKR_TEST_OUT="pckr_test"
|
||||||
|
|
||||||
|
PAKRD_TEST_SRC="\
|
||||||
|
intern/cpath/src/cpath.c \
|
||||||
|
src/io.c \
|
||||||
|
src/darr.c \
|
||||||
|
src/pak.c \
|
||||||
|
src/pakrd_test.c"
|
||||||
|
PAKRD_TEST_OUT="pakrd_test"
|
||||||
|
|
||||||
|
BUILD_TYPE="debug"
|
||||||
|
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
-r|--release)
|
||||||
|
BUILD_TYPE="release"
|
||||||
|
shift # past argument
|
||||||
|
;;
|
||||||
|
-*|--*|*)
|
||||||
|
echo "Usage: build [-r | --release]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
if [[ $BUILD_TYPE == "debug" ]]; then
|
||||||
|
CFLAGS+="-g "
|
||||||
|
PCKR_OUT="pckr"
|
||||||
|
PAKRD_OUT="libpakrd.so"
|
||||||
|
else
|
||||||
|
mkdir -p dist
|
||||||
|
cp ./include/pak.h dist
|
||||||
|
CFLAGS+="-O3 "
|
||||||
|
PCKR_OUT="dist/pckr"
|
||||||
|
PAKRD_OUT="dist/libpakrd.so"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Build pckr executable
|
||||||
|
(set -x ; $CC $CFLAGS $PCKR_SRC -o $PCKR_OUT)
|
||||||
|
|
||||||
|
|
||||||
|
# Build pakrd shared library
|
||||||
|
(set -x ; $CC $CFLAGS $PAKRD_FLAGS $PAKRD_SRC -o $PAKRD_OUT)
|
||||||
|
|
||||||
|
|
||||||
|
# Build pckr_test executable
|
||||||
|
(set -x ; $CC $CFLAGS $PCKR_TEST_SRC -o $PCKR_TEST_OUT)
|
||||||
|
|
||||||
|
|
||||||
|
# Build pakrd_test executable
|
||||||
|
(set -x ; $CC $CFLAGS $PAKRD_TEST_SRC -o $PAKRD_TEST_OUT)
|
||||||
|
|
||||||
|
|
||||||
|
# Create test pak
|
||||||
|
./pckr ./test_assets ./assets
|
||||||
|
|
||||||
|
|
||||||
|
#ESCAPE SEQUENCES
|
||||||
|
CLEAR="\033[0m"
|
||||||
|
BOLD="\033[1"
|
||||||
|
FG_BLACK="\033[30"
|
||||||
|
FG_RED="\033[31"
|
||||||
|
FG_GREEN="\033[32"
|
||||||
|
FG_YELLOW="\033[33"
|
||||||
|
FG_BLUE="\033[34"
|
||||||
|
FG_MAGENTA="\033[35"
|
||||||
|
FG_CYAN="\033[36"
|
||||||
|
FG_WHITE="\033[37"
|
||||||
|
FG_BR_BLACK="\033[90"
|
||||||
|
FG_BR_RED="\033[91"
|
||||||
|
FG_BR_GREEN="\033[92"
|
||||||
|
FG_BR_YELLOW="\033[93"
|
||||||
|
FG_BR_BLUE="\033[94"
|
||||||
|
FG_BR_MAGENTA="\033[95"
|
||||||
|
FG_BR_CYAN="\033[96"
|
||||||
|
FG_BR_WHITE="\033[97"
|
||||||
|
|
||||||
|
|
||||||
|
# Run pckr_test
|
||||||
|
(./$PCKR_TEST_OUT && echo -e "\npckr_test [${FG_BR_GREEN}m${BOLD}m SUCCESS $CLEAR]") || echo -e "\npckr_test [${FG_BR_RED}m${BOLD}m FAILURE $CLEAR]"
|
||||||
|
|
||||||
|
|
||||||
|
# Run pakrd_test
|
||||||
|
(./$PAKRD_TEST_OUT && echo -e "pakrd_test [${FG_BR_GREEN}m${BOLD}m SUCCESS $CLEAR]") || echo -e "pakrd_test [${FG_BR_RED}m${BOLD}m FAILURE $CLEAR]"
|
||||||
|
|
||||||
|
|
||||||
|
# Clean test assets
|
||||||
|
rm ./assets.pak
|
||||||
|
rm pckr_test
|
||||||
|
rm pakrd_test
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#ifndef ALIASES_H
|
|
||||||
#define ALIASES_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define u8 uint8_t
|
|
||||||
#define u16 uint16_t
|
|
||||||
#define u32 uint32_t
|
|
||||||
#define u64 uint64_t
|
|
||||||
|
|
||||||
#define i8 int8_t
|
|
||||||
#define i16 int16_t
|
|
||||||
#define i32 int32_t
|
|
||||||
#define i64 int64_t
|
|
||||||
|
|
||||||
#define f32 float
|
|
||||||
#define f64 double
|
|
||||||
#define f128 long double
|
|
||||||
|
|
||||||
#define INTERNAL static
|
|
||||||
#define PERSISTENT static
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#define CLASS_MEMBER static
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#endif // !ALIASES_H
|
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
#ifndef ARGPARSE_H
|
#ifndef ARGPARSE_H
|
||||||
#define ARGPARSE_H
|
#define ARGPARSE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#include "aliases.h"
|
#include "aliases.h"
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@@ -17,4 +21,8 @@ typedef struct {
|
|||||||
|
|
||||||
argparser_t parse_args(i32 argc, char *argv[]);
|
argparser_t parse_args(i32 argc, char *argv[]);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif // !ARGPARSE_H
|
#endif // !ARGPARSE_H
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
#ifndef D_ARR_H
|
#ifndef D_ARR_H
|
||||||
#define D_ARR_H
|
#define D_ARR_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#include "aliases.h"
|
#include "aliases.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
@@ -13,4 +17,8 @@ i64 darr_add(darr_t **darr, void *item);
|
|||||||
void **darr_get_items(darr_t *darr);
|
void **darr_get_items(darr_t *darr);
|
||||||
void darr_free(darr_t **darr);
|
void darr_free(darr_t **darr);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif // !D_ARR_H
|
#endif // !D_ARR_H
|
||||||
|
|||||||
12
include/io.h
12
include/io.h
@@ -1,12 +1,18 @@
|
|||||||
#ifndef IO_H
|
#ifndef IO_H
|
||||||
#define IO_H
|
#define IO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#include "aliases.h"
|
#include "aliases.h"
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define STREQ(S1, S2) (strcmp(S1, S2) == 0)
|
#define STREQ(S1, S2) (strcmp(S1, S2) == 0)
|
||||||
|
#define STRNEQ(S1, S2, COUNT) (strncmp(S1, S2, COUNT) == 0)
|
||||||
|
|
||||||
typedef struct dirwalk dirwalk_t;
|
typedef struct dirwalk dirwalk_t;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -16,7 +22,11 @@ typedef struct {
|
|||||||
} dirwalk_result_t;
|
} dirwalk_result_t;
|
||||||
|
|
||||||
u64 get_file_length(FILE *fp);
|
u64 get_file_length(FILE *fp);
|
||||||
void read_entire_file(void *dst, u64 length, FILE *fp);
|
void read_entire_file(void *dst, FILE *fp);
|
||||||
dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath);
|
dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif // !IO_H
|
#endif // !IO_H
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
#ifndef PAK_H
|
#ifndef PAK_H
|
||||||
#define PAK_H
|
#define PAK_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#include "aliases.h"
|
#include "aliases.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u64 size;
|
||||||
|
u8 data[];
|
||||||
|
} buf_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u64 offset;
|
u64 offset;
|
||||||
u64 length;
|
u64 length;
|
||||||
@@ -32,6 +41,16 @@ typedef struct {
|
|||||||
toc_t toc;
|
toc_t toc;
|
||||||
} pak_t;
|
} pak_t;
|
||||||
|
|
||||||
|
typedef struct asset_pack asset_pack_t;
|
||||||
|
|
||||||
bool create_asset_pack(const char *dirpath, const char *output);
|
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);
|
||||||
|
void close_asset_pack(asset_pack_t **pack);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif // !PAK_H
|
#endif // !PAK_H
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
#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
|
|
||||||
@@ -1,8 +1,16 @@
|
|||||||
#ifndef PCKR_H
|
#ifndef PCKR_H
|
||||||
#define PCKR_H
|
#define PCKR_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#include "aliases.h"
|
#include "aliases.h"
|
||||||
|
|
||||||
i32 run_pckr(i32 argc, char *argv[]);
|
i32 run_pckr(i32 argc, char *argv[]);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif // !PCKR_H
|
#endif // !PCKR_H
|
||||||
|
|||||||
19
include/test_utils.h
Normal file
19
include/test_utils.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef TEST_UTILS_H
|
||||||
|
#define TEST_UTILS_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#define ARRLEN(ARR) (sizeof ARR / sizeof ARR[0])
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
const char *contents;
|
||||||
|
} asset_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif // !TEST_UTILS_H
|
||||||
1
intern/c-cpp-aliases
Submodule
1
intern/c-cpp-aliases
Submodule
Submodule intern/c-cpp-aliases added at f95f3aa499
1
intern/cpath
Submodule
1
intern/cpath
Submodule
Submodule intern/cpath added at 076b1310e3
@@ -7,10 +7,9 @@ argparser_t parse_args(i32 argc, char *argv[]) {
|
|||||||
return (argparser_t){0};
|
return (argparser_t){0};
|
||||||
}
|
}
|
||||||
|
|
||||||
argparser_t output = {
|
argparser_t output = {0};
|
||||||
.succeeded = true,
|
output.succeeded = true;
|
||||||
.args = (pckr_args_t){0},
|
output.args = (pckr_args_t){0};
|
||||||
};
|
|
||||||
|
|
||||||
realpath(argv[1], output.args.dir);
|
realpath(argv[1], output.args.dir);
|
||||||
realpath(argv[2], output.args.output);
|
realpath(argv[2], output.args.output);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ i64 darr_add(darr_t **darr, void *item) {
|
|||||||
return INVALID_IDX;
|
return INVALID_IDX;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*darr)->capacity = orig->capacity + BASE_CAPACITY;
|
(*darr)->capacity += BASE_CAPACITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 index = (*darr)->count;
|
u64 index = (*darr)->count;
|
||||||
|
|||||||
20
src/io.c
20
src/io.c
@@ -1,6 +1,6 @@
|
|||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "aliases.h"
|
#include "aliases.h"
|
||||||
#include "path_utils.h"
|
#include "cpath.h"
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -16,8 +16,8 @@ struct dirwalk {
|
|||||||
u64 count;
|
u64 count;
|
||||||
FILE *current_file;
|
FILE *current_file;
|
||||||
DIR *current_dir;
|
DIR *current_dir;
|
||||||
char dst[PATH_MAX];
|
char dst[PATH_MAX + 1];
|
||||||
DIR *directories[MAX_DIR_DEPTH];
|
DIR *directories[MAX_DIR_DEPTH + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
u64 get_file_length(FILE *fp) {
|
u64 get_file_length(FILE *fp) {
|
||||||
@@ -33,7 +33,9 @@ u64 get_file_length(FILE *fp) {
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_entire_file(void *dst, u64 length, FILE *fp) {
|
void read_entire_file(void *dst, FILE *fp) {
|
||||||
|
u64 length = get_file_length(fp);
|
||||||
|
|
||||||
u64 current = ftell(fp);
|
u64 current = ftell(fp);
|
||||||
|
|
||||||
fseek(fp, 0, SEEK_SET);
|
fseek(fp, 0, SEEK_SET);
|
||||||
@@ -71,7 +73,7 @@ dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath) {
|
|||||||
|
|
||||||
dirwalk_t *dw = *dirwalk;
|
dirwalk_t *dw = *dirwalk;
|
||||||
|
|
||||||
char tmp[PATH_MAX] = {0};
|
char tmp[PATH_MAX + 1] = {0};
|
||||||
|
|
||||||
dirent_t *ep = NULL;
|
dirent_t *ep = NULL;
|
||||||
stat_t dirstat = {0};
|
stat_t dirstat = {0};
|
||||||
@@ -100,7 +102,7 @@ dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath) {
|
|||||||
|
|
||||||
result.reading = true;
|
result.reading = true;
|
||||||
result.fp = dw->current_file;
|
result.fp = dw->current_file;
|
||||||
strncpy(result.name, ep->d_name, NAME_MAX);
|
strncpy(result.name, ep->d_name, NAME_MAX + 1);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -114,7 +116,7 @@ dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath) {
|
|||||||
if ((dirstat.st_mode & S_IFDIR) == S_IFDIR) {
|
if ((dirstat.st_mode & S_IFDIR) == S_IFDIR) {
|
||||||
memset(dw->dst, 0, length);
|
memset(dw->dst, 0, length);
|
||||||
|
|
||||||
strncpy(dw->dst, tmp, length);
|
strncpy(dw->dst, tmp, length + 1);
|
||||||
|
|
||||||
dw->directories[(dw->count)++] = opendir(dw->dst);
|
dw->directories[(dw->count)++] = opendir(dw->dst);
|
||||||
|
|
||||||
@@ -126,7 +128,7 @@ dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath) {
|
|||||||
|
|
||||||
result.reading = true;
|
result.reading = true;
|
||||||
result.fp = dw->current_file;
|
result.fp = dw->current_file;
|
||||||
strncpy(result.name, ep->d_name, NAME_MAX);
|
strncpy(result.name, ep->d_name, NAME_MAX + 1);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -148,7 +150,7 @@ dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath) {
|
|||||||
|
|
||||||
u64 length = strlen(dw->dst);
|
u64 length = strlen(dw->dst);
|
||||||
|
|
||||||
strncpy(tmp, dw->dst, length);
|
strcpy(tmp, dw->dst);
|
||||||
|
|
||||||
memset(dw->dst, 0, length);
|
memset(dw->dst, 0, length);
|
||||||
|
|
||||||
|
|||||||
147
src/pak.c
147
src/pak.c
@@ -13,6 +13,15 @@
|
|||||||
#define PAK_PATCH 0
|
#define PAK_PATCH 0
|
||||||
#define PAK_EXT ".pak"
|
#define PAK_EXT ".pak"
|
||||||
|
|
||||||
|
struct asset_pack {
|
||||||
|
pak_t header;
|
||||||
|
FILE *fp;
|
||||||
|
u8 *toc;
|
||||||
|
toc_entry_t **toc_entries;
|
||||||
|
u64 assets_length;
|
||||||
|
u64 assets_offset;
|
||||||
|
};
|
||||||
|
|
||||||
toc_entry_t *create_toc_entry(const char *name, u64 offset);
|
toc_entry_t *create_toc_entry(const char *name, u64 offset);
|
||||||
void write_toc_entry(toc_entry_t *entry, FILE *fp);
|
void write_toc_entry(toc_entry_t *entry, FILE *fp);
|
||||||
void write_toc_entries(const toc_t *toc, toc_entry_t **entries, FILE *fp);
|
void write_toc_entries(const toc_t *toc, toc_entry_t **entries, FILE *fp);
|
||||||
@@ -25,13 +34,11 @@ void write_pak(const pak_t *pak, toc_entry_t **toc_entries,
|
|||||||
bool create_asset_pack(const char *dirpath, const char *output) {
|
bool create_asset_pack(const char *dirpath, const char *output) {
|
||||||
bool created = false;
|
bool created = false;
|
||||||
|
|
||||||
char dst[PATH_MAX] = {0};
|
char dst[PATH_MAX + 1] = {0};
|
||||||
|
|
||||||
u64 output_length = strlen(output);
|
strcpy(dst, output);
|
||||||
strncpy(dst, output, output_length);
|
|
||||||
|
|
||||||
u64 ext_length = strlen(PAK_EXT);
|
strcat(dst, PAK_EXT);
|
||||||
strncat(dst, PAK_EXT, ext_length);
|
|
||||||
|
|
||||||
FILE *fp = fopen(dst, "wb");
|
FILE *fp = fopen(dst, "wb");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
@@ -77,8 +84,6 @@ bool create_asset_pack(const char *dirpath, const char *output) {
|
|||||||
if (result.fp) {
|
if (result.fp) {
|
||||||
++(pak.toc.count);
|
++(pak.toc.count);
|
||||||
|
|
||||||
offset += sizeof(pak_entry_t);
|
|
||||||
|
|
||||||
toc_entry_t *toc_entry = create_toc_entry(result.name, offset);
|
toc_entry_t *toc_entry = create_toc_entry(result.name, offset);
|
||||||
pak_entry_t *pak_entry = create_pak_entry_from_file(result.fp);
|
pak_entry_t *pak_entry = create_pak_entry_from_file(result.fp);
|
||||||
|
|
||||||
@@ -87,7 +92,7 @@ bool create_asset_pack(const char *dirpath, const char *output) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pak.toc.size += sizeof(toc_entry_t) + toc_entry->length;
|
pak.toc.size += sizeof(toc_entry_t) + toc_entry->length;
|
||||||
offset += pak_entry->size;
|
offset += sizeof(pak_entry_t) + pak_entry->size;
|
||||||
|
|
||||||
darr_add(&toc_entries_darr, (void *)toc_entry);
|
darr_add(&toc_entries_darr, (void *)toc_entry);
|
||||||
darr_add(&pak_entries_darr, (void *)pak_entry);
|
darr_add(&pak_entries_darr, (void *)pak_entry);
|
||||||
@@ -113,6 +118,126 @@ RETURN_CREATE_ASSET_PAK:
|
|||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asset_pack_t *load_asset_pack(const char *filepath) {
|
||||||
|
char full_path[PATH_MAX] = {0};
|
||||||
|
|
||||||
|
realpath(filepath, full_path);
|
||||||
|
|
||||||
|
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->fp = fopen(full_path, "rb");
|
||||||
|
if (!(pack->fp)) {
|
||||||
|
close_asset_pack(&pack);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 file_size = get_file_length(pack->fp);
|
||||||
|
|
||||||
|
fread((void *)(&(pack->header)), sizeof(pak_t), 1, pack->fp);
|
||||||
|
|
||||||
|
u64 toc_size = pack->header.toc.size;
|
||||||
|
|
||||||
|
pack->toc = (u8 *)malloc(toc_size);
|
||||||
|
if (!(pack->toc)) {
|
||||||
|
close_asset_pack(&pack);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fread((void *)(pack->toc), toc_size, 1, pack->fp);
|
||||||
|
|
||||||
|
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 = ftell(pack->fp);
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
fseek(pack->fp, pack->assets_offset + entry->offset, SEEK_SET);
|
||||||
|
|
||||||
|
u64 size = 0;
|
||||||
|
fread(&size, sizeof(u64), 1, pack->fp);
|
||||||
|
|
||||||
|
output = (buf_t *)malloc(sizeof(buf_t) + size);
|
||||||
|
if (!output) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
output->size = size;
|
||||||
|
|
||||||
|
fread(&(output->data), size, 1, pack->fp);
|
||||||
|
|
||||||
|
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)->fp) {
|
||||||
|
fclose((*pack)->fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(*pack);
|
||||||
|
|
||||||
|
*pack = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
toc_entry_t *create_toc_entry(const char *name, u64 offset) {
|
toc_entry_t *create_toc_entry(const char *name, u64 offset) {
|
||||||
u64 length = strlen(name);
|
u64 length = strlen(name);
|
||||||
u64 size = sizeof(toc_entry_t) + length + 1;
|
u64 size = sizeof(toc_entry_t) + length + 1;
|
||||||
@@ -127,7 +252,7 @@ toc_entry_t *create_toc_entry(const char *name, u64 offset) {
|
|||||||
entry->offset = offset;
|
entry->offset = offset;
|
||||||
entry->length = length + 1;
|
entry->length = length + 1;
|
||||||
|
|
||||||
strncpy(entry->name, name, length);
|
strcpy(entry->name, name);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
@@ -160,6 +285,8 @@ pak_entry_t *create_pak_entry(u64 data_length) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(entry, 0, data_length);
|
||||||
|
|
||||||
entry->size = data_length;
|
entry->size = data_length;
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
@@ -179,7 +306,7 @@ pak_entry_t *create_pak_entry_from_file(FILE *fp) {
|
|||||||
goto RETURN_PAK_ENTRY;
|
goto RETURN_PAK_ENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_entire_file((void *)(entry->data), length, fp);
|
read_entire_file((void *)(entry->data), fp);
|
||||||
|
|
||||||
RETURN_PAK_ENTRY:
|
RETURN_PAK_ENTRY:
|
||||||
return entry;
|
return entry;
|
||||||
|
|||||||
51
src/pakrd_test.c
Normal file
51
src/pakrd_test.c
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include "io.h"
|
||||||
|
#include "pak.h"
|
||||||
|
#include "test_utils.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
asset_pack_t *pack = load_asset_pack("assets.pak");
|
||||||
|
if (!pack) {
|
||||||
|
printf("Failed to load asset pack");
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
asset_t assets[] = {
|
||||||
|
(asset_t){.name = "file01", .contents = "Hello\n"},
|
||||||
|
(asset_t){.name = "name.txt", .contents = "Abdelrahman\n"},
|
||||||
|
(asset_t){.name = "file02", .contents = "This is the second file\n"},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (u64 i = 0; i < ARRLEN(assets); ++i) {
|
||||||
|
buf_t *buf = read_file_from_pack(pack, assets[i].name);
|
||||||
|
if (!buf || buf->size == 0) {
|
||||||
|
printf("Failed to read file %s\n", assets[i].name);
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(STREQ((char *)(buf->data), assets[i].contents))) {
|
||||||
|
printf("File contents mismatch for file %s\n", assets[i].name);
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
close_pack_file(&buf);
|
||||||
|
if (buf) {
|
||||||
|
printf("Failed to close file %s\n", assets[i].name);
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close_asset_pack(&pack);
|
||||||
|
if (pack) {
|
||||||
|
printf("Failed to close asset pack");
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
#include "path_utils.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(dst, root, ++root_end);
|
|
||||||
dst[root_end] = path_sep;
|
|
||||||
strncpy(&(dst[++root_end]), &(leaf[leaf_start]), leaf_length - leaf_start);
|
|
||||||
}
|
|
||||||
171
src/pckr_test.c
Normal file
171
src/pckr_test.c
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
#include "aliases.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "pak.h"
|
||||||
|
#include "test_utils.h"
|
||||||
|
#include <linux/limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
i32 main(i32 argc, char *argv[]) {
|
||||||
|
char filepath[PATH_MAX] = {0};
|
||||||
|
realpath("assets.pak", filepath);
|
||||||
|
|
||||||
|
FILE *fp = fopen(filepath, "rb");
|
||||||
|
if (!fp) {
|
||||||
|
printf("Failed to open file\n");
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
asset_t assets[] = {
|
||||||
|
(asset_t){.name = "file01", .contents = "Hello\n"},
|
||||||
|
(asset_t){.name = "name.txt", .contents = "Abdelrahman\n"},
|
||||||
|
(asset_t){.name = "file02", .contents = "This is the second file\n"},
|
||||||
|
};
|
||||||
|
|
||||||
|
u64 expected_pak_size = sizeof(pak_t);
|
||||||
|
|
||||||
|
u64 expected_count = ARRLEN(assets);
|
||||||
|
|
||||||
|
u64 expected_entries_size = 0;
|
||||||
|
|
||||||
|
for (u64 i = 0; i < expected_count; ++i) {
|
||||||
|
u64 name_length = strlen(assets[i].name) + 1;
|
||||||
|
u64 contents_length = strlen(assets[i].contents) + 1;
|
||||||
|
|
||||||
|
expected_pak_size += name_length + contents_length + sizeof(toc_entry_t) +
|
||||||
|
sizeof(pak_entry_t);
|
||||||
|
|
||||||
|
expected_entries_size += name_length + sizeof(toc_entry_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 real_size = get_file_length(fp);
|
||||||
|
|
||||||
|
if (expected_pak_size != real_size) {
|
||||||
|
printf("Real size (%zu) doesn't match expected size (%zu)\n", real_size,
|
||||||
|
expected_pak_size);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pak_t pack = {0};
|
||||||
|
fread((void *)&pack, sizeof(pak_t), 1, fp);
|
||||||
|
|
||||||
|
if (pack.toc.count != expected_count) {
|
||||||
|
printf("Pack file count (%zu) doesn't match expected count (%zu)\n",
|
||||||
|
pack.toc.count, expected_count);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pack.toc.size != expected_entries_size) {
|
||||||
|
printf(
|
||||||
|
"Table of contents real size (%zu) doesn't match expected size (%zu)\n",
|
||||||
|
pack.toc.size, expected_entries_size);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
toc_entry_t *toc_entries[pack.toc.count];
|
||||||
|
memset((void *)toc_entries, 0, sizeof(toc_entry_t *) * pack.toc.count);
|
||||||
|
|
||||||
|
pak_entry_t *pak_entries[pack.toc.count];
|
||||||
|
memset((void *)pak_entries, 0, sizeof(pak_entry_t *) * pack.toc.count);
|
||||||
|
|
||||||
|
bool match = true;
|
||||||
|
|
||||||
|
for (u64 i = 0; i < pack.toc.count; ++i) {
|
||||||
|
u64 pos = ftell(fp);
|
||||||
|
|
||||||
|
u64 data[2] = {0};
|
||||||
|
|
||||||
|
fread(data, sizeof(u64) * ARRLEN(data), 1, fp);
|
||||||
|
|
||||||
|
u64 toc_entry_size = sizeof(toc_entry_t) + data[1];
|
||||||
|
|
||||||
|
toc_entries[i] = malloc(toc_entry_size);
|
||||||
|
if (!(toc_entries[i])) {
|
||||||
|
printf("TOC entry allocation failed\n");
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(fp, pos, SEEK_SET);
|
||||||
|
|
||||||
|
fread(toc_entries[i], toc_entry_size, 1, fp);
|
||||||
|
|
||||||
|
i64 entry_in_assets = -1;
|
||||||
|
|
||||||
|
for (u64 j = 0; j < pack.toc.count; ++j) {
|
||||||
|
if (STREQ((toc_entries[i])->name, assets[j].name)) {
|
||||||
|
match = true;
|
||||||
|
entry_in_assets = j;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
match = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = ftell(fp);
|
||||||
|
|
||||||
|
u64 new_pos = toc_entries[i]->offset + sizeof(pak_t) + pack.toc.size;
|
||||||
|
|
||||||
|
fseek(fp, new_pos, SEEK_SET);
|
||||||
|
|
||||||
|
u64 entry_size = 0;
|
||||||
|
fread(&entry_size, sizeof(u64), 1, fp);
|
||||||
|
|
||||||
|
u64 pak_entry_size = entry_size + sizeof(pak_entry_t);
|
||||||
|
|
||||||
|
pak_entries[i] = malloc(pak_entry_size);
|
||||||
|
if (!(pak_entries[i])) {
|
||||||
|
printf("PAK entry allocation failed\n");
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fread(pak_entries[i]->data, entry_size, 1, fp);
|
||||||
|
|
||||||
|
if (!(STREQ((char *)(pak_entries[i]->data),
|
||||||
|
assets[entry_in_assets].contents))) {
|
||||||
|
printf("%s, %s\n", (char *)(pak_entries[i]->data),
|
||||||
|
assets[entry_in_assets].contents);
|
||||||
|
match = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(fp, pos, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u64 i = 0; i < pack.toc.count; ++i) {
|
||||||
|
if (toc_entries[i]) {
|
||||||
|
free(toc_entries[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pak_entries[i]) {
|
||||||
|
free(pak_entries[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
printf("Pack contents doesn't match expected contents\n");
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user