From e412400c116a9633724d6b417448d05ce214b558 Mon Sep 17 00:00:00 2001 From: Katajisto Date: Mon, 2 Feb 2026 20:04:49 +0200 Subject: [PATCH] work on asset packer --- resources/{ => boot}/DroidSerif-Regular.ttf | Bin .../{ => core}/utiltex/apollo.colorgrade.png | Bin resources/{ => core}/utiltex/lut.png | Bin .../{ => core}/utiltex/mono.colorgrade.png | Bin .../{ => core}/utiltex/nes.colorgrade.png | Bin .../{ => core}/utiltex/neutral.colorgrade.png | Bin .../{ => core}/utiltex/pico.colorgrade.png | Bin .../{ => core}/utiltex/retro.colorgrade.png | Bin resources/{ => core}/utiltex/water_small.png | Bin src/assets/asset_manager.jai | 98 ++++++++++++++++++ src/audio/load.jai | 2 +- src/load.jai | 56 +--------- src/main.jai | 30 ++++-- src/meta/pack.jai | 77 +++++++------- src/rendering/animation.jai | 14 +-- src/rendering/pipelines.jai | 2 +- src/rendering/post_processing.jai | 13 ++- src/trile.jai | 2 +- src/world.jai | 2 +- 19 files changed, 173 insertions(+), 123 deletions(-) rename resources/{ => boot}/DroidSerif-Regular.ttf (100%) rename resources/{ => core}/utiltex/apollo.colorgrade.png (100%) rename resources/{ => core}/utiltex/lut.png (100%) rename resources/{ => core}/utiltex/mono.colorgrade.png (100%) rename resources/{ => core}/utiltex/nes.colorgrade.png (100%) rename resources/{ => core}/utiltex/neutral.colorgrade.png (100%) rename resources/{ => core}/utiltex/pico.colorgrade.png (100%) rename resources/{ => core}/utiltex/retro.colorgrade.png (100%) rename resources/{ => core}/utiltex/water_small.png (100%) diff --git a/resources/DroidSerif-Regular.ttf b/resources/boot/DroidSerif-Regular.ttf similarity index 100% rename from resources/DroidSerif-Regular.ttf rename to resources/boot/DroidSerif-Regular.ttf diff --git a/resources/utiltex/apollo.colorgrade.png b/resources/core/utiltex/apollo.colorgrade.png similarity index 100% rename from resources/utiltex/apollo.colorgrade.png rename to resources/core/utiltex/apollo.colorgrade.png diff --git a/resources/utiltex/lut.png b/resources/core/utiltex/lut.png similarity index 100% rename from resources/utiltex/lut.png rename to resources/core/utiltex/lut.png diff --git a/resources/utiltex/mono.colorgrade.png b/resources/core/utiltex/mono.colorgrade.png similarity index 100% rename from resources/utiltex/mono.colorgrade.png rename to resources/core/utiltex/mono.colorgrade.png diff --git a/resources/utiltex/nes.colorgrade.png b/resources/core/utiltex/nes.colorgrade.png similarity index 100% rename from resources/utiltex/nes.colorgrade.png rename to resources/core/utiltex/nes.colorgrade.png diff --git a/resources/utiltex/neutral.colorgrade.png b/resources/core/utiltex/neutral.colorgrade.png similarity index 100% rename from resources/utiltex/neutral.colorgrade.png rename to resources/core/utiltex/neutral.colorgrade.png diff --git a/resources/utiltex/pico.colorgrade.png b/resources/core/utiltex/pico.colorgrade.png similarity index 100% rename from resources/utiltex/pico.colorgrade.png rename to resources/core/utiltex/pico.colorgrade.png diff --git a/resources/utiltex/retro.colorgrade.png b/resources/core/utiltex/retro.colorgrade.png similarity index 100% rename from resources/utiltex/retro.colorgrade.png rename to resources/core/utiltex/retro.colorgrade.png diff --git a/resources/utiltex/water_small.png b/resources/core/utiltex/water_small.png similarity index 100% rename from resources/utiltex/water_small.png rename to resources/core/utiltex/water_small.png diff --git a/src/assets/asset_manager.jai b/src/assets/asset_manager.jai index 79eeb0c..c2c02f2 100644 --- a/src/assets/asset_manager.jai +++ b/src/assets/asset_manager.jai @@ -13,8 +13,13 @@ Pack_Request :: struct { } Loaded_Pack :: struct { + name : string; nameHash : u32 = 0; content : Load_Package; + textures : [..]sg_image; + sounds : [..]Audio_Data; + //fonts : [..]Font??; + } Asset_Manager :: struct { @@ -31,10 +36,30 @@ packcb :: (res: *sfetch_response_t) #c_call { mem.data = res.data.ptr; pack: Loaded_Pack; pack.nameHash = hash.get_hash(g_asset_manager.packQueue[0].name); + pack.name = g_asset_manager.packQueue[0].name; success := init_from_memory(*pack.content, mem, sprint("%", g_asset_manager.packQueue[0].name)); if !success then print("Failed to load pack!!\n"); array_add(*g_asset_manager.loadedPacks, pack); array_unordered_remove_by_index(*g_asset_manager.packQueue, 0); + + add_resources_from_pack(*pack); +} + +add_resources_from_pack :: (pack: *Loaded_Pack) { + add_new_spritesheets_from_pack(*pack.content, pack.name); + load_color_lut_images(*pack.content, pack.name); +} + +find_pack_by_name :: (name: string) -> (bool, Loaded_Pack) { + nameHash := get_hash(name); + asset_pack : Loaded_Pack; + for g_asset_manager.loadedPacks { + if it.nameHash == nameHash { + return true, it; + } + } + print("Was unable to find pack: %\n", name); + return false, .{}; } #scope_export @@ -80,4 +105,77 @@ load_pack :: (name: string, shouldBlock: bool = true, shouldBlockEngine: bool = // Asset management: +#scope_file +#scope_export +create_texture_from_pack :: (pack: string, path: string) -> (sg_image, s32, s32) { + pack_ok, pack := find_pack_by_name(pack); + ok, entry := table_find(*pack.content.lookup, path); + if !ok { + print("Failed to find texture % from pack...\n", path); + img : sg_image; + return img, 0, 0; + } + + x : s32; + y : s32; + channels : s32; + data := stbi.stbi_load_from_memory(entry.data.data, xx entry.data.count, *x, *y, *channels, 4); + img := sg_alloc_image(); + + subimg : [6][16]sg_range; + subimg[0][0] = .{ + ptr = data, + size = xx (x * y * 4) + }; + + sg_init_image(img, *(sg_image_desc.{ + width = x, + height = y, + pixel_format = sg_pixel_format.RGBA8, + data = .{ + subimage = subimg + } + })); + + stbi.stbi_image_free(data); + + return img, x, y; +} + + +// get_texture_pointer :: (pack: string, path: string) -> (ready: bool, texture: *sg_image) { + + +// } + +add_font_from_pack :: (pack: string, path: string) { + pack_ok, pack := find_pack_by_name(pack); + if !pack_ok then return; + for _, key : pack.content.lookup { + print("Key: %\n", key); + } + ok, entry := table_find(*pack.content.lookup, path); + if !ok { + print("Failed to find font % from pack...\n", path); + return; + } + state.font_default.fons_font = fonsAddFontMem(state.fons, "sans", entry.data.data, xx entry.data.count, 0); +} + +load_string_from_pack :: (pack: string, path: string) -> string { + print("Warning: you are circumventing the asset management system....\n"); + pack_ok, pack := find_pack_by_name(pack); + if !pack_ok return ""; + + ok, entry := table_find(*pack.content.lookup, path); + if !ok { + print("Failed to load string from pack: %\n", path); + return ""; + } + + s: string; + s.data = entry.data.data; + s.count = entry.data.count; + return s; +} diff --git a/src/audio/load.jai b/src/audio/load.jai index f2b8a89..a9dfe53 100644 --- a/src/audio/load.jai +++ b/src/audio/load.jai @@ -8,7 +8,7 @@ Wav :: #import "Wav_File"; audio_info : Wav.Waveformatex; load_wav_file :: () { - audio := load_string_from_pack("./game/resources/sound/music/monoco.wav"); + audio := load_string_from_pack("game_core", "sound/music/monoco.wav"); format, samples, success := Wav.get_wav_header(audio); if !success print("Failed to load wav file!!!!!\n"); audio_info = format; diff --git a/src/load.jai b/src/load.jai index 02023d6..30ae331 100644 --- a/src/load.jai +++ b/src/load.jai @@ -3,62 +3,8 @@ g_asset_pack : Load_Package; #scope_export init_after_mandatory_done : bool = false; +init_after_core_done : bool = false; -add_font_from_pack :: (path: string) { - ok, entry := table_find(*g_asset_pack.lookup, path); - if !ok { - print("Failed to find font % from pack...\n", path); - return; - } - state.font_default.fons_font = fonsAddFontMem(state.fons, "sans", entry.data.data, xx entry.data.count, 0); -} - -create_texture_from_pack :: (path: string) -> (sg_image, s32, s32) { - ok, entry := table_find(*g_asset_pack.lookup, path); - if !ok { - print("Failed to find texture % from pack...\n", path); - img : sg_image; - return img, 0, 0; - } - - x : s32; - y : s32; - channels : s32; - data := stbi.stbi_load_from_memory(entry.data.data, xx entry.data.count, *x, *y, *channels, 4); - img := sg_alloc_image(); - - subimg : [6][16]sg_range; - subimg[0][0] = .{ - ptr = data, - size = xx (x * y * 4) - }; - - sg_init_image(img, *(sg_image_desc.{ - width = x, - height = y, - pixel_format = sg_pixel_format.RGBA8, - data = .{ - subimage = subimg - } - })); - - stbi.stbi_image_free(data); - - return img, x, y; -} - -load_string_from_pack :: (path: string) -> string { - ok, entry := table_find(*g_asset_pack.lookup, path); - if !ok { - print("Failed to load string from pack: %\n", path); - return ""; - } - - s: string; - s.data = entry.data.data; - s.count = entry.data.count; - return s; -} asset_list :: () -> string #expand { count := 0; diff --git a/src/main.jai b/src/main.jai index 157956b..4046986 100644 --- a/src/main.jai +++ b/src/main.jai @@ -110,13 +110,19 @@ init :: () { useless_mem : [1]u8; debug_font = get_font_at_size(useless_mem, 15); - load_pack("assets", true, true); + load_pack("boot", true, true); + load_pack("core", true, false); + load_pack("game_core", true, false); } -init_after_asset_pack :: () { +init_after_mandatory :: () { + +} + +init_after_core :: () { init_plane_textures(); - add_font_from_pack("./resources/DroidSerif-Regular.ttf"); + add_font_from_pack("boot", "DroidSerif-Regular.ttf"); ui_init_font_fields(*state.font_default); init_ui(); @@ -133,9 +139,7 @@ init_after_asset_pack :: () { } init_editor(); lworlds(); - init_spritesheets(); init_rendering(); - load_color_lut_images(); load_post_process_from_pack(); audio_init(); @@ -157,12 +161,22 @@ frame :: () { asset_manager_tick(); - if mandatory_loads_done() && !init_after_mandatory_done { - init_after_asset_pack(); + if !mandatory_loads_done() then return; + + if !init_after_mandatory_done { + init_after_mandatory(); init_after_mandatory_done = true; } - if !mandatory_loads_done() then return; + if show_loading_screen() { + print("Should show loading screen....\n"); + return; + } + + if !init_after_core_done { + init_after_core(); + init_after_core_done = true; + } fonsClearState(state.fons); diff --git a/src/meta/pack.jai b/src/meta/pack.jai index 7bce7e2..3f76cd4 100644 --- a/src/meta/pack.jai +++ b/src/meta/pack.jai @@ -1,6 +1,6 @@ -should_ignore_file :: (name: string) -> bool { - #import "String"; +#import "String"; +should_ignore_file :: (name: string) -> bool { ok, left, right := split_from_right(name, #char "."); if right == "aseprite" { @@ -11,48 +11,45 @@ should_ignore_file :: (name: string) -> bool { return false; } + +util :: #import "File_Utilities"; +#import "Hash_Table"; + +packs : Table(string, Create_Package); + +file_visit_handler :: (info: *util.File_Visit_Info, user_data: bool) { + if should_ignore_file(info.short_name) then return; + + _, _, packPath := split_from_left(info.full_name, "/resources/"); + _, packName, fileName := split_from_left(packPath, "/"); + + if !table_contains(*packs, packName) { + package : Create_Package; + init(*package); + table_set(*packs, packName, package); + } + + packPtr := table_find_pointer(*packs, packName); + + file, ok := read_entire_file(info.full_name); + if !ok { + print("Failed in loading file to pack: %\n", fileName); + return; + } + filedata : []u8; + filedata.count = file.count; + filedata.data = file.data; + add(packPtr, fileName, filedata); +} + create_pack :: () { #import "Simple_Package"; #import "File"; - util :: #import "File_Utilities"; - files_to_pack := util.file_list("./resources", true); - - files_to_pack_game := util.file_list("./game/resources", true); + util.visit_files("./resources", true, true, file_visit_handler); + util.visit_files("./game/resources", true, true, file_visit_handler); - package: Create_Package; - defer deinit(*package); - init(*package); - - - for files_to_pack { - if should_ignore_file(it) then continue; - file, ok := read_entire_file(it); - if !ok { - print("Failed in loading file to pack: %\n", it); - continue; - } - filedata : []u8; - filedata.count = file.count; - filedata.data = file.data; - add(*package, it, filedata); + for pack, key : packs { + write(*pack, tprint("./packs/%.pack", key)); } - - for files_to_pack_game { - if should_ignore_file(it) then continue; - file, ok := read_entire_file(it); - if !ok { - print("Failed in loading file to pack: %\n", it); - continue; - } - filedata : []u8; - filedata.count = file.count; - filedata.data = file.data; - add(*package, it, filedata); - } - - print("Packing % engine files -> ./packs/assets.pack\n", files_to_pack.count); - print("Packing % game files -> ./packs/assets.pack\n", files_to_pack_game.count); - - write(*package, "./packs/assets.pack"); } diff --git a/src/rendering/animation.jai b/src/rendering/animation.jai index 384c839..9880601 100644 --- a/src/rendering/animation.jai +++ b/src/rendering/animation.jai @@ -92,24 +92,20 @@ Aseprite_Sheet :: struct { meta : Aseprite_Sheet_Info; } -init_spritesheets :: () { - add_new_spritesheets_from_pack(); -} - -add_new_spritesheets_from_pack :: () { +add_new_spritesheets_from_pack :: (pack: *Load_Package, packName: string) { String :: #import "String"; - for v : g_asset_pack.lookup { - isSpritesheet, remainder := String.contains(v.name, "/sprites/"); + for v : pack.lookup { + isSpritesheet, remainder := String.contains(v.name, "sprites/"); isData := String.contains(remainder, ".json"); if isSpritesheet && isData { print("Adding sheet: %\n", remainder); is_ok, name_without_fileformat := split_from_right(v.name, #char "."); sheet_image_name := sprint("%.png", name_without_fileformat); - sheet_image, sheet_w, sheet_h := create_texture_from_pack(sheet_image_name); + sheet_image, sheet_w, sheet_h := create_texture_from_pack(packName, sheet_image_name); - s := load_string_from_pack(v.name); + s := load_string_from_pack(packName, v.name); success, sheet := Jaison.json_parse_string(s, Aseprite_Sheet,, temp); for sheet.meta.frameTags { diff --git a/src/rendering/pipelines.jai b/src/rendering/pipelines.jai index 56ae6ee..862d0ec 100644 --- a/src/rendering/pipelines.jai +++ b/src/rendering/pipelines.jai @@ -1063,7 +1063,7 @@ create_ssao_pipeline :: () { } init_plane_textures :: () { - gPipelines.plane.bind.images[2] = create_texture_from_pack("./resources/utiltex/water_small.png"); + gPipelines.plane.bind.images[2] = create_texture_from_pack("core", "utiltex/water_small.png"); } g_plane_gbuffer_vertex_buffer : sg_buffer; diff --git a/src/rendering/post_processing.jai b/src/rendering/post_processing.jai index c6481d4..d605f75 100644 --- a/src/rendering/post_processing.jai +++ b/src/rendering/post_processing.jai @@ -33,7 +33,7 @@ Post_Process :: struct { current_post_process : Post_Process; load_post_process_from_pack :: () { - s := load_string_from_pack("./game/resources/postprocess.json"); + s := load_string_from_pack("game_core", "postprocess.json"); success, pp:= Jaison.json_parse_string(s, Post_Process,, temp); if success { current_post_process = pp; @@ -53,15 +53,14 @@ LUT_list : [..]Color_LUT; LUT_name_list : [..]string; g_current_lut_texture_index : s32 = 0; -load_color_lut_images :: () { - for v : g_asset_pack.lookup { +load_color_lut_images :: (pack: *Load_Package, packName: string) { + for v : pack.lookup { isSpritesheet := String.contains(v.name, ".colorgrade.png"); - noop, remainder := String.contains(v.name, "/resources/"); if isSpritesheet { - print("Adding LUT: %\n", remainder); - img, w, h := create_texture_from_pack(v.name); + print("Adding LUT: %\n", v.name); + img, w, h := create_texture_from_pack(packName, v.name); newSheet := Color_LUT.{ - name = remainder, + name = v.name, image = img, }; array_add(*LUT_list, newSheet); diff --git a/src/trile.jai b/src/trile.jai index 196917c..5a9366a 100644 --- a/src/trile.jai +++ b/src/trile.jai @@ -95,7 +95,7 @@ striles :: () { ltriles :: () { Jaison :: #import "Jaison"; - s := load_string_from_pack("./game/resources/triles.json"); + s := load_string_from_pack("game_core", "triles.json"); success, triles := Jaison.json_parse_string(s, [..]TrileSerialize,, temp); for triles { set_trile(sprint("%",it.name), trile_from_serialize_form(it)); diff --git a/src/world.jai b/src/world.jai index 54c81f0..a909bc8 100644 --- a/src/world.jai +++ b/src/world.jai @@ -53,7 +53,7 @@ sworlds :: () { } @Command lworlds :: () { - s := load_string_from_pack("./game/resources/worlds.json"); + s := load_string_from_pack("game_core", "worlds.json"); success, worlds := Jaison.json_parse_string(s, [..]World_Serialized,, temp); for worlds { w : World;