fadeout cutscene and some bugs
authorhgn <hgodden00@gmail.com>
Wed, 12 Mar 2025 01:32:58 +0000 (01:32 +0000)
committerhgn <hgodden00@gmail.com>
Wed, 12 Mar 2025 01:32:58 +0000 (01:32 +0000)
src/metascene.c
src/metascene.h
src/player_dead.c
src/player_ragdoll.c
src/skaterift.c
src/skaterift_script.c
src/world_load.c
src/world_water.c

index 1812db44a155c486e9e8001cc348b46f891da93a..19b7dbdc79d1ddc99d653a3d3550059ded0f7913 100644 (file)
@@ -93,6 +93,8 @@ void _cutscene_unload(void)
    _cutscene.subtitle = NULL;
    _cutscene.subtitle_list = NULL;
    _cutscene.subtitle_index = 0;
+   _cutscene.fadeout = 0;
+   _cutscene.fadeout_start = 0.0f;
 }
 
 /*
@@ -107,8 +109,7 @@ struct cs_asoc
    ms_override *override;
 };
 
-static void _cutscene_override_asoc( u32 instance_id, u32 override_index,
-                                     struct cs_asoc *out_asoc )
+static void _cutscene_override_asoc( u32 instance_id, u32 override_index, struct cs_asoc *out_asoc )
 {
    struct cs_instance *instance = &_cutscene.instances[ instance_id ];
    mdl_context *mdl = &_cutscene.refs[ instance->ref_id ].mdl;
@@ -209,8 +210,7 @@ static void cutscene_load_thread( void *data )
 
       if( !ref )
       {
-         _cutscene.refs = vg_linear_extend( _cutscene.arena, _cutscene.refs, 
-                              sizeof( struct model_ref ) );
+         _cutscene.refs = vg_linear_extend( _cutscene.arena, _cutscene.refs, sizeof( struct model_ref ) );
          ref_id = _cutscene.unique_refs;
          ref = &_cutscene.refs[ ref_id ];
          ref->name = name;
@@ -340,7 +340,7 @@ static int cmd_cutscene_load( int argc, const char *argv[] )
       if( _cutscene.state != k_cutscene_state_none )
       {
          vg_error( "Cutscene already in use..\n" );
-         return 1;
+         return 0;
       }
 
       if( vg_loader_availible() )
@@ -577,7 +577,13 @@ void cutscene_update( f32 delta )
 
          bool absorbed = 0;
 
-         if( _cutscene.subtitle_list )
+         if( vg_str_eq( marker, "$fadeout" ) )
+         {
+            _cutscene.fadeout = 1;
+            _cutscene.fadeout_start = _cutscene.time;
+            absorbed = 1;
+         }
+         else if( _cutscene.subtitle_list )
          {
             const cs_subtitle *next = &_cutscene.subtitle_list[ _cutscene.subtitle_index ];
 
@@ -788,6 +794,46 @@ void cutscene_update( f32 delta )
       _cutscene.state = k_cutscene_state_done;
 }
 
+void cutscene_render_fadeout(void)
+{
+   bool render = 0;
+   f32 render_alpha = 0.0f;
+
+   if( _cutscene.state >= k_cutscene_state_ready )
+   {
+      if( _cutscene.fadeout )
+      {
+         f32 l = ((f32)_cutscene.meta.info.end_frame/(f32)_cutscene.meta.info.framerate) - _cutscene.fadeout_start,
+             t = (_cutscene.time - _cutscene.fadeout_start) / l;
+         render = 1;
+         render_alpha = t;
+         _cutscene.fadeout_cooldown = 1.0f;
+      }
+   }
+   else
+   {
+      if( _cutscene.fadeout_cooldown > 0.0f )
+      {
+         render = 1;
+         render_alpha = _cutscene.fadeout_cooldown;
+         _cutscene.fadeout_cooldown -= vg.time_delta;
+      }
+   }
+
+   if( render )
+   {
+      glEnable(GL_BLEND);
+      glDisable(GL_DEPTH_TEST);
+      glDepthMask(GL_FALSE);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+      glBlendEquation(GL_FUNC_ADD);
+
+      shader_blitcolour_use();
+      shader_blitcolour_uColour( (v4f){ 0.04f, 0.02f, 0.03f, vg_clampf( render_alpha, 0.0f, 1.0f ) } );
+      render_fsquad();
+   }
+}
+
 void cutscene_render( world_instance *world, vg_camera *cam )
 {
    if( _cutscene.state >= k_cutscene_state_ready )
@@ -819,20 +865,17 @@ void _cutscene_gui( ui_context *ctx )
  * ----------------------------------------------------------------------------
  */
 
-static void cb_cutscene_view( ui_context *ctx, ui_rect rect, 
-                              struct vg_magi_panel *magi )
+static void cb_cutscene_view( ui_context *ctx, ui_rect rect, struct vg_magi_panel *magi )
 {
    if( _cutscene.state == k_cutscene_state_none )
    {
-      ui_text( ctx, rect, "No cutscene loaded.", 1, 
-               k_ui_align_middle_center, 0 );
+      ui_text( ctx, rect, "No cutscene loaded.", 1, k_ui_align_middle_center, 0 );
       return;
    }
 
    if( _cutscene.state == k_cutscene_state_loading )
    {
-      ui_text( ctx, rect, "Cutscene loading..", 1, 
-               k_ui_align_middle_center, 0 );
+      ui_text( ctx, rect, "Cutscene loading..", 1, k_ui_align_middle_center, 0 );
       return;
    }
 
index 87d45fc098c73aad2ff9c2a48f0114a475998dea..e6b931433d5c3f5e4466f0ad504f8ef93820d09d 100644 (file)
@@ -158,6 +158,9 @@ struct _cutscene
    u32 strip;
    f32 time;
 
+   bool fadeout;
+   f32 fadeout_start, fadeout_cooldown;
+
    const char *marker_this_frame;
    const char *subtitle;
    struct cs_subtitle
@@ -172,6 +175,7 @@ extern _cutscene;
 void metascene_load( ms_context *ms, const char *path, void *alloc );
 void cutscene_init(void);
 void cutscene_render( world_instance *world, vg_camera *cam );
+void cutscene_render_fadeout(void);
 void _cutscene_play(void);
 void _cutscene_unload(void);
 void cutscene_update( f32 delta );
index 7f1b5e9e9ac70dfe5299a5c0047254d9e4a2a3dc..dd2b9aeba5188437b4ff98cb2f28f84754db5ae8 100644 (file)
@@ -164,11 +164,17 @@ void player__dead_transition( enum player_die_type type )
    if( localplayer.subsystem == k_player_subsystem_dead )
       return;
 
+   static bool dont_ask = 1;
+   if( dont_ask )
+   {
+      dont_ask = 0;
+      return;
+   }
+
    localplayer.subsystem = k_player_subsystem_dead;
    copy_localplayer_to_ragdoll( &localplayer.ragdoll, type );
 
-   struct ragdoll_part *part = 
-      &localplayer.ragdoll.parts[ localplayer.id_hip-1 ];
+   struct ragdoll_part *part = &localplayer.ragdoll.parts[ localplayer.id_hip-1 ];
    v3_copy( part->rb.co, player_dead.co_lpf );
    v3_copy( part->rb.v,  player_dead.v_lpf );
    v3_copy( part->rb.w,  player_dead.w_lpf );
index a919eebc7e6637a9c7b9d85ddd7b705756999c37..ebaa55d3b6c8f526a37406f4676c504b1511297c 100644 (file)
@@ -299,16 +299,15 @@ void copy_ragdoll_pose_to_localplayer( struct player_ragdoll *rd )
 /*
  * Make the ragdoll copy the player model
  */
-void copy_localplayer_to_ragdoll( struct player_ragdoll *rd, 
-                                  enum player_die_type type )
+void copy_localplayer_to_ragdoll( struct player_ragdoll *rd, enum player_die_type type )
 {
    v3f centroid;
 
    v3f *bone_mtx = localplayer.final_mtx[localplayer.id_hip];
-   m4x3_mulv( bone_mtx, 
-              localplayer.skeleton.bones[localplayer.id_hip].co, centroid );
+   m4x3_mulv( bone_mtx, localplayer.skeleton.bones[localplayer.id_hip].co, centroid );
 
-   for( int i=0; i<rd->part_count; i++ ){
+   for( int i=0; i<rd->part_count; i++ )
+   {
       struct ragdoll_part *part = &rd->parts[i];
 
       v3f pos, offset;
@@ -329,9 +328,10 @@ void copy_localplayer_to_ragdoll( struct player_ragdoll *rd,
       v3_cross( localplayer.rb.w, ra, v );
       v3_add( localplayer.rb.v, v, part->rb.v );
 
-      if( type == k_player_die_type_feet ){
-         if( (bone == localplayer.id_foot_l) || 
-             (bone == localplayer.id_foot_r) ){
+      if( type == k_player_die_type_feet )
+      {
+         if( (bone == localplayer.id_foot_l) || (bone == localplayer.id_foot_r) )
+         {
             v3_zero( part->rb.v );
          }
       }
index abe5cd060f854b85c4b39f4b27cf6f847a40f374..ef15b9466ee94f2aeb67f72d8a5dbda70803cf2b 100644 (file)
@@ -475,6 +475,7 @@ static void render_main_game(void)
 
    postprocess_to_screen( g_render.fb_main );
    skaterift_replay_post_render();
+   cutscene_render_fadeout();
 
    if( gui.helper_count == 0 )
       control_overlay_render();
index 603953c02503f1dda4f82f40d6866751a68777b7..e44a2326d7ed07cd55de886a3368570caad57f0f 100644 (file)
@@ -1394,13 +1394,16 @@ enum generic_cutscene_event generic_cutscene_wrapper( const struct generic_cutsc
       {
          if( generic->state == k_generic_cutscene_state_wake )
          {
-            if( generic->freeze_player )
-               localplayer.immobile = 1;
-
-            if( cmd_cutscene_load( 1, (const char *[]){ generic->metascene_path } ) )
+            if( _cutscene.state == k_cutscene_state_none )
             {
-               generic->state = k_generic_cutscene_state_init;
-               vg_info( "generic_cutscene:state = initializing\n" );
+               if( cmd_cutscene_load( 1, (const char *[]){ generic->metascene_path } ) )
+               {
+                  generic->state = k_generic_cutscene_state_init;
+                  vg_info( "generic_cutscene:state = initializing\n" );
+
+                  if( generic->freeze_player )
+                     localplayer.immobile = 1;
+               }
             }
 
             if( generic->trigger_start == 0 )
index 2874197a8cb666027f73966df438c9a33d9246e8..0e2ec6295d2b6219f9cb58f52b7c025488c0b902 100644 (file)
@@ -421,7 +421,7 @@ void world_switcher_update(void)
    /* pre-load step aka waiting for audio to end. */
    if( _world.loader_state == k_world_loader_unloading_current )
    {
-      if( !vg_audio_flagged_stopped( AUDIO_FLAG_WORLD ) )
+      if( !vg_audio_flagged_stopped( AUDIO_FLAG_WORLD|AUDIO_FLAG_CUTSCENE ) )
          return;
       
       world_instance_free_graphics_data( &_world.main );
@@ -500,7 +500,13 @@ void skaterift_load_world_start( addon_reg *reg, bool preview )
       }
    }
    else
+   {
+      if( _cutscene.state != k_cutscene_state_none )
+      {
+         _cutscene_unload();
+      }
       vg_audio_fadeout_flagged_audio( AUDIO_FLAG_WORLD, 1.0f );
+   }
 
    _world.loader_reg = reg;
    _world.loader_instance = world;
index fd25b5608980cde56a356f0ec53530d2d6d263e8..984a370b8762aebc533f29cce3c51c76986a6d1f 100644 (file)
@@ -228,10 +228,10 @@ void render_water_surface( world_instance *world, vg_camera *cam )
 
 static void world_water_drown(void)
 {
-   if( localplayer.drowned ) return;
-   player__networked_sfx( k_player_subsystem_walk, 32, 
-                          k_player_walk_soundeffect_splash,
-                          localplayer.rb.co, 1.0f );
+   if( localplayer.drowned ) 
+      return;
+
+   player__networked_sfx( k_player_subsystem_walk, 32, k_player_walk_soundeffect_splash, localplayer.rb.co, 1.0f );
    vg_info( "player fell of due to walking into walker\n" );
    localplayer.drowned = 1;
    player__dead_transition( k_player_die_type_generic );