// ::Assets::Globals::Start:: u8 ASSET_PACK[] = { #embed "../assets.sgp" }; static FileHeader File_Header = {0}; static AssetFile Texture_Assets[TEXTURE_ASSET_MAX]; static Asset Texture_Asset_Lookup[TEXTURE_ASSET_MAX]; static AssetFile Shader_Assets[SHADER_ASSET_MAX]; static Asset Shader_Asset_Lookup[SHADER_ASSET_MAX]; // TODO(MA): Implement async asset handling static u32 Shader_Asset_Ref_Count[SHADER_ASSET_MAX]; static u32 Texture_Asset_Ref_Count[TEXTURE_ASSET_MAX]; static b32 ASSET_HEADER_LOADED = false; // ::Assets::Global::End:: // ::Assets::Init::Functions::Start:: static void LoadAssetPackHeader() { MemCpy(&File_Header, ASSET_PACK, sizeof(FileHeader)); Assert(File_Header.magic_num == CreateMagicValue('s', 't', 'e', 'g'), "Magic value is incorrect"); MemCpy(Texture_Assets, &ASSET_PACK[File_Header.asset_offsets[TEXTURE_ASSET]], sizeof(AssetFile) * File_Header.asset_counts[TEXTURE_ASSET]); MemCpy(Shader_Assets, &ASSET_PACK[File_Header.asset_offsets[SHADER_ASSET]], sizeof(AssetFile) * File_Header.asset_counts[SHADER_ASSET]); ASSET_HEADER_LOADED = true; } // ::Assets::Init::Functions::End:: // ::Assets::Loading::Functions::Start:: static Asset AssetPackLoadTexture(TextureAsset asset_id) { if (!ASSET_HEADER_LOADED) { LoadAssetPackHeader(); } Assert(asset_id < i32(TEXTURE_ASSET_MAX), "LoadTextureAsset failure: asset_id is higher than TEXTURE_ASSET_MAX"); Asset asset = Texture_Asset_Lookup[asset_id]; if (asset.bytes == NULL) { AssetFile *asset_info = Texture_Assets + asset_id; u8 *img = FLMemAlloc(asset_info->len); MemCpy(img, &ASSET_PACK[asset_info->data_offset], asset_info->len); int x, y, ch; asset.bytes = stbi_load_from_memory(img, asset_info->len, &x, &y, &ch, 4); asset.len = asset_info->len; asset.texture_meta.w = u32(x); asset.texture_meta.h = u32(y); Texture_Asset_Lookup[asset_id] = asset; FLMemFree(img); } return asset; } static Asset AssetPackLoadShader(ShaderAsset asset_id) { if (!ASSET_HEADER_LOADED) { LoadAssetPackHeader(); } Assert(asset_id < SHADER_ASSET_MAX, "LoadShaderAsset failure: asset_id is higher than SHADER_ASSET_MAX"); Asset asset = Shader_Asset_Lookup[asset_id]; if (asset.bytes == NULL) { AssetFile *asset_info = Shader_Assets + asset_id; asset.bytes = FLMemAlloc(asset_info->len); MemCpy(asset.bytes, &ASSET_PACK[asset_info->data_offset], asset_info->len); asset.len = asset_info->len; Shader_Asset_Lookup[asset_id] = asset; } return asset; } static void AssetPackUnloadTexture(Asset asset) { Assert(asset.bytes != NULL, "UnloadTextureAsset assert failure: ptr is NULL"); for (u32 i = 0; i < TEXTURE_ASSET_MAX; i++) { if (asset.bytes == Texture_Asset_Lookup[i].bytes) { Texture_Asset_Lookup[i].bytes = NULL; Texture_Asset_Lookup[i].len = 0; stbi_image_free(asset.bytes); break; } } } static void AssetPackUnloadShader(Asset asset) { Assert(asset.bytes != NULL, "UnloadShaderAsset assert failure: ptr is NULL"); for (u32 i = 0; i < SHADER_ASSET_MAX; i++) { if (asset.bytes == Shader_Asset_Lookup[i].bytes) { Shader_Asset_Lookup[i].bytes = NULL; Shader_Asset_Lookup[i].len = 0; FLMemFree(asset.bytes); break; } } } // ::Assets::Loading::Functions::End::