394 lines
10 KiB
C
394 lines
10 KiB
C
// ::Packer::Includes::CFiles::Start::
|
|
|
|
#include "packer.h"
|
|
|
|
#include "xxhash/xxhash.c"
|
|
#include "fastlz/fastlz.c"
|
|
|
|
#include "platform/platform.c"
|
|
#include "ds.c"
|
|
#include "util.c"
|
|
#include "allocators.c"
|
|
#include "renderer.c"
|
|
#include "game.c"
|
|
|
|
// ::Packer::Includes::CFiles::End::
|
|
|
|
|
|
|
|
// ::Packer::Globals::Start::
|
|
|
|
const FileMapping g_Shader_File_Map[] = {
|
|
{ .file_name = "quad.frag.spv", .ix = QUAD_FRAG_SPIRV_SHADER },
|
|
{ .file_name = "quad.vert.spv", .ix = QUAD_VERT_SPIRV_SHADER },
|
|
{ .file_name = "gui.frag.spv", .ix = GUI_FRAG_SPIRV_SHADER },
|
|
{ .file_name = "gui.vert.spv", .ix = GUI_VERT_SPIRV_SHADER },
|
|
};
|
|
|
|
const FileMapping g_Texture_File_Map[] = {
|
|
{ .file_name = "pattermon.png", .ix = PATTERMON_OBESE },
|
|
{ .file_name = "patamon.png", .ix = PATTERMON_ORIENTAL },
|
|
{ .file_name = "purplemon.png", .ix = PATTERMON_PURPLOID },
|
|
};
|
|
|
|
c8 *g_Shader_File_Names[SHADER_ASSET_MAX] = {0};
|
|
c8 *g_Texture_File_Names[TEXTURE_ASSET_MAX] = {0};
|
|
|
|
// ::Packer::Globals::End::
|
|
|
|
|
|
|
|
// ::Packer::Files::Functions::Start::
|
|
|
|
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");
|
|
u64 written = (u64)FWrite(buf, size, 1, file);
|
|
fflush(file);
|
|
return written;
|
|
}
|
|
|
|
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");
|
|
}
|
|
|
|
// ::Packer::Files::Functions::End::
|
|
|
|
|
|
|
|
// ::Packer::Packing::Functions::Start::
|
|
|
|
void SetArrayLookups()
|
|
{
|
|
for (i32 i = 0; i < Len(g_Shader_File_Map); i++)
|
|
{
|
|
FileMapping file_mapping = g_Shader_File_Map[i];
|
|
g_Shader_File_Names[file_mapping.ix] = file_mapping.file_name;
|
|
}
|
|
|
|
for (int i = 0; i < SHADER_ASSET_MAX; i++)
|
|
{
|
|
Assert(g_Shader_File_Names[i] != NULL, "Spirv shader file name is null");
|
|
}
|
|
|
|
for (i32 i = 0; i < Len(g_Texture_File_Map); i++)
|
|
{
|
|
FileMapping file_mapping = g_Texture_File_Map[i];
|
|
g_Texture_File_Names[file_mapping.ix] = file_mapping.file_name;
|
|
}
|
|
|
|
for (int i = 0; i < TEXTURE_ASSET_MAX; i++)
|
|
{
|
|
Assert(g_Texture_File_Names[i] != NULL, "Texture file name is null");
|
|
}
|
|
}
|
|
|
|
i32 WriteHeader(FILE *file, FileHeader *header)
|
|
{
|
|
i32 offset = 0;
|
|
|
|
return offset;
|
|
}
|
|
|
|
void MoveToShaderDir(c8 **return_dir)
|
|
{
|
|
if (DirVisible("build"))
|
|
{
|
|
Assert(ChangeDir("./build/shaders/glsl") == 0, "Unable to change to shader directory");
|
|
*return_dir = "../../..";
|
|
}
|
|
else if (DirVisible("shaders"))
|
|
{
|
|
Assert(ChangeDir("./shaders/glsl") == 0 , "Unable to change to shader directory");
|
|
*return_dir = "../..";
|
|
}
|
|
else
|
|
Assert(false, "Unable to find shader directory");
|
|
}
|
|
|
|
void MoveToTextureDir(c8 **return_dir)
|
|
{
|
|
if (DirVisible("assets"))
|
|
{
|
|
Assert(ChangeDir("./assets") == 0, "Unable to change to assets directory");
|
|
*return_dir = "..";
|
|
}
|
|
else if (DirVisible("shaders"))
|
|
{
|
|
Assert(ChangeDir("../assets") == 0, "Unable to change to assets directory");
|
|
*return_dir = "../build";
|
|
}
|
|
else
|
|
Assert(false, "Unable to find assets directory");
|
|
}
|
|
|
|
void InitHeader(FileHeader *header)
|
|
{
|
|
Assert(header != NULL, "File header is null");
|
|
|
|
header->magic_num = CreateMagicValue('s', 't', 'e', 'g');
|
|
header->version = FILE_VERSION;
|
|
|
|
header->asset_counts[SHADER_ASSET] = SHADER_ASSET_MAX;
|
|
header->tag_counts[SHADER_ASSET] = 0;
|
|
|
|
header->asset_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;
|
|
|
|
header->asset_counts[MODEL_ASSET] = MODEL_ASSET_MAX;
|
|
header->tag_counts[MODEL_ASSET] = MODEL_ASSET_TAG_MAX;
|
|
|
|
u64 offset = sizeof(FileHeader);
|
|
|
|
for (u32 i = 0; i < ASSET_TYPE_MAX; i++)
|
|
{
|
|
if (header->tag_counts[i] > 0)
|
|
{
|
|
header->tag_offsets[i] = offset;
|
|
offset += sizeof(AssetTag) * header->tag_counts[i];
|
|
}
|
|
else
|
|
header->tag_offsets[i] = 0;
|
|
|
|
if (header->asset_counts[i] > 0)
|
|
{
|
|
header->asset_offsets[i] = offset;
|
|
offset += sizeof(AssetFile) * header->asset_counts[i];
|
|
}
|
|
else
|
|
header->asset_offsets[i] = 0;
|
|
}
|
|
}
|
|
|
|
void PackFiles(Arena *arena, FileHeader *header)
|
|
{
|
|
FILE *file = OpenFile("assets.sgp", "w+");
|
|
|
|
u64 file_pos = WriteData(header, 0, sizeof(FileHeader), file);
|
|
|
|
u64 data_offset = 0;
|
|
for (u32 i = 0; i < ASSET_TYPE_MAX; i++)
|
|
{
|
|
u64 tag_offset = header->tag_offsets[i] + (header->tag_counts[i] * sizeof(AssetTag));
|
|
if (tag_offset > data_offset)
|
|
data_offset = tag_offset;
|
|
|
|
u64 asset_offset = header->asset_offsets[i] + (header->asset_counts[i] * sizeof(AssetFile));
|
|
if (asset_offset > data_offset)
|
|
data_offset = asset_offset;
|
|
}
|
|
|
|
c8 *return_dir = ".";
|
|
u32 file_count;
|
|
MoveToShaderDir(&return_dir);
|
|
|
|
AssetFile *shader_assets = MakeArray(arena, AssetFile, SHADER_ASSET_MAX);
|
|
for (u32 i = 0; i < SHADER_ASSET_MAX; i++)
|
|
{
|
|
c8 *asset_name = g_Shader_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;
|
|
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);
|
|
|
|
ChangeDir(return_dir);
|
|
}
|
|
|
|
// ::Packer::Packing::Functions::End::
|
|
|
|
|
|
|
|
// ::Packer::Tests::Functions::Start::
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
// ::Packer::Tests::Functions::End::
|
|
|
|
|
|
|
|
// ::Packer::Main::Functions::Start::
|
|
|
|
int main(int argc, c8 **argv)
|
|
{
|
|
Printfln("Header: %d", sizeof(FileHeader));
|
|
|
|
SetArrayLookups();
|
|
|
|
void *mem = MemAllocZeroed(GB(1));
|
|
Arena *arena = CreateArenaDebug(mem, GB(1), __LINE__);
|
|
|
|
FILE *file = fopen("assets.sgp", "w+");
|
|
Assert(file != NULL, "File is null");
|
|
|
|
FileHeader header = {0};
|
|
InitHeader(&header);
|
|
|
|
PackFiles(arena, &header);
|
|
|
|
CloseFile(file);
|
|
|
|
TestAssetPack(arena);
|
|
}
|
|
|
|
// ::Packer::Main::Functions::End::
|