#include #include #include #include #include #include #include #include "pack.h" #include "file.h" #include "zlib.h" extern "C" { #ifdef __APPLE__ extern uint8_t const files_pack_start[]; extern uint8_t const files_pack_end[]; #define files_pack_start files_pack_start #define files_pack_end files_pack_end #else extern uint8_t const _files_pack_start[]; extern uint8_t const _files_pack_end[]; #define files_pack_start _files_pack_start #define files_pack_end _files_pack_end #endif }; uint8_t * decompressed_start = NULL; namespace file { void init() { uint32_t * header = (uint32_t *)files_pack_start; if (header[0] != 0x56c8f1cb) { fprintf(stderr, "invalid compressed header magic: %08x expected magic value: %08x\n", header[0], 0x56c8f1cb); exit(EXIT_FAILURE); } printf("decompressed size %d\n", header[1]); printf("compressed size %d\n", header[2]); uint8_t * dest = (uint8_t *)malloc(header[1]); uint64_t dest_len = header[1]; uint8_t * src = (uint8_t *)&header[3]; uint64_t src_len = header[2]; int ret = uncompress2(dest, &dest_len, src, &src_len); assert(ret == Z_OK); decompressed_start = dest; } void const * open(const char * filename, uint32_t * out_size) { assert(decompressed_start != NULL); fprintf(stderr, "(pack) filename: %s\n", filename); pack::header const * header = (pack::header const *)&decompressed_start[0]; if (header->magic != pack::magic_value) { fprintf(stderr, "invalid header magic: %08x expected magic value: %08x\n", header->magic, pack::magic_value); exit(EXIT_FAILURE); } ptrdiff_t data = (ptrdiff_t)&decompressed_start[header->header_size]; for (unsigned int i = 0; i < header->entry_count; i++) { if (strcmp(header->entry[i].filename, filename) == 0) { *out_size = header->entry[i].size; return (void const *)(data + header->entry[i].offset); } } fprintf(stderr, "filename not found in pack file %s\n", filename); exit(EXIT_FAILURE); } void * openRelative(char const * filename, uint32_t * out_size) { FILE * f = fopen(filename, "rb"); if (f == NULL) { fprintf(stderr, "fopen(%s): %s\n", filename, strerror(errno)); return NULL; } int fseek_end_ret = fseek(f, 0, SEEK_END); if (fseek_end_ret < 0) { fprintf(stderr, "fseek(%s, SEEK_END): %s\n", filename, strerror(errno)); return NULL; } size_t size = ftell(f); if (size < 0) { fprintf(stderr, "ftell(%s): %s\n", filename, strerror(errno)); return NULL; } int fseek_set_ret = fseek(f, 0, SEEK_SET); if (fseek_set_ret < 0) { fprintf(stderr, "lseek(%s, SEEK_SET): %s\n", filename, strerror(errno)); return NULL; } rewind(f); void * buf = malloc(size); size_t read_size = fread(buf, 1, size, f); if (read_size != size) { fprintf(stderr, "fread(%s): %s\n", filename, strerror(errno)); return NULL; } *out_size = size; return buf; } }