diff --git a/source/engine/editor.c b/source/engine/editor.c index 2ab5413..c7b362b 100644 --- a/source/engine/editor.c +++ b/source/engine/editor.c @@ -61,12 +61,10 @@ void asset_srch_cb(GLFWwindow *win, unsigned int codepoint) static const char *editor_filename = "editor.ini"; -struct asset { +static struct { char *key; struct fileasset *value; -}; - -static struct asset *assets = NULL; +} *assets = NULL; static char asset_search_buffer[100] = {'\0'}; @@ -99,31 +97,6 @@ static const char *get_extension(const char *filepath) { return strrchr(filepath, '.'); } -static int check_if_resource(const char *fpath, const struct stat *sb, int typeflag) { - if (typeflag != FTW_F) - return 0; - - const char *ext = get_extension(fpath); - if (ext && is_allowed_extension(ext)) { - struct fileasset *newasset = calloc(1, sizeof(struct fileasset)); - newasset->filename = malloc(sizeof(char) * strlen(fpath) + 1); - strcpy(newasset->filename, fpath); - newasset->extension_len = strlen(ext); - newasset->searched = true; - shput(assets, newasset->filename, newasset); - } - - - return 0; -} - -static void print_files_in_directory(const char *dirpath) { - shfree(assets); - ftw(dirpath, check_if_resource, 10); -} - -static void get_all_files() { print_files_in_directory("."); } - size_t asset_side_size(struct fileasset *asset) { if (asset->type == ASSET_TYPE_IMAGE) return sizeof(struct Texture); @@ -131,38 +104,89 @@ size_t asset_side_size(struct fileasset *asset) { return 0; } -void save_asset() { - if (selected_asset == NULL) { +void save_asset(struct fileasset *asset) { + if (asset == NULL) { YughWarn("No asset to save.", 0); return; } - if (selected_asset->type != ASSET_TYPE_IMAGE) return; + if (asset->type != ASSET_TYPE_IMAGE) return; - FILE *f = res_open(str_replace_ext(selected_asset->filename, EXT_ASSET), "w"); - fwrite(selected_asset->data, asset_side_size(selected_asset), 1, f); + FILE *f = res_open(str_replace_ext(asset->filename, EXT_ASSET), "w"); + fwrite(asset->data, asset_side_size(asset), 1, f); fclose(f); } -void load_asset() { - if (selected_asset == NULL) { +void load_asset(struct fileasset *asset) { + if (asset == NULL) { YughWarn("No asset to load.", 0); return; } - if (selected_asset->type != ASSET_TYPE_IMAGE) return; + if (asset->type != ASSET_TYPE_IMAGE) + return; - if (selected_asset->data == NULL) - selected_asset->data = malloc(asset_side_size(selected_asset)); + if (asset->data == NULL) + asset->data = malloc(asset_side_size(asset)); - FILE *f = res_open(str_replace_ext(selected_asset->filename, EXT_ASSET), "r"); + FILE *f = res_open(str_replace_ext(asset->filename, EXT_ASSET), "r"); if (f == NULL) return; - fread(selected_asset->data, asset_side_size(selected_asset), 1, f); + struct Texture tex; + struct Texture *asset_tex = asset->data; + + fread(&tex, asset_side_size(asset), 1, f); + + asset_tex->opts = tex.opts; + asset_tex->anim = tex.anim; fclose(f); } + + +static int check_if_resource(const char *fpath, const struct stat *sb, int typeflag) { + if (typeflag != FTW_F) + return 0; + + const char *ext = get_extension(fpath); + if (ext && is_allowed_extension(ext)) { + struct fileasset *newasset = calloc(1, sizeof(struct fileasset)); + newasset->searched = true; + + if (!strcmp(ext+1, "png") || !strcmp(ext+1, "jpg")) + newasset->type = ASSET_TYPE_IMAGE; + else if (!strcmp(ext+1, "rb")) + newasset->type = ASSET_TYPE_TEXT; + else if (!strcmp(ext+1, "wav") || !strcmp(ext+1, "mp3")) + newasset->type = ASSET_TYPE_SOUND; + else + newasset->type = ASSET_TYPE_NULL; + + newasset->filename = strdup(fpath); + + shput(assets, newasset->filename, newasset); + } + + + return 0; +} + + +static void print_files_in_directory(const char *dirpath) { + struct fileasset *n = NULL; + for (int i = 0; i < shlen(assets); i++) { + free(assets[i].key); + free(assets[i].value); + } + + shfree(assets); + ftw(dirpath, check_if_resource, 10); +} + +static void get_all_files() { print_files_in_directory("."); } + + static int *compute_prefix_function(const char *str) { int str_len = strlen(str); int *pi = (int *)malloc(sizeof(int) * str_len); @@ -422,6 +446,8 @@ void editor_init(struct mSDLWindow *window) { //glfwSetCharCallback(window->window, text_ed_cb); //glfwSetCharCallback(window->window, asset_srch_cb); + + get_all_files(); } int editor_wantkeyboard() { @@ -495,17 +521,14 @@ void editor_project_gui() { vec_walk(levels, editor_level_btn); NK_MENU_END() - if (editor.export.show) { - nk_begin(ctx, "Export and Bake", editor.export.rect, nuk_std); - + NK_MENU_START(export) nk_layout_row_dynamic(ctx, 25,2); if (nk_button_label(ctx, "Bake")) { } if (nk_button_label(ctx, "Build")) { } - nk_end(ctx); - } + NK_MENU_END() // Shadow map vars NK_MENU_START(lighting) @@ -645,8 +668,8 @@ void editor_project_gui() { if (!assets[i].value->searched) continue; - if (nk_button_label(ctx, assets[i].value->filename + stemlen)) { - editor_selectasset(assets[i].value); + if (nk_button_label(ctx, assets[i].key)) { + editor_selectasset_str(assets[i].key); } } @@ -712,8 +735,18 @@ startobjectgui: object_gui(selectedobject); + + // nuke_label("Components"); + nk_layout_row_dynamic(ctx,25,3); + for (int i = 0; i < ncomponent; i++) { + if (nk_button_label(ctx, components[i].name)) { + gameobject_addcomponent(selectedobject, &components[i]); + } + } + NK_FORCE_END() +/* NK_FORCE(components) nk_layout_row_dynamic(ctx,25,1); for (int i = 0; i < ncomponent; i++) { @@ -723,6 +756,7 @@ startobjectgui: } NK_FORCE_END() + */ } } @@ -754,43 +788,62 @@ void editor_level_btn(char *level) { } } -void editor_selectasset(struct fileasset *asset) { - const char *ext = get_extension(asset->filename); - - if (!strcmp(ext + 1, "png") || !strcmp(ext + 1, "jpg")) { - asset->data = texture_loadfromfile(asset->filename); - tex_gui_anim.tex = asset->data; - asset->type = ASSET_TYPE_IMAGE; - tex_anim_set(&tex_gui_anim); - float tex_scale = (float) ASSET_WIN_SIZE / (float)tex_gui_anim.tex->width; - if (tex_scale >= 10.f) - tex_scale = 10.f; - } else if (!strcmp(ext + 1, "rb")) { - asset->type = ASSET_TYPE_TEXT; - - FILE *fasset = fopen(asset->filename, "rb"); - - fseek(fasset, 0, SEEK_END); - long length = ftell(fasset); - fseek(fasset, 0, SEEK_SET); - asset->data = malloc(ASSET_TEXT_BUF); - fread(asset->data, 1, length, fasset); - fclose(fasset); - } - - if (selected_asset != NULL) - save_asset(); - - - selected_asset = asset; - load_asset(); +struct fileasset *asset_from_path(const char *p) +{ + return shget(assets, p); } -void editor_selectasset_str(char *path) { - struct fileasset *asset = shget(assets, path); +void editor_selectasset_str(const char *path) { + struct fileasset *asset = asset_from_path(path); + + + + FILE *fasset; + + switch (asset->type) { + case ASSET_TYPE_IMAGE: + if (asset->data == NULL) { + asset->data = texture_loadfromfile(path); + load_asset(asset); + } + else + tex_pull(asset->data); + + tex_gui_anim.tex = asset->data; + tex_anim_set(&tex_gui_anim); + anim_setframe(&tex_gui_anim, 0); + float tex_scale = (float) ASSET_WIN_SIZE / (float)tex_gui_anim.tex->width; + if (tex_scale >= 10.f) { + tex_scale = 10.f; + } + + break; + + case ASSET_TYPE_TEXT: + fasset = fopen(asset->filename, "rb"); + + fseek(fasset, 0, SEEK_END); + long length = ftell(fasset); + fseek(fasset, 0, SEEK_SET); + asset->data = malloc(ASSET_TEXT_BUF); + fread(asset->data, 1, length, fasset); + fclose(fasset); + break; + + case ASSET_TYPE_SOUND: + break; + + default: + break; + } + + load_asset(asset); + + if (selected_asset != NULL) + save_asset(selected_asset); + + selected_asset = asset; - if (asset) - editor_selectasset(asset); } void editor_asset_tex_gui(struct Texture *tex) { @@ -803,16 +856,19 @@ void editor_asset_tex_gui(struct Texture *tex) { if (old_sprite != tex->opts.sprite) tex_gpu_load(tex); + nuke_nel(4); nuke_radio_btn("Raw", &tex_view, 0); nuke_radio_btn("View 1", &tex_view, 1); nuke_radio_btn("View 2", &tex_view, 2); nuke_checkbox("Animation", &tex->opts.animation); + if (tex->opts.animation) { int old_frames = tex->anim.frames; int old_ms = tex->anim.ms; + nuke_nel(2); nuke_property_int("Frames", 1, &tex->anim.frames, 20, 1); nuke_property_int("FPS", 1, &tex->anim.ms, 24, 1); @@ -822,6 +878,7 @@ void editor_asset_tex_gui(struct Texture *tex) { if (tex_gui_anim.playing && nuke_btn("Stop")) anim_stop(&tex_gui_anim); } else { + nuke_nel(3); if (nuke_btn("Play")) anim_play(&tex_gui_anim); @@ -832,6 +889,7 @@ void editor_asset_tex_gui(struct Texture *tex) { anim_fwd(&tex_gui_anim); } + nuke_nel(1); nuke_labelf("Frame %d/%d", tex_gui_anim.frame+1, tex_gui_anim.tex->anim.frames); if (old_frames != tex->anim.frames || old_ms != tex->anim.ms) @@ -876,6 +934,11 @@ void editor_asset_text_gui(char *text) { /* TODO: Nicer formatting for text input. Auto indent. */ } +void editor_asset_sound_gui(struct wav *wav) +{ + +} + void editor_asset_gui(struct fileasset *asset) { NK_FORCE(asset) @@ -898,6 +961,10 @@ void editor_asset_gui(struct fileasset *asset) { case ASSET_TYPE_TEXT: editor_asset_text_gui(asset->data); break; + + case ASSET_TYPE_SOUND: + editor_asset_sound_gui(asset->data); + break; } NK_FORCE_END() diff --git a/source/engine/editor.h b/source/engine/editor.h index 1e125c0..d302143 100644 --- a/source/engine/editor.h +++ b/source/engine/editor.h @@ -10,11 +10,10 @@ #define ASSET_TYPE_NULL 0 #define ASSET_TYPE_IMAGE 1 #define ASSET_TYPE_TEXT 2 +#define ASSET_TYPE_SOUND 3 struct fileasset { char *filename; - short extension_len; - short filename_len; bool searched; short type; void *data; // Struct of the underlying asset - Texture struct, etc @@ -88,7 +87,7 @@ void editor_makenewobject(); void editor_project_gui(); void editor_selectasset(struct fileasset *asset); -void editor_selectasset_str(char *path); +void editor_selectasset_str(const char *path); void editor_asset_gui(struct fileasset *asset); void editor_asset_tex_gui(struct Texture *tex); void editor_asset_text_gui(char *text); diff --git a/source/engine/engine.c b/source/engine/engine.c index b8f5341..4248260 100644 --- a/source/engine/engine.c +++ b/source/engine/engine.c @@ -62,7 +62,6 @@ void engine_init() script_init(); registry_init(); init_gameobjects(); - timer_init(); prefabs = vec_make(MAXNAME, 25); stbi_set_flip_vertically_on_load(1); diff --git a/source/engine/gameobject.c b/source/engine/gameobject.c index b30cd0b..26cc58d 100644 --- a/source/engine/gameobject.c +++ b/source/engine/gameobject.c @@ -243,21 +243,25 @@ void object_gui(struct mGameObject *go) int n = -1; + + for (int i = 0; i < go->components->len; i++) { struct component *c = vec_get(go->components, i); if (c->draw_debug) c->draw_debug(c->data); - if (nk_tree_push(ctx, NK_TREE_NODE, c->name, NK_MINIMIZED)) { - if (nk_button_label(ctx, "Del")) { - n = i; - } + + nuke_nel(5); + if (nk_button_label(ctx, "Del")) n = i; + if (nk_tree_push_id(ctx, NK_TREE_NODE, c->name, NK_MINIMIZED, i)) { c->draw_gui(c->data); nk_tree_pop(ctx); } + + } if (n >= 0) diff --git a/source/engine/nuke.c b/source/engine/nuke.c index 25c86aa..fb71b93 100644 --- a/source/engine/nuke.c +++ b/source/engine/nuke.c @@ -69,11 +69,12 @@ void nuke_property_int(const char *lbl, int min, int *val, int max, int step) { } void nk_radio_button_label(struct nk_context *ctx, const char *label, int *val, int cmp) { - if (nk_option_label(ctx, label, (bool)*val == cmp)) *val = cmp; + if (nk_option_label(ctx, label, *val == cmp)) *val = cmp; } void nuke_radio_btn(const char *lbl, int *val, int cmp) { - nk_radio_button_label(ctx, lbl, val, cmp); + //nk_radio_button_label(ctx, lbl, val, cmp); + if (nk_option_label(ctx, lbl, *val==cmp)) *val = cmp; } void nuke_checkbox(const char *lbl, int *val) { diff --git a/source/engine/resources.c b/source/engine/resources.c index 6172a4e..20fdf03 100644 --- a/source/engine/resources.c +++ b/source/engine/resources.c @@ -128,3 +128,10 @@ char *make_path(const char *file) strncat(pathbuf, file, MAXPATH); return pathbuf; } + +char *strdup(const char *s) +{ + char *new = malloc(sizeof(char)*(strlen(s)+1)); + strcpy(new, s); + return new; +} diff --git a/source/engine/resources.h b/source/engine/resources.h index a91fcad..e11f610 100644 --- a/source/engine/resources.h +++ b/source/engine/resources.h @@ -27,4 +27,6 @@ FILE *res_open(char *path, const char *tag); FILE *path_open(const char *tag, const char *fmt, ...); char *make_path(const char *file); +char *strdup(const char *s); + #endif diff --git a/source/engine/texture.c b/source/engine/texture.c index 967ee07..2cdbb19 100644 --- a/source/engine/texture.c +++ b/source/engine/texture.c @@ -21,9 +21,6 @@ struct Texture *texture_pullfromfile(const char *path) struct Texture *tex = calloc(1, sizeof(*tex)); - /* tex->path = malloc(strlen(path) + 1); - strncpy(tex->path, path, strlen(path) + 1); - */ tex->flipy = 0; tex->opts.sprite = 1; tex->opts.gamma = 0; @@ -34,11 +31,8 @@ struct Texture *texture_pullfromfile(const char *path) stbi_set_flip_vertically_on_load(0); unsigned char *data = stbi_load(path, &tex->width, &tex->height, &n, 4); - if (stbi_failure_reason()) { - YughLog(0, 3, "STBI failed to load file %s with message: %s", - path, stbi_failure_reason()); - - } + if (stbi_failure_reason()) + YughLog(0, 3, "STBI failed to load file %s with message: %s", path, stbi_failure_reason()); tex->data = data; @@ -71,6 +65,9 @@ struct Texture *texture_loadfromfile(const char *path) void tex_pull(struct Texture *tex) { + if (tex->data != NULL) + tex_flush(tex); + int n; char *path = tex_get_path(tex); stbi_set_flip_vertically_on_load(0); @@ -139,6 +136,12 @@ void anim_decr(struct TexAnimation *anim) tex_anim_calc_uv(anim); } +void anim_setframe(struct TexAnimation *anim, int frame) +{ + anim->frame = frame; + tex_anim_calc_uv(anim); +} + void tex_anim_set(struct TexAnimation *anim) { if (anim->playing) { diff --git a/source/engine/texture.h b/source/engine/texture.h index 616e632..2d6b66f 100644 --- a/source/engine/texture.h +++ b/source/engine/texture.h @@ -41,7 +41,6 @@ struct TextureOptions { struct Texture { int type; unsigned int id; - //char *path; int width; int height; short flipy; @@ -51,21 +50,20 @@ struct Texture { struct TexAnim anim; }; -struct Texture *texture_pullfromfile(const char *path); -struct Texture *texture_loadfromfile(const char *path); -void tex_gpu_load(struct Texture *tex); -void tex_gpu_reload(struct Texture *tex); -void tex_gpu_free(struct Texture *tex); -void tex_free(struct Texture *tex); -void tex_flush(struct Texture *tex); -void tex_pull(struct Texture *tex); -void tex_bind(struct Texture *tex); -unsigned int powof2(unsigned int num); -int ispow2(int num); +struct Texture *texture_pullfromfile(const char *path); // Create texture from image +struct Texture *texture_loadfromfile(const char *path); // Create texture & load to gpu +void tex_gpu_load(struct Texture *tex); // Send texture data to gpu +void tex_gpu_reload(struct Texture *tex); // gpu_free then gpu_load +void tex_gpu_free(struct Texture *tex); // Remove texture data from gpu +void tex_free(struct Texture *tex); // Delete struct +void tex_flush(struct Texture *tex); // Remove pixel data from struct +void tex_pull(struct Texture *tex); // Pull pixel data from image +void tex_bind(struct Texture *tex); // Bind to gl context -char * tex_get_path(struct Texture *tex); +char * tex_get_path(struct Texture *tex); // Get image path for texture void anim_play(struct TexAnimation *anim); +void anim_setframe(struct TexAnimation *anim, int frame); void anim_stop(struct TexAnimation *anim); void anim_pause(struct TexAnimation *anim); void anim_fwd(struct TexAnimation *anim); diff --git a/source/engine/timer.c b/source/engine/timer.c index d583b22..f9fe5cb 100644 --- a/source/engine/timer.c +++ b/source/engine/timer.c @@ -1,16 +1,12 @@ #include "timer.h" #include #include -#include "vec.h" + +#include ; static double time; -struct vec timers; - -void timer_init() { - time = glfwGetTime(); - timers = vec_init(sizeof(struct timer), 10); -} +struct timer *timers; void check_timer(struct timer *t) { @@ -33,51 +29,60 @@ void check_timer(struct timer *t) void timer_update(double s) { time = s; - vec_walk(&timers, check_timer); + + for (int i = 0; i < arrlen(timers); i++) + check_timer(&timers[i]); + } struct timer *timer_make(double interval, void (*callback)(void *param), void *param) { - struct timer *new = calloc(sizeof(*new),1); + struct timer new; + new.remain_time = interval; + new.interval = interval; + new.cb = callback; + new.data = param; + new.repeat = 1; + new.timerid = arrlen(timers); - new->remain_time = interval; - new->interval = interval; - new->cb = callback; - new->data = param; - new->repeat = 1; + timer_start(&new); + arrput(timers, new); - timer_start(new); - - struct timer *nn = vec_add(&timers, new); - free(new); - - nn->timerid = timers.len-1; - - return nn; + return &arrlast(timers); } void timer_pause(struct timer *t) { + if (!t->on) return; + t->on = 0; t->remain_time = t->fire_time - time; } void timer_stop(struct timer *t) { + if (!t->on) return; + t->on = 0; t->remain_time = t->interval; } void timer_start(struct timer *t) { + if (t->on) return; + t->on = 1; t->fire_time = time + t->remain_time; } void timer_remove(struct timer *t) { - vec_delete(&timers, t->timerid); + int i = t->timerid; + arrdelswap(timers, i); + timers[i].timerid = i; } void timer_settime(struct timer *t, double interval) { - double elapsed = time - (t->fire_time - t->interval); + //double elapsed = time - (t->fire_time - t->interval); t->interval = interval; - t->remain_time = time + t->interval - elapsed; + t->remain_time = t->interval; + + // TODO: timer_settime reacts to elapsed time } diff --git a/source/engine/timer.h b/source/engine/timer.h index dd807b9..67a0acb 100644 --- a/source/engine/timer.h +++ b/source/engine/timer.h @@ -4,15 +4,15 @@ struct timer { int timerid; int on; - double fire_time; - double interval; + double fire_time; // Time the timer will fire + double interval; // Time of timer + double start_time; // Time the timer started this loop int repeat; - double remain_time; + double remain_time; // How much time until the timer executes void (*cb)(void *data); void *data; }; -void timer_init(); struct timer *timer_make(double interval, void (*callback)(void *param), void *param); void timer_remove(struct timer *t); void timer_start(struct timer *t);