asset packer completed
This commit is contained in:
parent
6984296e0c
commit
d9ec3f4be2
238
src/packer.c
238
src/packer.c
@ -11,6 +11,7 @@
|
|||||||
#include "game.c"
|
#include "game.c"
|
||||||
|
|
||||||
#define FWrite(buf, size, count, file) ((size) * (fwrite(buf, size, count, file)))
|
#define FWrite(buf, size, count, file) ((size) * (fwrite(buf, size, count, file)))
|
||||||
|
#define FRead(buf, size, count, file) ((size) * (fread(buf, size, count, file)))
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
b32 ChangeDir(c8 *dir)
|
b32 ChangeDir(c8 *dir)
|
||||||
@ -80,6 +81,36 @@ b8 DirVisible(c8 *dir_name)
|
|||||||
# error Not yet implemented
|
# error Not yet implemented
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
u64 FileLength(FILE *file)
|
||||||
|
{
|
||||||
|
Assert(fseek(file, 0, SEEK_END) == 0, "fseek failure");
|
||||||
|
return (u64)ftell(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 WriteData(void *buf, u64 pos, u64 size, FILE *file)
|
||||||
|
{
|
||||||
|
Assert(fseek(file, pos, SEEK_SET) == 0, "WriteData fseek failure");
|
||||||
|
return FWrite(buf, size, 1, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 ReadData(void *buf, u64 pos, u64 size, FILE *file)
|
||||||
|
{
|
||||||
|
Assert(fseek(file, pos, SEEK_SET) == 0, "ReadData fseek failure");
|
||||||
|
return FRead(buf, size, 1, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *OpenFile(c8 *name, c8 *mode)
|
||||||
|
{
|
||||||
|
FILE *file = fopen(name, mode);
|
||||||
|
Assert(file != NULL, "OpenFile: file is null");
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloseFile(FILE *file)
|
||||||
|
{
|
||||||
|
Assert(fclose(file) != EOF, "Error closing file");
|
||||||
|
}
|
||||||
|
|
||||||
void SetArrayLookups()
|
void SetArrayLookups()
|
||||||
{
|
{
|
||||||
for (i32 i = 0; i < Len(g_Shader_File_Map); i++)
|
for (i32 i = 0; i < Len(g_Shader_File_Map); i++)
|
||||||
@ -112,33 +143,33 @@ i32 WriteHeader(FILE *file, FileHeader *header)
|
|||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveToShaderDir(c8 *return_dir)
|
void MoveToShaderDir(c8 **return_dir)
|
||||||
{
|
{
|
||||||
if (DirVisible("build"))
|
if (DirVisible("build"))
|
||||||
{
|
{
|
||||||
Assert(ChangeDir("./build/shaders/glsl") == 0, "Unable to change to shader directory");
|
Assert(ChangeDir("./build/shaders/glsl") == 0, "Unable to change to shader directory");
|
||||||
return_dir = "../../..";
|
*return_dir = "../../..";
|
||||||
}
|
}
|
||||||
else if (DirVisible("shaders"))
|
else if (DirVisible("shaders"))
|
||||||
{
|
{
|
||||||
Assert(ChangeDir("./shaders/glsl") == 0 , "Unable to change to shader directory");
|
Assert(ChangeDir("./shaders/glsl") == 0 , "Unable to change to shader directory");
|
||||||
return_dir = "../..";
|
*return_dir = "../..";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Assert(false, "Unable to find shader directory");
|
Assert(false, "Unable to find shader directory");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveToTextureDir(c8 *return_dir)
|
void MoveToTextureDir(c8 **return_dir)
|
||||||
{
|
{
|
||||||
if (DirVisible("assets"))
|
if (DirVisible("assets"))
|
||||||
{
|
{
|
||||||
Assert(ChangeDir("./assets") == 0, "Unable to change to assets directory");
|
Assert(ChangeDir("./assets") == 0, "Unable to change to assets directory");
|
||||||
return_dir = "..";
|
*return_dir = "..";
|
||||||
}
|
}
|
||||||
if (DirVisible("shaders"))
|
else if (DirVisible("shaders"))
|
||||||
{
|
{
|
||||||
Assert(ChangeDir("../assets") == 0, "Unable to change to assets directory");
|
Assert(ChangeDir("../assets") == 0, "Unable to change to assets directory");
|
||||||
return_dir = "../build";
|
*return_dir = "../build";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Assert(false, "Unable to find assets directory");
|
Assert(false, "Unable to find assets directory");
|
||||||
@ -155,7 +186,7 @@ void InitHeader(FileHeader *header)
|
|||||||
header->tag_counts[SHADER_ASSET] = 0;
|
header->tag_counts[SHADER_ASSET] = 0;
|
||||||
|
|
||||||
header->asset_counts[TEXTURE_ASSET] = TEXTURE_ASSET_MAX;
|
header->asset_counts[TEXTURE_ASSET] = TEXTURE_ASSET_MAX;
|
||||||
header->tag_counts[TEXTURE_ASSET] = TEXTURE_ASSET_MAX;
|
header->tag_counts[TEXTURE_ASSET] = TEXTURE_ASSET_TAG_MAX;
|
||||||
|
|
||||||
header->asset_counts[SOUND_ASSET] = SOUND_ASSET_MAX;
|
header->asset_counts[SOUND_ASSET] = SOUND_ASSET_MAX;
|
||||||
header->tag_counts[SOUND_ASSET] = SOUND_ASSET_TAG_MAX;
|
header->tag_counts[SOUND_ASSET] = SOUND_ASSET_TAG_MAX;
|
||||||
@ -187,10 +218,9 @@ void InitHeader(FileHeader *header)
|
|||||||
|
|
||||||
void PackFiles(Arena *arena, FileHeader *header)
|
void PackFiles(Arena *arena, FileHeader *header)
|
||||||
{
|
{
|
||||||
FILE *file = fopen("assets.sgp", "w+");
|
FILE *file = OpenFile("assets.sgp", "w+");
|
||||||
Assert(file != NULL, "File is null");
|
|
||||||
|
|
||||||
Assert(fwrite(header, sizeof(FileHeader), 1, file) == 1, "Unable to write file header");
|
u64 file_pos = WriteData(header, 0, sizeof(FileHeader), file);
|
||||||
|
|
||||||
u64 data_offset = 0;
|
u64 data_offset = 0;
|
||||||
for (u32 i = 0; i < ASSET_TYPE_MAX; i++)
|
for (u32 i = 0; i < ASSET_TYPE_MAX; i++)
|
||||||
@ -204,9 +234,9 @@ void PackFiles(Arena *arena, FileHeader *header)
|
|||||||
data_offset = asset_offset;
|
data_offset = asset_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
c8 *return_dir = "";
|
c8 *return_dir = ".";
|
||||||
u32 file_count;
|
u32 file_count;
|
||||||
MoveToShaderDir(return_dir);
|
MoveToShaderDir(&return_dir);
|
||||||
|
|
||||||
AssetFile *shader_assets = MakeArray(arena, AssetFile, SHADER_ASSET_MAX);
|
AssetFile *shader_assets = MakeArray(arena, AssetFile, SHADER_ASSET_MAX);
|
||||||
for (u32 i = 0; i < SHADER_ASSET_MAX; i++)
|
for (u32 i = 0; i < SHADER_ASSET_MAX; i++)
|
||||||
@ -215,27 +245,175 @@ void PackFiles(Arena *arena, FileHeader *header)
|
|||||||
|
|
||||||
Printfln("Packing file: %s...", asset_name);
|
Printfln("Packing file: %s...", asset_name);
|
||||||
|
|
||||||
FILE *asset_file = fopen(asset_name, "r");
|
FILE *asset_file = OpenFile(asset_name, "r");
|
||||||
Assert(asset_file != NULL, "Asset file is null");
|
u64 file_size = FileLength(asset_file);
|
||||||
|
|
||||||
int ch = getc(asset_file);
|
u8 *file_data = MakeArray(arena, u8, file_size);
|
||||||
Assert(ch != EOF, "File begins with EOF");
|
ReadData(file_data, 0, file_size, asset_file);
|
||||||
|
|
||||||
while (ch != EOF)
|
u64 prev_offset = data_offset;
|
||||||
|
data_offset += WriteData(file_data, data_offset, file_size, file);
|
||||||
|
|
||||||
|
Assert((data_offset - prev_offset) == file_size, "File write size invalid");
|
||||||
|
|
||||||
|
shader_assets[i].data_offset = prev_offset;
|
||||||
|
shader_assets[i].len = file_size;
|
||||||
|
|
||||||
|
CloseFile(asset_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(ChangeDir(return_dir) == 0, "Unable to return to previous directory");
|
||||||
|
MoveToTextureDir(&return_dir);
|
||||||
|
|
||||||
|
AssetFile *texture_assets = MakeArray(arena, AssetFile, TEXTURE_ASSET_MAX);
|
||||||
|
for (u32 i = 0; i < TEXTURE_ASSET_MAX; i++)
|
||||||
|
{
|
||||||
|
c8 *asset_name = g_Texture_File_Names[i];
|
||||||
|
|
||||||
|
Printfln("Packing file: %s...", asset_name);
|
||||||
|
|
||||||
|
FILE *asset_file = OpenFile(asset_name, "r");
|
||||||
|
u64 file_size = FileLength(asset_file);
|
||||||
|
|
||||||
|
u8 *file_data = MakeArray(arena, u8, file_size);
|
||||||
|
ReadData(file_data, 0, file_size, asset_file);
|
||||||
|
|
||||||
|
u64 prev_offset = data_offset;
|
||||||
|
Printfln("data_offset %llu", data_offset);
|
||||||
|
data_offset += WriteData(file_data, data_offset, file_size, file);
|
||||||
|
|
||||||
|
Assert((data_offset - prev_offset) == file_size, "File write size invalid");
|
||||||
|
|
||||||
|
texture_assets[i].data_offset = prev_offset;
|
||||||
|
texture_assets[i].len = file_size;
|
||||||
|
|
||||||
|
CloseFile(asset_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteData(shader_assets, header->asset_offsets[SHADER_ASSET], sizeof(AssetFile)*SHADER_ASSET_MAX, file);
|
||||||
|
WriteData(texture_assets, header->asset_offsets[TEXTURE_ASSET], sizeof(AssetFile)*TEXTURE_ASSET_MAX, file);
|
||||||
|
|
||||||
|
FileLength(file);
|
||||||
|
|
||||||
|
ChangeDir(return_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintBytes(u8 *bytes, u64 len)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
|
||||||
|
u32 count = 0;
|
||||||
|
while (count + 8 < len)
|
||||||
|
{
|
||||||
|
Printfln("%#02X %#02X %#02X %#02X %#02X %#02X %#02X %#02X", bytes[count], bytes[count+1], bytes[count+2], bytes[count+3],
|
||||||
|
bytes[count+4], bytes[count+5], bytes[count+6], bytes[count+7]);
|
||||||
|
count += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (count < len)
|
||||||
|
{
|
||||||
|
Printf("%u", bytes[count]);
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, FILE *file)
|
||||||
|
{
|
||||||
|
Printfln("Testing file %s...", file_name);
|
||||||
|
|
||||||
|
FILE *asset_file = OpenFile(file_name, "r");
|
||||||
|
u64 size = FileLength(asset_file);
|
||||||
|
|
||||||
|
u8 *file_data = MakeArray(arena, u8, size);
|
||||||
|
u64 write_count = ReadData(file_data, 0, size, asset_file);
|
||||||
|
Assert(write_count == size, "Incorrect asset size retrieved");
|
||||||
|
|
||||||
|
Printfln("len %llu size %llu", file_info->len, size);
|
||||||
|
Assert(file_info->len == size, "file length incorrect");
|
||||||
|
|
||||||
|
u8 *packed_asset = MakeArray(arena, u8, file_info->len);
|
||||||
|
|
||||||
|
ReadData(packed_asset, file_info->data_offset, file_info->len, file);
|
||||||
|
|
||||||
|
for (u64 i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
Assert(file_data[i] == packed_asset[i], "Asset file data is invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseFile(asset_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestAssetPack(Arena *arena)
|
||||||
|
{
|
||||||
|
FILE *file = OpenFile("assets.sgp", "r");
|
||||||
|
|
||||||
|
FileHeader header;
|
||||||
|
i64 offset = FRead(&header, sizeof(FileHeader), 1, file);
|
||||||
|
|
||||||
|
Assert(header.magic_num == CreateMagicValue('s', 't', 'e', 'g'), "Magic number is incorrect");
|
||||||
|
Assert(header.version == FILE_VERSION, "File version is incorrect");
|
||||||
|
|
||||||
|
Assert(header.tag_counts[SHADER_ASSET] == 0, "Shader tag count incorrect");
|
||||||
|
Assert(header.asset_counts[SHADER_ASSET] == SHADER_ASSET_MAX, "Shader count incorrect");
|
||||||
|
|
||||||
|
Assert(header.tag_counts[TEXTURE_ASSET] == TEXTURE_ASSET_TAG_MAX, "Texture tag count incorrect");
|
||||||
|
Assert(header.asset_counts[TEXTURE_ASSET] == TEXTURE_ASSET_MAX, "Texture count incorrect");
|
||||||
|
|
||||||
|
Assert(header.tag_counts[SOUND_ASSET] == SOUND_ASSET_TAG_MAX, "Sound tag count incorrect");
|
||||||
|
Assert(header.asset_counts[SOUND_ASSET] == SOUND_ASSET_MAX, "Sound count incorrect");
|
||||||
|
|
||||||
|
Assert(header.tag_counts[MODEL_ASSET] == MODEL_ASSET_TAG_MAX, "Model tag count incorrect");
|
||||||
|
Assert(header.asset_counts[MODEL_ASSET] == MODEL_ASSET_MAX, "Model count incorrect");
|
||||||
|
|
||||||
|
AssetTag *tags[ASSET_TYPE_MAX];
|
||||||
|
AssetFile *files[ASSET_TYPE_MAX];
|
||||||
|
|
||||||
|
for (u32 i = 0; i < ASSET_TYPE_MAX; i++)
|
||||||
|
{
|
||||||
|
if (header.tag_counts[i] > 0)
|
||||||
{
|
{
|
||||||
putc(ch, file);
|
tags[i] = MakeArray(arena, AssetTag, header.tag_counts[i]);
|
||||||
ch = getc(asset_file);
|
ReadData(tags[i], header.tag_offsets[i], sizeof(AssetTag)*header.tag_counts[i], file);
|
||||||
}
|
}
|
||||||
|
|
||||||
shader_assets[i].data_offset = data_offset;
|
if (header.asset_counts[i] > 0)
|
||||||
shader_assets[i].asset_id = i;
|
{
|
||||||
|
files[i] = MakeArray(arena, AssetFile, header.asset_counts[i]);
|
||||||
|
Printfln("Reading asset info from %llu...", header.asset_offsets[i]);
|
||||||
|
ReadData(files[i], header.asset_offsets[i], sizeof(AssetFile)*header.asset_counts[i], file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data_offset = (u64)ftell(file);
|
for (u32 i = 0; i < SHADER_ASSET_MAX; i++)
|
||||||
|
{
|
||||||
|
Printfln("offset %llu len %llu", files[SHADER_ASSET][i].data_offset, files[SHADER_ASSET][i].len);
|
||||||
|
}
|
||||||
|
for (u32 i = 0; i < TEXTURE_ASSET_MAX; i++)
|
||||||
|
{
|
||||||
|
Printfln("offset %llu len %llu", files[TEXTURE_ASSET][i].data_offset, files[TEXTURE_ASSET][i].len);
|
||||||
|
}
|
||||||
|
|
||||||
|
c8 *return_dir = ".";
|
||||||
|
MoveToShaderDir(&return_dir);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < SHADER_ASSET_MAX; i++)
|
||||||
|
{
|
||||||
|
TestAssetIsCorrect(arena, g_Shader_File_Names[i], &files[SHADER_ASSET][i], file);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeDir(return_dir);
|
||||||
|
MoveToTextureDir(&return_dir);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < TEXTURE_ASSET_MAX; i++)
|
||||||
|
{
|
||||||
|
TestAssetIsCorrect(arena, g_Texture_File_Names[i], &files[TEXTURE_ASSET][i], file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, c8 **argv)
|
int main(int argc, c8 **argv)
|
||||||
{
|
{
|
||||||
|
Printfln("Header: %d", sizeof(FileHeader));
|
||||||
|
|
||||||
SetArrayLookups();
|
SetArrayLookups();
|
||||||
|
|
||||||
void *mem = MemAllocZeroed(GB(1));
|
void *mem = MemAllocZeroed(GB(1));
|
||||||
@ -247,17 +425,9 @@ int main(int argc, c8 **argv)
|
|||||||
FileHeader header = {};
|
FileHeader header = {};
|
||||||
InitHeader(&header);
|
InitHeader(&header);
|
||||||
|
|
||||||
|
PackFiles(arena, &header);
|
||||||
|
|
||||||
|
CloseFile(file);
|
||||||
|
|
||||||
c8 *return_dir;
|
TestAssetPack(arena);
|
||||||
|
|
||||||
c8 **asset_names[ASSET_TYPE_MAX];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Assert(fseek(file, 0, SEEK_SET) == 0, "error seeking file");
|
|
||||||
|
|
||||||
Assert(fclose(file) != EOF, "error closing file");
|
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/packer.h
10
src/packer.h
@ -30,7 +30,7 @@
|
|||||||
# include <dirent.h>
|
# include <dirent.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CreateMagicValue(a, b, c, d) (u32)(a << 24) | (u32)(a << 16) | (u32)(a << 8) | (u32)(a)
|
#define CreateMagicValue(a, b, c, d) ((u32)(d << 24) | (u32)(c << 16) | (u32)(b << 8) | (u32)(a))
|
||||||
#define FILE_VERSION 0
|
#define FILE_VERSION 0
|
||||||
|
|
||||||
typedef struct AssetTag_t
|
typedef struct AssetTag_t
|
||||||
@ -42,7 +42,7 @@ typedef struct AssetTag_t
|
|||||||
typedef struct AssetFile_t
|
typedef struct AssetFile_t
|
||||||
{
|
{
|
||||||
u64 data_offset;
|
u64 data_offset;
|
||||||
u32 asset_id;
|
u64 len;
|
||||||
} AssetFile;
|
} AssetFile;
|
||||||
|
|
||||||
typedef struct AssetHeader_t
|
typedef struct AssetHeader_t
|
||||||
@ -92,3 +92,9 @@ u8 **GetFileNamesInDir(Arena *arena, u32 *count);
|
|||||||
b8 DirVisible(c8 *dir);
|
b8 DirVisible(c8 *dir);
|
||||||
void InitHeader(FileHeader *header);
|
void InitHeader(FileHeader *header);
|
||||||
i32 WriteHeader(FILE *file, FileHeader *header);
|
i32 WriteHeader(FILE *file, FileHeader *header);
|
||||||
|
FILE *OpenFile(c8 *name, c8 *mode);
|
||||||
|
void CloseFile(FILE *file);
|
||||||
|
u64 FileLength(FILE *file);
|
||||||
|
u64 WriteData(void *buf, u64 pos, u64 size, FILE *file);
|
||||||
|
u64 ReadData(void *buf, u64 pos, u64 size, FILE *file);
|
||||||
|
static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, FILE *file);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user