struct replay_globals player_replay =
{
- .active_keyframe = -1
+ .active_keyframe = -1,
+ .show_ui = 1,
+ .editor_mode = 0
};
void replay_clear( replay_buffer *replay )
{
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 ||
}
}
}
- 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;
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 )
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 );
gui_helper_clear();
}
- if( player_replay.use_freecam )
+ if( input )
{
- freecam_preupdate();
- }
- else
- {
- if( button_down( k_srbind_replay_resume ) )
+ if( player_replay.use_freecam )
{
- skaterift_replay_resume();
+ freecam_preupdate();
+ }
+ else
+ {
+ if( button_down( k_srbind_replay_resume ) )
+ {
+ skaterift_replay_resume();
+ }
}
}
}
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)
{
#ifndef SR_ALLOW_REWIND_HUB
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();
}
}
}
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)
sizeof(replay_keyframe), _keyframe_cmp );
}
-static void replay_editor_imgui(void)
+static void replay_fly_edit_keyframe( replay_keyframe *kf )
{
-
+ 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 );
+ v3_zero( player_replay.freecam_v );
+ v3_zero( player_replay.freecam_w );
+ player_replay.replay_freecam.fov = kf->cam.fov;
+ }
+
+ /* move freecam */
+ vg_ui.wants_mouse = 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, skaterift.cam.pos );
+ v3_copy( player_replay.replay_freecam.angles, skaterift.cam.angles);
+ skaterift.cam.fov = player_replay.replay_freecam.fov;
+
+ v3_copy( skaterift.cam.pos, kf->cam.pos );
+ v3_copy( skaterift.cam.angles, kf->cam.angles );
+ kf->cam.fov = skaterift.cam.fov;
}
void skaterift_replay_imgui(void)
{
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(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( cx, colour );
+ ui_fill( cy, colour );
+ }
+
replay_buffer *replay = &player_replay.local;
f64 start = replay->cursor,
end = replay->cursor;
ui_fill( tag, ui_colour( 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\n", len );
+ snprintf( buffer, 128, "-%.2fs (F1: Edit replay)", (end-replay->cursor) );
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 )
- {
- gui_helper_clear();
- vg_ui.wants_mouse = 1;
+ if( !player_replay.editor_mode ) return;
+ vg_ui.wants_mouse = 1;
- 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;
- }
+ 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 (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( script, ui_colour( k_ui_bg ) );
+ f64 mouse_t = start + ((f64)vg_ui.mouse[0] / (f64)vg.window_x)*len;
- /* script bar */
- ui_rect script = { 0, height + 2, vg.window_x, 16 };
- ui_fill( script, ui_colour( k_ui_bg ) );
+ /* keyframe draw and select */
+ bool absorb_by_keyframe = 0;
+ ui_px lx = 0;
+ for( u32 i=0; i<player_replay.keyframe_count; i ++ )
+ {
+ replay_keyframe *kf = &player_replay.keyframes[i];
+ f64 t = (kf->time-start)/len;
- f64 mouse_t = start + ((f64)vg_ui.mouse[0] / (f64)vg.window_x)*len;
+ ui_px x = t*(f64)vg.window_x-8;
- /* keyframe draw and select */
- bool absorb_by_keyframe = 0;
- ui_px lx = 0;
- for( u32 i=0; i<player_replay.keyframe_count; i ++ )
+ /* draw connections between keyframes */
+ if( i )
{
- replay_keyframe *kf = &player_replay.keyframes[i];
- f64 t = (kf->time-start)/len;
+ 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 );
+ }
- ui_px x = t*(f64)vg.window_x-8;
+ /* keyframe selection */
+ ui_rect tag = { x, script[1], 16, 16 };
- if( i )
- {
- ui_rect con = { lx, script[1]+7, x-lx, 1 };
- ui_fill( con, ui_colour(k_ui_blue) );
+ if( ui_inside_rect( tag, vg_ui.mouse ) )
+ {
+ absorb_by_keyframe = 1;
- vg_line( kf->cam.pos,
- player_replay.keyframes[i-1].cam.pos, VG__BLUE );
+ if( ui_click_down( UI_MOUSE_LEFT ) )
+ {
+ if( player_replay.active_keyframe != i )
+ {
+ player_replay.active_keyframe = i;
+ replay_seek( &player_replay.local, kf->time );
+ }
}
+ else
+ {
+ ui_outline( tag, 1, ui_colour(k_ui_fg), 0 );
+ }
+ }
- ui_rect tag = { x, script[1], 16, 16 };
+ /* edit controls */
+ u32 drag_colour = ui_opacity( ui_colour(k_ui_bg+2), 0.5f );
+ if( i == player_replay.active_keyframe )
+ {
+ ui_outline( tag, 2, ui_colour(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, vg_ui.mouse_click ) )
+ {
+ if( ui_clicking( UI_MOUSE_LEFT ) )
{
- if( player_replay.active_keyframe != i )
+ drag_colour = ui_opacity( ui_colour(k_ui_fg), 0.5f );
+ pos_correct = 1;
+ replay_seek( &player_replay.local, mouse_t );
+ }
+ else if( ui_click_up( UI_MOUSE_LEFT ) )
+ {
+ pos_correct = 1;
+ kf->time = mouse_t;
+ replay_keyframe_sort();
+
+ for( u32 j=0; j<player_replay.keyframe_count; j ++ )
{
- player_replay.drag_wait = 1;
- player_replay.active_keyframe = i;
- replay_seek( &player_replay.local, kf->time );
+ 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] = vg_ui.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, vg_ui.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();
- }
- }
+ vg_ui.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( tray, ui_opacity( ui_colour(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( dragbar, drag_colour );
+ ui_text( 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( btn, "X", 1 ) == k_ui_button_click )
{
- ui_start_modal( "Maximum keyframes reached", UI_MODAL_BAD );
+ for( u32 j=i; j<player_replay.keyframe_count-1; j ++ )
+ player_replay.keyframes[j] = player_replay.keyframes[j+1];
+
+ player_replay.keyframe_count --;
+ player_replay.active_keyframe = -1;
}
- else
- {
- replay_keyframe *kf =
- &player_replay.keyframes[player_replay.keyframe_count++];
- kf->time = 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( btn1, "E", 1 ) & mask_using )
+ {
+ replay_fly_edit_keyframe( kf );
+ ui_set_mouse_pos( btn1[0]+8, btn1[1]+8 );
}
}
}
+ ui_fill( tag, ui_colour(k_ui_blue) );
+ lx = x;
+ }
- /* 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;
+ /* adding keyframes */
+ if( ui_inside_rect( script, vg_ui.mouse ) )
+ {
+ vg_ui.cursor = k_ui_cursor_hand;
+
+ ui_rect cursor = { vg_ui.mouse[0], script[1], 4, 16 };
+ ui_fill( cursor, ui_colour( k_ui_fg ) );
- if( ui_clicking( UI_MOUSE_LEFT ) && start_in_timeline )
+ if( !absorb_by_keyframe && ui_click_down( UI_MOUSE_LEFT ) )
+ {
+ u32 max = vg_list_size( player_replay.keyframes );
+ if( player_replay.keyframe_count == max )
+ {
+ ui_start_modal( "Maximum keyframes reached", UI_MODAL_BAD );
+ }
+ else
{
- replay_seek( &player_replay.local, mouse_t );
- player_replay.active_keyframe = -1;
+ replay_keyframe *kf =
+ &player_replay.keyframes[player_replay.keyframe_count++];
+
+ kf->time = mouse_t;
+ v3_copy( skaterift.cam.pos, kf->cam.pos );
+ v3_copy( skaterift.cam.angles, kf->cam.angles );
+ kf->cam.fov = skaterift.cam.fov;
+
+ replay_keyframe_sort();
}
}
+ }
+
+ /* 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;
- if( player_replay.active_keyframe != -1 )
+ if( ui_clicking( 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( 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( 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( panel, "Edit cam" ) & mask_using )
+ {
+ replay_fly_edit_keyframe( kf );
}
}
+
+ ui_info( panel, "World settings" );
+ f32 new_time = world_current_instance()->time;
+ if( ui_slider( panel, "Time of day", 0, 1, &new_time, NULL ) )
+ {
+ world_current_instance()->time = new_time;
+ }
+
+ ui_info( panel, "" );
+ if( ui_button( panel, "Exit editor (F1)" ) == k_ui_button_click )
+ {
+ player_replay.editor_mode = 0;
+ replay_show_helpers();
+ }
}