300 lines
7.9 KiB
C
300 lines
7.9 KiB
C
// ::Packer::Includes::CFiles::Start::
|
|
|
|
#include "packer.h"
|
|
|
|
#include "fastlz/fastlz.c"
|
|
|
|
#include "assets.c"
|
|
|
|
#ifdef _WIN32
|
|
# include <fcntl.h>
|
|
#endif
|
|
|
|
// ::Packer::Packing::Functions::Start::
|
|
|
|
i32
|
|
WriteHeader(pFile file, FileHeader *header)
|
|
{
|
|
i32 offset = 0;
|
|
|
|
return offset;
|
|
}
|
|
|
|
void
|
|
MoveToShaderDir(c8 **return_dir)
|
|
{
|
|
Assert(pDirNavigate("../assets/shaders") == 0, "Unable to change to shader directory");
|
|
*return_dir = "../../build";
|
|
}
|
|
|
|
void
|
|
MoveToTextureDir(c8 **return_dir)
|
|
{
|
|
Assert(pDirNavigate("../assets/textures") == 0, "Unable to change to assets directory");
|
|
*return_dir = "../../build";
|
|
}
|
|
|
|
void
|
|
MoveToModelDir(c8 **return_dir)
|
|
{
|
|
Assert(pDirNavigate("../assets/models") == 0, "Unable to change to assets directory");
|
|
*return_dir = "../../build";
|
|
}
|
|
|
|
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_MAX + TEXTURE_ASSET_MAX + MODEL_ASSET_MAX;
|
|
header->asset_offset = sizeof(FileHeader);
|
|
}
|
|
|
|
void
|
|
PackFiles(Arena *arena, FileHeader *header)
|
|
{
|
|
pFile file = pFileOpen("assets.sgp", pFS_WRITE | pFS_TRUNC | pFS_CREATE);
|
|
|
|
u64 file_pos = pFileWrite(file, 0, header, sizeof(FileHeader));
|
|
|
|
Assert(pDirNavigate("../assets") == 0, "Unable to move to assets directory");
|
|
|
|
u64 total_assets = SHADER_ASSET_MAX + TEXTURE_ASSET_MAX + MODEL_ASSET_MAX;
|
|
u64 asset_count = 0;
|
|
AssetFile *assets = MakeArray(arena, AssetFile, total_assets);
|
|
|
|
u64 data_offset = header->asset_offset + (sizeof(AssetFile) * total_assets);
|
|
Printfln("%llu %d", data_offset, sizeof(FileHeader));
|
|
|
|
for (u32 i = 0; i < SHADER_ASSET_MAX; i++, asset_count++)
|
|
{
|
|
c8 *asset_name = g_Shader_Asset_Names[i];
|
|
|
|
Printfln("Packing file: %s at offset %llu...", asset_name, data_offset);
|
|
|
|
pFile asset_file = pFileOpen(asset_name, pFS_READ);
|
|
u64 file_size = pFileLength(asset_file);
|
|
|
|
u8 *file_data = MakeArray(arena, u8, file_size);
|
|
pFileRead(asset_file, 0, file_data, file_size);
|
|
|
|
u64 prev_offset = data_offset;
|
|
data_offset += pFileWrite(file, prev_offset, file_data, file_size);
|
|
|
|
Assert((data_offset - prev_offset) == file_size, "File write size invalid");
|
|
|
|
assets[asset_count].data_offset = prev_offset;
|
|
assets[asset_count].len = file_size;
|
|
assets[asset_count].type = AT_SHADER;
|
|
assets[asset_count].hash = g_Shader_Asset_Hashes[i];
|
|
|
|
pFileClose(asset_file);
|
|
}
|
|
|
|
for (u32 i = 0; i < TEXTURE_ASSET_MAX; i++, asset_count++)
|
|
{
|
|
c8 *asset_name = g_Texture_Asset_Names[i];
|
|
|
|
Printfln("Packing file: %s at offset %llu...", asset_name, data_offset);
|
|
|
|
pFile asset_file = pFileOpen(asset_name, pFS_READ);
|
|
u64 file_size = pFileLength(asset_file);
|
|
|
|
u8 *file_data = MakeArray(arena, u8, file_size);
|
|
pFileRead(asset_file, 0, file_data, file_size);
|
|
|
|
int ch = 4;
|
|
int w, h, has_ch;
|
|
u8 *image_bytes = stbi_load_from_memory(file_data, file_size, &w, &h, &has_ch, ch);
|
|
if (w <= 0 || h <= 0 || has_ch <= 0)
|
|
{
|
|
Printfln("%s", stbi_failure_reason());
|
|
Assert(0, "stbi_load_from_memory failure");
|
|
}
|
|
|
|
u64 loaded_length = u64(w * h * ch);
|
|
|
|
u64 prev_offset = data_offset;
|
|
data_offset += pFileWrite(file, data_offset, image_bytes, loaded_length);
|
|
|
|
Assert((data_offset - prev_offset) == loaded_length, "File write size invalid");
|
|
|
|
assets[asset_count].data_offset = prev_offset;
|
|
assets[asset_count].len = loaded_length;
|
|
assets[asset_count].type = AT_TEXTURE;
|
|
assets[asset_count].hash = g_Texture_Asset_Hashes[i];
|
|
assets[asset_count].texture_meta.w = u32(w);
|
|
assets[asset_count].texture_meta.h = u32(h);
|
|
assets[asset_count].texture_meta.ch = u32(ch);
|
|
|
|
stbi_image_free(image_bytes);
|
|
|
|
pFileClose(asset_file);
|
|
|
|
}
|
|
|
|
for (u32 i = 0; i < MODEL_ASSET_MAX; i++, asset_count++)
|
|
{
|
|
c8 *asset_name = g_Model_Asset_Names[i];
|
|
|
|
Printfln("Packing file: %s at offset %llu...", asset_name, data_offset);
|
|
|
|
pFile asset_file = pFileOpen(asset_name, pFS_READ);
|
|
u64 file_size = pFileLength(asset_file);
|
|
|
|
u8 *file_data = MakeArray(arena, u8, file_size);
|
|
pFileRead(asset_file, 0, file_data, file_size);
|
|
|
|
u64 prev_offset = data_offset;
|
|
data_offset += pFileWrite(file, data_offset, file_data, file_size);
|
|
|
|
Assert((data_offset - prev_offset) == file_size, "File write size invalid");
|
|
|
|
m3d_t *model = m3d_load(file_data, NULL, NULL, NULL);
|
|
|
|
assets[asset_count].data_offset = prev_offset;
|
|
assets[asset_count].type = AT_MODEL;
|
|
assets[asset_count].len = file_size;
|
|
assets[asset_count].hash = g_Model_Asset_Hashes[i];
|
|
assets[asset_count].model_meta.i_count = u64(model->numface * 3);
|
|
|
|
m3d_free(model);
|
|
|
|
pFileClose(asset_file);
|
|
}
|
|
|
|
pFileWrite(file, header->asset_offset, assets, sizeof(AssetFile)*asset_count);
|
|
|
|
pFileClose(file);
|
|
|
|
Assert(pDirNavigate("../build") == 0, "Unable to navigate back to build directory");
|
|
}
|
|
|
|
// ::Packer::Packing::Functions::End::
|
|
|
|
|
|
|
|
// ::Packer::Tests::Functions::Start::
|
|
|
|
static inline void
|
|
TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, pFile file)
|
|
{
|
|
pFile asset_file = pFileOpen(file_name, pFS_READ);
|
|
u64 size = pFileLength(asset_file);
|
|
|
|
u8 *file_data = MakeArray(arena, u8, size);
|
|
u64 write_count = pFileRead(asset_file, 0, file_data, size);
|
|
Assert(write_count == size, "Incorrect asset size retrieved");
|
|
|
|
u8 *packed_asset = MakeArray(arena, u8, file_info->len);
|
|
pFileRead(file, file_info->data_offset, packed_asset, file_info->len);
|
|
|
|
u8 *image_bytes;
|
|
u64 image_length;
|
|
if (file_info->type == TEXTURE_ASSET)
|
|
{
|
|
int ch = 4;
|
|
int w, h, has_ch;
|
|
image_bytes = stbi_load_from_memory(file_data, size, &w, &h, &has_ch, ch);
|
|
image_length = u64(w * h * ch);
|
|
|
|
Assert(file_info->len == image_length, "file length incorrect");
|
|
|
|
for (u64 i = 0; i < image_length; i++)
|
|
{
|
|
Assert(image_bytes[i] == packed_asset[i], "Asset file data is invalid");
|
|
}
|
|
|
|
stbi_image_free(image_bytes);
|
|
}
|
|
else
|
|
{
|
|
Assert(file_info->len == size, "file length incorrect");
|
|
|
|
for (u64 i = 0; i < size; i++)
|
|
{
|
|
Assert(file_data[i] == packed_asset[i], "Asset file data is invalid");
|
|
}
|
|
}
|
|
|
|
pFileClose(asset_file);
|
|
}
|
|
|
|
void
|
|
TestAssetPack(Arena *arena)
|
|
{
|
|
pFile file = pFileOpen("assets.sgp", pFS_READ);
|
|
|
|
Assert(pDirNavigate("../assets") == 0, "Unable to navigate back to assets directory");
|
|
|
|
FileHeader header;
|
|
i64 offset = pFileRead(file, 0, &header, sizeof(FileHeader));
|
|
|
|
u64 asset_count = SHADER_ASSET_MAX + MODEL_ASSET_MAX + TEXTURE_ASSET_MAX;
|
|
|
|
Assert(header.magic_num == CreateMagicValue('s', 't', 'e', 'g'), "Magic number is incorrect");
|
|
Assert(header.version == FILE_VERSION, "File version is incorrect");
|
|
|
|
Assert(header.asset_counts == asset_count, "Asset count incorrect");
|
|
|
|
AssetFile *files = MakeArray(arena, AssetFile, asset_count);
|
|
pFileRead(file, header.asset_offset, files, sizeof(AssetFile)*header.asset_counts);
|
|
|
|
u64 current_asset = 0;
|
|
for (u32 i = 0; i < SHADER_ASSET_MAX; i++, current_asset++)
|
|
{
|
|
TestAssetIsCorrect(arena, g_Shader_Asset_Names[i], files + current_asset, file);
|
|
Assert(files[current_asset].hash == g_Shader_Asset_Hashes[i], "Shader asset hash mismatch");
|
|
}
|
|
|
|
for (u32 i = 0; i < TEXTURE_ASSET_MAX; i++, current_asset++)
|
|
{
|
|
TestAssetIsCorrect(arena, g_Texture_Asset_Names[i], files + current_asset, file);
|
|
Assert(files[current_asset].hash == g_Texture_Asset_Hashes[i], "Texture asset hash mismatch");
|
|
}
|
|
|
|
for (u32 i = 0; i < MODEL_ASSET_MAX; i++, current_asset++)
|
|
{
|
|
TestAssetIsCorrect(arena, g_Model_Asset_Names[i], files + current_asset, file);
|
|
Assert(files[current_asset].hash == g_Model_Asset_Hashes[i], "Model asset hash mismatch");
|
|
}
|
|
}
|
|
|
|
// ::Packer::Tests::Functions::End::
|
|
|
|
|
|
|
|
// ::Packer::Main::Functions::Start::
|
|
|
|
int
|
|
main(int argc, c8 **argv)
|
|
{
|
|
#ifdef _WIN32
|
|
{
|
|
_set_fmode(_O_BINARY);
|
|
}
|
|
#endif
|
|
|
|
if (pDirIsVisible("build"))
|
|
{
|
|
Assert(pDirNavigate("./build") == 0, "Unable to change to build directory");
|
|
}
|
|
|
|
void *mem = pMemAllocZeroed(GB(1));
|
|
Arena *arena = ArenaInitDebug(mem, GB(1), __LINE__);
|
|
|
|
FileHeader header = {0};
|
|
InitHeader(&header);
|
|
|
|
PackFiles(arena, &header);
|
|
|
|
TestAssetPack(arena);
|
|
}
|
|
|
|
|
|
|
|
// ::Packer::Main::Functions::End::
|