Improved texture handling
This commit is contained in:
parent
3040dc1f7f
commit
ff4168d279
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
#include "timer.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <stdlib.h>
|
||||
#include "vec.h"
|
||||
|
||||
#include <stb_ds.h>;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue