Add a makefile, change imgui with nuklear and add file dropping and loading

This commit is contained in:
Clément Pons 2025-06-23 17:48:17 +02:00
parent e8516827e1
commit 24c9cd2fc7
11 changed files with 265 additions and 105 deletions

View File

@ -20,9 +20,7 @@
"name": "Emscripten", "name": "Emscripten",
"includePath": [ "includePath": [
"${workspaceFolder}/../sokol", "${workspaceFolder}/../sokol",
"${workspaceFolder}/../sokol_gp", "${workspaceFolder}/../nuklear"
"${workspaceFolder}/../cimgui",
"${workspaceFolder}/../flecs/distr"
], ],
"defines": [ "defines": [
"_DEBUG", "_DEBUG",
@ -30,8 +28,8 @@
"_UNICODE" "_UNICODE"
], ],
"windowsSdkVersion": "10.0.22621.0", "windowsSdkVersion": "10.0.22621.0",
"compilerPath": "D:\\UserDefaults\\Desktop\\Dev\\Git\\emsdk\\upstream\\emscripten\\emcc.bat", "compilerPath": "C:\\Users\\c.pons\\Documents\\Perso\\Git\\emsdk\\upstream\\emscripten\\emcc.bat",
"cStandard": "c17", "cStandard": "c99",
"cppStandard": "c++17", "cppStandard": "c++17",
"intelliSenseMode": "windows-clang-x64", "intelliSenseMode": "windows-clang-x64",
"mergeConfigurations": false, "mergeConfigurations": false,
@ -43,16 +41,12 @@
"limitSymbolsToIncludedHeaders": true "limitSymbolsToIncludedHeaders": true
}, },
"compilerArgs": [ "compilerArgs": [
"-O2", "-sUSE_WEBGPU",
"-sUSE_WEBGL2",
"-sASSERTIONS", "-sASSERTIONS",
"-sWASM_BIGINT", "-sWASM_BIGINT",
"-sFILESYSTEM=0", "-sALLOW_MEMORY_GROWTH",
"-sALLOW_MEMORY_GROWTH=1", "-msimd128",
"-sSTACK_SIZE=1mb", "-sFILESYSTEM=0"
"-sEXPORTED_RUNTIME_METHODS=cwrap",
"-sMODULARIZE=1",
"-sEXPORT_NAME=\"flecs_tests\""
] ]
} }
], ],

View File

@ -28,6 +28,9 @@
"sokol_imgui.h": "c", "sokol_imgui.h": "c",
"typeinfo": "c", "typeinfo": "c",
"api.h": "c", "api.h": "c",
"sprite.h": "c" "sprite.h": "c",
"stdint.h": "c",
"sokol_nuklear.h": "c",
"nuklear.h": "c"
} }
} }

View File

@ -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 \ emcc -O3 src/main.c \
../cimgui/cimgui.cpp \ ../cimgui/cimgui.cpp \
../cimgui/imgui.cpp \ ../cimgui/imgui.cpp \
@ -11,10 +9,9 @@ emcc -O3 src/main.c \
-sWASM_BIGINT \ -sWASM_BIGINT \
-sALLOW_MEMORY_GROWTH \ -sALLOW_MEMORY_GROWTH \
-I../sokol \ -I../sokol \
-I../sokol_gp \
-I../cimgui \ -I../cimgui \
-I../flecs/distr \
-msimd128 \ -msimd128 \
-flto \ -flto \
--llvm-lto 1 \
--shell-file=shell.html \ --shell-file=shell.html \
-sFILESYSTEM=0 -sFILESYSTEM=0

View File

@ -1,4 +1,5 @@
xxd -i src/shaders/sprite.wgsl src/generated/sprite.h xxd -i src/shaders/sprite.wgsl src/generated/sprite.h
emcc src/main.c \ emcc src/main.c \
../cimgui/cimgui.cpp \ ../cimgui/cimgui.cpp \
../cimgui/imgui.cpp \ ../cimgui/imgui.cpp \
@ -11,9 +12,7 @@ emcc src/main.c \
-sWASM_BIGINT \ -sWASM_BIGINT \
-sALLOW_MEMORY_GROWTH \ -sALLOW_MEMORY_GROWTH \
-I../sokol \ -I../sokol \
-I../sokol_gp \
-I../cimgui \ -I../cimgui \
-I../flecs/distr \
-msimd128 \ -msimd128 \
--shell-file=shell.html \ --shell-file=shell.html \
-sFILESYSTEM=0 -sFILESYSTEM=0

82
makefile Normal file
View File

@ -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

View File

@ -4,20 +4,26 @@
#define SOKOL_IMPL #define SOKOL_IMPL
#define SOKOL_WGPU #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_gfx.h"
#include "sokol_app.h" #include "sokol_app.h"
#include "sokol_glue.h" #include "sokol_glue.h"
#include "sokol_log.h" #include "sokol_log.h"
#include "nuklear.h"
#include "util/sokol_memtrack.h" #include "util/sokol_memtrack.h"
#include "util/sokol_imgui.h" #include "util/sokol_nuklear.h"
#include "math.h" #include "math.h"
#include "rand.h" #include "rand.h"
#include "util.h" #include "util.h"
#include "sprite.h" #include "sprite.h"
#include "generated/sprite.h" #include "generated/sprite.wgsl.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>

View File

@ -117,28 +117,29 @@ unsigned char src_shaders_sprite_wgsl[] = {
0x3e, 0x20, 0x75, 0x33, 0x32, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x3e, 0x20, 0x75, 0x33, 0x32, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x6c, 0x65, 0x74, 0x20, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 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, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x66, 0x6c, 0x6f, 0x6f,
0x72, 0x28, 0x75, 0x76, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x77, 0x69, 0x64, 0x72, 0x28, 0x75, 0x76, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x66, 0x33, 0x32,
0x74, 0x68, 0x29, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x28, 0x77, 0x69, 0x64, 0x74, 0x68, 0x29, 0x29, 0x2c, 0x20, 0x30, 0x2c,
0x68, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
0x20, 0x79, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x79, 0x3a, 0x20, 0x75, 0x33, 0x32,
0x61, 0x6d, 0x70, 0x28, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x75, 0x76, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x66, 0x6c, 0x6f,
0x2e, 0x79, 0x20, 0x2a, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29, 0x6f, 0x72, 0x28, 0x75, 0x76, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x66, 0x33,
0x2c, 0x20, 0x30, 0x2c, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29, 0x32, 0x28, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29, 0x29, 0x2c, 0x20,
0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x30, 0x2c, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29, 0x3b, 0x0d,
0x6e, 0x20, 0x79, 0x20, 0x2a, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
0x2b, 0x20, 0x78, 0x3b, 0x0d, 0x0a, 0x7d, 0x2a, 0x2f, 0x0d, 0x0a, 0x0d, 0x79, 0x20, 0x2a, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x2b, 0x20,
0x0a, 0x40, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x78, 0x3b, 0x0d, 0x0a, 0x7d, 0x2a, 0x2f, 0x0d, 0x0a, 0x0d, 0x0a, 0x40,
0x6e, 0x20, 0x66, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x6e, 0x20,
0x70, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x29, 0x20, 0x66, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x70, 0x75,
0x2d, 0x3e, 0x20, 0x46, 0x73, 0x4f, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x74, 0x3a, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x29, 0x20, 0x2d, 0x3e,
0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x46, 0x73, 0x4f, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x3a, 0x20, 0x46, 0x73, 0x4f, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3a, 0x20,
0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x63, 0x6f, 0x6c, 0x46, 0x73, 0x4f, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72,
0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61,
0x73, 0x61, 0x6d, 0x70, 0x2c, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x73, 0x61,
0x75, 0x76, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x70, 0x2c, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x75, 0x76,
0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
0x74, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a 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;

View File

@ -16,10 +16,6 @@ typedef struct renderer_t {
uniform_t uniform; //Uniform data uniform_t uniform; //Uniform data
} renderer_t; } renderer_t;
typedef struct manager_t {
vector_t textures;
} manager_t;
typedef struct dragger_t { typedef struct dragger_t {
bool dragging; bool dragging;
float origin_x, origin_y; float origin_x, origin_y;
@ -34,7 +30,7 @@ typedef struct userdata_t {
manager_t manager; manager_t manager;
} userdata_t; } userdata_t;
void js_log(int severity, const char* format, ...) const char* format(const char* format, ...)
{ {
char buffer[_SLOG_LINE_LENGTH]; 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); int size = vsnprintf(buffer, _SLOG_LINE_LENGTH, format, va);
va_end(va); va_end(va);
slog_js_log(severity, buffer);
return buffer;
} }
void compute_mvp(userdata_t *userdata) void compute_mvp(userdata_t *userdata)
{ {
@ -58,21 +55,22 @@ static void frame(void* _userdata)
{ {
userdata_t* userdata = (userdata_t*) _userdata; userdata_t* userdata = (userdata_t*) _userdata;
simgui_new_frame(&(simgui_frame_desc_t){ struct nk_context *nk_ctx = snk_new_frame();
.width = userdata->width,
.height = userdata->height, if(nk_begin(nk_ctx, "Menu", nk_rect(20, 20, 600, 200), NK_WINDOW_BORDER | NK_WINDOW_BACKGROUND | NK_WINDOW_MOVABLE | NK_WINDOW_CLOSABLE))
.delta_time = sapp_frame_duration(), {
.dpi_scale = 1.0f, 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){ sg_begin_pass(&(sg_pass){
.action = userdata->renderer.clear_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_end_pass();
sg_commit(); sg_commit();
@ -139,21 +137,6 @@ static void init(void* _userdata)
userdata->pan = (vec2f) { 0.0f, 0.0f }; userdata->pan = (vec2f) { 0.0f, 0.0f };
userdata->zoom = 2; 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) { sg_shader sprite_shader = sg_make_shader(&(sg_shader_desc) {
.vertex_func = { .vertex_func = {
.source = (const char*) src_shaders_sprite_wgsl, .source = (const char*) src_shaders_sprite_wgsl,
@ -227,15 +210,12 @@ static void init(void* _userdata)
} }
}; };
userdata->manager = (manager_t) { gs_init(&userdata->manager);
.textures = vector_create(sizeof(texture_t)),
};
compute_mvp(userdata); compute_mvp(userdata);
FREE(tmp_buffer); snk_setup(&(snk_desc_t) {
.enable_set_mouse_cursor = true,
simgui_setup(&(simgui_desc_t) {
.logger.func = slog_func, .logger.func = slog_func,
.allocator = { .allocator = {
.alloc_fn = smemtrack_alloc, .alloc_fn = smemtrack_alloc,
@ -252,7 +232,7 @@ static void cleanup(void* _userdata)
FREE(userdata); FREE(userdata);
simgui_shutdown(); snk_shutdown();
sg_shutdown(); sg_shutdown();
} }
@ -260,11 +240,37 @@ static void event(const sapp_event* event, void* _userdata)
{ {
userdata_t* userdata = (userdata_t*) _userdata; userdata_t* userdata = (userdata_t*) _userdata;
if(simgui_handle_event(event)) if(snk_handle_event(event))
return; return;
switch(event->type) 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: case SAPP_EVENTTYPE_RESIZED:
userdata->width = sapp_width(); userdata->width = sapp_width();
userdata->height = sapp_height(); userdata->height = sapp_height();

View File

@ -42,8 +42,8 @@ struct FsO { //Fragment shader output
}*/ }*/
// Get the texture array index from the UV // Get the texture array index from the UV
/*fn indexFromCoord(uv: vec2f, width: u32, height: u32) -> u32 { /*fn indexFromCoord(uv: vec2f, width: u32, height: u32) -> u32 {
let x: u32 = clamp(floor(uv.x * width), 0, width); let x: u32 = clamp(floor(uv.x * f32(width)), 0, width);
let y: u32 = clamp(floor(uv.y * height), 0, height); let y: u32 = clamp(floor(uv.y * f32(height)), 0, height);
return y * width + x; return y * width + x;
}*/ }*/

View File

@ -3,6 +3,11 @@
#include "api.h" #include "api.h"
#define KB (1024u)
#define MB (1024u * KB)
#define GB (1024u * MB)
#define MAX_FILE_SIZE (10u * MB)
typedef struct texture_t { typedef struct texture_t {
uint32_t id; //Texture ID uint32_t id; //Texture ID
sg_bindings binding; //Texture bindings (texture, sampler and buffer) sg_bindings binding; //Texture bindings (texture, sampler and buffer)
@ -14,4 +19,66 @@ typedef struct sprite_t {
mat4x4f transform; mat4x4f transform;
} sprite_t; } 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 #endif

View File

@ -84,10 +84,10 @@ typedef struct vector_t {
} vector_t; } vector_t;
#define MAX_BUCKET_SIZE (0xffffffffu) #define MAX_BUCKET_SIZE (0xffffffffu)
#define MAX_STRIPE_SIZE (0xffffu) #define MAX_STRIPE_SIZE (0xffffffu)
#define FIXED_START (0xfffu) #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_clear(vector_t *vector);
static void vector_free(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 uint32_t vector_push(vector_t *vector, void *data);
static sg_range vector_range(vector_t *vector); 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 >= sizeof(uint32_t));
assert(stripe <= MAX_STRIPE_SIZE); assert(stripe <= MAX_STRIPE_SIZE);
@ -158,32 +158,37 @@ static sg_range vector_range(vector_t *vector)
typedef struct mem_pool_t { typedef struct mem_pool_t {
void **data; //Memory pool 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 size; //Current amount of items
uint32_t capacity; //Max capacity uint32_t capacity; //Max capacity
uint32_t free; //Linked list of available indices uint32_t free; //Linked list of available indices
} mem_pool_t; } 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_clear(mem_pool_t *pool);
static void pool_free(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 const 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 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 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 >= sizeof(uint32_t));
assert(stripe <= MAX_STRIPE_SIZE); assert(stripe <= MAX_STRIPE_SIZE);
assert(FIXED_START * stripe <= MAX_BUCKET_SIZE); assert(size * stripe <= MAX_BUCKET_SIZE);
return (mem_pool_t) { return (mem_pool_t) {
.capacity = FIXED_START, .capacity = size,
.size = 0, .size = 0,
.stripe = stripe, .stripe = stripe,
.free = UINT32_MAX, .free = UINT32_MAX,
.data = (void**) malloc(FIXED_START * stripe), .data = (void**) malloc(size * stripe),
}; };
} }
static void pool_clear(mem_pool_t *pool) static void pool_clear(mem_pool_t *pool)
@ -196,7 +201,7 @@ static void pool_free(mem_pool_t *pool)
free(pool->data); 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) if(pool->free != UINT32_MAX)
{ {
@ -218,7 +223,7 @@ static uint32_t pool_add(mem_pool_t *pool)
return pool->size++; 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 > 0);
assert(index < pool->capacity); assert(index < pool->capacity);