transition: use the callchain system for callbacks

This commit is contained in:
Andrei Alexeyev 2023-04-07 05:47:47 +02:00
parent 886ba290a9
commit 27a1a6fc7a
No known key found for this signature in database
GPG key ID: 72D26128040B9690
13 changed files with 50 additions and 61 deletions

View file

@ -515,9 +515,9 @@ static void credits_draw(void) {
draw_transition();
}
static void credits_finish(void *arg) {
static void credits_finish(CallChainResult ccr) {
credits.end = 0;
set_transition(TransLoader, 0, FADE_TIME*10);
set_transition(TransLoader, 0, FADE_TIME*10, NO_CALLCHAIN);
}
static void credits_process(void) {
@ -536,7 +536,7 @@ static void credits_process(void) {
}
if(global.frames == credits.end) {
set_transition_callback(TransFadeWhite, CREDITS_FADEOUT, CREDITS_FADEOUT, credits_finish, NULL);
set_transition(TransFadeWhite, CREDITS_FADEOUT, CREDITS_FADEOUT, CALLCHAIN(credits_finish, NULL));
}
}

View file

@ -118,7 +118,7 @@ static bool skip_text_animation(CutsceneState *st) {
static void begin_fadeout(CutsceneState *st) {
const int fade_frames = CUTSCENE_FADE_OUT;
audio_bgm_stop((FPS * fade_frames) / 4000.0);
set_transition(TransFadeBlack, fade_frames, fade_frames);
set_transition(TransFadeBlack, fade_frames, fade_frames, NO_CALLCHAIN);
st->fadeout_timer = fade_frames;
st->bg_state.next_scene = NULL;
st->bg_state.fade_out = true;

View file

@ -383,7 +383,7 @@ static void main_post_vfsinit(CallChainResult ccr) {
progress_load();
video_post_init();
set_transition(TransLoader, 0, FADE_TIME*2);
set_transition(TransLoader, 0, FADE_TIME*2, NO_CALLCHAIN);
log_info("Initialization complete");

View file

@ -23,7 +23,7 @@ static void give_up(MenuData *m, void *arg) {
global.gameover = (MAX_CONTINUES - global.plr.stats.total.continues_used) ? GAMEOVER_ABORT : GAMEOVER_DEFEAT;
}
MenuData* create_gameover_menu(void) {
MenuData *create_gameover_menu(void) {
MenuData *m = alloc_menu();
m->draw = draw_ingame_menu;
@ -50,6 +50,6 @@ MenuData* create_gameover_menu(void) {
m->cursor = 1;
}
set_transition(TransEmpty, 0, m->transition_out_time);
set_transition(TransEmpty, 0, m->transition_out_time, NO_CALLCHAIN);
return m;
}

View file

@ -11,4 +11,4 @@
#include "menu.h"
MenuData* create_gameover_menu(void);
MenuData *create_gameover_menu(void);

View file

@ -113,7 +113,7 @@ static void ingame_menu_input(MenuData *m) {
}, EFLAG_MENU);
}
MenuData* create_ingame_menu(void) {
MenuData *create_ingame_menu(void) {
MenuData *m = alloc_menu();
m->draw = draw_ingame_menu;
@ -127,7 +127,7 @@ MenuData* create_ingame_menu(void) {
add_menu_entry(m, "Return to Game", menu_action_close, NULL);
add_menu_entry(m, "Restart the Game", restart_game, NULL)->transition = TransFadeBlack;
add_menu_entry(m, "Stop the Game", return_to_title, NULL)->transition = TransFadeBlack;
set_transition(TransEmpty, 0, m->transition_out_time);
set_transition(TransEmpty, 0, m->transition_out_time, NO_CALLCHAIN);
return m;
}
@ -137,7 +137,7 @@ static void skip_stage(MenuData *m, void *arg) {
menu_action_close(m, arg);
}
MenuData* create_ingame_menu_replay(void) {
MenuData *create_ingame_menu_replay(void) {
MenuData *m = alloc_menu();
m->draw = draw_ingame_menu;
@ -152,7 +152,7 @@ MenuData* create_ingame_menu_replay(void) {
add_menu_entry(m, "Skip the Stage", skip_stage, NULL)->transition = TransFadeBlack;
add_menu_entry(m, "Stop Watching", return_to_title, NULL)->transition = TransFadeBlack;
m->cursor = 1;
set_transition(TransEmpty, 0, m->transition_out_time);
set_transition(TransEmpty, 0, m->transition_out_time, NO_CALLCHAIN);
return m;
}

View file

@ -14,8 +14,8 @@
void draw_ingame_menu_bg(MenuData *menu, float f);
void draw_ingame_menu(MenuData *menu);
MenuData* create_ingame_menu(void);
MenuData* create_ingame_menu_replay(void);
MenuData *create_ingame_menu(void);
MenuData *create_ingame_menu_replay(void);
void update_ingame_menu(MenuData *menu);

View file

@ -59,8 +59,8 @@ void kill_menu(MenuData *menu) {
}
}
static void close_menu_finish(void *vmenu) {
MenuData *menu = vmenu;
static void close_menu_finish(CallChainResult ccr) {
MenuData *menu = ccr.ctx;
// This may happen with MF_AlwaysProcessInput menus, so make absolutely sure we
// never run the call chain with menu->state == MS_Dead more than once.
@ -95,15 +95,17 @@ void close_menu(MenuData *menu) {
trans = dynarray_get(&menu->entries, menu->selected).transition;
}
CallChain cc = CALLCHAIN(close_menu_finish, menu);
if(trans) {
set_transition_callback(
set_transition(
trans,
menu->transition_in_time,
menu->transition_out_time,
(TransitionCallback)close_menu_finish, menu
cc
);
} else {
close_menu_finish(menu);
run_call_chain(&cc, NULL);
}
}

View file

@ -32,7 +32,7 @@ typedef struct ReplayviewItemContext {
char *replayname;
} ReplayviewItemContext;
static MenuData* replayview_sub_messagebox(MenuData *parent, const char *message);
static MenuData *replayview_sub_messagebox(MenuData *parent, const char *message);
static void replayview_set_submenu(MenuData *parent, MenuData *submenu) {
ReplayviewContext *ctx = parent->context;
@ -59,10 +59,11 @@ static void on_replay_finished(CallChainResult ccr) {
audio_bgm_play(res_bgm("menu"), true, 0, 0);
}
static void really_start_replay(void *varg) {
startrpy_arg_t arg = *(startrpy_arg_t*)varg;
mem_free(varg);
replay_play(arg.rpy, arg.stgnum, CALLCHAIN(on_replay_finished, NULL));
static void really_start_replay(CallChainResult ccr) {
startrpy_arg_t *argp = ccr.ctx;
auto arg = *argp;
mem_free(argp);
replay_play(arg.rpy, arg.stgnum, false, CALLCHAIN(on_replay_finished, NULL));
}
static void start_replay(MenuData *menu, void *arg) {
@ -99,18 +100,18 @@ static void start_replay(MenuData *menu, void *arg) {
return;
}
set_transition_callback(TransFadeBlack, FADE_TIME, FADE_TIME, really_start_replay,
memdup(&(startrpy_arg_t) {
set_transition(TransFadeBlack, FADE_TIME, FADE_TIME,
CALLCHAIN(really_start_replay, ALLOC(startrpy_arg_t, {
.rpy = ictx->replay,
.stgnum = stagenum
}, sizeof(startrpy_arg_t))
}))
);
}
static void replayview_draw_stagemenu(MenuData*);
static void replayview_draw_messagebox(MenuData*);
static MenuData* replayview_sub_stageselect(MenuData *parent, ReplayviewItemContext *ictx) {
static MenuData *replayview_sub_stageselect(MenuData *parent, ReplayviewItemContext *ictx) {
MenuData *m = alloc_menu();
Replay *rpy = ictx->replay;
@ -135,7 +136,7 @@ static MenuData* replayview_sub_stageselect(MenuData *parent, ReplayviewItemCont
return m;
}
static MenuData* replayview_sub_messagebox(MenuData *parent, const char *message) {
static MenuData *replayview_sub_messagebox(MenuData *parent, const char *message) {
MenuData *m = alloc_menu();
m->draw = replayview_draw_messagebox;
m->flags = MF_Transient | MF_Abortable;
@ -441,7 +442,7 @@ static void replayview_free(MenuData *m) {
});
}
MenuData* create_replayview_menu(void) {
MenuData *create_replayview_menu(void) {
MenuData *m = alloc_menu();
m->logic = replayview_logic;

View file

@ -11,4 +11,4 @@
#include "menu.h"
MenuData* create_replayview_menu(void);
MenuData *create_replayview_menu(void);

View file

@ -728,8 +728,8 @@ static void stage_free(void) {
stagetext_free();
}
static void stage_finalize(void *arg) {
global.gameover = (intptr_t)arg;
static void stage_finalize(CallChainResult ccr) {
global.gameover = (intptr_t)ccr.ctx;
}
void stage_finish(int gameover) {
@ -744,7 +744,8 @@ void stage_finish(int gameover) {
global.gameover = GAMEOVER_SCORESCREEN;
} else {
global.gameover = GAMEOVER_TRANSITIONING;
set_transition_callback(TransFadeBlack, FADE_TIME, FADE_TIME*2, stage_finalize, (void*)(intptr_t)gameover);
CallChain cc = CALLCHAIN(stage_finalize, (void*)(intptr_t)gameover);
set_transition(TransFadeBlack, FADE_TIME, FADE_TIME*2, cc);
audio_bgm_stop(BGM_FADE_LONG);
}

View file

@ -41,8 +41,7 @@ static bool popq(void) {
transition.dur1 = transition.queued.dur1;
transition.dur2 = transition.queued.dur2;
transition.callback = transition.queued.callback;
transition.arg = transition.queued.arg;
transition.cc = transition.queued.cc;
transition.queued.rule = NULL;
if(transition.dur1 <= 0) {
@ -58,29 +57,21 @@ static bool popq(void) {
return false;
}
static void setq(TransitionRule rule, int dur1, int dur2, TransitionCallback cb, void *arg) {
static void setq(TransitionRule rule, int dur1, int dur2, CallChain cc) {
transition.queued.rule = rule;
transition.queued.dur1 = dur1;
transition.queued.dur2 = dur2;
transition.queued.callback = cb;
transition.queued.arg = arg;
transition.queued.cc = cc;
}
static void call_callback(void) {
if(transition.callback) {
transition.callback(transition.arg);
transition.callback = NULL;
}
}
void set_transition_callback(TransitionRule rule, int dur1, int dur2, TransitionCallback cb, void *arg) {
void set_transition(TransitionRule rule, int dur1, int dur2, CallChain cc) {
static bool initialized = false;
if(!rule) {
return;
}
setq(rule, dur1, dur2, cb, arg);
setq(rule, dur1, dur2, cc);
if(!initialized) {
popq();
@ -93,10 +84,6 @@ void set_transition_callback(TransitionRule rule, int dur1, int dur2, Transition
}
}
void set_transition(TransitionRule rule, int dur1, int dur2) {
set_transition_callback(rule, dur1, dur2, NULL, NULL);
}
static bool check_transition(void) {
if(transition.state == TRANS_IDLE) {
return false;
@ -131,9 +118,9 @@ void update_transition(void) {
transition.fade = approach(transition.fade, 1.0, 1.0/transition.dur1);
if(transition.fade == 1.0) {
transition.state = TRANS_FADE_OUT;
call_callback();
run_call_chain(&transition.cc, NULL);
if(popq()) {
call_callback();
run_call_chain(&transition.cc, NULL);
}
}
} else if(transition.state == TRANS_FADE_OUT) {

View file

@ -9,16 +9,16 @@
#pragma once
#include "taisei.h"
#include "util/callchain.h"
typedef struct Transition Transition;
typedef void (*TransitionRule)(double fade);
typedef void (*TransitionCallback)(void *a);
struct Transition {
double fade;
int dur1; // first half
int dur2; // second half
TransitionCallback callback;
void *arg;
CallChain cc;
enum {
TRANS_IDLE,
@ -33,8 +33,7 @@ struct Transition {
int dur1;
int dur2;
TransitionRule rule;
TransitionCallback callback;
void *arg;
CallChain cc;
} queued;
};
@ -45,7 +44,6 @@ void TransFadeWhite(double fade);
void TransLoader(double fade);
void TransEmpty(double fade);
void set_transition(TransitionRule rule, int dur1, int dur2);
void set_transition_callback(TransitionRule rule, int dur1, int dur2, TransitionCallback cb, void *arg);
void set_transition(TransitionRule rule, int dur1, int dur2, CallChain cc);
void draw_transition(void);
void update_transition(void);