small improvements

This commit is contained in:
Tuomas Katajisto 2026-03-04 16:33:17 +02:00
parent 629af83d9b
commit 8668157060
17 changed files with 6053 additions and 5918 deletions

View File

@ -31,10 +31,12 @@ Fetch_Request :: struct {
}
Asset_Manager :: struct {
fetch_queue : [..]Fetch_Request;
is_fetching : bool;
current_fetch : Fetch_Request;
loadedPacks : [..]Loaded_Pack;
fetch_queue : [..]Fetch_Request;
is_fetching : bool;
current_fetch : Fetch_Request;
loadedPacks : [..]Loaded_Pack;
pending_hot_reload : bool;
hot_reload_unpause_pending : bool;
}
g_asset_manager : Asset_Manager;
@ -276,14 +278,6 @@ add_resources_from_pack :: (pack: *Loaded_Pack) {
// load_color_lut_images(*pack.content, pack.name);
}
free_resources_from_pack :: (pack: *Loaded_Pack) {
for pack.textures sg_destroy_image(it);
for *pack.audio array_free(it.data);
table_reset(*pack.textures);
table_reset(*pack.audio);
table_reset(*pack.animations);
}
find_pack_by_name :: (name: string) -> (bool, Loaded_Pack) {
nameHash := get_hash(name);
for g_asset_manager.loadedPacks {
@ -297,6 +291,14 @@ find_pack_by_name :: (name: string) -> (bool, Loaded_Pack) {
#scope_export
free_resources_from_pack :: (pack: *Loaded_Pack) {
for pack.textures sg_destroy_image(it);
for *pack.audio array_free(it.data);
table_reset(*pack.textures);
table_reset(*pack.audio);
table_reset(*pack.animations);
}
mandatory_loads_done :: () -> bool {
if g_asset_manager.is_fetching && g_asset_manager.current_fetch.should_block_engine then return false;
for g_asset_manager.fetch_queue {
@ -314,6 +316,17 @@ show_loading_screen :: () -> bool {
}
asset_manager_tick :: () {
#if !RELEASE_BUILD && OS != .WASM {
if g_asset_manager.pending_hot_reload && !g_asset_manager.is_fetching && g_asset_manager.fetch_queue.count == 0 {
g_asset_manager.pending_hot_reload = false;
hot_reload_all_packs();
}
if g_asset_manager.hot_reload_unpause_pending && !show_loading_screen() {
g_mixer.paused = false;
g_asset_manager.hot_reload_unpause_pending = false;
}
}
if !g_asset_manager.is_fetching && g_asset_manager.fetch_queue.count > 0 {
req := g_asset_manager.fetch_queue[0];
// Ordered remove from front to preserve queue priority.

View File

@ -94,6 +94,13 @@ tick_editor_ui :: () {
g_mixer.paused = in_editor_view;
}
#if !RELEASE_BUILD && OS != .WASM {
if input_button_states[Key_Code.F5] & .START {
g_asset_manager.pending_hot_reload = true;
print("Hot-reload: queued, waiting for in-flight loads to finish...\n");
}
}
#if OS != .WASM {
if in_editor_view {
if current_editor_view == {

View File

@ -338,7 +338,7 @@ tick_level_editor :: () {
draw_level_editor :: () {
curworld := get_current_world();
if !curworld.valid then return;
create_set_cam_rendering_task(get_level_editor_camera(), curworld.world.conf.planeHeight);
create_set_cam_rendering_task(get_level_editor_camera(), effective_plane_height(*curworld.world.conf));
create_world_rendering_tasks(*curworld.world);
}

View File

@ -138,9 +138,24 @@ handle_tool_click :: () {
current_color : Vector3 = .{1.0, 0.0, 0.0};
reset_trile :: () {
newt : Trile;
set_trile("test", newt);
editor_current_trile = get_trile("test");
for x: 0..15 {
for y: 0..15 {
for z: 0..15 {
editor_current_trile.trixels[x][y][z].empty = false;
}
}
}
} @Command
trile_copy :: (from: string) {
src := get_trile(from);
for x: 0..15 {
for y: 0..15 {
for z: 0..15 {
editor_current_trile.trixels[x][y][z] = src.trixels[x][y][z];
}
}
}
} @Command
tick_trile_editor :: () {

View File

@ -30,7 +30,8 @@ stbi :: #import "stb_image";
#load "utils.jai";
#load "audio/audio.jai";
#load "assets/asset_manager.jai";
#load "pack_hotreload.jai";
#if USE_SAMPLE_GAME {
#load "../sample_game/game.jai";
} else {

84
src/pack_hotreload.jai Normal file
View File

@ -0,0 +1,84 @@
#if !RELEASE_BUILD && OS != .WASM {
#import "String";
Pack_Writer :: #import "Simple_Package";
File_Util :: #import "File_Utilities";
File_IO :: #import "File";
_hotreload_visitor :: (info: *File_Util.File_Visit_Info, packs: *Table(string, Pack_Writer.Create_Package)) {
{
ok, left, right := split_from_right(info.short_name, #char ".");
if right == "aseprite" return;
}
if contains(info.full_name, "/worlds/") return;
_, _, pack_path := split_from_left(info.full_name, "/resources/");
_, pack_name, file_name := split_from_left(pack_path, "/");
if !table_contains(packs, pack_name) {
package: Pack_Writer.Create_Package;
Pack_Writer.init(*package);
table_set(packs, pack_name, package);
}
pack_ptr := table_find_pointer(packs, pack_name);
file_content, ok := File_IO.read_entire_file(info.full_name);
if !ok {
print("Hot-reload: failed to read '%'\n", info.full_name);
return;
}
data: []u8;
data.data = file_content.data;
data.count = file_content.count;
Pack_Writer.add(pack_ptr, file_name, data);
}
recreate_packs_on_disk :: () {
packs: Table(string, Pack_Writer.Create_Package);
File_Util.visit_files("./resources", true, *packs, _hotreload_visitor);
File_Util.visit_files("./game/resources", true, *packs, _hotreload_visitor);
for pack, key: packs {
Pack_Writer.write(*pack, tprint("./packs/%.pack", key));
print("Hot-reload: wrote pack '%'\n", key);
}
}
hot_reload_all_packs :: () {
pack_names: [..]string;
pack_names.allocator = temp;
for pack: g_asset_manager.loadedPacks {
array_add(*pack_names, sprint("%", pack.name));
}
array_reset(*g_asset_manager.fetch_queue);
g_mixer.paused = true;
g_asset_manager.hot_reload_unpause_pending = true;
// Clear tasks while holding the lock so the audio thread can't be
// mid-sample when we free the audio data below.
mixer_lock(*g_mixer);
array_reset(*g_mixer.tasks);
mixer_unlock(*g_mixer);
for *pack: g_asset_manager.loadedPacks {
free_resources_from_pack(pack);
}
array_reset(*g_asset_manager.loadedPacks);
// Force init_after_core to re-run once the new packs are loaded,
// so that all pack-dependent state (textures, post-process, game_init, etc.)
// is refreshed with the new content.
init_after_core_done = false;
print("Hot-reload: recreating packs on disk...\n");
recreate_packs_on_disk();
for name: pack_names {
load_pack(name, true, false);
}
print("Hot-reload: queued % pack(s) for reload\n", pack_names.count);
}
} // #if !RELEASE_BUILD && OS != .WASM

View File

@ -166,6 +166,7 @@ backend_draw_trile_positions_main :: (trile : string, amount : s32, worldConf: *
sg_apply_pipeline(gPipelines.trile.pipeline);
world_conf : Trile_World_Config;
world_config_to_shader_type(worldConf, *world_conf);
world_conf.planeHeight = effective_plane_height(worldConf);
offset := trile_offsets[current_trile_offset_index];
current_trile_offset_index += 1;
@ -261,7 +262,7 @@ backend_draw_ground :: (wc: *World_Config) {
world_config_to_shader_type(wc, *world_conf);
vs_params.mvp = mvp.floats;
vs_params.planeHeight = wc.planeHeight;
vs_params.planeHeight = effective_plane_height(wc);
sg_apply_pipeline(gPipelines.plane.pipeline);
gPipelines.plane.bind.samplers[1] = g_shadowmap_sampler;
gPipelines.plane.bind.images[1] = g_shadowmap;
@ -341,7 +342,7 @@ backend_draw_ground_gbuf :: (wc: *World_Config) {
vs_params.mvp = mvp.floats;
vs_params.view_matrix = view.floats;
vs_params.isGround = 1;
vs_params.planeHeight = wc.planeHeight;
vs_params.planeHeight = effective_plane_height(wc);
sg_apply_pipeline(gPipelines.gbuffer.pipeline);
bindings : sg_bindings;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,7 @@ layout(binding=1) uniform plane_world_config {
float skyIntensity;
int hasClouds;
float planeHeight;
int planeType;
int animatePlaneHeight;
vec3 waterColor;
vec3 deepColor;
float time;

View File

@ -32,7 +32,7 @@ layout(binding=1) uniform sky_world_config {
int hasClouds;
float planeHeight;
int planeType;
int animatePlaneHeight;
vec3 waterColor;
vec3 deepColor;

View File

@ -47,7 +47,7 @@ layout(binding=1) uniform trile_world_config {
int hasClouds;
float planeHeight;
int planeType;
int animatePlaneHeight;
vec3 waterColor;
vec3 deepColor;

View File

@ -47,7 +47,7 @@ layout(binding=1) uniform trixel_world_config {
int hasClouds;
float planeHeight;
int planeType;
int animatePlaneHeight;
vec3 waterColor;
vec3 deepColor;

View File

@ -180,7 +180,7 @@ World_Config_Binary :: struct {
sky_intensity: float;
has_clouds: s32;
plane_height: float;
plane_type: s32;
animate_plane_height: s32;
water_color: [3]float;
deep_color: [3]float;
}
@ -198,7 +198,7 @@ world_config_to_binary :: (conf: *World_Config) -> World_Config_Binary {
b.sky_intensity = conf.skyIntensity;
b.has_clouds = conf.hasClouds;
b.plane_height = conf.planeHeight;
b.plane_type = conf.planeType;
b.animate_plane_height = conf.animatePlaneHeight;
b.water_color = conf.waterColor.component;
b.deep_color = conf.deepColor.component;
return b;
@ -217,7 +217,7 @@ world_config_from_binary :: (b: *World_Config_Binary) -> World_Config {
conf.skyIntensity = b.sky_intensity;
conf.hasClouds = b.has_clouds;
conf.planeHeight = b.plane_height;
conf.planeType = b.plane_type;
conf.animatePlaneHeight = b.animate_plane_height;
conf.waterColor.component = b.water_color;
conf.deepColor.component = b.deep_color;
return conf;
@ -435,7 +435,7 @@ World_Config :: struct {
hasClouds : s32 = 1; @Slider,0,1,1
planeHeight : float = 0.0; @Slider,0,3,0.1
planeType : s32 = 1; @Slider,0,1,1
animatePlaneHeight : s32 = 1; @Slider,0,1,1
waterColor : Vector3 = .{1.0, 1.0, 1.0}; @Color // @ToDo: sensible default values.
deepColor : Vector3 = .{1.0, 1.0, 1.0}; @Color // @ToDo: sensible default values.
@ -460,6 +460,13 @@ world_config_to_shader_type :: (wc: *World_Config, data: *$T) {
#insert #run,stallable generate_copy_code();
}
effective_plane_height :: (wc: *World_Config) -> float {
if wc.animatePlaneHeight {
return wc.planeHeight * (1.0 + sin(cast(float)get_time() * 0.5) * 0.1);
}
return wc.planeHeight;
}
draw_world_picker :: (r_in: GR.Rect, theme: *GR.Overall_Theme) {
r := r_in;
r.h = ui_h(4,4);