From 24c9cd2fc75fc3fa4f67cff804706c2644699d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Pons?= Date: Mon, 23 Jun 2025 17:48:17 +0200 Subject: [PATCH] Add a makefile, change imgui with nuklear and add file dropping and loading --- .vscode/c_cpp_properties.json | 20 ++--- .vscode/settings.json | 5 +- build.sh | 5 +- debug.sh | 3 +- makefile | 82 ++++++++++++++++++++ src/api.h | 12 ++- src/generated/{sprite.h => sprite.wgsl.h} | 49 ++++++------ src/main.c | 92 ++++++++++++----------- src/shaders/sprite.wgsl | 4 +- src/sprite.h | 67 +++++++++++++++++ src/util.h | 31 ++++---- 11 files changed, 265 insertions(+), 105 deletions(-) create mode 100644 makefile rename src/generated/{sprite.h => sprite.wgsl.h} (83%) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index a68ad47..876204d 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -20,9 +20,7 @@ "name": "Emscripten", "includePath": [ "${workspaceFolder}/../sokol", - "${workspaceFolder}/../sokol_gp", - "${workspaceFolder}/../cimgui", - "${workspaceFolder}/../flecs/distr" + "${workspaceFolder}/../nuklear" ], "defines": [ "_DEBUG", @@ -30,8 +28,8 @@ "_UNICODE" ], "windowsSdkVersion": "10.0.22621.0", - "compilerPath": "D:\\UserDefaults\\Desktop\\Dev\\Git\\emsdk\\upstream\\emscripten\\emcc.bat", - "cStandard": "c17", + "compilerPath": "C:\\Users\\c.pons\\Documents\\Perso\\Git\\emsdk\\upstream\\emscripten\\emcc.bat", + "cStandard": "c99", "cppStandard": "c++17", "intelliSenseMode": "windows-clang-x64", "mergeConfigurations": false, @@ -43,16 +41,12 @@ "limitSymbolsToIncludedHeaders": true }, "compilerArgs": [ - "-O2", - "-sUSE_WEBGL2", + "-sUSE_WEBGPU", "-sASSERTIONS", "-sWASM_BIGINT", - "-sFILESYSTEM=0", - "-sALLOW_MEMORY_GROWTH=1", - "-sSTACK_SIZE=1mb", - "-sEXPORTED_RUNTIME_METHODS=cwrap", - "-sMODULARIZE=1", - "-sEXPORT_NAME=\"flecs_tests\"" + "-sALLOW_MEMORY_GROWTH", + "-msimd128", + "-sFILESYSTEM=0" ] } ], diff --git a/.vscode/settings.json b/.vscode/settings.json index 8b3a62b..8ed66de 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -28,6 +28,9 @@ "sokol_imgui.h": "c", "typeinfo": "c", "api.h": "c", - "sprite.h": "c" + "sprite.h": "c", + "stdint.h": "c", + "sokol_nuklear.h": "c", + "nuklear.h": "c" } } \ No newline at end of file diff --git a/build.sh b/build.sh index 288e7fa..3706b8e 100644 --- a/build.sh +++ b/build.sh @@ -1,5 +1,3 @@ -emcc -O3 src/main.c -o app.html -sUSE_WEBGPU -sWASM_BIGINT -sALLOW_MEMORY_GROWTH -I../sokol -I../sokol_gp -I../cimgui -msimd128 -flto --llvm-lto 1 --shell-file=shell.html -sFILESYSTEM=0 - emcc -O3 src/main.c \ ../cimgui/cimgui.cpp \ ../cimgui/imgui.cpp \ @@ -11,10 +9,9 @@ emcc -O3 src/main.c \ -sWASM_BIGINT \ -sALLOW_MEMORY_GROWTH \ -I../sokol \ - -I../sokol_gp \ -I../cimgui \ - -I../flecs/distr \ -msimd128 \ -flto \ + --llvm-lto 1 \ --shell-file=shell.html \ -sFILESYSTEM=0 \ No newline at end of file diff --git a/debug.sh b/debug.sh index 21341e7..0f6d425 100644 --- a/debug.sh +++ b/debug.sh @@ -1,4 +1,5 @@ xxd -i src/shaders/sprite.wgsl src/generated/sprite.h + emcc src/main.c \ ../cimgui/cimgui.cpp \ ../cimgui/imgui.cpp \ @@ -11,9 +12,7 @@ emcc src/main.c \ -sWASM_BIGINT \ -sALLOW_MEMORY_GROWTH \ -I../sokol \ - -I../sokol_gp \ -I../cimgui \ - -I../flecs/distr \ -msimd128 \ --shell-file=shell.html \ -sFILESYSTEM=0 \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..ea54402 --- /dev/null +++ b/makefile @@ -0,0 +1,82 @@ +# Compiler and tools +CC = emcc +XXD = xxd + +# Directories +SRC_DIR = src +SHADER_DIR = $(SRC_DIR)/shaders +GENERATED_DIR = $(SRC_DIR)/generated +SOKOL_DIR = ../sokol +NUKLEAR_DIR = ../nuklear + +# Output +TARGET = app.html + +# Source files +C_SOURCES = $(SRC_DIR)/main.c + +# Dynamic shader processing +SHADER_FILES = $(wildcard $(SHADER_DIR)/*) +SHADER_HEADERS = $(patsubst $(SHADER_DIR)/%,$(GENERATED_DIR)/%.h,$(SHADER_FILES)) + +# Compiler flags +EMCC_FLAGS = -sUSE_WEBGPU \ + -sASSERTIONS \ + -sWASM_BIGINT \ + -sALLOW_MEMORY_GROWTH \ + -msimd128 \ + -sFILESYSTEM=0 + +# Include directories +INCLUDES = -I$(SOKOL_DIR) -I$(NUKLEAR_DIR) + +# Shell template +SHELL_FILE = shell.html + +# Default target +all: $(TARGET) + +# Main build target +$(TARGET): $(SHADER_HEADERS) $(C_SOURCES) $(SHELL_FILE) + $(CC) $(C_SOURCES) \ + -o $(TARGET) \ + $(EMCC_FLAGS) \ + -O3 \ + $(INCLUDES) \ + --shell-file=$(SHELL_FILE) + +# Pattern rule for generating shader headers +$(GENERATED_DIR)/%.h: $(SHADER_DIR)/% | $(GENERATED_DIR) + @echo "Generating header for $<" + $(XXD) -i $< $@ + +# Create generated directory if it doesn't exist +$(GENERATED_DIR): + mkdir -p $(GENERATED_DIR) + +debug: $(SHADER_HEADERS) $(C_SOURCES) $(SHELL_FILE) + $(CC) $(C_SOURCES) \ + -o $(TARGET) \ + $(EMCC_FLAGS) \ + -g -gsource-map=inline \ + $(INCLUDES) \ + --shell-file=$(SHELL_FILE) + +# Clean build artifacts +clean: + rm -f $(TARGET) app.js app.wasm + rm -rf $(GENERATED_DIR) + +# Rebuild everything +rebuild: clean all + +# List all shader files (for debugging) +list-shaders: + @echo "Shader files found:" + @echo "$(SHADER_FILES)" + @echo "" + @echo "Generated headers:" + @echo "$(SHADER_HEADERS)" + +# Phony targets +.PHONY: all clean rebuild list-shaders \ No newline at end of file diff --git a/src/api.h b/src/api.h index 60fdd5b..f4aaaf0 100644 --- a/src/api.h +++ b/src/api.h @@ -4,20 +4,26 @@ #define SOKOL_IMPL #define SOKOL_WGPU -#include "cimgui.h" +#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT +#define NK_INCLUDE_FONT_BAKING +#define NK_INCLUDE_DEFAULT_ALLOCATOR +#define NK_INCLUDE_DEFAULT_FONT +#define NK_IMPLEMENTATION + #include "sokol_gfx.h" #include "sokol_app.h" #include "sokol_glue.h" #include "sokol_log.h" +#include "nuklear.h" #include "util/sokol_memtrack.h" -#include "util/sokol_imgui.h" +#include "util/sokol_nuklear.h" #include "math.h" #include "rand.h" #include "util.h" #include "sprite.h" -#include "generated/sprite.h" +#include "generated/sprite.wgsl.h" #include #include diff --git a/src/generated/sprite.h b/src/generated/sprite.wgsl.h similarity index 83% rename from src/generated/sprite.h rename to src/generated/sprite.wgsl.h index fa48e93..ae760b9 100644 --- a/src/generated/sprite.h +++ b/src/generated/sprite.wgsl.h @@ -117,28 +117,29 @@ unsigned char src_shaders_sprite_wgsl[] = { 0x3e, 0x20, 0x75, 0x33, 0x32, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x66, 0x6c, 0x6f, 0x6f, - 0x72, 0x28, 0x75, 0x76, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x77, 0x69, 0x64, - 0x74, 0x68, 0x29, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x77, 0x69, 0x64, 0x74, - 0x68, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, - 0x20, 0x79, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x20, 0x3d, 0x20, 0x63, 0x6c, - 0x61, 0x6d, 0x70, 0x28, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x75, 0x76, - 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29, - 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29, - 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x79, 0x20, 0x2a, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, - 0x2b, 0x20, 0x78, 0x3b, 0x0d, 0x0a, 0x7d, 0x2a, 0x2f, 0x0d, 0x0a, 0x0d, - 0x0a, 0x40, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x66, - 0x6e, 0x20, 0x66, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x69, 0x6e, - 0x70, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x29, 0x20, - 0x2d, 0x3e, 0x20, 0x46, 0x73, 0x4f, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x3a, 0x20, 0x46, 0x73, 0x4f, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x63, 0x6f, 0x6c, - 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, - 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x74, 0x65, 0x78, 0x2c, 0x20, - 0x73, 0x61, 0x6d, 0x70, 0x2c, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e, - 0x75, 0x76, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a + 0x72, 0x28, 0x75, 0x76, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x66, 0x33, 0x32, + 0x28, 0x77, 0x69, 0x64, 0x74, 0x68, 0x29, 0x29, 0x2c, 0x20, 0x30, 0x2c, + 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x79, 0x3a, 0x20, 0x75, 0x33, 0x32, + 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x66, 0x6c, 0x6f, + 0x6f, 0x72, 0x28, 0x75, 0x76, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x66, 0x33, + 0x32, 0x28, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29, 0x29, 0x2c, 0x20, + 0x30, 0x2c, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29, 0x3b, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x79, 0x20, 0x2a, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x2b, 0x20, + 0x78, 0x3b, 0x0d, 0x0a, 0x7d, 0x2a, 0x2f, 0x0d, 0x0a, 0x0d, 0x0a, 0x40, + 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x6e, 0x20, + 0x66, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x3a, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x29, 0x20, 0x2d, 0x3e, + 0x20, 0x46, 0x73, 0x4f, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3a, 0x20, + 0x46, 0x73, 0x4f, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x73, 0x61, + 0x6d, 0x70, 0x2c, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x75, 0x76, + 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3b, + 0x0d, 0x0a, 0x7d, 0x0d, 0x0a }; -unsigned int src_shaders_sprite_wgsl_len = 1687; +unsigned int src_shaders_sprite_wgsl_len = 1697; diff --git a/src/main.c b/src/main.c index f2e5c60..e8fca8e 100644 --- a/src/main.c +++ b/src/main.c @@ -16,10 +16,6 @@ typedef struct renderer_t { uniform_t uniform; //Uniform data } renderer_t; -typedef struct manager_t { - vector_t textures; -} manager_t; - typedef struct dragger_t { bool dragging; float origin_x, origin_y; @@ -34,7 +30,7 @@ typedef struct userdata_t { manager_t manager; } userdata_t; -void js_log(int severity, const char* format, ...) +const char* format(const char* format, ...) { char buffer[_SLOG_LINE_LENGTH]; @@ -44,7 +40,8 @@ void js_log(int severity, const char* format, ...) int size = vsnprintf(buffer, _SLOG_LINE_LENGTH, format, va); va_end(va); - slog_js_log(severity, buffer); + + return buffer; } void compute_mvp(userdata_t *userdata) { @@ -58,21 +55,22 @@ static void frame(void* _userdata) { userdata_t* userdata = (userdata_t*) _userdata; - simgui_new_frame(&(simgui_frame_desc_t){ - .width = userdata->width, - .height = userdata->height, - .delta_time = sapp_frame_duration(), - .dpi_scale = 1.0f, - }); + struct nk_context *nk_ctx = snk_new_frame(); + + if(nk_begin(nk_ctx, "Menu", nk_rect(20, 20, 600, 200), NK_WINDOW_BORDER | NK_WINDOW_BACKGROUND | NK_WINDOW_MOVABLE | NK_WINDOW_CLOSABLE)) + { + nk_layout_row_dynamic(nk_ctx, 0, 1); + nk_label(nk_ctx, format("Frame duration: %.4fms", sapp_frame_duration() * 1000.0), NK_TEXT_ALIGN_CENTERED); + + nk_layout_row_dynamic(nk_ctx, 0, 1); + nk_label(nk_ctx, format("Zoom: %.3f", userdata->zoom), NK_TEXT_ALIGN_CENTERED); + + nk_layout_row_dynamic(nk_ctx, 0, 1); + nk_label(nk_ctx, format("Pan: %.3f/%.3f", userdata->pan.x, userdata->pan.y), NK_TEXT_ALIGN_CENTERED); + - igSetNextWindowPos((ImVec2){20,20}, ImGuiCond_Once); - igSetNextWindowSize((ImVec2){600,200}, ImGuiCond_Once); - if (igBegin("Menu", 0, ImGuiWindowFlags_NoResize)) { - igText("Frame duration: %.4fms", sapp_frame_duration() * 1000.0); - igText("Zoom: %.3f", userdata->zoom); - igText("Pan: %.3f/%.3f", userdata->pan.x, userdata->pan.y); } - igEnd(); + nk_end(nk_ctx); sg_begin_pass(&(sg_pass){ .action = userdata->renderer.clear_pass, @@ -102,7 +100,7 @@ static void frame(void* _userdata) } } - simgui_render(); + snk_render(userdata->width, userdata->height); sg_end_pass(); sg_commit(); @@ -139,21 +137,6 @@ static void init(void* _userdata) userdata->pan = (vec2f) { 0.0f, 0.0f }; userdata->zoom = 2; - vec2f* tmp_buffer = malloc(sizeof(vec2f) * GRID_X * GRID_Y); - - uint32_t i = 0; - for(uint32_t x = 0; x < GRID_X; x++) - { - for(uint32_t y = 0; y < GRID_Y; y++) - { - const float angle = next_float_max(PI), radius = next_float_max(0.5f); - tmp_buffer[i].x = x + sin(angle) * radius - GRID_X / 2.0f; - tmp_buffer[i].y = y + cos(angle) * radius - GRID_Y / 2.0f; - - i++; - } - } - sg_shader sprite_shader = sg_make_shader(&(sg_shader_desc) { .vertex_func = { .source = (const char*) src_shaders_sprite_wgsl, @@ -227,15 +210,12 @@ static void init(void* _userdata) } }; - userdata->manager = (manager_t) { - .textures = vector_create(sizeof(texture_t)), - }; + gs_init(&userdata->manager); compute_mvp(userdata); - FREE(tmp_buffer); - - simgui_setup(&(simgui_desc_t) { + snk_setup(&(snk_desc_t) { + .enable_set_mouse_cursor = true, .logger.func = slog_func, .allocator = { .alloc_fn = smemtrack_alloc, @@ -252,7 +232,7 @@ static void cleanup(void* _userdata) FREE(userdata); - simgui_shutdown(); + snk_shutdown(); sg_shutdown(); } @@ -260,11 +240,37 @@ static void event(const sapp_event* event, void* _userdata) { userdata_t* userdata = (userdata_t*) _userdata; - if(simgui_handle_event(event)) + if(snk_handle_event(event)) return; switch(event->type) { + case SAPP_EVENTTYPE_FILES_DROPPED: + uint32_t files = sapp_get_num_dropped_files(); + + for(uint32_t i = 0; i < files; i++) + { + const uint32_t size = sapp_html5_get_dropped_file_size(i); + + if(size > MAX_FILE_SIZE) + { + //Toast error + continue; + } + + void* buffer = malloc(size); + + sapp_html5_fetch_dropped_file(&(sapp_html5_fetch_request) { + .buffer = (sapp_range) { .ptr = buffer, .size = size }, + .dropped_file_index = i, + .callback = gs_import_file, + .user_data = &(import_t) { + .userdata = userdata, + }, + }); + } + + break; case SAPP_EVENTTYPE_RESIZED: userdata->width = sapp_width(); userdata->height = sapp_height(); diff --git a/src/shaders/sprite.wgsl b/src/shaders/sprite.wgsl index 5d12597..6795211 100644 --- a/src/shaders/sprite.wgsl +++ b/src/shaders/sprite.wgsl @@ -42,8 +42,8 @@ struct FsO { //Fragment shader output }*/ // Get the texture array index from the UV /*fn indexFromCoord(uv: vec2f, width: u32, height: u32) -> u32 { - let x: u32 = clamp(floor(uv.x * width), 0, width); - let y: u32 = clamp(floor(uv.y * height), 0, height); + let x: u32 = clamp(floor(uv.x * f32(width)), 0, width); + let y: u32 = clamp(floor(uv.y * f32(height)), 0, height); return y * width + x; }*/ diff --git a/src/sprite.h b/src/sprite.h index 6d39af3..cebcf2e 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -3,6 +3,11 @@ #include "api.h" +#define KB (1024u) +#define MB (1024u * KB) +#define GB (1024u * MB) +#define MAX_FILE_SIZE (10u * MB) + typedef struct texture_t { uint32_t id; //Texture ID sg_bindings binding; //Texture bindings (texture, sampler and buffer) @@ -14,4 +19,66 @@ typedef struct sprite_t { mat4x4f transform; } sprite_t; +typedef struct manager_t { + vector_t textures; +} manager_t; + +typedef struct import_t { + userdata_t *userdata; + +} import_t; + +typedef struct loader_t { + uint8_t buffer[MAX_FILE_SIZE]; +} loader_t; + +typedef void (*ForEachTexture)(texture_t *texture, userdata_t *userdata); +typedef void (*ForEachSprite)(sprite_t *sprite, userdata_t *userdata); + +void gs_init(manager_t *manager); +void gs_shutdown(manager_t *manager); +void gs_import_file(const sapp_html5_fetch_response *response); + +void gs_each_textures(manager_t *manager, ForEachTexture callback, userdata_t *userdata); +void gs_each_sprites(manager_t *manager, ForEachSprite callback, userdata_t *userdata); + +void gs_init(manager_t *manager) +{ + manager->textures = vector_create(sizeof(texture_t)); +} +void gs_shutdown(manager_t *manager) +{ + vector_free(&manager->textures); +} + +void fs_import_file(const sapp_html5_fetch_response *response) +{ + const char* filename = sapp_get_dropped_file_path(response->file_index); + + if(response->succeeded) + { + + } + else + { + //Toast error + } +} +void gs_each_textures(manager_t *manager, ForEachTexture callback, userdata_t *userdata) +{ + for(uint32_t i = 0; i < manager->textures.size; i++) + callback((texture_t*) manager->textures.data[i], userdata); +} +void gs_each_sprites(manager_t *manager, ForEachSprite callback, userdata_t *userdata) +{ + for(uint32_t i = 0; i < manager->textures.size; i++) + { + const texture_t* texture = (texture_t*) manager->textures.data[i]; + for(uint32_t j = 0; j < texture->sprites.size; j++) + { + callback((sprite_t*) texture->sprites.data[j], userdata); + } + } +} + #endif \ No newline at end of file diff --git a/src/util.h b/src/util.h index 26c7b93..f746ef9 100644 --- a/src/util.h +++ b/src/util.h @@ -84,10 +84,10 @@ typedef struct vector_t { } vector_t; #define MAX_BUCKET_SIZE (0xffffffffu) -#define MAX_STRIPE_SIZE (0xffffu) +#define MAX_STRIPE_SIZE (0xffffffu) #define FIXED_START (0xfffu) -static vector_t vector_create(uint16_t stripe); //Create a new vector with a default size +static vector_t vector_create(uint32_t stripe); //Create a new vector with a default size static void vector_clear(vector_t *vector); static void vector_free(vector_t *vector); @@ -97,7 +97,7 @@ static void vector_set(vector_t *vector, uint32_t index, void *data); static uint32_t vector_push(vector_t *vector, void *data); static sg_range vector_range(vector_t *vector); -static vector_t vector_create(uint16_t stripe) +static vector_t vector_create(uint32_t stripe) { assert(stripe >= sizeof(uint32_t)); assert(stripe <= MAX_STRIPE_SIZE); @@ -158,32 +158,37 @@ static sg_range vector_range(vector_t *vector) typedef struct mem_pool_t { void **data; //Memory pool - uint16_t stripe; //Bit per item + uint32_t stripe; //Bit per item uint32_t size; //Current amount of items uint32_t capacity; //Max capacity uint32_t free; //Linked list of available indices } mem_pool_t; -static mem_pool_t pool_create(uint16_t stripe); //Create a new memory pool with a default size +static mem_pool_t pool_create_default(uint32_t stripe); //Create a new memory pool with a default size +static mem_pool_t pool_create(uint32_t stripe, uint32_t size); //Create a new memory pool with a default size static void pool_clear(mem_pool_t *pool); static void pool_free(mem_pool_t *pool); -static uint32_t pool_add(mem_pool_t *pool); //Request a new free index -static void* pool_get(mem_pool_t *pool, uint32_t index); //Get the pointer +static const uint32_t pool_add(mem_pool_t *pool); //Request a new free index +static const void* pool_get(mem_pool_t *pool, uint32_t index); //Get the pointer static void pool_remove(mem_pool_t *pool, uint32_t index); //Flag the given index as free -static mem_pool_t pool_create(uint16_t stripe) +static mem_pool_t pool_create_default(uint32_t stripe) +{ + return pool_create(stripe, FIXED_START); +} +static mem_pool_t pool_create(uint32_t stripe, uint32_t size) { assert(stripe >= sizeof(uint32_t)); assert(stripe <= MAX_STRIPE_SIZE); - assert(FIXED_START * stripe <= MAX_BUCKET_SIZE); + assert(size * stripe <= MAX_BUCKET_SIZE); return (mem_pool_t) { - .capacity = FIXED_START, + .capacity = size, .size = 0, .stripe = stripe, .free = UINT32_MAX, - .data = (void**) malloc(FIXED_START * stripe), + .data = (void**) malloc(size * stripe), }; } static void pool_clear(mem_pool_t *pool) @@ -196,7 +201,7 @@ static void pool_free(mem_pool_t *pool) free(pool->data); } -static uint32_t pool_add(mem_pool_t *pool) +static const uint32_t pool_add(mem_pool_t *pool) { if(pool->free != UINT32_MAX) { @@ -218,7 +223,7 @@ static uint32_t pool_add(mem_pool_t *pool) return pool->size++; } } -static void* pool_get(mem_pool_t *pool, uint32_t index) +static const void* pool_get(mem_pool_t *pool, uint32_t index) { assert(index > 0); assert(index < pool->capacity);