Add pack writing functionality
This commit is contained in:
parent
d7792998ea
commit
ea19c2767f
37
include/pak.h
Normal file
37
include/pak.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef PAK_H
|
||||
#define PAK_H
|
||||
|
||||
#include "aliases.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct {
|
||||
u64 offset;
|
||||
u64 length;
|
||||
char name[];
|
||||
} toc_entry_t;
|
||||
|
||||
typedef struct {
|
||||
u64 count;
|
||||
u64 size;
|
||||
} toc_t;
|
||||
|
||||
typedef struct {
|
||||
u64 major;
|
||||
u64 minor;
|
||||
u64 patch;
|
||||
} pak_ver_t;
|
||||
|
||||
typedef struct {
|
||||
u64 size;
|
||||
u8 data[];
|
||||
} pak_entry_t;
|
||||
|
||||
typedef struct {
|
||||
u64 magic;
|
||||
pak_ver_t version;
|
||||
toc_t toc;
|
||||
} pak_t;
|
||||
|
||||
bool create_asset_pack(const char *dirpath, const char *output);
|
||||
|
||||
#endif // !PAK_H
|
203
src/pak.c
Normal file
203
src/pak.c
Normal file
@ -0,0 +1,203 @@
|
||||
#include "pak.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"
|
||||
|
||||
toc_entry_t *create_toc_entry(const char *name, u64 offset);
|
||||
void write_toc_entry(toc_entry_t *entry, FILE *fp);
|
||||
void write_toc_entries(const toc_t *toc, toc_entry_t **entries, FILE *fp);
|
||||
pak_entry_t *create_pak_entry(u64 data_length);
|
||||
pak_entry_t *create_pak_entry_from_file(FILE *fp);
|
||||
void write_pak_entry(const pak_entry_t *entry, FILE *fp);
|
||||
void write_pak(const pak_t *pak, toc_entry_t **toc_entries,
|
||||
pak_entry_t **pak_entries, FILE *fp);
|
||||
|
||||
bool create_asset_pack(const char *dirpath, const char *output) {
|
||||
bool created = false;
|
||||
|
||||
char dst[PATH_MAX] = {0};
|
||||
|
||||
u64 output_length = strlen(output);
|
||||
strncpy(dst, output, output_length);
|
||||
|
||||
u64 ext_length = strlen(PAK_EXT);
|
||||
strncat(dst, PAK_EXT, ext_length);
|
||||
|
||||
FILE *fp = fopen(dst, "wb");
|
||||
if (!fp) {
|
||||
goto RETURN_CREATE_ASSET_PAK;
|
||||
}
|
||||
|
||||
darr_t *toc_entries_darr = NULL;
|
||||
darr_t *pak_entries_darr = NULL;
|
||||
|
||||
bool initialiased =
|
||||
darr_init(&toc_entries_darr) && darr_init(&pak_entries_darr);
|
||||
|
||||
if (!initialiased) {
|
||||
goto FREE_ARRAYS_CREATE_ASSET_PAK;
|
||||
}
|
||||
|
||||
pak_t pak = {
|
||||
.magic = PAK_MAGIC,
|
||||
.version =
|
||||
(pak_ver_t){
|
||||
.major = PAK_MAJOR,
|
||||
.minor = PAK_MINOR,
|
||||
.patch = PAK_PATCH,
|
||||
},
|
||||
.toc =
|
||||
(toc_t){
|
||||
.count = 0,
|
||||
.size = 0,
|
||||
},
|
||||
};
|
||||
|
||||
dirwalk_t *dw = NULL;
|
||||
dirwalk_result_t result = {0};
|
||||
|
||||
result = walk_dir(&dw, dirpath);
|
||||
if (!(result.fp)) {
|
||||
goto FREE_ARRAYS_CREATE_ASSET_PAK;
|
||||
}
|
||||
|
||||
u64 offset = 0;
|
||||
|
||||
while (result.reading) {
|
||||
if (result.fp) {
|
||||
++(pak.toc.count);
|
||||
|
||||
offset += sizeof(pak_entry_t);
|
||||
|
||||
toc_entry_t *toc_entry = create_toc_entry(result.name, offset);
|
||||
pak_entry_t *pak_entry = create_pak_entry_from_file(result.fp);
|
||||
|
||||
if (!toc_entry || !pak_entry) {
|
||||
goto FREE_ARRAYS_CREATE_ASSET_PAK;
|
||||
}
|
||||
|
||||
pak.toc.size += sizeof(toc_entry_t) + toc_entry->length;
|
||||
offset += pak_entry->size;
|
||||
|
||||
darr_add(&toc_entries_darr, (void *)toc_entry);
|
||||
darr_add(&pak_entries_darr, (void *)pak_entry);
|
||||
}
|
||||
|
||||
result = walk_dir(&dw, NULL);
|
||||
}
|
||||
|
||||
toc_entry_t **toc_entries = (toc_entry_t **)darr_get_items(toc_entries_darr);
|
||||
pak_entry_t **pak_entries = (pak_entry_t **)darr_get_items(pak_entries_darr);
|
||||
|
||||
write_pak(&pak, toc_entries, pak_entries, fp);
|
||||
|
||||
created = true;
|
||||
|
||||
FREE_ARRAYS_CREATE_ASSET_PAK:
|
||||
darr_free(&pak_entries_darr);
|
||||
darr_free(&toc_entries_darr);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
RETURN_CREATE_ASSET_PAK:
|
||||
return created;
|
||||
}
|
||||
|
||||
toc_entry_t *create_toc_entry(const char *name, u64 offset) {
|
||||
u64 length = strlen(name);
|
||||
u64 size = sizeof(toc_entry_t) + length + 1;
|
||||
|
||||
toc_entry_t *entry = (toc_entry_t *)malloc(size);
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset((void *)entry, 0, size);
|
||||
|
||||
entry->offset = offset;
|
||||
entry->length = length + 1;
|
||||
|
||||
strncpy(entry->name, name, length);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
void write_toc_entry(toc_entry_t *entry, FILE *fp) {
|
||||
fwrite((void *)entry, sizeof(toc_entry_t) + entry->length, 1, fp);
|
||||
}
|
||||
|
||||
void write_toc_entries(const toc_t *toc, toc_entry_t **entries, FILE *fp) {
|
||||
if (!fp || !entries) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (u64 i = 0; i < toc->count; ++i) {
|
||||
write_toc_entry(entries[i], fp);
|
||||
|
||||
if (!entries[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
free(entries[i]);
|
||||
|
||||
entries[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pak_entry_t *create_pak_entry(u64 data_length) {
|
||||
pak_entry_t *entry = (pak_entry_t *)malloc(sizeof(pak_entry_t) + data_length);
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entry->size = data_length;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
pak_entry_t *create_pak_entry_from_file(FILE *fp) {
|
||||
pak_entry_t *entry = NULL;
|
||||
|
||||
if (!fp) {
|
||||
goto RETURN_PAK_ENTRY;
|
||||
}
|
||||
|
||||
u64 length = get_file_length(fp) + 1;
|
||||
|
||||
entry = create_pak_entry(length);
|
||||
if (!entry) {
|
||||
goto RETURN_PAK_ENTRY;
|
||||
}
|
||||
|
||||
read_entire_file((void *)(entry->data), length, fp);
|
||||
|
||||
RETURN_PAK_ENTRY:
|
||||
return entry;
|
||||
}
|
||||
|
||||
void write_pak_entry(const pak_entry_t *entry, FILE *fp) {
|
||||
fwrite((void *)entry, sizeof(pak_entry_t) + entry->size, 1, fp);
|
||||
}
|
||||
|
||||
void write_pak(const pak_t *pak, toc_entry_t **toc_entries,
|
||||
pak_entry_t **pak_entries, FILE *fp) {
|
||||
fwrite(pak, sizeof(pak_t), 1, fp);
|
||||
|
||||
write_toc_entries(&(pak->toc), toc_entries, fp);
|
||||
|
||||
for (u64 i = 0; i < pak->toc.count; ++i) {
|
||||
write_pak_entry(pak_entries[i], fp);
|
||||
|
||||
free(pak_entries[i]);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user