npcs and tutorial stuff
authorhgn <hgodden00@gmail.com>
Wed, 28 Feb 2024 00:27:13 +0000 (00:27 +0000)
committerhgn <hgodden00@gmail.com>
Wed, 28 Feb 2024 00:27:13 +0000 (00:27 +0000)
28 files changed:
blender_export.py
ent_challenge.c
ent_npc.c
ent_npc.h
ent_route.c
ent_skateshop.c
entity.c
entity.h
font.h
maps_src/dev_hub/main.mdl
maps_src/dev_tutorial/main.mdl
models_src/slowmos.mdl [new file with mode: 0644]
models_src/volc_flight.mdl [new file with mode: 0644]
player.c
player_common.c
player_glide.c
player_render.c
player_skate.c
render.c
shaders/depth_compare.glsl
shaders/impl.c
shaders/model_board_view.h
shaders/model_character_view.h
shaders/model_font.h
skaterift.c
sound_src/gumpa-theme.ogg [new file with mode: 0644]
world_entity.c
world_entity.h

index 7c8c69f6ab104cfdcb821d902e9e199e62066dc0..b1e7677fb232cf5c071a74ff4cff5f6a26af3e21 100644 (file)
@@ -51,7 +51,8 @@ sr_entity_list = [
 MDL_VERSION_NR = 105
 SR_TRIGGERABLE = [ 'ent_audio', 'ent_ccmd', 'ent_gate', 'ent_challenge', \
                    'ent_relay', 'ent_skateshop', 'ent_objective', 'ent_route',\
-                   'ent_miniworld', 'ent_region', 'ent_glider', 'ent_list' ]
+                   'ent_miniworld', 'ent_region', 'ent_glider', 'ent_list',\
+                   'ent_npc' ]
 
 def get_entity_enum_id( alias ):
 #{
@@ -306,7 +307,9 @@ class ent_glider(Structure):#{
 class ent_npc(Structure):#{
    _fields_ = [("transform",mdl_transform),
                ("id",c_uint32),
-               ("context",c_uint32)]
+               ("context",c_uint32),
+               ("camera",c_uint32)]
+   sr_functions = { 0: 'proximity', -1: 'leave' }
 #}
 
 class ent_water(Structure):
@@ -320,7 +323,7 @@ class ent_water(Structure):
 class volume_trigger(Structure):
 #{
    _fields_ = [("event",c_uint32),
-               ("event_leave",c_uint32)]
+               ("event_leave",c_int32)]
 #}
 
 class volume_particles(Structure):
@@ -530,7 +533,7 @@ class ent_objective(Structure):#{
                ("id_next",c_uint32),
                ("filter",c_uint32),("filter2",c_uint32),
                ("id_win",c_uint32),
-               ("win_event",c_uint32),
+               ("win_event",c_int32),
                ("time_limit",c_float)]
 
    sr_functions = { 0: 'trigger',
@@ -543,9 +546,9 @@ class ent_challenge(Structure):#{
                ("pstr_alias",c_uint32),
                ("flags",c_uint32),
                ("target",c_uint32),
-               ("target_event",c_uint32),
+               ("target_event",c_int32),
                ("reset",c_uint32),
-               ("reset_event",c_uint32),
+               ("reset_event",c_int32),
                ("first",c_uint32),
                ("camera",c_uint32),
                ("status",c_uint32)] #runtime
@@ -566,7 +569,7 @@ class ent_region(Structure):#{
 
 class ent_relay(Structure):#{
    _fields_ = [("targets",(c_uint32*2)*4),
-               ("targets_events",c_uint32*4)]
+               ("targets_events",c_int32*4)]
    sr_functions = { 0: 'trigger' }
 #}
 
@@ -1920,10 +1923,7 @@ def sr_compile( collection ):
             if obj_data.target:#{
                volume.target = sr_entity_id( obj_data.target )
                volume._anon.trigger.event = obj_data.target_event
-
-               ev = 0xffffffff if obj_data.target_event_leave < 0 else \
-                     obj_data.target_event_leave
-               volume._anon.trigger.event_leave = ev
+               volume._anon.trigger.event_leave = obj_data.target_event_leave
             #}
 
             sr_ent_push(volume)
@@ -2080,6 +2080,7 @@ def sr_compile( collection ):
             compile_obj_transform( obj, npc.transform )
             npc.id = obj_data.au
             npc.context = obj_data.context
+            npc.camera = sr_entity_id( obj_data.cam )
             sr_ent_push( npc )
          #}
          elif ent_type == 'ent_cubemap':#{
@@ -3166,6 +3167,9 @@ class SR_OBJECT_ENT_GLIDER(bpy.types.PropertyGroup):#{
 class SR_OBJECT_ENT_NPC(bpy.types.PropertyGroup):#{
    au: bpy.props.IntProperty()
    context: bpy.props.IntProperty()
+   cam: bpy.props.PointerProperty( \
+           type=bpy.types.Object, name="Viewpoint", \
+           poll=lambda self,obj: sr_filter_ent_type(obj,['ent_camera']))
 #}
 
 class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{
index c2ee3b6434eb163fc2687efa247f49ced237716c..8f8c277338f3312562591e0b9924a951fd712ba6 100644 (file)
@@ -25,7 +25,8 @@ void ent_challenge_call( world_instance *world, ent_call *call )
       if( (localplayer.subsystem == k_player_subsystem_walk) &&
           (world_static.challenge_target == NULL) ){
          world_static.challenge_target = NULL;
-         world_entity_focus( call->id );
+         world_entity_set_focus( call->id );
+         world_entity_focus_modal();
 
          gui_helper_clear();
          vg_str text;
@@ -66,7 +67,7 @@ void ent_challenge_preupdate( ent_challenge *challenge, int active )
       if( min_dist2 > max_dist*max_dist ){
          world_static.challenge_target = NULL;
          world_static.challenge_timer = 0.0f;
-         world_static.focused_entity = 0;
+         world_entity_clear_focus();
          audio_lock();
          audio_oneshot_3d( &audio_challenge[6], localplayer.rb.co,
                            30.0f, 1.0f );
@@ -83,7 +84,7 @@ void ent_challenge_preupdate( ent_challenge *challenge, int active )
          world_static.challenge_target = mdl_arritm( &world->ent_objective, 
                                                      index );
          world_static.challenge_timer = 0.0f;
-         world_entity_unfocus();
+         world_entity_exit_modal();
          gui_helper_clear();
 
          u32 next = challenge->first;
@@ -101,9 +102,11 @@ void ent_challenge_preupdate( ent_challenge *challenge, int active )
       }
    }
 
-   if( button_down( k_srbind_mback ) ){
+   if( button_down( k_srbind_mback ) )
+   {
       world_static.challenge_target = NULL;
-      world_entity_unfocus();
+      world_entity_exit_modal();
+      world_entity_clear_focus();
       gui_helper_clear();
       audio_lock();
       audio_oneshot( &audio_challenge[4], 1.0f, 0.0f );
index 048a1b9b27bd20f6685512fb42b6dc3d7684fa90..774edff45806ae47ea40dfeefe555847fdf7b7ba 100644 (file)
--- a/ent_npc.c
+++ b/ent_npc.c
@@ -1,9 +1,16 @@
 #include "vg/vg_mem.h"
 #include "ent_npc.h"
 #include "shaders/model_character_view.h"
+#include "input.h"
+#include "player.h"
+#include "gui.h"
 
-struct npc npc_gumpa;
+struct npc npc_gumpa, npc_slowmo, npc_volc_flight;
 static struct skeleton_anim *gumpa_idle;
+static struct skeleton_anim *slowmo_momentum, *slowmo_slide, *slowmo_rewind,
+                            *anim_tutorial_cam;
+static float slowmo_opacity = 0.0f;
+static f64 volc_start_preview = 0.0;
 
 void npc_load_model( struct npc *npc, const char *path )
 {
@@ -20,16 +27,20 @@ void npc_load_model( struct npc *npc, const char *path )
    u32 mtx_size = sizeof(m4x3f)*sk->bone_count;
    npc->final_mtx = vg_linear_alloc( vg_mem.rtmemory, mtx_size );
 
-   if( !mdl_arrcount( &meta->textures ) )
-      vg_fatal_error( "No texture in model" );
+   if( mdl_arrcount( &meta->textures ) )
+   {
+      mdl_texture *tex0 = mdl_arritm( &meta->textures, 0 );
+      void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
+      mdl_fread_pack_file( meta, &tex0->file, data );
 
-   mdl_texture *tex0 = mdl_arritm( &meta->textures, 0 );
-   void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
-   mdl_fread_pack_file( meta, &tex0->file, data );
-
-   vg_tex2d_load_qoi_async( data, tex0->file.pack_size,
-                            VG_TEX2D_NEAREST|VG_TEX2D_CLAMP,
-                            &npc->texture );
+      vg_tex2d_load_qoi_async( data, tex0->file.pack_size,
+                               VG_TEX2D_NEAREST|VG_TEX2D_CLAMP,
+                               &npc->texture );
+   }
+   else
+   {
+      npc->texture = vg.tex_missing;
+   }
 
    mdl_async_load_glmesh( meta, &npc->mesh, NULL );
    mdl_close( meta );
@@ -39,16 +50,162 @@ void npc_init(void)
 {
    npc_load_model( &npc_gumpa, "models/gumpa.mdl" );
    gumpa_idle = skeleton_get_anim( &npc_gumpa.skeleton, "gumpa_idle" );
+
+   npc_load_model( &npc_slowmo, "models/slowmos.mdl" );
+   slowmo_momentum = 
+      skeleton_get_anim( &npc_slowmo.skeleton, "slowmo_momentum" );
+   slowmo_slide = skeleton_get_anim( &npc_slowmo.skeleton, "slowmo_slide" );
+   slowmo_rewind = skeleton_get_anim( &npc_slowmo.skeleton, "slowmo_rewind" );
+
+   npc_load_model( &npc_volc_flight, "models/volc_flight.mdl" );
+   anim_tutorial_cam = 
+      skeleton_get_anim( &npc_volc_flight.skeleton, "tutorial" );
 }
 
 static struct npc *npc_resolve( u32 id )
 {
    if( id == 1 ) return &npc_gumpa;
+   else if( id == 2 ) return &npc_slowmo;
+   else if( id == 3 ) return &npc_volc_flight;
    else return NULL;
 }
 
+static void npc_slowmo_call( ent_npc *npc, ent_call *call )
+{
+   if( call->function == 0 )
+   {
+      gui_helper_clear();
+      vg_str text;
+
+      if( npc->context == 2 )
+      {
+         if( gui_new_helper( input_axis_list[k_sraxis_grab], &text ))
+            vg_strcat( &text, "Crouch (store energy)" );
+         if( gui_new_helper( input_joy_list[k_srjoystick_steer], &text ))
+            vg_strcat( &text, "Slide" );
+      }
+      else if( npc->context == 1 )
+      {
+         if( gui_new_helper( input_axis_list[k_sraxis_grab], &text ))
+            vg_strcat( &text, "Crouch (store energy)" );
+      }
+      else if( npc->context == 3 )
+      {
+         if( gui_new_helper( input_button_list[k_srbind_reset], &text ))
+            vg_strcat( &text, "Rewind time" );
+         if( gui_new_helper( input_button_list[k_srbind_replay_resume], &text ))
+            vg_strcat( &text, "Resume" );
+      }
+   }
+   else if( call->function == -1 )
+   {
+      world_entity_clear_focus();
+      gui_helper_clear();
+   }
+}
+
+void ent_npc_call( world_instance *world, ent_call *call )
+{
+   u32 index = mdl_entity_id_id( call->id );
+   ent_npc *npc = mdl_arritm( &world->ent_npc, index );
+
+   if( npc->id == 2 )
+   {
+      npc_slowmo_call( npc, call );
+   }
+   else if( npc->id == 3 )
+   {
+      if( call->function == 0 )
+      {
+         world_entity_set_focus( call->id );
+         gui_helper_clear();
+         vg_str text;
+         if( gui_new_helper( input_button_list[k_srbind_maccept], &text ))
+            vg_strcat( &text, "Preview course" );
+      }
+      else if( call->function == -1 )
+      {
+         world_entity_clear_focus();
+         gui_helper_clear();
+      }
+   }
+   else
+   {
+      if( call->function == 0 )
+      {
+         world_entity_set_focus( call->id );
+         gui_helper_clear();
+         vg_str text;
+         if( gui_new_helper( input_button_list[k_srbind_maccept], &text ))
+            vg_strcat( &text, "Talk to ???" );
+      }
+      else if( call->function == -1 )
+      {
+         world_entity_clear_focus();
+         gui_helper_clear();
+      }
+      else 
+      {
+         vg_print_backtrace();
+         vg_error( "Unhandled function id: %i\n", call->function );
+      }
+   }
+}
+
+void ent_npc_preupdate( ent_npc *ent, int active )
+{
+   world_instance *world = world_current_instance();
+
+   if( !active )
+   {
+      if( button_down(k_srbind_maccept) )
+      {
+         world_entity_focus_modal();
+         gui_helper_clear();
+         vg_str text;
+         if( gui_new_helper( input_button_list[k_srbind_mback], &text ))
+            vg_strcat( &text, "leave" );
+
+         volc_start_preview = vg.time;
+      }
+
+      return;
+   }
+
+   if( ent->id == 3 )
+   {
+      player_pose pose;
+      struct skeleton *sk = &npc_volc_flight.skeleton;
+
+      f64 t = (vg.time - volc_start_preview) * 0.5;
+      skeleton_sample_anim_clamped( sk, anim_tutorial_cam, t, pose.keyframes );
+      
+      ent_camera *cam = mdl_arritm( &world->ent_camera, 
+                                     mdl_entity_id_id(ent->camera) );
+      v3_copy( pose.keyframes[0].co, cam->transform.co );
+
+      v4f qp;
+      q_axis_angle( qp, (v3f){1,0,0}, VG_TAUf*0.25f );
+      q_mul( pose.keyframes[0].q, qp, cam->transform.q );
+      q_normalize( cam->transform.q );
+
+      v3_add( ent->transform.co, cam->transform.co, cam->transform.co );
+   }
+
+   world_entity_focus_camera( world, ent->camera );
+
+   if( button_down( k_srbind_mback ) )
+   {
+      world_entity_exit_modal();
+      world_entity_clear_focus();
+      gui_helper_clear();
+   }
+}
+
 void npc_update( ent_npc *ent )
 {
+   if( ent->id == 3 ) return;
+
    struct npc *npc_def = npc_resolve( ent->id );
    VG_ASSERT( npc_def );
 
@@ -57,7 +214,25 @@ void npc_update( ent_npc *ent )
    pose.type = k_player_pose_type_ik;
    pose.board.lean = 0.0f;
 
-   skeleton_sample_anim( sk, gumpa_idle, vg.time, pose.keyframes );
+   if( ent->id == 1 )
+   {
+      skeleton_sample_anim( sk, gumpa_idle, vg.time, pose.keyframes );
+   }
+   else if( ent->id == 2 )
+   {
+      struct skeleton_anim *anim = NULL;
+      if( ent->context == 1 ) anim = slowmo_momentum;
+      else if( ent->context == 2 ) anim = slowmo_slide;
+      else if( ent->context == 3 ) anim = slowmo_rewind;
+
+      VG_ASSERT( anim );
+
+      f32 t        = vg.time*0.5f,
+          animtime = fmodf( t*anim->rate, anim->length ),
+          lt       = animtime / (f32)anim->length;
+      skeleton_sample_anim( sk, anim, t, pose.keyframes );
+      slowmo_opacity = vg_clampf(fabsf(lt-0.5f)*9.0f-3.0f,0,1);
+   }
 
    v3_copy( ent->transform.co, pose.root_co );
    v4_copy( ent->transform.q, pose.root_q );
@@ -66,6 +241,8 @@ void npc_update( ent_npc *ent )
 
 void npc_render( ent_npc *ent, world_instance *world, vg_camera *cam )
 {
+   if( ent->id == 3 ) return;
+
    struct npc *npc_def = npc_resolve( ent->id );
    VG_ASSERT( npc_def );
 
@@ -76,7 +253,16 @@ void npc_render( ent_npc *ent, world_instance *world, vg_camera *cam )
    shader_model_character_view_uTexMain( 0 );
    shader_model_character_view_uCamera( cam->transform[3] );
    shader_model_character_view_uPv( cam->mtx.pv );
-   shader_model_character_view_uDepthCompare( 0 );
+
+   if( ent->id == 2 )
+   {
+      shader_model_character_view_uDepthMode( 2 );
+      shader_model_character_view_uDitherCutoff( slowmo_opacity );
+   }
+   else 
+   {
+      shader_model_character_view_uDepthMode( 0 );
+   }
 
    WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_character_view );
 
index f474d0d165bc5cec60ca2ad108f365dfcb0c721a..24e7e02bcb5922bbba6baa54508e944ab08dd35c 100644 (file)
--- a/ent_npc.h
+++ b/ent_npc.h
@@ -21,6 +21,8 @@ enum npc_id
 };
 
 void npc_load_model( struct npc *npc, const char *path );
+void ent_npc_preupdate( ent_npc *ent, int active );
+void ent_npc_call( world_instance *world, ent_call *call );
 void npc_update( ent_npc *ent );
 void npc_render( ent_npc *ent, world_instance *world, vg_camera *cam );
 void npc_init(void);
index 8f95a26d292ce22c76c528e1819d8394f6cb7408..11b680d6f08a00cb6419754ad2998fe676200017 100644 (file)
@@ -10,8 +10,10 @@ void ent_route_call( world_instance *world, ent_call *call )
    ent_route *route = mdl_arritm( &world->ent_route, index );
 
    if( call->function == 0 ){ /* view() */
-      if( localplayer.subsystem == k_player_subsystem_walk ){
-         world_entity_focus( call->id );
+      if( localplayer.subsystem == k_player_subsystem_walk )
+      {
+         world_entity_set_focus( call->id );
+         world_entity_focus_modal();
 
          gui_helper_clear();
          vg_str text;
@@ -61,8 +63,10 @@ void ent_route_preupdate( ent_route *route, int active )
    global_ent_route.helper_alltime->greyed =!world_sfd.view_weekly;
    global_ent_route.helper_weekly->greyed =  world_sfd.view_weekly;
 
-   if( button_down( k_srbind_mback ) ){
-      world_entity_unfocus();
+   if( button_down( k_srbind_mback ) )
+   {
+      world_entity_exit_modal();
+      world_entity_clear_focus();
       gui_helper_clear();
       return;
    }
index ed222168ab59a94e2aab0df426645fa78b06e453..fd59f3eb047cf652cdca82f3e0c065ac34e34f79 100644 (file)
@@ -317,7 +317,8 @@ void ent_skateshop_preupdate( ent_skateshop *shop, int active )
          localplayer.board_view_slot = cache_id;
          network_send_item( k_netmsg_playeritem_board );
 
-         world_entity_unfocus();
+         world_entity_exit_modal();
+         world_entity_clear_focus();
          gui_helper_clear();
          skaterift_autosave(1);
          return;
@@ -364,7 +365,8 @@ void ent_skateshop_preupdate( ent_skateshop *shop, int active )
 
       if( button_down( k_srbind_maccept ) ){
          network_send_item( k_netmsg_playeritem_player );
-         world_entity_unfocus();
+         world_entity_exit_modal();
+         world_entity_clear_focus();
          gui_helper_clear();
       }
    }
@@ -437,11 +439,13 @@ void ent_skateshop_preupdate( ent_skateshop *shop, int active )
       vg_fatal_error( "Unknown store (%u)\n", shop->type );
    }
 
-   if( button_down( k_srbind_mback ) ){
+   if( button_down( k_srbind_mback ) )
+   {
       if( shop->type == k_skateshop_type_charshop )
          network_send_item( k_netmsg_playeritem_player );
 
-      world_entity_unfocus();
+      world_entity_exit_modal();
+      world_entity_clear_focus();
       gui_helper_clear();
       return;
    }
@@ -802,7 +806,8 @@ void ent_skateshop_call( world_instance *world, ent_call *call )
       
       vg_info( "Entering skateshop\n" );
 
-      world_entity_focus( call->id );
+      world_entity_set_focus( call->id );
+      world_entity_focus_modal();
       gui_helper_clear();
       
       if( shop->type == k_skateshop_type_boardshop ){
index 261dbbcd2c1ba89c89b58d4ff45997eae0f2871a..557ba799a792d2e61e96f8fa3591b67ed72a4b78 100644 (file)
--- a/entity.c
+++ b/entity.c
@@ -10,6 +10,7 @@
 #include "ent_miniworld.h"
 #include "ent_region.h"
 #include "ent_glider.h"
+#include "ent_npc.h"
 
 typedef void (*fn_entity_call_handler)( world_instance *, ent_call *);
 
@@ -29,7 +30,8 @@ void entity_call( world_instance *world, ent_call *call )
       [k_ent_route]     = ent_route_call,
       [k_ent_miniworld] = ent_miniworld_call,
       [k_ent_region]    = ent_region_call,
-      [k_ent_glider]    = ent_glider_call
+      [k_ent_glider]    = ent_glider_call,
+      [k_ent_npc]       = ent_npc_call
    };
 
    if( type >= vg_list_size(table) ){
index 105f4496c78b2469d95e2b10c5959f52e6fe5e18..d67c5f35d81683fda4bec559a5d7b344eb170357 100644 (file)
--- a/entity.h
+++ b/entity.h
@@ -243,7 +243,7 @@ struct volume_particles{
 };
 
 struct volume_trigger{
-   u32 event, event_leave;
+   i32 event, event_leave;
 };
 
 enum ent_volume_flag {
@@ -494,8 +494,8 @@ struct ent_objective{
        flags,
        id_next,
        filter,filter2,
-       id_win,
-       win_event;
+       id_win;
+   i32 win_event;
    f32 time_limit;
 };
 
@@ -507,18 +507,18 @@ struct ent_challenge{
    mdl_transform transform;
    u32 pstr_alias,
        flags,
-       target,
-       target_event,
-       reset,
-       reset_event,
-       first,
+       target;
+   i32 target_event;
+   u32 reset;
+   i32 reset_event;
+   u32 first,
        camera,
        status;
 };
 
 struct ent_relay {
    u32 targets[4][2];
-   u32 targets_events[4];
+   i32 targets_events[4];
 };
 
 struct ent_cubemap {
@@ -529,7 +529,8 @@ struct ent_cubemap {
 
 typedef struct ent_call ent_call;
 struct ent_call{
-   u32 id, function;
+   u32 id;
+   i32 function;
    void *data;
 };
 
@@ -562,7 +563,7 @@ struct ent_glider {
 struct ent_npc 
 {
    mdl_transform transform;
-   u32 id, context;
+   u32 id, context, camera;
 };
 
 #include "world.h"
diff --git a/font.h b/font.h
index a7836139ffc574b06a082c35362b499d5f71a245..608c71d38c02c4953f37efeede7be00ebb7ed211 100644 (file)
--- a/font.h
+++ b/font.h
@@ -139,12 +139,13 @@ static void font3d_bind( font3d *font, enum font_shader shader,
    glActiveTexture( GL_TEXTURE1 );
    glBindTexture( GL_TEXTURE_2D, font->texture );
 
-   if( shader == k_font_shader_default ){
+   if( shader == k_font_shader_default )
+   {
       shader_model_font_use();
       shader_model_font_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} );
       shader_model_font_uTexMain( 1 );
+      shader_model_font_uDepthMode( depth_compare );
 
-      shader_model_font_uDepthCompare( depth_compare );
       if( depth_compare ){
          depth_compare_bind( 
             shader_model_font_uTexSceneDepth,
@@ -154,7 +155,8 @@ static void font3d_bind( font3d *font, enum font_shader shader,
 
       shader_model_font_uPv( cam->mtx.pv );
    }
-   else if( shader == k_font_shader_world ){
+   else if( shader == k_font_shader_world )
+   {
       shader_scene_font_use();
       shader_scene_font_uTexGarbage(0);
       shader_scene_font_uTexMain(1);
index 75298a2d952e59009e1d73ff1425d26fe802c147..bcd332b11a5dcdddbd7cbc1d45fd70a8826dbebe 100644 (file)
Binary files a/maps_src/dev_hub/main.mdl and b/maps_src/dev_hub/main.mdl differ
index 4fac47a698abb8e9c1c64d38fe0a370c2532788f..2ec47c5b0e5dd98e96993f11f29c1cc9aafd8173 100644 (file)
Binary files a/maps_src/dev_tutorial/main.mdl and b/maps_src/dev_tutorial/main.mdl differ
diff --git a/models_src/slowmos.mdl b/models_src/slowmos.mdl
new file mode 100644 (file)
index 0000000..90d508f
Binary files /dev/null and b/models_src/slowmos.mdl differ
diff --git a/models_src/volc_flight.mdl b/models_src/volc_flight.mdl
new file mode 100644 (file)
index 0000000..02a7c78
Binary files /dev/null and b/models_src/volc_flight.mdl differ
index b11eacb1777618a4d66740358ebf939cec038b89..bbe76ea7de91ba1491913f8db0ce696362155d39 100644 (file)
--- a/player.c
+++ b/player.c
@@ -296,10 +296,10 @@ void player__clean_refs(void)
 
    world_static.challenge_target = NULL;
    world_static.challenge_timer = 0.0f;
-   world_static.focused_entity = 0;
    world_static.active_trigger_volume_count = 0;
    world_static.last_use = 0.0;
-   world_entity_unfocus();
+   world_entity_exit_modal();
+   world_entity_clear_focus();
 
    localplayer.boundary_hash ^= NETMSG_BOUNDARY_BIT;
 
index e1961b91a984cf0f9cc096d3895d6cc17f0b141b..6ab378d6039d8317ea3cbdc774a7c9bb168f4155 100644 (file)
@@ -68,7 +68,7 @@ void player__cam_iterate(void)
    if( localplayer.subsystem == k_player_subsystem_walk ){
       v3_copy( (v3f){-0.1f,1.8f,0.0f}, cc->fpv_viewpoint );
       v3_copy( (v3f){0.0f,0.0f,0.0f}, cc->fpv_offset );
-      v3_copy( (v3f){0.0f,1.4f,0.0f}, cc->tpv_offset );
+      v3_copy( (v3f){0.0f,1.8f,0.0f}, cc->tpv_offset );
    }
    else if( localplayer.subsystem == k_player_subsystem_glide ){
       v3_copy( (v3f){-0.15f,1.75f,0.0f}, cc->fpv_viewpoint );
@@ -224,6 +224,18 @@ void player__cam_iterate(void)
 
    v3_add( tpv_origin, tpv_offset, tpv_pos );
 
+#if 0
+   if( localplayer.subsystem == k_player_subsystem_walk )
+   {
+      v3f fwd, right;
+      v3_angles_vector( localplayer.angles, fwd );
+      v3_cross( fwd, (v3f){0,1.001f,0}, right );
+      right[1] = 0.0f;
+      v3_normalize( right );
+      v3_muladds( tpv_pos, right, 0.5f, tpv_pos );
+   }
+#endif
+
    /* 
     * Blend cameras 
     */
index f7339373869924086ceb02272a80b1af9a01da89..06070dea88000fdd65aa12cf56bd148099218faf 100644 (file)
@@ -595,8 +595,7 @@ void player_glide_render( vg_camera *cam, world_instance *world,
    shader_model_board_view_uTexMain( 0 );
    shader_model_board_view_uCamera( cam->transform[3] );
    shader_model_board_view_uPv( cam->mtx.pv );
-
-   shader_model_board_view_uDepthCompare(1);
+   shader_model_board_view_uDepthMode(1);
    depth_compare_bind(
       shader_model_board_view_uTexSceneDepth,
       shader_model_board_view_uInverseRatioDepth,
index 689f7a8b7345684398f3d23719573dc83374c99b..15dec10523bb7b2a0bd528c29ed755a081dedba8 100644 (file)
@@ -438,13 +438,14 @@ void render_board( vg_camera *cam, world_instance *world,
    glActiveTexture( GL_TEXTURE0 );
    glBindTexture( GL_TEXTURE_2D, board->mdl.texture );
 
-   if( shader == k_board_shader_player ){
+   if( shader == k_board_shader_player )
+   {
       shader_model_board_view_use();
       shader_model_board_view_uTexMain( 0 );
       shader_model_board_view_uCamera( cam->transform[3] );
       shader_model_board_view_uPv( cam->mtx.pv );
 
-      shader_model_board_view_uDepthCompare(1);
+      shader_model_board_view_uDepthMode(1);
       depth_compare_bind(
          shader_model_board_view_uTexSceneDepth,
          shader_model_board_view_uInverseRatioDepth,
@@ -453,7 +454,8 @@ void render_board( vg_camera *cam, world_instance *world,
 
       WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_board_view );
    }
-   else if( shader == k_board_shader_entity ){
+   else if( shader == k_board_shader_entity )
+   {
       shader_model_entity_use();
       shader_model_entity_uTexMain( 0 );
       shader_model_entity_uCamera( cam->transform[3] );
@@ -556,9 +558,9 @@ void render_playermodel( vg_camera *cam, world_instance *world,
    shader_model_character_view_uTexMain( 0 );
    shader_model_character_view_uCamera( cam->transform[3] );
    shader_model_character_view_uPv( cam->mtx.pv );
-
-   shader_model_character_view_uDepthCompare( depth_compare );
-   if( depth_compare ){
+   shader_model_character_view_uDepthMode( depth_compare );
+   if( depth_compare )
+   {
       depth_compare_bind(
          shader_model_character_view_uTexSceneDepth,
          shader_model_character_view_uInverseRatioDepth,
index 11ff6ae8348e88bfda5862532b2905de5bf84344..7014c778afcdba4d3d0b49e465923e9f2b64d994 100644 (file)
@@ -3551,7 +3551,8 @@ void player__skate_reset_animator(void){
       player_skate.animator.fly = 0.0f;
 }
 
-void player__skate_clear_mechanics(void){
+void player__skate_clear_mechanics(void)
+{
    struct player_skate_state *state = &player_skate.state;
    state->jump_charge    = 0.0f;
    state->charging_jump  = 0;
@@ -3586,6 +3587,9 @@ void player__skate_clear_mechanics(void){
    v3_copy( localplayer.rb.to_world[1], player_skate.surface_picture );
    v3_copy( localplayer.rb.co, state->prev_pos );
    v3_zero( player_skate.weight_distribution );
+
+   v3f head = { 0.0f, 1.8f, 0.0f };
+   m4x3_mulv( localplayer.rb.to_world, head, state->head_position );
 }
 
 #include "network_compression.h"
index ae11b8bd900b8f31b9457c47322930ec35407747..0050f943f4773cf0ea42b311f8e991bac3ba3956 100644 (file)
--- a/render.c
+++ b/render.c
@@ -472,6 +472,8 @@ static void async_render_init( void *payload, u32 size )
 
       0.00f,0.00f, 1.00f,rh,     0.00f,rh,    /* fsquad1 */
       0.00f,0.00f, 1.00f,0.00f,  1.00f,rh,
+      0.00f,1.00f, 0.00f,1.0f-rh,1.00f,1.0f-rh,
+      0.00f,1.00f, 1.00f,1.0f-rh,1.00f,1.0f,   
 
       /* 9x9 debug grid */
       /* row0 */
@@ -545,13 +547,13 @@ void render_fsquad(void)
 void render_fsquad1(void)
 {
    glBindVertexArray( gpipeline.fsquad.vao );
-   glDrawArrays( GL_TRIANGLES, 6, 6 );
+   glDrawArrays( GL_TRIANGLES, 6, 6+6 );
 }
 
 void render_fsquad2(void)
 {
    glBindVertexArray( gpipeline.fsquad.vao );
-   glDrawArrays( GL_TRIANGLES, 66,6 );
+   glDrawArrays( GL_TRIANGLES, 66+6,6 );
 }
 
 /*
index 5e02144f17b8a18b8f09b7537a4e1cfa8e006966..c03b8f76e7a7b20a69fa1cba7020a5ba6eba793a 100644 (file)
@@ -1,15 +1,18 @@
 uniform sampler2D uTexSceneDepth;
 uniform vec3 uInverseRatioDepth;
 uniform vec3 uInverseRatioMain;
-uniform bool uDepthCompare;
+uniform int uDepthMode;
+uniform float uDitherCutoff;
 
 float linear_depth( float depth, float near, float far ) {
    float z = depth * 2.0 - 1.0;
    return (2.0 * near * far) / (far + near - z * (far - near));        
 }
 
-void depth_compare_dither(){
-   if( uDepthCompare ){
+void depth_compare_dither()
+{
+   if( uDepthMode == 1 )
+   {
       vec2 back_coord = gl_FragCoord.xy * uInverseRatioMain.xy 
                                         * uInverseRatioDepth.xy;
       float back_depth = texture( uTexSceneDepth, back_coord ).r;
@@ -25,4 +28,12 @@ void depth_compare_dither(){
       if( step(0.0,diff)+dither<0.3 )
          discard;
    }
+
+   if( uDepthMode == 2 )
+   {
+      vec2 ssuv = gl_FragCoord.xy;
+      vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );
+      float dither = fract( vDither.g / 71.0 );
+      if( dither<uDitherCutoff ) discard;
+   }
 }
index 0bc64bb9d19dfde3955c2ce1fb22ab3b5d901c1c..01e1b84ebd047bc3ffe6aa2554df9161d4808ebd 100644 (file)
@@ -9084,15 +9084,18 @@ struct vg_shader _shader_model_character_view = {
 "uniform sampler2D uTexSceneDepth;\n"
 "uniform vec3 uInverseRatioDepth;\n"
 "uniform vec3 uInverseRatioMain;\n"
-"uniform bool uDepthCompare;\n"
+"uniform int uDepthMode;\n"
+"uniform float uDitherCutoff;\n"
 "\n"
 "float linear_depth( float depth, float near, float far ) {\n"
 "   float z = depth * 2.0 - 1.0;\n"
 "   return (2.0 * near * far) / (far + near - z * (far - near));       \n"
 "}\n"
 "\n"
-"void depth_compare_dither(){\n"
-"   if( uDepthCompare ){\n"
+"void depth_compare_dither()\n"
+"{\n"
+"   if( uDepthMode == 1 )\n"
+"   {\n"
 "      vec2 back_coord = gl_FragCoord.xy * uInverseRatioMain.xy \n"
 "                                        * uInverseRatioDepth.xy;\n"
 "      float back_depth = texture( uTexSceneDepth, back_coord ).r;\n"
@@ -9108,6 +9111,14 @@ struct vg_shader _shader_model_character_view = {
 "      if( step(0.0,diff)+dither<0.3 )\n"
 "         discard;\n"
 "   }\n"
+"\n"
+"   if( uDepthMode == 2 )\n"
+"   {\n"
+"      vec2 ssuv = gl_FragCoord.xy;\n"
+"      vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+"      float dither = fract( vDither.g / 71.0 );\n"
+"      if( dither<uDitherCutoff ) discard;\n"
+"   }\n"
 "}\n"
 "\n"
 "#line     14        0 \n"
@@ -9219,7 +9230,8 @@ GLuint _uniform_model_character_view_uLightsIndex;
 GLuint _uniform_model_character_view_uTexSceneDepth;
 GLuint _uniform_model_character_view_uInverseRatioDepth;
 GLuint _uniform_model_character_view_uInverseRatioMain;
-GLuint _uniform_model_character_view_uDepthCompare;
+GLuint _uniform_model_character_view_uDepthMode;
+GLuint _uniform_model_character_view_uDitherCutoff;
 #include "shaders/model_board_view.h"
 struct vg_shader _shader_model_board_view = {
    .name = "model_board_view",
@@ -9656,15 +9668,18 @@ struct vg_shader _shader_model_board_view = {
 "uniform sampler2D uTexSceneDepth;\n"
 "uniform vec3 uInverseRatioDepth;\n"
 "uniform vec3 uInverseRatioMain;\n"
-"uniform bool uDepthCompare;\n"
+"uniform int uDepthMode;\n"
+"uniform float uDitherCutoff;\n"
 "\n"
 "float linear_depth( float depth, float near, float far ) {\n"
 "   float z = depth * 2.0 - 1.0;\n"
 "   return (2.0 * near * far) / (far + near - z * (far - near));       \n"
 "}\n"
 "\n"
-"void depth_compare_dither(){\n"
-"   if( uDepthCompare ){\n"
+"void depth_compare_dither()\n"
+"{\n"
+"   if( uDepthMode == 1 )\n"
+"   {\n"
 "      vec2 back_coord = gl_FragCoord.xy * uInverseRatioMain.xy \n"
 "                                        * uInverseRatioDepth.xy;\n"
 "      float back_depth = texture( uTexSceneDepth, back_coord ).r;\n"
@@ -9680,6 +9695,14 @@ struct vg_shader _shader_model_board_view = {
 "      if( step(0.0,diff)+dither<0.3 )\n"
 "         discard;\n"
 "   }\n"
+"\n"
+"   if( uDepthMode == 2 )\n"
+"   {\n"
+"      vec2 ssuv = gl_FragCoord.xy;\n"
+"      vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+"      float dither = fract( vDither.g / 71.0 );\n"
+"      if( dither<uDitherCutoff ) discard;\n"
+"   }\n"
 "}\n"
 "\n"
 "#line     14        0 \n"
@@ -9792,7 +9815,8 @@ GLuint _uniform_model_board_view_uLightsIndex;
 GLuint _uniform_model_board_view_uTexSceneDepth;
 GLuint _uniform_model_board_view_uInverseRatioDepth;
 GLuint _uniform_model_board_view_uInverseRatioMain;
-GLuint _uniform_model_board_view_uDepthCompare;
+GLuint _uniform_model_board_view_uDepthMode;
+GLuint _uniform_model_board_view_uDitherCutoff;
 #include "shaders/model_entity.h"
 struct vg_shader _shader_model_entity = {
    .name = "model_entity",
@@ -10573,15 +10597,18 @@ struct vg_shader _shader_model_font = {
 "uniform sampler2D uTexSceneDepth;\n"
 "uniform vec3 uInverseRatioDepth;\n"
 "uniform vec3 uInverseRatioMain;\n"
-"uniform bool uDepthCompare;\n"
+"uniform int uDepthMode;\n"
+"uniform float uDitherCutoff;\n"
 "\n"
 "float linear_depth( float depth, float near, float far ) {\n"
 "   float z = depth * 2.0 - 1.0;\n"
 "   return (2.0 * near * far) / (far + near - z * (far - near));       \n"
 "}\n"
 "\n"
-"void depth_compare_dither(){\n"
-"   if( uDepthCompare ){\n"
+"void depth_compare_dither()\n"
+"{\n"
+"   if( uDepthMode == 1 )\n"
+"   {\n"
 "      vec2 back_coord = gl_FragCoord.xy * uInverseRatioMain.xy \n"
 "                                        * uInverseRatioDepth.xy;\n"
 "      float back_depth = texture( uTexSceneDepth, back_coord ).r;\n"
@@ -10597,6 +10624,14 @@ struct vg_shader _shader_model_font = {
 "      if( step(0.0,diff)+dither<0.3 )\n"
 "         discard;\n"
 "   }\n"
+"\n"
+"   if( uDepthMode == 2 )\n"
+"   {\n"
+"      vec2 ssuv = gl_FragCoord.xy;\n"
+"      vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+"      float dither = fract( vDither.g / 71.0 );\n"
+"      if( dither<uDitherCutoff ) discard;\n"
+"   }\n"
 "}\n"
 "\n"
 "#line     12        0 \n"
@@ -10618,7 +10653,8 @@ GLuint _uniform_model_font_uColour;
 GLuint _uniform_model_font_uTexSceneDepth;
 GLuint _uniform_model_font_uInverseRatioDepth;
 GLuint _uniform_model_font_uInverseRatioMain;
-GLuint _uniform_model_font_uDepthCompare;
+GLuint _uniform_model_font_uDepthMode;
+GLuint _uniform_model_font_uDitherCutoff;
 #include "shaders/particle.h"
 struct vg_shader _shader_particle = {
    .name = "particle",
@@ -11261,7 +11297,8 @@ void vg_auto_shader_link(void)
    _uniform_model_character_view_uTexSceneDepth = glGetUniformLocation( _shader_model_character_view.id, "uTexSceneDepth" );
    _uniform_model_character_view_uInverseRatioDepth = glGetUniformLocation( _shader_model_character_view.id, "uInverseRatioDepth" );
    _uniform_model_character_view_uInverseRatioMain = glGetUniformLocation( _shader_model_character_view.id, "uInverseRatioMain" );
-   _uniform_model_character_view_uDepthCompare = glGetUniformLocation( _shader_model_character_view.id, "uDepthCompare" );
+   _uniform_model_character_view_uDepthMode = glGetUniformLocation( _shader_model_character_view.id, "uDepthMode" );
+   _uniform_model_character_view_uDitherCutoff = glGetUniformLocation( _shader_model_character_view.id, "uDitherCutoff" );
    _uniform_model_board_view_uMdl = glGetUniformLocation( _shader_model_board_view.id, "uMdl" );
    _uniform_model_board_view_uPv = glGetUniformLocation( _shader_model_board_view.id, "uPv" );
    _uniform_model_board_view_uPvmPrev = glGetUniformLocation( _shader_model_board_view.id, "uPvmPrev" );
@@ -11273,7 +11310,8 @@ void vg_auto_shader_link(void)
    _uniform_model_board_view_uTexSceneDepth = glGetUniformLocation( _shader_model_board_view.id, "uTexSceneDepth" );
    _uniform_model_board_view_uInverseRatioDepth = glGetUniformLocation( _shader_model_board_view.id, "uInverseRatioDepth" );
    _uniform_model_board_view_uInverseRatioMain = glGetUniformLocation( _shader_model_board_view.id, "uInverseRatioMain" );
-   _uniform_model_board_view_uDepthCompare = glGetUniformLocation( _shader_model_board_view.id, "uDepthCompare" );
+   _uniform_model_board_view_uDepthMode = glGetUniformLocation( _shader_model_board_view.id, "uDepthMode" );
+   _uniform_model_board_view_uDitherCutoff = glGetUniformLocation( _shader_model_board_view.id, "uDitherCutoff" );
    _uniform_model_entity_uMdl = glGetUniformLocation( _shader_model_entity.id, "uMdl" );
    _uniform_model_entity_uPv = glGetUniformLocation( _shader_model_entity.id, "uPv" );
    _uniform_model_entity_uPvmPrev = glGetUniformLocation( _shader_model_entity.id, "uPvmPrev" );
@@ -11304,7 +11342,8 @@ void vg_auto_shader_link(void)
    _uniform_model_font_uTexSceneDepth = glGetUniformLocation( _shader_model_font.id, "uTexSceneDepth" );
    _uniform_model_font_uInverseRatioDepth = glGetUniformLocation( _shader_model_font.id, "uInverseRatioDepth" );
    _uniform_model_font_uInverseRatioMain = glGetUniformLocation( _shader_model_font.id, "uInverseRatioMain" );
-   _uniform_model_font_uDepthCompare = glGetUniformLocation( _shader_model_font.id, "uDepthCompare" );
+   _uniform_model_font_uDepthMode = glGetUniformLocation( _shader_model_font.id, "uDepthMode" );
+   _uniform_model_font_uDitherCutoff = glGetUniformLocation( _shader_model_font.id, "uDitherCutoff" );
    _uniform_particle_uPv = glGetUniformLocation( _shader_particle.id, "uPv" );
    _uniform_particle_uPvPrev = glGetUniformLocation( _shader_particle.id, "uPvPrev" );
    _uniform_trail_uPv = glGetUniformLocation( _shader_trail.id, "uPv" );
index 42eac9e604b089f3bdbe79e091c87ef51bdc417f..c5aa59a7b1ffb1abd1aa735064ca692503e7e862 100644 (file)
@@ -12,7 +12,8 @@ extern GLuint _uniform_model_board_view_uLightsIndex;
 extern GLuint _uniform_model_board_view_uTexSceneDepth;
 extern GLuint _uniform_model_board_view_uInverseRatioDepth;
 extern GLuint _uniform_model_board_view_uInverseRatioMain;
-extern GLuint _uniform_model_board_view_uDepthCompare;
+extern GLuint _uniform_model_board_view_uDepthMode;
+extern GLuint _uniform_model_board_view_uDitherCutoff;
 static inline void shader_model_board_view_uMdl(m4x3f m)
 {
    glUniformMatrix4x3fv(_uniform_model_board_view_uMdl,1,GL_FALSE,(f32*)m);
@@ -49,9 +50,13 @@ static inline void shader_model_board_view_uInverseRatioMain(v3f v)
 {
    glUniform3fv(_uniform_model_board_view_uInverseRatioMain,1,v);
 }
-static inline void shader_model_board_view_uDepthCompare(int b)
+static inline void shader_model_board_view_uDepthMode(int b)
 {
-   glUniform1i(_uniform_model_board_view_uDepthCompare,b);
+   glUniform1i(_uniform_model_board_view_uDepthMode,b);
+}
+static inline void shader_model_board_view_uDitherCutoff(f32 f)
+{
+   glUniform1f(_uniform_model_board_view_uDitherCutoff,f);
 }
 static inline void shader_model_board_view_use(void);
 static inline void shader_model_board_view_use(void)
index 9489520c51b8f1fc33e33cd257742570ce395e7a..40e27cbd853d3320173e3f3b4af36e3af0ee1417 100644 (file)
@@ -11,7 +11,8 @@ extern GLuint _uniform_model_character_view_uLightsIndex;
 extern GLuint _uniform_model_character_view_uTexSceneDepth;
 extern GLuint _uniform_model_character_view_uInverseRatioDepth;
 extern GLuint _uniform_model_character_view_uInverseRatioMain;
-extern GLuint _uniform_model_character_view_uDepthCompare;
+extern GLuint _uniform_model_character_view_uDepthMode;
+extern GLuint _uniform_model_character_view_uDitherCutoff;
 static inline void shader_model_character_view_uPv(m4x4f m)
 {
    glUniformMatrix4fv(_uniform_model_character_view_uPv,1,GL_FALSE,(f32*)m);
@@ -40,9 +41,13 @@ static inline void shader_model_character_view_uInverseRatioMain(v3f v)
 {
    glUniform3fv(_uniform_model_character_view_uInverseRatioMain,1,v);
 }
-static inline void shader_model_character_view_uDepthCompare(int b)
+static inline void shader_model_character_view_uDepthMode(int b)
 {
-   glUniform1i(_uniform_model_character_view_uDepthCompare,b);
+   glUniform1i(_uniform_model_character_view_uDepthMode,b);
+}
+static inline void shader_model_character_view_uDitherCutoff(f32 f)
+{
+   glUniform1f(_uniform_model_character_view_uDitherCutoff,f);
 }
 static inline void shader_model_character_view_use(void);
 static inline void shader_model_character_view_use(void)
index 8ba6c7a20bde0308ad1f116c644b453a1f1b400c..0b3fc25a02885e78c3737db4961663081d24b957 100644 (file)
@@ -10,7 +10,8 @@ extern GLuint _uniform_model_font_uColour;
 extern GLuint _uniform_model_font_uTexSceneDepth;
 extern GLuint _uniform_model_font_uInverseRatioDepth;
 extern GLuint _uniform_model_font_uInverseRatioMain;
-extern GLuint _uniform_model_font_uDepthCompare;
+extern GLuint _uniform_model_font_uDepthMode;
+extern GLuint _uniform_model_font_uDitherCutoff;
 static inline void shader_model_font_uMdl(m4x3f m)
 {
    glUniformMatrix4x3fv(_uniform_model_font_uMdl,1,GL_FALSE,(f32*)m);
@@ -47,9 +48,13 @@ static inline void shader_model_font_uInverseRatioMain(v3f v)
 {
    glUniform3fv(_uniform_model_font_uInverseRatioMain,1,v);
 }
-static inline void shader_model_font_uDepthCompare(int b)
+static inline void shader_model_font_uDepthMode(int b)
 {
-   glUniform1i(_uniform_model_font_uDepthCompare,b);
+   glUniform1i(_uniform_model_font_uDepthMode,b);
+}
+static inline void shader_model_font_uDitherCutoff(f32 f)
+{
+   glUniform1f(_uniform_model_font_uDitherCutoff,f);
 }
 static inline void shader_model_font_use(void);
 static inline void shader_model_font_use(void)
index 7d28c0adb5c3d28ab212f4f36fa547cf0eaa4f4a..d295ccfd04bae45c092dc22d1ce078efda7072d7 100644 (file)
@@ -298,7 +298,8 @@ void vg_pre_update(void)
    /* time rate */
    f32 target = 1;
    if( skaterift.activity & (k_skaterift_replay|k_skaterift_menu|
-                             k_skaterift_world_map) ){
+                             k_skaterift_world_map) )
+   {
       target = 0;
    }
 
@@ -307,8 +308,8 @@ void vg_pre_update(void)
    
    /* TODO: how can we compress this? */
    ent_miniworld_preupdate();
-   player__pre_update();
    world_entity_focus_preupdate();
+   player__pre_update();
    skaterift_replay_pre_update();
    remote_sfx_pre_update();
    skateshop_world_preupdate( world_current_instance() );
diff --git a/sound_src/gumpa-theme.ogg b/sound_src/gumpa-theme.ogg
new file mode 100644 (file)
index 0000000..60bdf82
Binary files /dev/null and b/sound_src/gumpa-theme.ogg differ
index 725c8989dda8b57f919849d31af3a0d9d9dd8da0..40d6d78a58acc7684fca56ee8495e35df4673320 100644 (file)
@@ -13,6 +13,7 @@
 #include "ent_traffic.h"
 #include "ent_glider.h"
 #include "ent_region.h"
+#include "ent_npc.h"
 #include "input.h"
 #include "player_walk.h"
 
@@ -26,24 +27,60 @@ bh_system bh_system_entity_list =
    .cast_ray = NULL
 };
 
-void world_entity_focus( u32 entity_id )
+void world_entity_set_focus( u32 entity_id )
+{
+   if( world_static.focused_entity )
+   {
+      vg_warn( "Entity %u#%u tried to take focus from %u#%u\n",
+                  mdl_entity_id_type( entity_id ),
+                  mdl_entity_id_id( entity_id ),
+                  mdl_entity_id_type( world_static.focused_entity ),
+                  mdl_entity_id_id( world_static.focused_entity ) );
+      return;
+   }
+
+   world_static.focused_entity = entity_id;
+}
+
+void world_entity_focus_modal(void)
 {
    localplayer.immobile = 1;
    menu.disable_open = 1;
+   srinput.state = k_input_state_resume;
 
    v3_zero( localplayer.rb.v );
    v3_zero( localplayer.rb.w );
    player_walk.move_speed = 0.0f;
-   world_static.focused_entity = entity_id;
    skaterift.activity = k_skaterift_ent_focus;
 }
 
-void world_entity_unfocus(void)
+void world_entity_exit_modal(void)
 {
+   if( skaterift.activity != k_skaterift_ent_focus )
+   {
+      vg_warn( "Entity %u#%u tried to exit modal when we weren't in one\n",
+                  mdl_entity_id_type( world_static.focused_entity ),
+                  mdl_entity_id_id( world_static.focused_entity ) );
+      return;
+   }
+
    localplayer.immobile = 0;
-   skaterift.activity = k_skaterift_default;
    menu.disable_open = 0;
    srinput.state = k_input_state_resume;
+   skaterift.activity = k_skaterift_default;
+}
+
+void world_entity_clear_focus(void)
+{
+   if( skaterift.activity == k_skaterift_ent_focus )
+   {
+      vg_warn( "Entity %u#%u tried to clear focus before exiting modal\n",
+                  mdl_entity_id_type( world_static.focused_entity ),
+                  mdl_entity_id_id( world_static.focused_entity ) );
+      return;
+   }
+
+   world_static.focused_entity = 0;
 }
 
 void world_entity_focus_camera( world_instance *world, u32 uid )
@@ -83,18 +120,26 @@ void world_entity_focus_preupdate(void)
    world_instance *world = world_current_instance();
 
    /* TODO: Table. */
-   if( type == k_ent_skateshop ){
+   if( type == k_ent_skateshop )
+   {
       ent_skateshop *skateshop = mdl_arritm( &world->ent_skateshop, index );
       ent_skateshop_preupdate( skateshop, active );
    }
-   else if( type == k_ent_challenge ){
+   else if( type == k_ent_challenge )
+   {
       ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
       ent_challenge_preupdate( challenge, active );
    }
-   else if( type == k_ent_route ){
+   else if( type == k_ent_route )
+   {
       ent_route *route = mdl_arritm( &world->ent_route, index );
       ent_route_preupdate( route, active );
    }
+   else if( type == k_ent_npc )
+   {
+      ent_npc *npc = mdl_arritm( &world->ent_npc, index );
+      ent_npc_preupdate( npc, active );
+   }
 }
 
 /* additional renderings like text etc.. */
@@ -116,6 +161,7 @@ void world_entity_focus_render(void)
    else if( type == k_ent_challenge ){}
    else if( type == k_ent_route ){}
    else if( type == k_ent_miniworld ){}
+   else if( type == k_ent_npc ){}
    else {
       vg_fatal_error( "Programming error\n" );
    }
@@ -380,20 +426,24 @@ void ent_audio_call( world_instance *world, ent_call *call )
             p   = clip->probability * mod;
 
       bar += p;
-      if( chance < bar ){
+      if( chance < bar )
+      {
          audio_lock();
 
-         if( audio->behaviour == k_channel_behaviour_unlimited ){
+         if( audio->behaviour == k_channel_behaviour_unlimited )
+         {
             audio_oneshot_3d( &clip->_.clip, sound_co,
                               audio->transform.s[0],
                               audio->volume );
          }
-         else if( audio->behaviour == k_channel_behaviour_discard_if_full ){
+         else if( audio->behaviour == k_channel_behaviour_discard_if_full )
+         {
             audio_channel *ch = 
                audio_get_group_idle_channel( audio->group, 
                                              audio->max_channels );
 
-            if( ch ){
+            if( ch )
+            {
                audio_channel_init( ch, &clip->_.clip, audio->flags );
                audio_channel_group( ch, audio->group );
                audio_channel_world( ch, world_id );
@@ -402,7 +452,8 @@ void ent_audio_call( world_instance *world, ent_call *call )
                ch = audio_relinquish_channel( ch );
             }
          }
-         else if( audio->behaviour == k_channel_behaviour_crossfade_if_full){
+         else if( audio->behaviour == k_channel_behaviour_crossfade_if_full)
+         {
             audio_channel *ch =
                audio_get_group_idle_channel( audio->group,
                                              audio->max_channels );
@@ -425,7 +476,8 @@ void ent_audio_call( world_instance *world, ent_call *call )
                ch = audio_get_first_idle_channel();
             }
 
-            if( ch ){
+            if( ch )
+            {
                audio_channel_init( ch, &clip->_.clip, audio->flags );
                audio_channel_group( ch, audio->group );
                audio_channel_world( ch, world_id );
@@ -680,9 +732,11 @@ void world_entity_start( world_instance *world, vg_msg *sav )
    vg_info( "Start instance %p\n", world );
 
    world->probabilities[ k_probability_curve_constant ] = 1.0f;
-   for( u32 i=0; i<mdl_arrcount(&world->ent_audio); i++ ){
+   for( u32 i=0; i<mdl_arrcount(&world->ent_audio); i++ )
+   {
       ent_audio *audio = mdl_arritm(&world->ent_audio,i);
-      if( audio->flags & AUDIO_FLAG_AUTO_START ){
+      if( audio->flags & AUDIO_FLAG_AUTO_START )
+      {
          ent_call call;
          call.data = NULL;
          call.function = k_ent_function_trigger;
index df5cbfadac5c3dc1cb25490652d56352720ec32e..f9a3ec9447212b8428b743dd7e1fb681432636a3 100644 (file)
@@ -24,10 +24,14 @@ void entity_bh_debug( void *user, u32 item_index );
 void entity_bh_closest( void *user, u32 item_index, v3f point,
                            v3f closest );
 
-void world_entity_focus( u32 entity_id );
+void world_entity_set_focus( u32 entity_id );
+void world_entity_focus_modal(void);
+
+void world_entity_exit_modal(void);
+void world_entity_clear_focus(void);
+
 void world_entity_focus_preupdate(void);
 void world_entity_focus_render(void);
-void world_entity_unfocus();
 void world_entity_focus_camera( world_instance *world, u32 uid );
 void update_ach_models(void);