diff --git a/rogueviz/ads/ads-game.cpp b/rogueviz/ads/ads-game.cpp index 2064ae79..85ac07f8 100644 --- a/rogueviz/ads/ads-game.cpp +++ b/rogueviz/ads/ads-game.cpp @@ -102,6 +102,7 @@ void run_ads_game() { rogueviz::rv_hook(hooks_prestats, 100, display_rsrc); rogueviz::rv_hook(hooks_handleKey, 0, handleKey); rogueviz::rv_hook(shmup::hooks_turn, 0, ads_turn); + rogueviz::rv_hook(anims::hooks_anim, 100, replay_animation); cgi.use_count++; hybrid::in_underlying_geometry([] { diff --git a/rogueviz/ads/display.cpp b/rogueviz/ads/display.cpp index f9cd8c5f..0fc62ac7 100644 --- a/rogueviz/ads/display.cpp +++ b/rogueviz/ads/display.cpp @@ -284,7 +284,7 @@ void view_ads_game() { }); } - if(!game_over && !paused) { + if(!game_over && !paused && !in_replay) { poly_outline = 0xFF; if(ship_pt < invincibility_pt) { ld u = (invincibility_pt-ship_pt) / ads_how_much_invincibility; diff --git a/rogueviz/ads/ds-game.cpp b/rogueviz/ads/ds-game.cpp index 13fdc6f2..18a4189d 100644 --- a/rogueviz/ads/ds-game.cpp +++ b/rogueviz/ads/ds-game.cpp @@ -568,7 +568,7 @@ void view_ds_game() { queuestr(shiftless(sphereflip), .1, str, 0xFFFF00, 8); } - if(paused && !game_over && !inHighQual) { + if(paused && !game_over && !in_replay) { vector pts; int ok = 0, bad = 0; for(int i=0; i<=360; i++) { @@ -606,6 +606,30 @@ void ds_restart() { init_rsrc(); } +void replay_animation() { + if(!in_replay) return; + view_pt = (ticks / 1000.) * DS_(simspeed); + ld maxt = history.back().start + 0.001; + view_pt -= maxt * floor(view_pt / maxt); + for(auto& ss: history) + if(ss.start + ss.duration > view_pt) { + current = ss.current; + if(sphere) { + dynamicval g(geometry, gSpace435); + current.T = inverse(ss.at.T * spin(-(ss.ang+90)*degree)); + current.T = lorentz(3, 2, view_pt - ss.start) * current.T; + } + else PIA({ + vctr = new_vctr = ss.vctr; + vctrV = new_vctrV = ss.vctrV; + current.T = cspin(3, 2, view_pt - ss.start) * current.T; + if(auto_rotate) + current.T = cspin(1, 0, view_pt - ss.start) * current.T; + }); + break; + } + } + void run_ds_game() { stop_game(); @@ -621,43 +645,22 @@ void run_ds_game() { rogueviz::rv_hook(shmup::hooks_turn, 0, ds_turn); rogueviz::rv_hook(hooks_prestats, 100, display_rsrc); rogueviz::rv_hook(hooks_handleKey, 0, handleKey); + rogueviz::rv_hook(anims::hooks_anim, 100, replay_animation); } -void ds_record() { - #if CAP_VIDEO - ld full = 1000; - anims::period = full * history.back().start / DS_(simspeed); - anims::noframes = anims::period * 60 / 1000; - dynamicval b(paused, true); - int a = addHook(anims::hooks_anim, 100, [&] { - view_pt = (ticks / full) * DS_(simspeed); - for(auto& ss: history) - if(ss.start + ss.duration > view_pt) { - current = ss.current; - if(sphere) { - dynamicval g(geometry, gSpace435); - current.T = inverse(ss.at.T * spin(-(ss.ang+90)*degree)); - current.T = lorentz(3, 2, view_pt - ss.start) * current.T; - } - else PIA({ - vctr = new_vctr = ss.vctr; - vctrV = new_vctrV = ss.vctrV; - current.T = cspin(3, 2, view_pt - ss.start) * current.T; - if(auto_rotate) - current.T = cspin(1, 0, view_pt - ss.start) * current.T; - }); - break; - } - }); - anims::record_video_std(); - delHook(anims::hooks_anim, a); - #endif +void switch_replay() { + in_replay = !in_replay; + if(in_replay) { + paused = true; + anims::period = 1000. * history.back().start / DS_(simspeed); + anims::noframes = anims::period * 60 / 1000; + } } auto ds_hooks = arg::add3("-ds-game", run_ds_game) + arg::add3("-ds-recenter", [] { current = Id; }) -+ arg::add3("-ds-record", ds_record); ++ arg::add3("-ds-record", switch_replay); } } diff --git a/rogueviz/ads/globals.cpp b/rogueviz/ads/globals.cpp index 02270a33..e4ad1174 100644 --- a/rogueviz/ads/globals.cpp +++ b/rogueviz/ads/globals.cpp @@ -124,4 +124,9 @@ void reset_textures(); void ds_restart(); void run_ads_game_std(); void run_ds_game(); + +/** in the replay mode */ +bool in_replay; +void switch_replay(); + }} diff --git a/rogueviz/ads/menu.cpp b/rogueviz/ads/menu.cpp index ed774f3c..b25f9eee 100644 --- a/rogueviz/ads/menu.cpp +++ b/rogueviz/ads/menu.cpp @@ -107,6 +107,11 @@ void game_menu() { dialog::addItem(XLAT("recenter cheat"), 'C'); dialog::add_action([] { current.T = Id; vctrV = Id; }); + if(paused) { + dialog::addBoolItem(XLAT("view replay"), in_replay, 'V'); + dialog::add_action(switch_replay); + } + dialog::addItem("configure keys", 'k'); dialog::add_action_push(multi::get_key_configurer(1, move_names, "Relative Hell keys"));