bool menu_animation_update(menu_animation_t *anim, float dt) { unsigned i; unsigned active_tweens = 0; for(i = 0; i < anim->size; i++) menu_animation_iterate(&anim->list[i], dt, &active_tweens); if (!active_tweens) { anim->size = 0; return false; } anim->is_active = true; return true; }
bool menu_animation_ctl(enum menu_animation_ctl_state state, void *data) { static menu_animation_t anim; static retro_time_t cur_time = 0; static retro_time_t old_time = 0; static float delta_time = 0.0f; static bool animation_is_active = false; switch (state) { case MENU_ANIMATION_CTL_DEINIT: { size_t i; for (i = 0; i < anim.size; i++) { if (anim.list[i].subject) anim.list[i].subject = NULL; } free(anim.list); memset(&anim, 0, sizeof(menu_animation_t)); } cur_time = 0; old_time = 0; delta_time = 0.0f; break; case MENU_ANIMATION_CTL_IS_ACTIVE: return animation_is_active; case MENU_ANIMATION_CTL_CLEAR_ACTIVE: animation_is_active = false; break; case MENU_ANIMATION_CTL_SET_ACTIVE: animation_is_active = true; break; case MENU_ANIMATION_CTL_DELTA_TIME: { float *ptr = (float*)data; if (!ptr) return false; *ptr = delta_time; } break; case MENU_ANIMATION_CTL_UPDATE_TIME: { static retro_time_t last_clock_update = 0; settings_t *settings = config_get_ptr(); cur_time = cpu_features_get_time_usec(); delta_time = cur_time - old_time; if (delta_time >= IDEAL_DELTA_TIME* 4) delta_time = IDEAL_DELTA_TIME * 4; if (delta_time <= IDEAL_DELTA_TIME / 4) delta_time = IDEAL_DELTA_TIME / 4; old_time = cur_time; if (((cur_time - last_clock_update) > 1000000) && settings->menu.timedate_enable) { animation_is_active = true; last_clock_update = cur_time; } } break; case MENU_ANIMATION_CTL_UPDATE: { unsigned i; unsigned active_tweens = 0; float *dt = (float*)data; if (!dt) return false; for(i = 0; i < anim.size; i++) menu_animation_iterate(&anim, i, *dt, &active_tweens); if (!active_tweens) { anim.size = 0; anim.first_dead = 0; return false; } animation_is_active = true; } break; case MENU_ANIMATION_CTL_KILL_BY_TAG: { unsigned i; menu_animation_ctx_tag_t *tag = (menu_animation_ctx_tag_t*)data; if (!tag || tag->id == -1) return false; for (i = 0; i < anim.size; ++i) { if (anim.list[i].tag != tag->id) continue; anim.list[i].alive = false; anim.list[i].subject = NULL; if (i < anim.first_dead) anim.first_dead = i; } } break; case MENU_ANIMATION_CTL_KILL_BY_SUBJECT: { unsigned i, j, killed = 0; menu_animation_ctx_subject_t *subject = (menu_animation_ctx_subject_t*)data; float **sub = (float**)subject->data; for (i = 0; i < anim.size; ++i) { if (!anim.list[i].alive) continue; for (j = 0; j < subject->count; ++j) { if (anim.list[i].subject != sub[j]) continue; anim.list[i].alive = false; anim.list[i].subject = NULL; if (i < anim.first_dead) anim.first_dead = i; killed++; break; } } } break; case MENU_ANIMATION_CTL_TICKER: { menu_animation_ctx_ticker_t *ticker = (menu_animation_ctx_ticker_t*) data; size_t str_len = utf8len(ticker->str); size_t offset = 0; if ((size_t)str_len <= ticker->len) { utf8cpy(ticker->s, PATH_MAX_LENGTH, ticker->str, ticker->len); return true; } if (!ticker->selected) { utf8cpy(ticker->s, PATH_MAX_LENGTH, ticker->str, ticker->len - 3); strlcat(ticker->s, "...", PATH_MAX_LENGTH); return true; } menu_animation_ticker_generic( ticker->idx, ticker->len, &offset, &str_len); utf8cpy( ticker->s, PATH_MAX_LENGTH, utf8skip(ticker->str, offset), str_len); animation_is_active = true; } break; case MENU_ANIMATION_CTL_IDEAL_DELTA_TIME_GET: { menu_animation_ctx_delta_t *delta = (menu_animation_ctx_delta_t*)data; if (!delta) return false; delta->ideal = delta->current / IDEAL_DELTA_TIME; } break; case MENU_ANIMATION_CTL_PUSH: return menu_animation_push(&anim, data); case MENU_ANIMATION_CTL_NONE: default: break; } return true; }
bool menu_animation_ctl(enum menu_animation_ctl_state state, void *data) { menu_animation_t *anim = menu_animation_get_ptr(); if (!anim) return false; switch (state) { case MENU_ANIMATION_CTL_DEINIT: menu_animation_free(); break; case MENU_ANIMATION_CTL_IS_ACTIVE: return anim->is_active; case MENU_ANIMATION_CTL_CLEAR_ACTIVE: anim->is_active = false; return true; case MENU_ANIMATION_CTL_SET_ACTIVE: anim->is_active = true; return true; case MENU_ANIMATION_CTL_DELTA_TIME: { float *ptr = (float*)data; if (!ptr) return false; *ptr = anim->delta_time; } return true; case MENU_ANIMATION_CTL_UPDATE_TIME: { static retro_time_t last_clock_update = 0; settings_t *settings = config_get_ptr(); anim->cur_time = retro_get_time_usec(); anim->delta_time = anim->cur_time - anim->old_time; if (anim->delta_time >= IDEAL_DT * 4) anim->delta_time = IDEAL_DT * 4; if (anim->delta_time <= IDEAL_DT / 4) anim->delta_time = IDEAL_DT / 4; anim->old_time = anim->cur_time; if (((anim->cur_time - last_clock_update) > 1000000) && settings->menu.timedate_enable) { anim->is_active = true; last_clock_update = anim->cur_time; } } return true; case MENU_ANIMATION_CTL_UPDATE: { unsigned i; unsigned active_tweens = 0; float *dt = (float*)data; if (!dt) return false; for(i = 0; i < anim->size; i++) menu_animation_iterate(anim, i, *dt, &active_tweens); if (!active_tweens) { anim->size = 0; anim->first_dead = 0; return false; } anim->is_active = true; } return true; } return false; }