1 /* RetroArch - A frontend for libretro. 2 * Copyright (C) 2014-2017 - Jean-André Santoni 3 * Copyright (C) 2011-2017 - Daniel De Matteis 4 * 5 * RetroArch is free software: you can redistribute it and/or modify it under the terms 6 * of the GNU General Public License as published by the Free Software Found- 7 * ation, either version 3 of the License, or (at your option) any later version. 8 * 9 * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 10 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 11 * PURPOSE. See the GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License along with RetroArch. 14 * If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #ifndef _GFX_ANIMATION_H 18 #define _GFX_ANIMATION_H 19 20 #include <stdint.h> 21 #include <stdlib.h> 22 23 #include <boolean.h> 24 #include <retro_common_api.h> 25 26 #include "font_driver.h" 27 28 RETRO_BEGIN_DECLS 29 30 #define TICKER_SPACER_DEFAULT " | " 31 32 #define ANIM_IS_ACTIVE(_p) ((_p)->animation_is_active || (_p)->ticker_is_active) 33 34 #define GFX_ANIMATION_CLEAR_ACTIVE(anim) \ 35 { \ 36 (anim)->animation_is_active = false; \ 37 (anim)->ticker_is_active = false; \ 38 } 39 40 #define GFX_ANIMATION_SET_ACTIVE(anim) \ 41 { \ 42 (anim)->animation_is_active = true; \ 43 (anim)->ticker_is_active = true; \ 44 } 45 46 typedef void (*tween_cb) (void*); 47 48 typedef void (*update_time_cb) (float *ticker_pixel_increment, 49 unsigned width, unsigned height); 50 51 enum gfx_animation_easing_type 52 { 53 /* Linear */ 54 EASING_LINEAR = 0, 55 /* Quad */ 56 EASING_IN_QUAD, 57 EASING_OUT_QUAD, 58 EASING_IN_OUT_QUAD, 59 EASING_OUT_IN_QUAD, 60 /* Cubic */ 61 EASING_IN_CUBIC, 62 EASING_OUT_CUBIC, 63 EASING_IN_OUT_CUBIC, 64 EASING_OUT_IN_CUBIC, 65 /* Quart */ 66 EASING_IN_QUART, 67 EASING_OUT_QUART, 68 EASING_IN_OUT_QUART, 69 EASING_OUT_IN_QUART, 70 /* Quint */ 71 EASING_IN_QUINT, 72 EASING_OUT_QUINT, 73 EASING_IN_OUT_QUINT, 74 EASING_OUT_IN_QUINT, 75 /* Sine */ 76 EASING_IN_SINE, 77 EASING_OUT_SINE, 78 EASING_IN_OUT_SINE, 79 EASING_OUT_IN_SINE, 80 /* Expo */ 81 EASING_IN_EXPO, 82 EASING_OUT_EXPO, 83 EASING_IN_OUT_EXPO, 84 EASING_OUT_IN_EXPO, 85 /* Circ */ 86 EASING_IN_CIRC, 87 EASING_OUT_CIRC, 88 EASING_IN_OUT_CIRC, 89 EASING_OUT_IN_CIRC, 90 /* Bounce */ 91 EASING_IN_BOUNCE, 92 EASING_OUT_BOUNCE, 93 EASING_IN_OUT_BOUNCE, 94 EASING_OUT_IN_BOUNCE, 95 96 EASING_LAST 97 }; 98 99 /* TODO: 100 * Add a reverse loop ticker for languages 101 * that read right to left */ 102 enum gfx_animation_ticker_type 103 { 104 TICKER_TYPE_BOUNCE = 0, 105 TICKER_TYPE_LOOP, 106 TICKER_TYPE_LAST 107 }; 108 109 typedef struct gfx_animation_ctx_entry 110 { 111 float *subject; 112 void *userdata; 113 tween_cb cb; 114 uintptr_t tag; 115 float duration; 116 float target_value; 117 enum gfx_animation_easing_type easing_enum; 118 } gfx_animation_ctx_entry_t; 119 120 typedef struct gfx_animation_ctx_ticker 121 { 122 uint64_t idx; 123 char *s; 124 const char *str; 125 const char *spacer; 126 size_t len; 127 enum gfx_animation_ticker_type type_enum; 128 bool selected; 129 } gfx_animation_ctx_ticker_t; 130 131 typedef struct gfx_animation_ctx_ticker_smooth 132 { 133 uint64_t idx; 134 const char *src_str; 135 const char *spacer; 136 char *dst_str; 137 unsigned *dst_str_width; /* May be set to NULL 138 (RGUI + XMB do not require this info) */ 139 unsigned *x_offset; 140 font_data_t *font; 141 size_t dst_str_len; 142 unsigned glyph_width; /* Fallback if font == NULL */ 143 unsigned field_width; 144 float font_scale; 145 enum gfx_animation_ticker_type type_enum; 146 bool selected; 147 } gfx_animation_ctx_ticker_smooth_t; 148 149 typedef struct gfx_animation_ctx_line_ticker 150 { 151 uint64_t idx; 152 const char *str; 153 char *s; 154 size_t len; 155 size_t line_len; 156 size_t max_lines; 157 enum gfx_animation_ticker_type type_enum; 158 } gfx_animation_ctx_line_ticker_t; 159 160 typedef struct gfx_animation_ctx_line_ticker_smooth 161 { 162 uint64_t idx; 163 font_data_t *font; 164 const char *src_str; 165 float *y_offset; 166 char *dst_str; 167 size_t dst_str_len; 168 char *top_fade_str; 169 size_t top_fade_str_len; 170 float *top_fade_y_offset; 171 float *top_fade_alpha; 172 float *bottom_fade_y_offset; 173 float *bottom_fade_alpha; 174 char *bottom_fade_str; 175 size_t bottom_fade_str_len; 176 unsigned field_width; 177 unsigned field_height; 178 float font_scale; 179 enum gfx_animation_ticker_type type_enum; 180 bool fade_enabled; 181 } gfx_animation_ctx_line_ticker_smooth_t; 182 183 typedef float gfx_timer_t; 184 185 typedef struct gfx_timer_ctx_entry 186 { 187 tween_cb cb; 188 void *userdata; 189 float duration; 190 } gfx_timer_ctx_entry_t; 191 192 typedef struct gfx_delayed_animation 193 { 194 gfx_animation_ctx_entry_t entry; /* pointer alignment */ 195 gfx_timer_t timer; 196 } gfx_delayed_animation_t; 197 198 typedef float (*easing_cb) (float, float, float, float); 199 200 struct tween 201 { 202 easing_cb easing; 203 tween_cb cb; 204 void *userdata; 205 uintptr_t tag; 206 float duration; 207 float running_since; 208 float initial_value; 209 float target_value; 210 float *subject; 211 bool deleted; 212 }; 213 214 struct gfx_animation 215 { 216 uint64_t ticker_idx; /* updated every TICKER_SPEED us */ 217 uint64_t ticker_slow_idx; /* updated every TICKER_SLOW_SPEED us */ 218 uint64_t ticker_pixel_idx; /* updated every frame */ 219 uint64_t ticker_pixel_line_idx; /* updated every frame */ 220 retro_time_t cur_time; 221 retro_time_t old_time; 222 update_time_cb updatetime_cb; /* ptr alignment */ 223 /* By default, this should be a NOOP */ 224 struct tween* list; 225 struct tween* pending; 226 227 float delta_time; 228 229 bool pending_deletes; 230 bool in_update; 231 bool animation_is_active; 232 bool ticker_is_active; 233 }; 234 235 typedef struct gfx_animation gfx_animation_t; 236 237 void gfx_animation_timer_start(gfx_timer_t *timer, 238 gfx_timer_ctx_entry_t *timer_entry); 239 240 bool gfx_animation_update( 241 gfx_animation_t *p_anim, 242 retro_time_t current_time, 243 bool timedate_enable, 244 float ticker_speed, 245 unsigned video_width, 246 unsigned video_height); 247 248 bool gfx_animation_ticker(gfx_animation_ctx_ticker_t *ticker); 249 250 bool gfx_animation_ticker_smooth(gfx_animation_ctx_ticker_smooth_t *ticker); 251 252 bool gfx_animation_line_ticker(gfx_animation_ctx_line_ticker_t *line_ticker); 253 254 bool gfx_animation_line_ticker_smooth(gfx_animation_ctx_line_ticker_smooth_t *line_ticker); 255 256 bool gfx_animation_kill_by_tag(uintptr_t *tag); 257 258 bool gfx_animation_push(gfx_animation_ctx_entry_t *entry); 259 260 void gfx_animation_push_delayed(unsigned delay, gfx_animation_ctx_entry_t *entry); 261 262 void gfx_animation_deinit(gfx_animation_t *p_anim); 263 264 gfx_animation_t *anim_get_ptr(void); 265 266 RETRO_END_DECLS 267 268 #endif 269