diff --git a/source/engine/anim.c b/source/engine/anim.c new file mode 100644 index 0000000..dfb2fb8 --- /dev/null +++ b/source/engine/anim.c @@ -0,0 +1,54 @@ +#include "anim.h" +#include "stb_ds.h" +#include "log.h" + +struct anim make_anim() { + struct anim a = {0}; + a.interp = 1; + + return a; +} + +struct anim anim_add_keyframe(struct anim a, struct keyframe key) { + arrput(a.frames, key); + + return a; +} + +double interval(struct keyframe a, struct keyframe b, double t) { + return (t - a.time) / (b.time - a.time); +} + +double near_val(struct anim anim, double t) { + for (int i = 0; i < arrlen(anim.frames) - 1; i++) { + + if (t > anim.frames[i+1].time) + continue; + + return (interval(anim.frames[i], anim.frames[i+1], t) >= 0.5f ? anim.frames[i+1].val : anim.frames[i].val); + } +} + +double lerp_val(struct anim anim, double t) { + + for (int i = 0; i < arrlen(anim.frames) - 1; i++) { + if (t > anim.frames[i+1].time) + continue; + + double intv = interval(anim.frames[i], anim.frames[i+1], t); + return ((1 - intv) * anim.frames[i].val) + (intv * anim.frames[i+1].val); + } + + return arrlast(anim.frames).val; +} + +double cubic_val(struct anim anim, double t) { + +} + +double anim_val(struct anim anim, double t) { + if (anim.interp == 0) + return near_val(anim, t); + + return lerp_val(anim, t); +} \ No newline at end of file diff --git a/source/engine/anim.h b/source/engine/anim.h new file mode 100644 index 0000000..358dfba --- /dev/null +++ b/source/engine/anim.h @@ -0,0 +1,20 @@ +#ifndef ANIM_H +#define ANIM_H + +struct keyframe { + double time; + double val; +}; + +struct anim { + struct keyframe *frames; + int loop; + int interp; +}; + +struct anim make_anim(); +struct anim anim_add_keyframe(struct anim a, struct keyframe f); +double anim_val(struct anim anim, double t); + + +#endif \ No newline at end of file diff --git a/source/engine/mrbffi.c b/source/engine/mrbffi.c index 524fa10..bb51e98 100644 --- a/source/engine/mrbffi.c +++ b/source/engine/mrbffi.c @@ -14,6 +14,7 @@ #include "openglrender.h" #include "2dphysics.h" #include "sprite.h" +#include "anim.h" #include "yugine.h" @@ -391,6 +392,73 @@ s7_pointer s7_int_cmd(s7_scheme *sc, s7_pointer args) { } } +s7_pointer s7_yield(s7_scheme *sc, s7_pointer args) { + /* arg 1: condition + arg 2: function to run + */ + + + s7_pointer cond = s7_car(args); + s7_pointer func = s7_cadr(args); + + +} + +void timer_s7_call(s7_pointer sym) { + s7_call(s7, sym, s7_nil(s7)); +} + +s7_pointer s7_timer(s7_scheme *sc, s7_pointer args) { + double delay = s7_real(s7_car(args)); + s7_pointer sym = s7_cadr(args); + + struct timer *timer = timer_make(delay, timer_s7_call, sym); + timer_start(timer); + return args; +} + +s7_pointer s7_timer_cmd(s7_scheme *sc, s7_pointer args) { + int cmd = s7_integer(s7_car(args)); + int id = s7_integer(s7_cadr(args)); + + struct timer *t = NULL; + + switch (cmd) { + case 0: + timer_pause(t); + break; + case 1: + timer_start(t); + break; + case 2: + timer_stop(t); + break; + } + + return args; +} + +s7_pointer s7_anim(s7_scheme *sc, s7_pointer args) { + s7_pointer prop = s7_car(args); + s7_pointer keyframes = s7_cadr(args); + + YughInfo("Animating property %s.", s7_symbol_name(prop)); + + struct anim a = make_anim(); + + for (int i = 0; i < s7_list_length(sc, keyframes); i++) { + struct keyframe k; + s7_pointer kf = s7_list_ref(sc, keyframes, i); + k.time = s7_real(s7_car(kf)); + k.val = s7_real(s7_cadr(kf)); + a = anim_add_keyframe(a, k); + } + + for (double i = 0; i < 3.0; i = i + 0.1) { + YughInfo("Val is now %f at time %f", anim_val(a, i), i); + } +} + #define S7_FUNC(NAME, ARGS) s7_define_function(s7, #NAME, s7_ ##NAME, ARGS, 0, 0, "") void ffi_load() { @@ -424,5 +492,11 @@ void ffi_load() { S7_FUNC(int_cmd, 2); S7_FUNC(log, 4); + + S7_FUNC(yield, 2); + S7_FUNC(timer, 2); + S7_FUNC(timer_cmd, 2); + + S7_FUNC(anim, 2); } diff --git a/source/engine/yugine.c b/source/engine/yugine.c index a12c310..11f9bd2 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -44,6 +44,8 @@ static double lastTick; static float timescale = 1.f; +static double framems; + void seghandle(int sig) { #ifdef __linux__ void *ents[512]; @@ -192,7 +194,6 @@ int main(int argc, char **args) { window_renderall(); } - double wait = fmax(0, renderMS-elapsed); input_poll(wait); window_all_handle_events();