asset packer completed
This commit is contained in:
parent
6984296e0c
commit
d9ec3f4be2
240
src/packer.c
240
src/packer.c
@ -11,6 +11,7 @@
|
||||
#include "game.c"
|
||||
|
||||
#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__
|
||||
b32 ChangeDir(c8 *dir)
|
||||
@ -80,6 +81,36 @@ b8 DirVisible(c8 *dir_name)
|
||||
# error Not yet implemented
|
||||
#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()
|
||||
{
|
||||
for (i32 i = 0; i < Len(g_Shader_File_Map); i++)
|
||||
@ -112,33 +143,33 @@ i32 WriteHeader(FILE *file, FileHeader *header)
|
||||
return offset;
|
||||
}
|
||||
|
||||
void MoveToShaderDir(c8 *return_dir)
|
||||
void MoveToShaderDir(c8 **return_dir)
|
||||
{
|
||||
if (DirVisible("build"))
|
||||
{
|
||||
Assert(ChangeDir("./build/shaders/glsl") == 0, "Unable to change to shader directory");
|
||||
return_dir = "../../..";
|
||||
*return_dir = "../../..";
|
||||
}
|
||||
else if (DirVisible("shaders"))
|
||||
{
|
||||
Assert(ChangeDir("./shaders/glsl") == 0 , "Unable to change to shader directory");
|
||||
return_dir = "../..";
|
||||
*return_dir = "../..";
|
||||
}
|
||||
else
|
||||
Assert(false, "Unable to find shader directory");
|
||||
}
|
||||
|
||||
void MoveToTextureDir(c8 *return_dir)
|
||||
void MoveToTextureDir(c8 **return_dir)
|
||||
{
|
||||
if (DirVisible("assets"))
|
||||
{
|
||||
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");
|
||||
return_dir = "../build";
|
||||
*return_dir = "../build";
|
||||
}
|
||||
else
|
||||
Assert(false, "Unable to find assets directory");
|
||||
@ -155,7 +186,7 @@ void InitHeader(FileHeader *header)
|
||||
header->tag_counts[SHADER_ASSET] = 0;
|
||||
|
||||
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->tag_counts[SOUND_ASSET] = SOUND_ASSET_TAG_MAX;
|
||||
@ -187,10 +218,9 @@ void InitHeader(FileHeader *header)
|
||||
|
||||
void PackFiles(Arena *arena, FileHeader *header)
|
||||
{
|
||||
FILE *file = fopen("assets.sgp", "w+");
|
||||
Assert(file != NULL, "File is null");
|
||||
FILE *file = OpenFile("assets.sgp", "w+");
|
||||
|
||||
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;
|
||||
for (u32 i = 0; i < ASSET_TYPE_MAX; i++)
|
||||
@ -204,9 +234,9 @@ void PackFiles(Arena *arena, FileHeader *header)
|
||||
data_offset = asset_offset;
|
||||
}
|
||||
|
||||
c8 *return_dir = "";
|
||||
c8 *return_dir = ".";
|
||||
u32 file_count;
|
||||
MoveToShaderDir(return_dir);
|
||||
MoveToShaderDir(&return_dir);
|
||||
|
||||
AssetFile *shader_assets = MakeArray(arena, AssetFile, SHADER_ASSET_MAX);
|
||||
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);
|
||||
|
||||
FILE *asset_file = fopen(asset_name, "r");
|
||||
Assert(asset_file != NULL, "Asset file is null");
|
||||
FILE *asset_file = OpenFile(asset_name, "r");
|
||||
u64 file_size = FileLength(asset_file);
|
||||
|
||||
int ch = getc(asset_file);
|
||||
Assert(ch != EOF, "File begins with EOF");
|
||||
u8 *file_data = MakeArray(arena, u8, file_size);
|
||||
ReadData(file_data, 0, file_size, asset_file);
|
||||
|
||||
while (ch != EOF)
|
||||
{
|
||||
putc(ch, file);
|
||||
ch = getc(asset_file);
|
||||
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);
|
||||
}
|
||||
|
||||
shader_assets[i].data_offset = data_offset;
|
||||
shader_assets[i].asset_id = i;
|
||||
Assert(ChangeDir(return_dir) == 0, "Unable to return to previous directory");
|
||||
MoveToTextureDir(&return_dir);
|
||||
|
||||
data_offset = (u64)ftell(file);
|
||||
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)
|
||||
{
|
||||
tags[i] = MakeArray(arena, AssetTag, header.tag_counts[i]);
|
||||
ReadData(tags[i], header.tag_offsets[i], sizeof(AssetTag)*header.tag_counts[i], file);
|
||||
}
|
||||
|
||||
if (header.asset_counts[i] > 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Printfln("Header: %d", sizeof(FileHeader));
|
||||
|
||||
SetArrayLookups();
|
||||
|
||||
void *mem = MemAllocZeroed(GB(1));
|
||||
@ -247,17 +425,9 @@ int main(int argc, c8 **argv)
|
||||
FileHeader header = {};
|
||||
InitHeader(&header);
|
||||
|
||||
PackFiles(arena, &header);
|
||||
|
||||
CloseFile(file);
|
||||
|
||||
c8 *return_dir;
|
||||
|
||||
c8 **asset_names[ASSET_TYPE_MAX];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Assert(fseek(file, 0, SEEK_SET) == 0, "error seeking file");
|
||||
|
||||
Assert(fclose(file) != EOF, "error closing file");
|
||||
TestAssetPack(arena);
|
||||
}
|
||||
|
||||
10
src/packer.h
10
src/packer.h
@ -30,7 +30,7 @@
|
||||
# include <dirent.h>
|
||||
#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
|
||||
|
||||
typedef struct AssetTag_t
|
||||
@ -42,7 +42,7 @@ typedef struct AssetTag_t
|
||||
typedef struct AssetFile_t
|
||||
{
|
||||
u64 data_offset;
|
||||
u32 asset_id;
|
||||
u64 len;
|
||||
} AssetFile;
|
||||
|
||||
typedef struct AssetHeader_t
|
||||
@ -92,3 +92,9 @@ u8 **GetFileNamesInDir(Arena *arena, u32 *count);
|
||||
b8 DirVisible(c8 *dir);
|
||||
void InitHeader(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