Compare commits
No commits in common. "7e08071e45c39d4732b7b64559a619d6270419f3" and "e162e078c542da6c4dbc09cf7ad0b69c80f1a741" have entirely different histories.
7e08071e45
...
e162e078c5
59
.vscode/launch.json
vendored
59
.vscode/launch.json
vendored
@ -1,59 +0,0 @@
|
|||||||
{
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,3 +1,3 @@
|
|||||||
# pckr (Asset packer)
|
# Asset packer
|
||||||
|
|
||||||
Simple asset packer and pack reader for my game
|
Simple asset packer and pack reader for my game
|
||||||
|
72
compile
72
compile
@ -1,72 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
#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"
|
|
||||||
|
|
||||||
CC=clang
|
|
||||||
CFLAGS="-Wall -Werror -pedantic -Iinclude "
|
|
||||||
PCKR_SRC="\
|
|
||||||
src/path_utils.c \
|
|
||||||
src/argparse.c \
|
|
||||||
src/io.c \
|
|
||||||
src/darr.c \
|
|
||||||
src/pak.c \
|
|
||||||
src/pckr.c \
|
|
||||||
src/main.c"
|
|
||||||
PCKR_TEST_SRC="\
|
|
||||||
src/path_utils.c \
|
|
||||||
src/io.c \
|
|
||||||
src/pckr_test.c"
|
|
||||||
PCKR_TEST_OUT="pckr_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"
|
|
||||||
else
|
|
||||||
CFLAGS+="-O3 "
|
|
||||||
PCKR_OUT="../proj/pckr"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build pckr executable
|
|
||||||
(set -x ; $CC $CFLAGS $PCKR_SRC -o $PCKR_OUT)
|
|
||||||
|
|
||||||
# Build pckr_test executable
|
|
||||||
(set -x ; $CC $CFLAGS $PCKR_TEST_SRC -o $PCKR_TEST_OUT)
|
|
||||||
|
|
||||||
# Run pckr test
|
|
||||||
./pckr ./test_assets ./assets
|
|
||||||
(./$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]"
|
|
||||||
rm ./assets.pak
|
|
||||||
rm pckr_test
|
|
@ -16,7 +16,7 @@ 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, FILE *fp);
|
void read_entire_file(void *dst, u64 length, FILE *fp);
|
||||||
dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath);
|
dirwalk_result_t walk_dir(dirwalk_t **dirwalk, const char *filepath);
|
||||||
|
|
||||||
#endif // !IO_H
|
#endif // !IO_H
|
||||||
|
4
src/io.c
4
src/io.c
@ -33,9 +33,7 @@ u64 get_file_length(FILE *fp) {
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_entire_file(void *dst, FILE *fp) {
|
void read_entire_file(void *dst, u64 length, 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);
|
||||||
|
@ -160,8 +160,6 @@ 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;
|
||||||
@ -181,7 +179,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), fp);
|
read_entire_file((void *)(entry->data), length, fp);
|
||||||
|
|
||||||
RETURN_PAK_ENTRY:
|
RETURN_PAK_ENTRY:
|
||||||
return entry;
|
return entry;
|
||||||
|
178
src/pckr_test.c
178
src/pckr_test.c
@ -1,178 +0,0 @@
|
|||||||
#include "aliases.h"
|
|
||||||
#include "io.h"
|
|
||||||
#include "pak.h"
|
|
||||||
#include <linux/limits.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define ARRLEN(ARR) (sizeof ARR / sizeof ARR[0])
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *name;
|
|
||||||
const char *contents;
|
|
||||||
} asset_t;
|
|
||||||
|
|
||||||
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 - sizeof(u64);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user