X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_replay.c;h=0db1ca4d665822b8251555d62b5289c412e89c97;hb=refs%2Fheads%2Fmenu2;hp=174851e952ba34c792427e97316940410c2cba48;hpb=c137bd8a21c36e63f564801ceb800b47f1ec3c7b;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_replay.c b/player_replay.c index 174851e..0db1ca4 100644 --- a/player_replay.c +++ b/player_replay.c @@ -12,7 +12,9 @@ struct replay_globals player_replay = { - .active_keyframe = -1 + .active_keyframe = -1, + .show_ui = 1, + .editor_mode = 0 }; void replay_clear( replay_buffer *replay ) @@ -322,6 +324,25 @@ void skaterift_get_replay_cam( vg_camera *cam ) l = te-ts; t = (replay->cursor-ts)/l; + /* + * Adjust t, so that its derivative matches at the endpoints. + * Since t needs to go from 0 to 1, it will naturally change at + * different rates between keyframes. So this smooths it out. + * + * Newton method, going through standard direct quadratic eq has + * precision / other problems. Also we only care about 0>t>1. + */ + f32 b = (kf[1].time-ts)/l, + x0 = 1.0-t; + for( u32 i=0; i<4; i ++ ) + { + f32 ix0 = 1.0f-x0, + fx_x0 = 2.0f*b*x0*ix0 + ix0*ix0 - t, + fxd_x0 = 2.0f*(-2.0f*b*x0 + b + x0 - 1.0f); + x0 = x0 - (fx_x0/fxd_x0); + } + t = 1.0-x0; + f32 t0 = t*m_start+(1.0f-m_start), t1 = t*m_end; @@ -421,6 +442,7 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ) replay_frame_data( frame, k_replay_framedata_internal_gamestate ); gs->current_run_version = world_static.current_run_version; + gs->drowned = localplayer.drowned; /* permanent block */ memcpy( &gs->rb, &localplayer.rb, sizeof(rigidbody) ); @@ -500,13 +522,14 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ) localplayer.local_sfx_buffer_count = 0; } -static -void skaterift_restore_frame( replay_frame *frame ){ +static void skaterift_restore_frame( replay_frame *frame ) +{ replay_gamestate *gs = replay_frame_data( frame, k_replay_framedata_internal_gamestate ); void *src = replay_frame_data( frame, k_replay_framedata_gamestate ); u16 src_size = frame->data_table[ k_replay_framedata_gamestate ][1]; world_static.current_run_version = gs->current_run_version; + localplayer.drowned = gs->drowned; if(frame->system == k_player_subsystem_walk ){ memcpy( &player_walk.state, src, src_size ); @@ -600,6 +623,8 @@ void skaterift_replay_pre_update(void) { if( skaterift.activity != k_skaterift_replay ) return; + bool input = player_replay.editor_mode^0x1; + if( player_replay.replay_control == k_replay_control_resume ) { if( player_replay.local.cursor_frame == player_replay.resume_target || @@ -625,10 +650,11 @@ void skaterift_replay_pre_update(void) } } } - else { - if( button_down( k_srbind_replay_play ) ) + else + { + if( input && button_down( k_srbind_replay_play ) ) player_replay.replay_control = k_replay_control_play; - if( button_down( k_srbind_replay_freecam ) ) + if( input && button_down( k_srbind_replay_freecam ) ) { player_replay.use_freecam ^= 0x1; @@ -640,8 +666,11 @@ void skaterift_replay_pre_update(void) skaterift_replay_update_helpers(); } - f32 target_speed = axis_state( k_sraxis_replay_h ) * 5.0; - if( button_press( k_srbind_reset ) ) + f32 target_speed = 0.0f; + if( input ) + target_speed = axis_state( k_sraxis_replay_h ) * 5.0; + + if( input && button_press( k_srbind_reset ) ) target_speed += -2.0; if( fabsf(target_speed) > 0.01f ) @@ -662,7 +691,7 @@ void skaterift_replay_pre_update(void) player_replay.track_velocity = 0.0f; } - if( button_down( k_srbind_mback ) ) + if( input && button_down( k_srbind_mback ) ) { if( player_replay.local.statehead ) skaterift_restore_frame( player_replay.local.statehead ); @@ -672,15 +701,18 @@ void skaterift_replay_pre_update(void) gui_helper_clear(); } - if( player_replay.use_freecam ) - { - freecam_preupdate(); - } - else + if( input ) { - if( button_down( k_srbind_replay_resume ) ) + if( player_replay.use_freecam ) + { + freecam_preupdate(); + } + else { - skaterift_replay_resume(); + if( button_down( k_srbind_replay_resume ) ) + { + skaterift_replay_resume(); + } } } } @@ -694,7 +726,28 @@ static void skaterift_replay_update_helpers(void) vg_strnull( &freecam_text, player_replay.helper_freecam->text, GUI_HELPER_TEXT_LENGTH ); vg_strcat( &freecam_text, - player_replay.use_freecam? "exit freecam": "freecam" ); + player_replay.use_freecam? "Exit freecam": "Freecam" ); +} + +static void replay_show_helpers(void) +{ + gui_helper_clear(); + vg_str text; + + if( gui_new_helper( input_axis_list[k_sraxis_replay_h], &text ) ) + vg_strcat( &text, "Scrub" ); + + if( (player_replay.helper_resume = gui_new_helper( + input_button_list[k_srbind_replay_resume], &text )) ) + vg_strcat( &text, "Resume" ); + + if( gui_new_helper( input_button_list[k_srbind_replay_play], &text )) + vg_strcat( &text, "Playback" ); + + player_replay.helper_freecam = gui_new_helper( + input_button_list[k_srbind_replay_freecam], &text ); + + skaterift_replay_update_helpers(); } void skaterift_replay_post_render(void) @@ -718,24 +771,7 @@ void skaterift_replay_post_render(void) player_replay.local.cursor_frame = player_replay.local.head; } player_replay.replay_control = k_replay_control_scrub; - - gui_helper_clear(); - vg_str text; - - if( gui_new_helper( input_axis_list[k_sraxis_replay_h], &text ) ) - vg_strcat( &text, "scrub" ); - - if( (player_replay.helper_resume = gui_new_helper( - input_button_list[k_srbind_replay_resume], &text )) ) - vg_strcat( &text, "resume" ); - - if( gui_new_helper( input_button_list[k_srbind_replay_play], &text )) - vg_strcat( &text, "playback" ); - - player_replay.helper_freecam = gui_new_helper( - input_button_list[k_srbind_replay_freecam], &text ); - - skaterift_replay_update_helpers(); + replay_show_helpers(); } } } @@ -746,14 +782,11 @@ void skaterift_replay_init(void) player_replay.local.data = vg_linear_alloc( vg_mem.rtmemory, bytes ); player_replay.local.size = bytes; replay_clear( &player_replay.local ); - - vg_console_reg_var( "replay_editor", &player_replay.editor_mode, - k_var_dtype_i32, VG_VAR_PERSISTENT ); } -void skaterift_replay_debug_info(void) +void skaterift_replay_debug_info( ui_context *ctx ) { - player__debugtext( 2, "replay info" ); + player__debugtext( ctx, 2, "replay info" ); replay_buffer *replay = &player_replay.local; u32 head = 0, @@ -761,21 +794,23 @@ void skaterift_replay_debug_info(void) if( replay->tail ) tail = (void *)replay->tail - replay->data; if( replay->head ) head = (void *)replay->head - replay->data; - player__debugtext( 1, "head @%u | tail @%u\n", head, tail ); + player__debugtext( ctx, 1, "head @%u | tail @%u\n", head, tail ); - if( replay->statehead ){ - for( u32 i=0; istatehead ) + { + for( u32 i=0; istatehead->data_table[i][0], replay->statehead->data_table[i][1] ); } u32 state = (void *)replay->statehead - replay->data; - player__debugtext( 1, "gs @%u\n", state ); - player__debugtext( 1, "gamestate_size: %hu\n", + player__debugtext( ctx, 1, "gs @%u\n", state ); + player__debugtext( ctx, 1, "gamestate_size: %hu\n", replay->statehead->data_table[k_replay_framedata_gamestate][1] ); } else - player__debugtext( 1, "gs @NULL\n" ); + player__debugtext( ctx, 1, "gs @NULL\n" ); f64 start = replay->cursor, end = replay->cursor; @@ -785,7 +820,7 @@ void skaterift_replay_debug_info(void) f64 cur = replay->cursor - start, len = end - start; - player__debugtext( 1, "cursor: %.2fs / %.2fs\n", cur, len ); + player__debugtext( ctx, 1, "cursor: %.2fs / %.2fs\n", cur, len ); } static int _keyframe_cmp( const void *p1, const void *p2 ) @@ -800,15 +835,84 @@ static void replay_keyframe_sort(void) sizeof(replay_keyframe), _keyframe_cmp ); } -static void replay_editor_imgui(void) +static void replay_fly_edit_keyframe( ui_context *ctx, replay_keyframe *kf ) { - + if( ui_click_down( ctx, UI_MOUSE_LEFT ) ) + { + /* init freecam */ + v3_copy( kf->cam.pos, player_replay.replay_freecam.pos ); + v3_copy( kf->cam.angles, player_replay.replay_freecam.angles ); + v3_zero( player_replay.freecam_v ); + v3_zero( player_replay.freecam_w ); + player_replay.replay_freecam.fov = kf->cam.fov; + } + + /* move freecam */ + ui_capture_mouse( ctx, 0 ); + freecam_preupdate(); + + if( vg_getkey(SDLK_q) ) + player_replay.freecam_v[1] -= vg.time_frame_delta*6.0f*20.0f; + if( vg_getkey(SDLK_e) ) + player_replay.freecam_v[1] += vg.time_frame_delta*6.0f*20.0f; + + v3_copy( player_replay.replay_freecam.pos, g_render.cam.pos ); + v3_copy( player_replay.replay_freecam.angles, g_render.cam.angles); + g_render.cam.fov = player_replay.replay_freecam.fov; + + v3_copy( g_render.cam.pos, kf->cam.pos ); + v3_copy( g_render.cam.angles, kf->cam.angles ); + kf->cam.fov = g_render.cam.fov; } -void skaterift_replay_imgui(void) +void skaterift_replay_imgui( ui_context *ctx ) { if( skaterift.activity != k_skaterift_replay ) return; + /* extra keys for entering editor */ + static u8 f1_key = 0; + u8 f1_now = vg_getkey(SDLK_F1); + if( f1_now && !f1_key && player_replay.show_ui ) + { + player_replay.editor_mode ^= 0x1; + + if( player_replay.editor_mode ) + gui_helper_clear(); + else + replay_show_helpers(); + } + f1_key = f1_now; + + static u8 f2_key = 0; + u8 f2_now = vg_getkey(SDLK_F2); + if( f2_now && !f2_key ) + { + player_replay.show_ui ^= 0x1; + } + f2_key = f2_now; + + if( player_replay.editor_mode ) + { + static u8 space_key = 0; + u8 space_now = vg_getkey(SDLK_SPACE); + if( space_now & !space_key ) + { + player_replay.replay_control ^= k_replay_control_play; + } + space_key = space_now; + } + + if( !player_replay.show_ui ) return; + + if( player_replay.editor_mode ) + { + u32 colour = ui_opacity( ui_colour(ctx,k_ui_fg), 0.3333f ); + ui_rect cx = { vg.window_x/2, 0, 1, vg.window_y }, + cy = { 0, vg.window_y/2, vg.window_x, 1 }; + ui_fill( ctx, cx, colour ); + ui_fill( ctx, cy, colour ); + } + replay_buffer *replay = &player_replay.local; f64 start = replay->cursor, end = replay->cursor; @@ -823,7 +927,7 @@ void skaterift_replay_imgui(void) ui_px height = 32, cwidth = 2; ui_rect timeline = { 0, 0, vg.window_x, height }; - ui_fill( timeline, ui_colour( k_ui_bg ) ); + ui_fill( ctx, timeline, ui_colour( ctx, k_ui_bg ) ); /* cursor frame block */ if( replay->cursor_frame ) @@ -834,21 +938,21 @@ void skaterift_replay_imgui(void) s = (replay->cursor_frame->time - start) / len; ui_rect box = { s*(f64)vg.window_x, 0, VG_MAX(4,(ui_px)(l*vg.window_x)), timeline[3]+2 }; - ui_fill( box, ui_colour( k_ui_bg+4 ) ); + ui_fill( ctx, box, ui_colour( ctx, k_ui_bg+4 ) ); } } /* cursor */ ui_rect cusor = { cur * (f64)vg.window_x - (cwidth/2), 0, cwidth, (player_replay.editor_mode? 0: 16) + timeline[3] }; - ui_fill( cusor, ui_colour( k_ui_bg+7 ) ); + ui_fill( ctx, cusor, ui_colour( ctx, k_ui_bg+7 ) ); /* latest state marker */ if( replay->statehead ) { f64 t = (replay->statehead->time - start) / len; ui_rect tag = { t*(f64)vg.window_x, 0, 2, timeline[3]+8 }; - ui_fill( tag, ui_colour( k_ui_green+k_ui_brighter ) ); + ui_fill( ctx, tag, ui_colour( ctx, k_ui_green+k_ui_brighter ) ); } /* previous state marker */ @@ -857,191 +961,247 @@ void skaterift_replay_imgui(void) { f64 t = (prev->time - start) / len; ui_rect tag = { t*(f64)vg.window_x, 0, 2, timeline[3]+8 }; - ui_fill( tag, ui_colour( k_ui_yellow+k_ui_brighter ) ); + ui_fill( ctx, tag, ui_colour( ctx, k_ui_yellow+k_ui_brighter ) ); } - cusor[1] -= height; - cusor[2] = 200; - snprintf( buffer, 128, "-%.2fs\n", (end-replay->cursor) ); - ui_text( cusor, buffer, 1, k_ui_align_middle_left, 0 ); + snprintf( buffer, 128, "-%.2fs (F1: Edit replay)", (end-replay->cursor) ); + ui_text( ctx, timeline, buffer, 1, k_ui_align_middle_left, 0 ); + ui_text( ctx, timeline, "0s", 1, k_ui_align_middle_right, 0 ); - snprintf( buffer, 128, "-%.2fs\n", len ); - ui_text( timeline, buffer, 1, k_ui_align_middle_left, 0 ); - ui_text( timeline, "0s", 1, k_ui_align_middle_right, 0 ); + if( !player_replay.editor_mode ) return; + ui_capture_mouse( ctx, 1 ); - if( player_replay.editor_mode ) - { - gui_helper_clear(); - vg_ui.wants_mouse = 1; + ui_rect panel = { 0, timeline[3] + 20, 200, 400 }; + ui_fill( ctx, panel, ui_opacity( ui_colour( ctx, k_ui_bg ), 0.5f ) ); + ui_rect_pad( panel, (ui_px[2]){4,4} ); - ui_rect panel = { 0, timeline[3] + 20, 200, 400 }; - ui_fill( panel, ui_opacity( ui_colour(k_ui_bg), 0.5f ) ); - ui_rect_pad( panel, (ui_px[2]){4,4} ); - - if( ui_button( panel, - (player_replay.replay_control == k_replay_control_play)? - "Pause": "Play" ) == k_ui_button_click ) - { - player_replay.replay_control ^= k_replay_control_play; - } + if( ui_button( ctx, panel, + (player_replay.replay_control == k_replay_control_play)? + "Pause (space)": "Play (space)" ) == k_ui_button_click ) + { + player_replay.replay_control ^= k_replay_control_play; + } + /* script bar */ + ui_rect script = { 0, height + 2, vg.window_x, 16 }; + ui_fill( ctx, script, ui_colour( ctx, k_ui_bg ) ); + f64 mouse_t = start + ((f64)ctx->mouse[0] / (f64)vg.window_x)*len; + /* keyframe draw and select */ + bool absorb_by_keyframe = 0; + ui_px lx = 0; + for( u32 i=0; itime-start)/len; + ui_px x = t*(f64)vg.window_x-8; - /* script bar */ - ui_rect script = { 0, height + 2, vg.window_x, 16 }; - ui_fill( script, ui_colour( k_ui_bg ) ); + /* draw connections between keyframes */ + if( i ) + { + ui_rect con = { lx, script[1]+7, x-lx, 1 }; + ui_fill( ctx, con, ui_colour( ctx, k_ui_blue ) ); + vg_line( kf->cam.pos, player_replay.keyframes[i-1].cam.pos, VG__BLUE ); + } - f64 mouse_t = start + ((f64)vg_ui.mouse[0] / (f64)vg.window_x)*len; + /* keyframe selection */ + ui_rect tag = { x, script[1], 16, 16 }; - /* keyframe draw and select */ - bool absorb_by_keyframe = 0; - ui_px lx = 0; - for( u32 i=0; imouse ) ) { - replay_keyframe *kf = &player_replay.keyframes[i]; - f64 t = (kf->time-start)/len; - - ui_px x = t*(f64)vg.window_x-8; + absorb_by_keyframe = 1; - if( i ) + if( ui_click_down( ctx, UI_MOUSE_LEFT ) ) { - ui_rect con = { lx, script[1]+7, x-lx, 1 }; - ui_fill( con, ui_colour(k_ui_blue) ); - - vg_line( kf->cam.pos, - player_replay.keyframes[i-1].cam.pos, VG__BLUE ); + if( player_replay.active_keyframe != i ) + { + player_replay.active_keyframe = i; + replay_seek( &player_replay.local, kf->time ); + } } + else + { + ui_outline( ctx, tag, 1, ui_colour(ctx, k_ui_fg), 0 ); + } + } - ui_rect tag = { x, script[1], 16, 16 }; + /* edit controls */ + u32 drag_colour = ui_opacity( ui_colour(ctx, k_ui_bg+2), 0.5f ); + if( i == player_replay.active_keyframe ) + { + ui_outline( ctx, tag, 2, ui_colour(ctx, k_ui_fg), 0 ); - if( ui_inside_rect( tag, vg_ui.mouse ) ) - { - absorb_by_keyframe = 1; + ui_rect tray = { tag[0]+8-32, tag[1]+16+2, 64, 16 }; + ui_rect dragbar = { tray[0]+16, tray[1], 32, 16 }; + + bool pos_correct = 0; - if( ui_click_down( UI_MOUSE_LEFT ) ) + if( ui_inside_rect( dragbar, ctx->mouse_click ) ) + { + if( ui_clicking( ctx, UI_MOUSE_LEFT ) ) + { + drag_colour = ui_opacity( ui_colour(ctx,k_ui_fg), 0.5f ); + pos_correct = 1; + replay_seek( &player_replay.local, mouse_t ); + } + else if( ui_click_up( ctx, UI_MOUSE_LEFT ) ) { - if( player_replay.active_keyframe != i ) + pos_correct = 1; + kf->time = mouse_t; + replay_keyframe_sort(); + + for( u32 j=0; jtime ); + if( player_replay.keyframes[j].time == mouse_t ) + { + player_replay.active_keyframe = j; + break; + } } } - else + + if( pos_correct ) { - ui_outline( tag, 1, ui_colour(k_ui_fg), 0 ); + tag[0] = ctx->mouse[0]-8; + tray[0] = tag[0]+8-32; + dragbar[0] = tray[0]+16; } } - if( i == player_replay.active_keyframe ) + if( ui_inside_rect( dragbar, ctx->mouse ) ) { - ui_outline( tag, 2, ui_colour(k_ui_fg), 0 ); - - if( ui_inside_rect( tag, vg_ui.mouse_click ) - && !player_replay.drag_wait ) - { - if( ui_clicking( UI_MOUSE_LEFT ) ) - { - absorb_by_keyframe = 1; - tag[0] = vg_ui.mouse[0]-8; - replay_seek( &player_replay.local, mouse_t ); - } - else if( ui_click_up( UI_MOUSE_LEFT ) ) - { - kf->time = mouse_t; - replay_keyframe_sort(); - } - } + ctx->cursor = k_ui_cursor_hand; } - ui_fill( tag, ui_colour(k_ui_blue) ); - lx = x; - } - - if( player_replay.drag_wait && !ui_clicking(UI_MOUSE_LEFT) ) - player_replay.drag_wait = 0; - - /* adding keyframes */ - if( ui_inside_rect( script, vg_ui.mouse ) ) - { - vg_ui.cursor = k_ui_cursor_hand; + if( !pos_correct ) + { + ui_fill( ctx, tray, + ui_opacity( ui_colour( ctx, k_ui_bg+2 ), 0.5f ) ); + } - ui_rect cursor = { vg_ui.mouse[0], script[1], 4, 16 }; - ui_fill( cursor, ui_colour( k_ui_fg ) ); + ui_fill( ctx, dragbar, drag_colour ); + ui_text( ctx, dragbar, ":::", 1, k_ui_align_middle_center, 0 ); - if( !absorb_by_keyframe && ui_click_down( UI_MOUSE_LEFT ) ) + if( !pos_correct ) { - u32 max = vg_list_size( player_replay.keyframes ); - if( player_replay.keyframe_count == max ) + ui_rect btn = { tray[0], tray[1], 16, 16 }; + if( ui_button_text( ctx, btn, "X", 1 ) == k_ui_button_click ) { - ui_start_modal( "Maximum keyframes reached", UI_MODAL_BAD ); + for( u32 j=i; jtime = mouse_t; - v3_copy( skaterift.cam.pos, kf->cam.pos ); - v3_copy( skaterift.cam.angles, kf->cam.angles ); - kf->cam.fov = skaterift.cam.fov; + ui_rect btn1 = { tray[0]+48, tray[1], 16, 16 }; - replay_keyframe_sort(); + enum ui_button_state mask_using = + k_ui_button_holding_inside | + k_ui_button_holding_outside | + k_ui_button_click; + + if( ui_button_text( ctx, btn1, "E", 1 ) & mask_using ) + { + replay_fly_edit_keyframe( ctx, kf ); + vg_ui_set_mouse_pos( btn1[0]+8, btn1[1]+8 ); } } } + ui_fill( ctx, tag, ui_colour( ctx, k_ui_blue ) ); + lx = x; + } + + /* adding keyframes */ + if( ui_inside_rect( script, ctx->mouse ) ) + { + ctx->cursor = k_ui_cursor_hand; - /* timeline scrub */ - bool start_in_timeline = - ui_clicking(UI_MOUSE_LEFT) && - ui_inside_rect(timeline, vg_ui.mouse_click); - if( (ui_inside_rect( timeline, vg_ui.mouse )) || start_in_timeline ) - { - ui_rect cursor = { vg_ui.mouse[0], timeline[1], 4, timeline[3] }; - ui_fill( cursor, ui_colour( k_ui_fg ) ); - vg_ui.cursor = k_ui_cursor_ibeam; + ui_rect cursor = { ctx->mouse[0], script[1], 4, 16 }; + ui_fill( ctx, cursor, ui_colour( ctx, k_ui_fg ) ); - if( ui_clicking( UI_MOUSE_LEFT ) && start_in_timeline ) + if( !absorb_by_keyframe && ui_click_down( ctx, UI_MOUSE_LEFT ) ) + { + u32 max = vg_list_size( player_replay.keyframes ); + if( player_replay.keyframe_count == max ) { - replay_seek( &player_replay.local, mouse_t ); - player_replay.active_keyframe = -1; + ui_start_modal( ctx, "Maximum keyframes reached", UI_MODAL_BAD ); + } + else + { + replay_keyframe *kf = + &player_replay.keyframes[player_replay.keyframe_count++]; + + kf->time = mouse_t; + v3_copy( g_render.cam.pos, kf->cam.pos ); + v3_copy( g_render.cam.angles, kf->cam.angles ); + kf->cam.fov = g_render.cam.fov; + + replay_keyframe_sort(); } } + } - if( player_replay.active_keyframe != -1 ) + /* timeline scrub */ + bool start_in_timeline = + ui_clicking(ctx, UI_MOUSE_LEFT) && + ui_inside_rect(timeline, ctx->mouse_click); + if( (ui_inside_rect( timeline, ctx->mouse )) || start_in_timeline ) + { + ui_rect cursor = { ctx->mouse[0], timeline[1], 4, timeline[3] }; + ui_fill( ctx, cursor, ui_colour( ctx, k_ui_fg ) ); + ctx->cursor = k_ui_cursor_ibeam; + + if( ui_clicking( ctx, UI_MOUSE_LEFT ) && start_in_timeline ) { - replay_keyframe *kf = - &player_replay.keyframes[ player_replay.active_keyframe ]; + replay_seek( &player_replay.local, mouse_t ); + player_replay.active_keyframe = -1; + } + } - enum ui_button_state mask_using = - k_ui_button_holding_inside | - k_ui_button_holding_outside | - k_ui_button_click; + if( ui_button( ctx, panel, "Clear keyframes" ) == k_ui_button_click ) + { + player_replay.keyframe_count = 0; + } - if( ui_button( panel, "Edit cam" ) & mask_using ) - { - if( ui_click_down( UI_MOUSE_LEFT ) ) - { - /* init freecam */ - v3_copy( kf->cam.pos, player_replay.replay_freecam.pos ); - v3_copy( kf->cam.angles, player_replay.replay_freecam.angles ); - player_replay.replay_freecam.fov = kf->cam.fov; - } + if( (ui_button( ctx, panel, "Hide UI (F2)" ) == k_ui_button_click) ) + { + player_replay.show_ui ^= 0x1; + } - /* move freecam */ - vg_ui.wants_mouse = 0; - freecam_preupdate(); + if( player_replay.active_keyframe != -1 ) + { + replay_keyframe *kf = + &player_replay.keyframes[ player_replay.active_keyframe ]; - v3_copy( player_replay.replay_freecam.pos, skaterift.cam.pos ); - v3_copy( player_replay.replay_freecam.angles, skaterift.cam.angles); - skaterift.cam.fov = player_replay.replay_freecam.fov; + enum ui_button_state mask_using = + k_ui_button_holding_inside | + k_ui_button_holding_outside | + k_ui_button_click; - v3_copy( skaterift.cam.pos, kf->cam.pos ); - v3_copy( skaterift.cam.angles, kf->cam.angles ); - kf->cam.fov = skaterift.cam.fov; - } + if( ui_button( ctx, panel, "Edit cam" ) & mask_using ) + { + replay_fly_edit_keyframe( ctx, kf ); } } + + ui_info( ctx, panel, "World settings" ); + f32 new_time = world_current_instance()->time; + if( ui_slider( ctx, panel, "Time of day", 0, 1, &new_time ) ) + { + world_current_instance()->time = new_time; + } + + ui_info( ctx, panel, "" ); + if( ui_button( ctx, panel, "Exit editor (F1)" ) == k_ui_button_click ) + { + player_replay.editor_mode = 0; + replay_show_helpers(); + } + + /* TODO: Add Q/E scrub here too. + * Add replay trimming + */ }