first cutscene. kinda
authorhgn <hgodden00@gmail.com>
Fri, 24 Jan 2025 08:58:30 +0000 (08:58 +0000)
committerhgn <hgodden00@gmail.com>
Fri, 24 Jan 2025 08:58:30 +0000 (08:58 +0000)
content_skaterift/metascenes/test_scene.ms
content_skaterift/sound/cs/ch1s1.EXO.ogg [new file with mode: 0644]
content_skaterift/sound/cs/ch1s1.JC.ogg [new file with mode: 0644]
content_skaterift/sound/cs/ch1s1.MIKE.ogg [new file with mode: 0644]
src/metascene.c
src/metascene.h
src/skaterift.c
src/skaterift_script.c

index c474f18b4f794445a06fbe73cfcc3d91f56e6b01..b5c5c1f85992762d84763ed6a78f68e60efec79d 100644 (file)
Binary files a/content_skaterift/metascenes/test_scene.ms and b/content_skaterift/metascenes/test_scene.ms differ
diff --git a/content_skaterift/sound/cs/ch1s1.EXO.ogg b/content_skaterift/sound/cs/ch1s1.EXO.ogg
new file mode 100644 (file)
index 0000000..fb29b0b
Binary files /dev/null and b/content_skaterift/sound/cs/ch1s1.EXO.ogg differ
diff --git a/content_skaterift/sound/cs/ch1s1.JC.ogg b/content_skaterift/sound/cs/ch1s1.JC.ogg
new file mode 100644 (file)
index 0000000..3cbcf23
Binary files /dev/null and b/content_skaterift/sound/cs/ch1s1.JC.ogg differ
diff --git a/content_skaterift/sound/cs/ch1s1.MIKE.ogg b/content_skaterift/sound/cs/ch1s1.MIKE.ogg
new file mode 100644 (file)
index 0000000..89dbeb8
Binary files /dev/null and b/content_skaterift/sound/cs/ch1s1.MIKE.ogg differ
index 0260c133fd1f4d8c55d77f4932c551ea5a120ebc..b22c3e579760649646b27e0f52f035d89cbaad3c 100644 (file)
@@ -13,6 +13,8 @@ void metascene_load( ms_context *ms, const char *path, void *alloc )
    AF_LOAD_ARRAY_STRUCT( &ms->af, &ms->tracks, ms_track, alloc );
    AF_LOAD_ARRAY_STRUCT( &ms->af, &ms->keyframes, ms_keyframe, alloc );
    AF_LOAD_ARRAY_STRUCT( &ms->af, &ms->cameras, ent_camera, alloc );
+   AF_LOAD_ARRAY_STRUCT( &ms->af, &ms->audios, ent_audio, alloc );
+   AF_LOAD_ARRAY_STRUCT( &ms->af, &ms->audio_clips, ent_audio_clip, alloc );
    af_load_array( &ms->af, &ms->curves, "ms_curves", 
                    alloc, sizeof(ms_curve_keyframe) );
    af_close( &ms->af );
@@ -47,22 +49,54 @@ struct cs_instance *_cutscene_get_first_model_instance( const char *mdl_name )
 void _cutscene_play(void)
 {
    _cutscene.state = k_cutscene_state_playing;
+
+   audio_lock();
+   for( u32 j=0; j<af_arrcount( &_cutscene.meta.audios ); j++ )
+   {
+      ent_audio *audio = af_arritm( &_cutscene.meta.audios, j );
+      ent_audio_clip *clip = af_arritm( &_cutscene.meta.audio_clips, 
+                                         audio->clip_start );
+
+      if( audio->flags & AUDIO_FLAG_AUTO_START )
+      {
+         audio_channel *ch;
+         if( audio->flags & AUDIO_FLAG_SPACIAL_3D )
+         {
+            ch = audio_oneshot_3d( &clip->_.clip, audio->transform.co,
+                                    audio->transform.s[0],
+                                    audio->volume );
+         }
+         else
+            ch = audio_oneshot( &clip->_.clip, 1.0f, 0.0f );
+
+         if( ch )
+            audio_channel_group( ch, 0xfff1 );
+      }
+   }
+   audio_unlock();
 }
 
 void _cutscene_unload(void)
 {
    vg_info( "Unloading cutscene\n" );
 
+   audio_lock();
+   for( u32 i=0; i<AUDIO_CHANNELS; i++ )
+   {
+      audio_channel *ch = &vg_audio.channels[i];
+      if( ch->allocated && (ch->group == 0xfff1) )
+         audio_channel_fadeout( ch, 1.0f );
+   }
+   audio_unlock();
+
    for( u32 i=0; i<_cutscene.unique_refs; i ++ )
       mdl_sync_std_unload( &_cutscene.refs[i].mdl );
 
-   vg_allocator_free( _cutscene.arena );
-   _cutscene.arena = NULL;
    _cutscene.active_camera = NULL;
    _cutscene.strip = 0;
    _cutscene.time = 0.0f;
    _cutscene.active_samplers = 0;
-   _cutscene.state = k_cutscene_state_none;
+   _cutscene.state = k_cutscene_state_unloading;
    _cutscene.player_binding = NULL;
 }
 
@@ -273,19 +307,43 @@ static void cutscene_load_thread( void *data )
       }
    }
 
+   /* audio packs */
+   for( u32 j=0; j<af_arrcount( &_cutscene.meta.audios ); j++ )
+   {
+      ent_audio *audio = af_arritm( &_cutscene.meta.audios, j );
+
+      for( u32 k=0; k<audio->clip_count; k++ )
+      {
+         ent_audio_clip *clip = af_arritm( &_cutscene.meta.audio_clips, 
+                                           audio->clip_start+k );
+
+         if( clip->_.file.pack_size )
+         {
+            vg_error( "Currently not support packed audio in metascene..." );
+         }
+         else
+         {
+            clip->_.clip.path = af_str( &_cutscene.meta.af,
+                                         clip->_.file.pstr_path );
+            clip->_.clip.flags = audio->flags;
+            clip->_.clip.data = NULL;
+            clip->_.clip.size = 0;
+         }
+
+         audio_clip_load( &clip->_.clip, _cutscene.arena );
+      }
+   }
+
    vg_async_call( sync_cutscene_loaded, NULL, 0 );
 }
 
-static int cmd_cutscene_play( int argc, const char *argv[] )
+static int cmd_cutscene_load( int argc, const char *argv[] )
 {
    if( argc == 1 )
    {
       if( _cutscene.state != k_cutscene_state_none )
       {
-         vg_info( "Resetting cutscene..\n" );
-         _cutscene.time = 0.0f;
-         _cutscene.strip = 0;
-         _cutscene.active_samplers = 0;
+         vg_error( "Cutscene already in use..\n" );
          return 1;
       }
 
@@ -438,6 +496,26 @@ ent_camera *_cutscene_active_camera(void)
 
 void cutscene_update( f32 delta )
 {
+   if( _cutscene.state == k_cutscene_state_unloading )
+   {
+      audio_lock();
+      for( u32 i=0; i<AUDIO_CHANNELS; i++ )
+      {
+         audio_channel *ch = &vg_audio.channels[i];
+         if( ch->allocated && (ch->group == 0xfff1) )
+         {
+            audio_unlock();
+            return;
+         }
+      }
+      audio_unlock();
+
+      vg_allocator_free( _cutscene.arena );
+      _cutscene.arena = NULL;
+      _cutscene.state = k_cutscene_state_none;
+      return;
+   }
+
    if( _cutscene.state != k_cutscene_state_playing )
       return; 
 
@@ -498,8 +576,8 @@ void cutscene_update( f32 delta )
 
             _cutscene.active_camera = cam;
          }
-         else
-            _cutscene.active_camera = NULL;
+         //else
+         //   _cutscene.active_camera = NULL;
 
          const char *marker = af_str( &_cutscene.meta.af, strip->pstr_name );
          _skaterift_script_marker( marker );
@@ -696,6 +774,27 @@ void cutscene_render( world_instance *world, vg_camera *cam )
    }
 }
 
+void _cutscene_gui( ui_context *ctx )
+{
+   if( _cutscene.subtitle )
+   {
+      ui_rect box = { 0,0, 800, 40 };
+      ui_rect_center( (ui_rect){0,0,vg.window_x,vg.window_y}, box );
+      box[1] = vg.window_y - (box[3] + 8);
+      ui_fill( ctx, box, ui_opacity( GUI_COL_DARK, 0.36f ) );
+
+      ctx->font = &vgf_default_large;
+      ui_text( ctx, box, _cutscene.subtitle, 1, k_ui_align_middle_center, 0 );
+
+      ctx->font = &vgf_default_small;
+   }
+}
+
+void _cutscene_subtitle( const char *text )
+{
+   _cutscene.subtitle = text;
+}
+
 /* cutscene magi 
  * ----------------------------------------------------------------------------
  */
@@ -821,6 +920,6 @@ static int cmd_cutscene_inspector( int argc, const char *argv[] )
 
 void cutscene_init(void)
 {
-   vg_console_reg_cmd( "cutscene", cmd_cutscene_play, NULL );
+   vg_console_reg_cmd( "cutscene", cmd_cutscene_load, NULL );
    vg_console_reg_cmd( "cutscene_inspector", cmd_cutscene_inspector, NULL );
 }
index 875f140ab6c42d94cfc16407982b73aba940d273..f0435f72f072eff81e55e6341fe7f6e334c0de9d 100644 (file)
@@ -32,7 +32,9 @@ struct ms_context
                          keyframes,
                          curves,
 
-                         cameras; /* kinda temp? */
+                         audios, /* kinda temp? */
+                         audio_clips,
+                         cameras;
 };
 
 struct ms_instance
@@ -92,9 +94,10 @@ struct _cutscene
    {
       k_cutscene_state_none,
       k_cutscene_state_loading,
+      k_cutscene_state_unloading,
       k_cutscene_state_ready,
       k_cutscene_state_playing,
-      k_cutscene_state_done
+      k_cutscene_state_done,
    }
    state;
 
@@ -151,6 +154,9 @@ struct _cutscene
 
    u32 strip;
    f32 time;
+
+   char subtitle_buf[128];
+   const char *subtitle;
 }
 extern _cutscene;
 
@@ -161,5 +167,6 @@ void _cutscene_play(void);
 void _cutscene_unload(void);
 void cutscene_update( f32 delta );
 ent_camera *_cutscene_active_camera(void);
+void _cutscene_gui( ui_context *ctx );
 
 struct cs_instance *_cutscene_get_first_model_instance( const char *mdl_name );
index 38a6b8887e431b223a618f774c8e2c3c0da88aab..1c2d4379bc6d6f1c8c369f31e0e6855660fa0d76 100644 (file)
@@ -629,6 +629,7 @@ void vg_gui( ui_context *ctx )
    vg_ui.tex_bg = g_render.fb_main->attachments[0].id;
    vg_framebuffer_inverse_ratio( g_render.fb_main, vg_ui.bg_inverse_ratio );
 
+   _cutscene_gui( ctx );
    menu_gui( ctx );
    player__im_gui( ctx );
    world_instance *world = world_current_instance();
index e987e919567adbc5b9cf195e2d0ae0a4a4d9d2a3..4ca9edc26900ecec5abddd470e436ce9c6c22152 100644 (file)
@@ -5,6 +5,9 @@
  * man.
  */
 
+#define KCOL_JOHN KRED
+#define KCOL_MIKE KBLU
+
 enum escript_event
 {
    k_escript_event_call = 0,
@@ -46,6 +49,59 @@ static bool _skaterift_script_test( enum escript_event ev, const char *inf )
       if( vg_str_eq( inf, "action_cam" ) )
          action_mode = 1;
 
+      if( vg_str_eq( inf, "john_line_0" ) )
+         _cutscene_subtitle( KCOL_JOHN "Mike mike mike, I need you to get over here now" );
+
+      if( vg_str_eq( inf, "mike_line_0" ) )
+         _cutscene_subtitle( KCOL_MIKE "What is it now JC?" );
+
+      if( vg_str_eq( inf, "john_line_1" ) )
+         _cutscene_subtitle( KCOL_JOHN "Well we were out here, shooting this massive gap right?" );
+
+      if( vg_str_eq( inf, "john_line_1a" ) )
+         _cutscene_subtitle( KCOL_JOHN "It was gonna be the perfect shot, and it was going so good" );
+
+      if( vg_str_eq( inf, "john_line_2" ) )
+         _cutscene_subtitle( KCOL_JOHN "Intro was perfect, got the perfect frame, angles lighting. PERFECT" );
+
+
+      if( vg_str_eq( inf, "mike_line_1" ) )
+         _cutscene_subtitle( KCOL_MIKE "Whatever mate, what happened?" );
+
+      if( vg_str_eq( inf, "john_line_3" ) )
+         _cutscene_subtitle( KCOL_JOHN "Uh yeah yeah, we were about 10 floors up right?" );
+
+      if( vg_str_eq( inf, "john_line_3a" ) )
+         _cutscene_subtitle( KCOL_JOHN "Yeah uhhh, they didn't make the gap." );
+
+      if( vg_str_eq( inf, "john_line_4" ) )
+         _cutscene_subtitle( KCOL_JOHN "And im im freaking out here man, it was worst case" );
+
+      if( vg_str_eq( inf, "john_line_4a" ) )
+         _cutscene_subtitle( KCOL_JOHN "I mean.. WORST CASE" );
+
+      if( vg_str_eq( inf, "mike_line_2" ) )
+         _cutscene_subtitle( KCOL_MIKE "yeaahkay, what are you doing calling me instead of an ambo?" );
+
+      if( vg_str_eq( inf, "john_line_5" ) )
+         _cutscene_subtitle( KCOL_JOHN "I thought you could help us!" );
+
+      if( vg_str_eq( inf, "mike_line_3" ) )
+         _cutscene_subtitle( KCOL_MIKE "Hang up, and call tripple zero mate" );
+
+      if( vg_str_eq( inf, "mike_line_3a" ) )
+         _cutscene_subtitle( KCOL_MIKE "Did you even check if they were okay?" );
+
+      if( vg_str_eq( inf, "john_line_6" ) )
+         _cutscene_subtitle( KCOL_JOHN "Holy crap, you're still alive!" );
+      if( vg_str_eq( inf, "john_line_6a" ) )
+         _cutscene_subtitle( KCOL_JOHN "Nevermind Mike, cheers" );
+      if( vg_str_eq( inf, "john_line_7" ) )
+         _cutscene_subtitle( KCOL_JOHN "Lets get out of here mate." );
+
+      if( vg_str_eq( inf, "clear_subs" ) )
+         _cutscene_subtitle( NULL );
+
       return 0;
    }
 
@@ -54,7 +110,7 @@ static bool _skaterift_script_test( enum escript_event ev, const char *inf )
 
    if( state == k_escript_state_loading )
    {
-      if( cmd_cutscene_play( 1, (const char *[]){ "metascenes/test_scene.ms" } ) )
+      if( cmd_cutscene_load( 1, (const char *[]){ "metascenes/test_scene.ms" } ) )
       {
          state = k_escript_state_initializing;
          vg_info( "test:state = initializing\n" );
@@ -159,6 +215,12 @@ static int _skaterift_script_hook( int argc, const char *argv[] )
       return 0;
    }
 
+   if( _cutscene.state != k_cutscene_state_none )
+   {
+      vg_error( "Cannot load script while cutscene is in use.\n" );
+      return 0;
+   }
+
    for( u32 i=0; i<k_escript_script_id_max; i ++ )
    {
       struct script_binding *bind = &_script_bindings[i];