diff --git a/Makefile.common b/Makefile.common index 62fb50f9a0..a32e4819a0 100644 --- a/Makefile.common +++ b/Makefile.common @@ -255,7 +255,9 @@ ifeq ($(HAVE_GLUI), 1) DEFINES += -DHAVE_GLUI endif ifeq ($(HAVE_LAKKA), 1) - OBJ += frontend/menu/backend/menu_lakka_backend.o frontend/menu/disp/lakka.o + OBJ += frontend/menu/backend/menu_lakka_backend.o \ + frontend/menu/disp/lakka.o \ + frontend/menu/disp/tween.o DEFINES += -DHAVE_LAKKA endif endif diff --git a/frontend/menu/backend/menu_lakka_backend.c b/frontend/menu/backend/menu_lakka_backend.c index 1192ef8706..f9cddac3cc 100644 --- a/frontend/menu/backend/menu_lakka_backend.c +++ b/frontend/menu/backend/menu_lakka_backend.c @@ -35,6 +35,7 @@ #include "../../../settings_data.h" #include "../disp/lakka.h" +#include "../disp/tween.h" #ifdef HAVE_CONFIG_H #include "../../../config.h" diff --git a/frontend/menu/disp/lakka.c b/frontend/menu/disp/lakka.c index a471b26bb5..6ace776ec7 100644 --- a/frontend/menu/disp/lakka.c +++ b/frontend/menu/disp/lakka.c @@ -43,6 +43,7 @@ #include "../../../gfx/fonts/bitmap.h" #include "lakka.h" +#include "tween.h" // Category variables menu_category_t *categories; @@ -118,9 +119,6 @@ struct lakka_texture_item struct lakka_texture_item textures[TEXTURE_LAST]; -static tween_t* tweens = NULL; -static int numtweens = 0; - static void lakka_responsive(void) { gl_t *gl = (gl_t*)driver_video_resolve(NULL); @@ -255,104 +253,6 @@ static char *str_replace (const char *string, const char *substr, const char *re return newstr; } -float inOutQuad(float t, float b, float c, float d) -{ - t = t / d * 2; - if (t < 1) - return c / 2 * pow(t, 2) + b; - return -c / 2 * ((t - 1) * (t - 3) - 1) + b; -} - -void add_tween(float duration, float target_value, float* subject, - easingFunc easing, tweenCallback callback) -{ - tween_t *tween; - tween_t *tweens_tmp; - - numtweens++; - - tweens_tmp = (tween_t*)realloc(tweens, numtweens * sizeof(tween_t)); - if (tweens_tmp != NULL) - { - tweens = tweens_tmp; - } - else // realloc failed - { - if (tweens != NULL) - { - free(tweens); - tweens = NULL; - } - - return; - } - - tween = (tween_t*)&tweens[numtweens-1]; - - if (!tween) - return; - - tween->alive = 1; - tween->duration = duration; - tween->running_since = 0; - tween->initial_value = *subject; - tween->target_value = target_value; - tween->subject = subject; - tween->easing = easing; - tween->callback = callback; -} - -static void update_tween(void *data, float dt) -{ - tween_t *tween = (tween_t*)data; - - if (!tween) - return; - -#if 0 - RARCH_LOG("delta: %f\n", dt); - RARCH_LOG("tween running since: %f\n", tween->running_since); - RARCH_LOG("tween duration: %f\n", tween->duration); -#endif - - if (tween->running_since < tween->duration) - { - tween->running_since += dt; - - if (tween->easing) - *tween->subject = tween->easing( - tween->running_since, - tween->initial_value, - tween->target_value - tween->initial_value, - tween->duration); - - if (tween->running_since >= tween->duration) - { - *tween->subject = tween->target_value; - - if (tween->callback) - tween->callback(); - } - } -} - -static void update_tweens(float dt) -{ - int i, active_tweens; - - active_tweens = 0; - - for(i = 0; i < numtweens; i++) - { - update_tween(&tweens[i], dt); - active_tweens += tweens[i].running_since < - tweens[i].duration ? 1 : 0; - } - - if (numtweens && !active_tweens) - numtweens = 0; -} - static void lakka_draw_text(const char *str, float x, float y, float scale, float alpha) { @@ -745,9 +645,6 @@ static void lakka_context_destroy(void *data) font_driver->free(font); font_driver = NULL; } - - //if (numtweens) - // free(tweens); } void lakka_init_settings(void) diff --git a/frontend/menu/disp/lakka.h b/frontend/menu/disp/lakka.h index 5f8e0b42ed..5edb870b39 100644 --- a/frontend/menu/disp/lakka.h +++ b/frontend/menu/disp/lakka.h @@ -79,24 +79,6 @@ typedef struct menu_item_t *items; } menu_category_t; -typedef float (*easingFunc)(float, float, float, float); -typedef void (*tweenCallback) (void); - -typedef struct -{ - int alive; - float duration; - float running_since; - float initial_value; - float target_value; - float* subject; - easingFunc easing; - tweenCallback callback; -} tween_t; - extern menu_category_t *categories; -void add_tween(float duration, float target_value, float* subject, easingFunc easing, tweenCallback callback); -float inOutQuad(float t, float b, float c, float d); - #endif /* MENU_DISP_LAKKA_H */ diff --git a/frontend/menu/disp/tween.c b/frontend/menu/disp/tween.c new file mode 100644 index 0000000000..ccf999ade8 --- /dev/null +++ b/frontend/menu/disp/tween.c @@ -0,0 +1,332 @@ +#include "tween.h" +#include + +tween_t* tweens = NULL; +int numtweens = 0; + +void add_tween(float duration, float target_value, float* subject, + easingFunc easing, tweenCallback callback) +{ + tween_t *tween; + tween_t *tweens_tmp; + + numtweens++; + + tweens_tmp = (tween_t*)realloc(tweens, numtweens * sizeof(tween_t)); + if (tweens_tmp != NULL) + { + tweens = tweens_tmp; + } + else // realloc failed + { + if (tweens != NULL) + { + free(tweens); + tweens = NULL; + } + + return; + } + + tween = (tween_t*)&tweens[numtweens-1]; + + if (!tween) + return; + + tween->alive = 1; + tween->duration = duration; + tween->running_since = 0; + tween->initial_value = *subject; + tween->target_value = target_value; + tween->subject = subject; + tween->easing = easing; + tween->callback = callback; +} + +void update_tween(void *data, float dt) +{ + tween_t *tween = (tween_t*)data; + + if (!tween) + return; + + if (tween->running_since < tween->duration) + { + tween->running_since += dt; + + if (tween->easing) + *tween->subject = tween->easing( + tween->running_since, + tween->initial_value, + tween->target_value - tween->initial_value, + tween->duration); + + if (tween->running_since >= tween->duration) + { + *tween->subject = tween->target_value; + + if (tween->callback) + tween->callback(); + } + } +} + +void update_tweens(float dt) +{ + int i, active_tweens; + + active_tweens = 0; + + for(i = 0; i < numtweens; i++) + { + update_tween(&tweens[i], dt); + active_tweens += tweens[i].running_since < tweens[i].duration ? 1 : 0; + } + + if (numtweens && !active_tweens) + numtweens = 0; +} + +// linear + +float linear(float t, float b, float c, float d) +{ + return c * t / d + b; +} + +// quad + +float inQuad(float t, float b, float c, float d) +{ + return c * pow(t / d, 2) + b; +} + +float outQuad(float t, float b, float c, float d) +{ + t = t / d; + return -c * t * (t - 2) + b; +} + +float inOutQuad(float t, float b, float c, float d) +{ + t = t / d * 2; + if (t < 1) + return c / 2 * pow(t, 2) + b; + return -c / 2 * ((t - 1) * (t - 3) - 1) + b; +} + +float outInQuad(float t, float b, float c, float d) +{ + if (t < d / 2) + return outQuad(t * 2, b, c / 2, d); + return inQuad((t * 2) - d, b + c / 2, c / 2, d); +} + +// cubic + +float inCubic(float t, float b, float c, float d) +{ + return c * pow(t / d, 3) + b; +} + +float outCubic(float t, float b, float c, float d) +{ + return c * (pow(t / d - 1, 3) + 1) + b; +} + +float inOutCubic(float t, float b, float c, float d) +{ + t = t / d * 2; + if (t < 1) + return c / 2 * t * t * t + b; + t = t - 2; + return c / 2 * (t * t * t + 2) + b; +} + +float outInCubic(float t, float b, float c, float d) +{ + if (t < d / 2) + return outCubic(t * 2, b, c / 2, d); + return inCubic((t * 2) - d, b + c / 2, c / 2, d); +} + +// quart + +float inQuart(float t, float b, float c, float d) +{ + return c * pow(t / d, 4) + b; +} + +float outQuart(float t, float b, float c, float d) +{ + return -c * (pow(t / d - 1, 4) - 1) + b; +} + +float inOutQuart(float t, float b, float c, float d) +{ + t = t / d * 2; + if (t < 1) + return c / 2 * pow(t, 4) + b; + return -c / 2 * (pow(t - 2, 4) - 2) + b; +} + +float outInQuart(float t, float b, float c, float d) +{ + if (t < d / 2) + return outQuart(t * 2, b, c / 2, d); + return inQuart((t * 2) - d, b + c / 2, c / 2, d); +} + +// quint + +float inQuint(float t, float b, float c, float d) +{ + return c * pow(t / d, 5) + b; +} + +float outQuint(float t, float b, float c, float d) +{ + return c * (pow(t / d - 1, 5) + 1) + b; +} + +float inOutQuint(float t, float b, float c, float d) +{ + t = t / d * 2; + if (t < 1) + return c / 2 * pow(t, 5) + b; + return c / 2 * (pow(t - 2, 5) + 2) + b; +} + +float outInQuint(float t, float b, float c, float d) +{ + if (t < d / 2) + return outQuint(t * 2, b, c / 2, d); + return inQuint((t * 2) - d, b + c / 2, c / 2, d); +} + +// sine + +float inSine(float t, float b, float c, float d) +{ + return -c * cos(t / d * (M_PI / 2)) + c + b; +} + +float outSine(float t, float b, float c, float d) +{ + return c * sin(t / d * (M_PI / 2)) + b; +} + +float inOutSine(float t, float b, float c, float d) +{ + return -c / 2 * (cos(M_PI * t / d) - 1) + b; +} + +float outInSine(float t, float b, float c, float d) +{ + if (t < d / 2) + return outSine(t * 2, b, c / 2, d); + return inSine((t * 2) -d, b + c / 2, c / 2, d); +} + +// expo + +float inExpo(float t, float b, float c, float d) +{ + if (t == 0) + return b; + return c * pow(2, 10 * (t / d - 1)) + b - c * 0.001; +} + +float outExpo(float t, float b, float c, float d) +{ + if (t == d) + return b + c; + return c * 1.001 * (-pow(2, -10 * t / d) + 1) + b; +} + +float inOutExpo(float t, float b, float c, float d) +{ + if (t == 0) + return b; + if (t == d) + return b + c; + t = t / d * 2; + if (t < 1) + return c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005; + return c / 2 * 1.0005 * (-pow(2, -10 * (t - 1)) + 2) + b; +} + +float outInExpo(float t, float b, float c, float d) +{ + if (t < d / 2) + return outExpo(t * 2, b, c / 2, d); + return inExpo((t * 2) - d, b + c / 2, c / 2, d); +} + +// circ + +float inCirc(float t, float b, float c, float d) +{ + return(-c * (sqrt(1 - pow(t / d, 2)) - 1) + b); +} + +float outCirc(float t, float b, float c, float d) +{ + return(c * sqrt(1 - pow(t / d - 1, 2)) + b); +} + +float inOutCirc(float t, float b, float c, float d) +{ + t = t / d * 2; + if (t < 1) + return -c / 2 * (sqrt(1 - t * t) - 1) + b; + t = t - 2; + return c / 2 * (sqrt(1 - t * t) + 1) + b; +} + +float outInCirc(float t, float b, float c, float d) +{ + if (t < d / 2) + return outCirc(t * 2, b, c / 2, d); + return inCirc((t * 2) - d, b + c / 2, c / 2, d); +} + +// bounce + +float outBounce(float t, float b, float c, float d) +{ + t = t / d; + if (t < 1 / 2.75) + return c * (7.5625 * t * t) + b; + if (t < 2 / 2.75) + { + t = t - (1.5 / 2.75); + return c * (7.5625 * t * t + 0.75) + b; + } + else if (t < 2.5 / 2.75) + { + t = t - (2.25 / 2.75); + return c * (7.5625 * t * t + 0.9375) + b; + } + t = t - (2.625 / 2.75); + return c * (7.5625 * t * t + 0.984375) + b; +} + +float inBounce(float t, float b, float c, float d) +{ + return c - outBounce(d - t, 0, c, d) + b; +} + +float inOutBounce(float t, float b, float c, float d) +{ + if (t < d / 2) + return inBounce(t * 2, 0, c, d) * 0.5 + b; + return outBounce(t * 2 - d, 0, c, d) * 0.5 + c * .5 + b; +} + +float outInBounce(float t, float b, float c, float d) +{ + if (t < d / 2) + return outBounce(t * 2, b, c / 2, d); + return inBounce((t * 2) - d, b + c / 2, c / 2, d); +} diff --git a/frontend/menu/disp/tween.h b/frontend/menu/disp/tween.h new file mode 100644 index 0000000000..f4bfaeaf24 --- /dev/null +++ b/frontend/menu/disp/tween.h @@ -0,0 +1,78 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2014 - Daniel De Matteis + * Copyright (C) 2014 - Jean-André Santoni + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef _TWEEN_H +#define _TWEEN_H + +#include + +typedef float (*easingFunc)(float, float, float, float); +typedef void (*tweenCallback) (void); + +typedef struct +{ + int alive; + float duration; + float running_since; + float initial_value; + float target_value; + float* subject; + easingFunc easing; + tweenCallback callback; +} tween_t; + +void add_tween(float duration, float target_value, float* subject, easingFunc easing, tweenCallback callback); +void update_tween(void *data, float dt); +void update_tweens(float dt); + +// from https://github.com/kikito/tween.lua/blob/master/tween.lua + +float linear(float t, float b, float c, float d); +float inQuad(float t, float b, float c, float d); +float outQuad(float t, float b, float c, float d); +float inOutQuad(float t, float b, float c, float d); +float outInQuad(float t, float b, float c, float d); +float inCubic(float t, float b, float c, float d); +float outCubic(float t, float b, float c, float d); +float inOutCubic(float t, float b, float c, float d); +float outInCubic(float t, float b, float c, float d); +float inQuart(float t, float b, float c, float d); +float outQuart(float t, float b, float c, float d); +float inOutQuart(float t, float b, float c, float d); +float outInQuart(float t, float b, float c, float d); +float inQuint(float t, float b, float c, float d); +float outQuint(float t, float b, float c, float d); +float inOutQuint(float t, float b, float c, float d); +float outInQuint(float t, float b, float c, float d); +float inSine(float t, float b, float c, float d); +float outSine(float t, float b, float c, float d); +float inOutSine(float t, float b, float c, float d); +float outInSine(float t, float b, float c, float d); +float inExpo(float t, float b, float c, float d); +float outExpo(float t, float b, float c, float d); +float inOutExpo(float t, float b, float c, float d); +float outInExpo(float t, float b, float c, float d); +float inCirc(float t, float b, float c, float d); +float outCirc(float t, float b, float c, float d); +float inOutCirc(float t, float b, float c, float d); +float outInCirc(float t, float b, float c, float d); +float inBounce(float t, float b, float c, float d); +float outBounce(float t, float b, float c, float d); +float inOutBounce(float t, float b, float c, float d); +float outInBounce(float t, float b, float c, float d); + +#endif /* TWEEN_H */