menu stuff
authorhgn <hgodden00@gmail.com>
Thu, 20 Oct 2022 10:38:40 +0000 (11:38 +0100)
committerhgn <hgodden00@gmail.com>
Thu, 20 Oct 2022 10:38:40 +0000 (11:38 +0100)
12 files changed:
camera.h [new file with mode: 0644]
main.c
menu.h
models_src/ch_jordan.mdl
models_src/ch_outlaw.mdl
models_src/rs_menu.mdl
player.h
player_audio.h
player_model.h
player_physics.h
shaders.sh
shaders/menu.h

diff --git a/camera.h b/camera.h
new file mode 100644 (file)
index 0000000..07205de
--- /dev/null
+++ b/camera.h
@@ -0,0 +1,26 @@
+#ifndef CAMERA_H
+#define CAMERA_H
+
+#include "common.h"
+
+static v2f camera_angles;
+static v3f camera_pos;
+
+static m4x3f camera_mtx,
+             camera_mtx_inverse;
+
+static void camera_update(void)
+{
+   /* Update camera matrices */
+   v4f qyaw, qpitch, qcam;
+   q_axis_angle( qyaw, (v3f){ 0.0f, 1.0f, 0.0f }, -camera_angles[0] );
+   q_axis_angle( qpitch, (v3f){ 1.0f, 0.0f, 0.0f }, -camera_angles[1] );
+
+   q_mul( qyaw, qpitch, qcam );
+   q_m3x3( qcam, camera_mtx );
+   v3_copy( camera_pos, camera_mtx[3] );
+
+   m4x3_invert_affine( camera_mtx, camera_mtx_inverse );
+}
+
+#endif /* CAMERA_H */
diff --git a/main.c b/main.c
index bbb4c321f310f8e297409801e3c3605c1874b2ae..61bd6dfcd15f94ad2dfbb8d6b672b11baa798eb0 100644 (file)
--- a/main.c
+++ b/main.c
@@ -29,8 +29,7 @@
 #include "network.h"
 #include "menu.h"
 
-static int cl_ui     = 1,
-           cl_menu   = 0;
+static int cl_ui     = 1;
 
 int main( int argc, char *argv[] )
 {
@@ -93,7 +92,7 @@ void vg_load(void)
 
 static void vg_start(void)
 {
-   player_load_model( "ch_jordan" );
+   player_load_model( "ch_jordan", 0 );
    reset_player( 1, (const char *[]){ "start" } );
 }
 
@@ -110,27 +109,17 @@ void vg_update( int loaded )
 
    if( loaded )
    {
-      if( vg_get_button_down( "menu" ) )
-      {
-         cl_menu = !cl_menu;
-      }
-
       draw_origin_axis();
       network_update();
 
-      if( !cl_menu )
-      {
-         player_update_pre();
-         world_update( player.phys.rb.co );
-      }
-
-      menu_update( cl_menu );
+      player_update_pre();
+      world_update( player.phys.rb.co );
    }
 }
 
 static void vg_update_fixed( int loaded )
 {
-   if( loaded && !cl_menu )
+   if( loaded )
    {
       player_update_fixed();
    }
@@ -138,9 +127,10 @@ static void vg_update_fixed( int loaded )
 
 static void vg_update_post( int loaded )
 {
-   if( loaded && !cl_menu )
+   if( loaded )
    {
       player_update_post();
+      menu_update();
    }
 }
 
@@ -153,27 +143,19 @@ static void vg_framebuffer_resize( int w, int h )
 
 static void render_main_game(void)
 {
-   v3f *active_cam_inv = NULL,
-       *active_cam     = NULL;
-
    m4x4f world_4x4;
+   m4x3_expand( camera_mtx_inverse, world_4x4 );
 
-   if( cl_menu )
-   {
-      active_cam = menu_cam;
-      active_cam_inv = menu_cam_inv;
-   }
-   else
-   {
-      active_cam_inv = player.camera_inverse;
-      active_cam = player.camera;
-   }
+   static float fov = 97.0f;
 
-   m4x3_expand( active_cam_inv, world_4x4 );
+   float fov_target = 108.0f;
+   if( player.phys.on_board )
+      fov_target = 125.0f;
 
-   static float fov = 97.0f;
-   float fov_target = (player.phys.on_board&&!cl_menu)? 125.0f: 108.0f;
-   fov = vg_lerpf( fov, fov_target, vg.time_delta * 2.0f );
+   if( cl_menu )
+      fov_target = menu_fov_target;
+
+   fov = vg_lerpf( fov, fov_target, vg.frame_delta * 2.0f );
 
    gpipeline.fov = freecam? 60.0f: fov; /* 120 */
    m4x4_projection( vg.pv, gpipeline.fov, 
@@ -189,18 +171,21 @@ static void render_main_game(void)
 
    int draw_solid = player.is_dead | freecam;
    
-   render_world( vg.pv, active_cam );
+   render_world( vg.pv, camera_mtx );
    if( draw_solid )
-      draw_player( active_cam );
+      draw_player( camera_mtx );
 
-   render_water_texture( active_cam );
+   render_water_texture( camera_mtx );
 
    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-   render_water_surface( vg.pv, active_cam );
-   render_world_gates( vg.pv, player.phys.rb.co, active_cam );
+   render_water_surface( vg.pv, camera_mtx );
+   render_world_gates( vg.pv, player.phys.rb.co, camera_mtx );
 
    if( cl_menu )
+   {
+      glClear( GL_DEPTH_BUFFER_BIT );
       menu_render( vg.pv );
+   }
    
    /* Copy the RGB of what we have into the background buffer */
    glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
@@ -223,9 +208,9 @@ static void render_main_game(void)
    {
       m4x4_projection( vg.pv, gpipeline.fov, 
             (float)vg.window_x / (float)vg.window_y, 
-            0.01f, 600.0f );
+            0.05f, 60.0f );
       m4x4_mul( vg.pv, world_4x4, vg.pv );
-      draw_player( active_cam );
+      draw_player( camera_mtx );
    }
 
    /* Draw back in the background
diff --git a/menu.h b/menu.h
index e062b30d7c0f69b1745810c9aae9841f8874b24b..d83538e8f28134f54331662178d14b6229cf8bcc 100644 (file)
--- a/menu.h
+++ b/menu.h
 
 static mdl_header *menu_model;
 static glmesh      menu_glmesh;
-static v3f         menu_cam_pos,
-                   menu_target_cam_pos;
-static v4f         menu_cam_q = { 0.0f, 0.0f, 0.0f, 1.0f },
-                   menu_target_cam_q;
-static m4x3f       menu_cam, menu_cam_inv;
+static m4x3f       menu_mdl_mtx;
 static float       menu_opacity = 0.0f;
+static float       menu_input_cooldown = 0.0f;
+static float       menu_fov_target = 97.0f;
+static v2f         menu_extra_angles;
+
+static int         menu_loc = 1,
+                   menu_loc_last = 1;
+static u32         menu_page     = 0;
+
+static int         cl_menu         = 0,
+                   cl_menu_go_away = 0;
+static int         cl_playermdl_id = 0;
+
+static const char *playermodels[] = { "ch_new", "ch_jordan", "ch_outlaw" };
+
+static void menu_btn_paused( int event );
+static void menu_btn_quit( int event );
+static void menu_btn_skater( int event );
+static void menu_btn_map( int event );
+static void menu_btn_map_a( int event );
+static void menu_btn_map_b( int event );
+static void menu_btn_map_c( int event );
+static void menu_btn_fuckoff( int event );
+
+struct menu_button
+{
+   const char *name;
+   u32 areas;
+
+   void (*fn_press)(int event);
+   int links[4];
+   mdl_node *pnode;
+
+   float falpha, fsize;
+}
+static menu_buttons[] = 
+{
+/*0*/{"text_paused",     1, menu_btn_paused },
+/*1*/{"text_quit",       9, menu_btn_quit,    {3,-1,4,2}},
+/*2*/{"text_skater",     3, menu_btn_skater,  {3,1,4,-1}},
+/*3*/{"text_map",        5, menu_btn_map, {-1,-1,2,-1}},
+/*4*/{"text_about_game", 1, NULL, {2,-1,-1,-1}},
+/*5*/{"skater_left",     2, NULL, {-1,-1,-1,-1}},
+/*6*/{"skater_right",    2, NULL, {-1,-1,-1,-1}},
+/*7*/{"map_a",           4, menu_btn_map_a,{8, -1, 9, 9 }},
+/*8*/{"map_b",           4, menu_btn_map_b,{-1,7,7,-1}},
+/*9*/{"map_c",           4, menu_btn_map_c,{7,7,-1,8}},
+/*a*/{"g_map",           5, NULL },
+/*b*/{"g_controls",      1, NULL },
+/*c*/{"text_quitty",     8, NULL },
+/*d*/{"text_yes",        8, menu_btn_fuckoff },
+};
+
+static void menu_btn_map_a( int event ){}
+static void menu_btn_map_b( int event ){}
+static void menu_btn_map_c( int event ){}
+
+static void menu_btn_paused( int event )
+{
+
+}
+
+static void menu_btn_fuckoff( int event )
+{
+   glfwSetWindowShouldClose( vg.window, 1 );
+}
+
+static void menu_btn_quit( int event )
+{
+   menu_page = 0x8;
+   menu_loc = 0xd;
+}
+
+static void menu_btn_map( int event )
+{
+   menu_page = 0x4;
+   menu_loc = 7;
+}
+
+static void menu_btn_skater( int event )
+{
+   menu_page = 0x2;
+}
 
 static void menu_init(void)
 {
@@ -24,6 +102,23 @@ static void menu_init(void)
    if( !menu_model )
       vg_fatal_exit_loop( "No menu model" );
 
+   for( int i=0; i<vg_list_size(menu_buttons); i++ )
+   {
+      struct menu_button *btn = &menu_buttons[i];
+      btn->pnode = mdl_node_from_name( menu_model, btn->name );
+
+      if( !btn->pnode )
+         vg_fatal_exit_loop( "Menu programming error" );
+   }
+
+   vg_convar_push( (struct vg_convar){
+      .name = "cl_playermdl_id",
+      .data = &cl_playermdl_id,
+      .data_type = k_convar_dtype_i32,
+      .opt_i32 = { .min=0, .max=2, .clamp=1 },
+      .persistent = 1
+   });
+
    vg_acquire_thread_sync();
    mdl_unpack_glmesh( menu_model, &menu_glmesh );
    vg_release_thread_sync();
@@ -31,54 +126,250 @@ static void menu_init(void)
    shader_menu_register();
 }
 
-static void menu_update( int enabled )
+static void menu_run_directional(void)
 {
-   static int enabled_last = 0;
+   struct menu_button *btn = &menu_buttons[ menu_loc ];
 
-   if( enabled && !enabled_last )
+   if( vg_get_button_down( "jump" ) )
    {
-      v3_copy( player.camera[3], menu_cam_pos );
-      m3x3_q( player.camera, menu_cam_q );
+      if( btn->fn_press )
+      {
+         btn->fn_press( 1 );
+         return;
+      }
+   }
+
+   if( menu_input_cooldown <= 0.0f )
+   {
+      v2f dir = { vg_get_axis( "lookh" ), vg_get_axis( "lookv" ) };
 
-      if( player.phys.on_board )
+      if( v2_length2( dir ) > 0.8f*0.8f )
       {
-         v4f r90;
-         q_axis_angle( r90, player.phys.rb.up, VG_PIf*-0.5f );
-         q_mul( r90, player.phys.rb.q, menu_target_cam_q );
-         m4x3_mulv( player.phys.rb.to_world, (v3f){-1.0f,1.6f,0.0f},
-                                             menu_target_cam_pos );
+         int idir = 0;
+
+         if( fabsf(dir[0]) > fabsf(dir[1]) )
+         {
+            if( dir[0] > 0.0f ) idir = 2;
+            else idir = 0;
+         }
+         else
+         {
+            if( dir[1] > 0.0f ) idir = 3;
+            else idir = 1;
+         }
+
+         int link = btn->links[idir];
+
+         if( link != -1 )
+         {
+            menu_loc_last = menu_loc;
+            menu_loc = link;
+            menu_input_cooldown = 0.25f;
+         }
+      }
+   }
+}
+
+static int menu_page_should_backout(void)
+{
+   return vg_get_button_down( "break" );
+}
+
+static void menu_close(void)
+{
+   cl_menu_go_away = 1;
+   menu_page = 0;
+}
+
+static void menu_page_main(void)
+{
+   if( menu_page_should_backout() )
+   {
+      menu_close();
+      return;
+   }
+
+   menu_fov_target = 112.0f;
+   menu_run_directional();
+}
+
+static void menu_page_map(void)
+{
+   if( menu_page_should_backout() )
+   {
+      menu_page = 1;
+      menu_loc = 3;
+   }
+
+   menu_fov_target = 80.0f;
+   menu_run_directional();
+}
+
+static void menu_page_quit(void)
+{
+   if( menu_page_should_backout() )
+   {
+      menu_page = 1;
+      menu_loc = 1;
+   }
+
+   menu_fov_target = 90.0f;
+   menu_run_directional();
+}
+
+static void menu_page_skater(void)
+{
+   float h = vg_get_axis( "lookh" );
+   menu_fov_target = 97.0f;
+
+   if( menu_page_should_backout() )
+   {
+      menu_page = 1;
+      menu_loc = 2;
+      return;
+   }
+
+   if( (fabsf(h) > 0.7f) && (menu_input_cooldown <= 0.0f) )
+   {
+      if( h < 0.0f )
+      {
+         cl_playermdl_id --;
+         if( cl_playermdl_id < 0 )
+            cl_playermdl_id = 2;
+
+         menu_buttons[5].fsize = 0.4f;
+         menu_buttons[5].falpha = 1.0f;
+
+         menu_input_cooldown = 0.25f;
+         player_load_model( playermodels[ cl_playermdl_id ], 1 );
+      }
+      else
+      {
+         cl_playermdl_id ++;
+         if( cl_playermdl_id > 2 )
+            cl_playermdl_id = 0;
+         
+         menu_buttons[6].fsize = 0.4f;
+         menu_buttons[6].falpha = 1.0f;
+
+         menu_input_cooldown = 0.25f;
+         player_load_model( playermodels[ cl_playermdl_id ], 1 );
+      }
+   }
+}
+
+static void menu_update(void)
+{
+   if( vg_get_button_down( "menu" ) )
+   {
+      if( cl_menu )
+      {
+         cl_menu_go_away = 1;
+         menu_page = 0;
+      }
+      else
+      {
+         cl_menu = 1;
+         menu_page = 1;
+      }
+   }
+
+   if( menu_page == 1 )
+      menu_page_main();
+   else if( menu_page == 2 )
+      menu_page_skater();
+   else if( menu_page == 4 )
+      menu_page_map();
+   else if( menu_page == 8 )
+      menu_page_quit();
+
+   struct menu_button *btn = &menu_buttons[ menu_loc ];
+
+   v3f pos;
+   v2f angles;
+
+   /* Base */
+   {
+      v3f lookdir;
+      v3f *mtx = player.mdl.sk.final_mtx[player.mdl.id_head];
+      m3x3_mulv( mtx, (v3f){-1.0f,0.0f,0.0f}, lookdir );
+
+      lookdir[1] = 0.0f;
+      v3_normalize( lookdir );
+
+      v3f center_rough;
+
+      if( player.is_dead )
+      {
+         v3_copy(player.mdl.ragdoll[ player.mdl.id_hip-1 ].rb.co, center_rough);
       }
       else
       {
-         v4f r180;
-         q_axis_angle( r180, player.phys.rb.up, VG_PIf );
-         q_mul( r180, player.phys.rb.q, menu_target_cam_q );
-         m4x3_mulv( player.phys.rb.to_world, (v3f){0.0f,1.6f,-1.0f},
-                                             menu_target_cam_pos );
+         v3_add( player.camera_pos, player.visual_transform[3], center_rough );
+         v3_muls( center_rough, 0.5f, center_rough );
       }
 
-      q_normalize( menu_target_cam_q );
-      q_normalize( menu_cam_q );
-      menu_opacity = 0.0f;
+      v3_muladds( center_rough, lookdir, 1.5f, pos );
+      v3_add( (v3f){ 0.0f,0.8f,0.0f}, pos, pos );
+
+      angles[1] = 0.0f;
+      angles[0] = -atan2f( lookdir[0], lookdir[2] );
+
+      /* setup model matrix */
+      v4f qmenu_mdl;
+      q_axis_angle( qmenu_mdl, (v3f){0.0f,1.0f,0.0f}, -angles[0] );
+
+      q_m3x3( qmenu_mdl, menu_mdl_mtx );
+      v3_copy( center_rough, menu_mdl_mtx[3] );
    }
 
-   if( enabled_last && !enabled )
+   /* Extra */
    {
-      m3x3_q( player.camera, menu_target_cam_q );
-      v3_copy( player.camera[3], menu_target_cam_pos );
+      v3f delta;
+      v3_sub( btn->pnode->co, (v3f){ 0.0f,1.5f,-1.5f }, delta );
+      v3_normalize( delta );
+
+      float y = atan2f( delta[0], delta[2] ),
+            p = -sinf(delta[1]),
+            dt = vg.frame_delta;
+
+      menu_extra_angles[0] = vg_lerpf( menu_extra_angles[0], y, dt );
+      menu_extra_angles[1] = vg_lerpf( menu_extra_angles[1], p, dt );
+
+      v2_muladds( angles, menu_extra_angles, 0.8f, angles );
+      angles[0] = fmodf( angles[0], VG_TAUf );
+   }
+   
+   /* Update camera */
+   {
+      camera_angles[0] = vg_alerpf( camera_angles[0], angles[0], menu_opacity );
+      camera_angles[1] = vg_lerpf ( camera_angles[1], angles[1], menu_opacity );
+      v3_lerp( camera_pos, pos, menu_opacity, camera_pos );
+      camera_update();
    }
 
-   float dt = vg.time_delta * 6.0f;
+   float dt = vg.frame_delta * 6.0f;
+   menu_opacity = vg_lerpf( menu_opacity, cl_menu&&!cl_menu_go_away, dt );
+
+   if( menu_opacity <= 0.01f )
+   {
+      cl_menu = 0;
+      cl_menu_go_away = 0;
+   }
 
-   q_nlerp( menu_cam_q, menu_target_cam_q, dt, menu_cam_q );
-   v3_lerp( menu_cam_pos, menu_target_cam_pos, dt, menu_cam_pos );
+   vg.time_rate = 1.0-(double)menu_opacity;
 
-   q_m3x3( menu_cam_q, menu_cam );
-   v3_copy( menu_cam_pos, menu_cam[3] );
-   m4x3_invert_affine( menu_cam, menu_cam_inv );
-   menu_opacity = vg_lerpf( menu_opacity, enabled, dt );
+   if( cl_menu )
+   {
+      menu_input_cooldown -= vg.frame_delta;
+   }
+}
 
-   enabled_last = enabled;
+/* https://iquilezles.org/articles/functions/ */
+float expSustainedImpulse( float x, float f, float k )
+{
+    float s = fmaxf(x-f,0.0f);
+    return fminf( x*x/(f*f), 1.0f+(2.0f/f)*s*expf(-k*s));
 }
 
 static void menu_render( m4x4f projection )
@@ -105,10 +396,43 @@ static void menu_render( m4x4f projection )
    shader_menu_uPv( projection );
    mesh_bind( &menu_glmesh );
 
-   m4x3_identity( mtx );
-   shader_menu_uMdl( mtx );
-   mesh_draw( &menu_glmesh );
+   for( int i=0; i<vg_list_size(menu_buttons); i++ )
+   {
+      struct menu_button *btn = &menu_buttons[i];
+      float talpha = i==menu_loc? 1.0f: 0.0f,
+            tsize0 = btn->areas & menu_page? 1.0f: 0.0f,
+            tsize1 = i==menu_loc? 0.07f: 0.0f,
+            tsize  = tsize0+tsize1;
+
+      btn->falpha = vg_lerpf( btn->falpha, talpha, vg.frame_delta * 14.0f );
+      btn->fsize  = vg_lerpf( btn->fsize,  tsize,  vg.frame_delta * 3.0f  );
+
+      /* Colour */
+      v4f vselected = {0.95f*1.3f,0.45f*1.3f,0.095f*1.3f, 1.0f},
+          vnormal   = {1.0f,1.0f,1.0f, 1.0f},
+          vcurrent;
 
+      v4_lerp( vnormal, vselected, btn->falpha, vcurrent );
+      shader_menu_uColour( vcurrent );
+
+      /* Create matrix */
+      m4x3f mtx_size;
+      mdl_node_transform( btn->pnode, mtx );
+      m4x3_mul( menu_mdl_mtx, mtx, mtx );
+      m4x3_identity( mtx_size );
+      m4x3_scale( mtx_size, expSustainedImpulse( btn->fsize, 0.5f, 8.7f) );
+      m4x3_mul( mtx, mtx_size, mtx );
+      shader_menu_uMdl( mtx );
+
+      for( int j=0; j<btn->pnode->submesh_count; j++ )
+      {
+         mdl_submesh *sm = 
+            mdl_submesh_from_id( menu_model, btn->pnode->submesh_start+j );
+         mdl_draw_submesh( sm );
+      }
+   }
+   
+   /*
    for( int i=0; i<menu_model->node_count; i++ )
    {
       mdl_node *pnode = mdl_node_from_id( menu_model, i );
@@ -119,12 +443,13 @@ static void menu_render( m4x4f projection )
             mdl_submesh_from_id( menu_model, pnode->submesh_start+j );
 
          mdl_node_transform( pnode, mtx );
-         m4x3_mul( player.phys.rb.to_world, mtx, mtx );
+         m4x3_mul( menu_mdl_mtx, mtx, mtx );
          shader_menu_uMdl( mtx );
 
          mdl_draw_submesh( sm );
       }
    }
+   */
 }
 
 static void menu_free(void *_)
index 3af60ac1f22eb24213dc6e4e6a060c3d6d805cb7..80482dc745b6766d2fefbdcfa937ac5611253d54 100644 (file)
Binary files a/models_src/ch_jordan.mdl and b/models_src/ch_jordan.mdl differ
index eb2aa3c1d89fda541a0b42ce58e15803ab9334d5..0fffc5ccd801b41564f3970d45b76d615c383ba9 100644 (file)
Binary files a/models_src/ch_outlaw.mdl and b/models_src/ch_outlaw.mdl differ
index a8524864eb40ae59fdd02312257d1729975b2874..160d37e2dca6b25ca9086728525b6478d340c7b6 100644 (file)
Binary files a/models_src/rs_menu.mdl and b/models_src/rs_menu.mdl differ
index 38c3224de7fd1ab06f2b4034c467ca23c6c3ed4d..c9502a32493d780a6504663af4423c78a3a38d63 100644 (file)
--- a/player.h
+++ b/player.h
@@ -89,7 +89,6 @@ static struct gplayer
    
    v3f camera_pos, smooth_localcam;
    v2f angles;
-   m4x3f camera, camera_inverse;
 
    /* animation */
    double jump_time;
@@ -284,11 +283,6 @@ static void player_update_fixed(void)                                    /* 2 */
    {
       player_do_motion();
    }
-
-   player_audio(); /* FUTURE: can probably move this to post()
-                              BUT, it uses deltas from fixed step physics,
-                              AND this *might* be what we want for realtime
-                              audio, anyway. */
 }
 
 static void player_update_post(void)
@@ -315,7 +309,12 @@ static void player_update_post(void)
    if( freecam )
       player_freecam();
 
-   player_camera_update();
+   /* CAMERA POSITIONING: LAYER 0 */
+   v2_copy( player.angles, camera_angles );
+   v3_copy( player.camera_pos, camera_pos );
+   camera_update();
+
+   player_audio();
 }
 
 static void draw_player( m4x3f cam )
index 757f495a1b761e3d94da2bafad365d5828cad33a..33a050a7d523457711f290c818bfcb4f71e2b3db 100644 (file)
@@ -39,13 +39,13 @@ static void player_audio(void)
    }
 
    static float air = 0.0f;
-   air = vg_lerpf(air, phys->in_air? 1.0f: 0.0f, 5.0f*VG_TIMESTEP_FIXED );
+   air = vg_lerpf( air, phys->in_air? 1.0f: 0.0f, 5.0f*vg.time_delta );
 
    /* Spacial info */
    v3f ears = { 1.0f,0.0f,0.0f };
    v3f delta;
 
-   float *cam = player.camera[3],
+   float *cam = camera_pos,
          *pos = phys->rb.co;
    
    audio_player_set_position( &audio_player0, phys->rb.co );
@@ -54,16 +54,16 @@ static void player_audio(void)
    audio_player_set_position( &audio_player_gate, world.render_gate_pos );
    audio_player_set_vol( &audio_player_gate, 5.0f );
 
-   v3_sub( phys->rb.co, player.camera[3], delta );
+   v3_sub( phys->rb.co, camera_pos, delta );
    v3_normalize( delta );
-   m3x3_mulv( player.camera, ears, ears );
+   m3x3_mulv( camera_mtx, ears, ears );
 
    /* TODO, Make function */
    v3_copy( ears, vg_audio.listener_ears );
-   v3_copy( player.camera[3], vg_audio.listener_pos );
+   v3_copy( camera_pos, vg_audio.listener_pos );
 
    /* Tunnel / occlusion */
-   audio_sample_occlusion( player.camera[3] );
+   audio_sample_occlusion( camera_pos );
 
    int sprite_avail = -1;
    for( int i=0; i<vg_list_size(ambient_sprites); i++ )
@@ -134,13 +134,13 @@ static void player_audio(void)
             vol1  =       air *attn,
             vol2  = (1.0f-air)*attn*slide;
       
-      audio_player_set_vol( &audio_player0, vol0 );
-      audio_player_set_vol( &audio_player1, vol1 );
-      audio_player_set_vol( &audio_player2, vol2 );
+      audio_player_set_vol( &audio_player0, vol0*vg.time_rate );
+      audio_player_set_vol( &audio_player1, vol1*vg.time_rate );
+      audio_player_set_vol( &audio_player2, vol2*vg.time_rate );
 
       float reverb_amt = vol0 * audio_occlusion_current * 0.5f;
       audio_player_set_pan( &audio_player3, 0.0f );
-      audio_player_set_vol( &audio_player3, reverb_amt );
+      audio_player_set_vol( &audio_player3, reverb_amt*vg.time_rate );
    }
    
 #if 0
index f2b375aa19988ba7391f5042cb67880ae8aa1ddf..4766c1695951653828931bc91c1a39fcc3478d96 100644 (file)
@@ -30,7 +30,7 @@ static void player_model_free(void *_)
 /*
  * Load model from file (.mdl)
  */
-static void player_load_model( const char *name )
+static void player_load_model( const char *name, int replace_mode )
 {
    char buf[64];
 
@@ -43,82 +43,87 @@ static void player_load_model( const char *name )
       return;
    }
 
-   struct player_model temp;
-
-   mdl_unpack_glmesh( src, &temp.mesh );
-   skeleton_setup( &temp.sk, src );
+   mesh_free( &player.mdl.mesh );
+   mdl_unpack_glmesh( src, &player.mdl.mesh );
 
-   /* 
-    * Link animations
-    */
-   struct _load_anim
+   if( !replace_mode )
    {
-      const char *name;
-      struct skeleton_anim **anim;
-   }
-   anims[] = {
-      { "pose_stand",   &temp.anim_stand },
-      { "pose_highg",   &temp.anim_highg },
-      { "pose_slide",   &temp.anim_slide },
-      { "pose_air",     &temp.anim_air   },
-      { "push",         &temp.anim_push  },
-      { "push_reverse", &temp.anim_push_reverse },
-      { "ollie",        &temp.anim_ollie },
-      { "ollie_reverse",&temp.anim_ollie_reverse },
-      { "grabs",        &temp.anim_grabs },
-      { "walk",         &temp.anim_walk  },
-      { "run",          &temp.anim_run   },
-      { "idle_cycle",   &temp.anim_idle  },
-      { "jump",         &temp.anim_jump  }
-   };
-   
-   for( int i=0; i<vg_list_size(anims); i++ )
-   {
-      *anims[i].anim = skeleton_get_anim( &temp.sk, anims[i].name );
-      
-      if( !(*anims[i].anim) )
+      if( !skeleton_setup( &player.mdl.sk, src ) )
       {
-         vg_error( "Animation '%s' is missing from character '%s'\n",
-                     anims[i].name, name );
-         vg_free( src );
-         return;
+         vg_error( "Model: %s\n", buf );
+         vg_fatal_exit_loop( "No skeleton" );
       }
-   }
 
-   /* 
-    * Link bones
-    */
-   struct _load_bone
-   {
-      const char *name;
-      u32 *bone_id;
-   }
-   bones[] = {
-      { "hips",      &temp.id_hip },
-      { "hand.IK.L", &temp.id_ik_hand_l },
-      { "hand.IK.R", &temp.id_ik_hand_r },
-      { "elbow.L",   &temp.id_ik_elbow_l },
-      { "elbow.R",   &temp.id_ik_elbow_r },
-      { "head",      &temp.id_head }
-   };
-
-   for( int i=0; i<vg_list_size(bones); i++ )
-   {
-      *bones[i].bone_id = skeleton_bone_id( &temp.sk, bones[i].name );
+      /* 
+       * Link animations
+       */
+      struct _load_anim
+      {
+         const char *name;
+         struct skeleton_anim **anim;
+      }
+      anims[] = {
+         { "pose_stand",   &player.mdl.anim_stand },
+         { "pose_highg",   &player.mdl.anim_highg },
+         { "pose_slide",   &player.mdl.anim_slide },
+         { "pose_air",     &player.mdl.anim_air   },
+         { "push",         &player.mdl.anim_push  },
+         { "push_reverse", &player.mdl.anim_push_reverse },
+         { "ollie",        &player.mdl.anim_ollie },
+         { "ollie_reverse",&player.mdl.anim_ollie_reverse },
+         { "grabs",        &player.mdl.anim_grabs },
+         { "walk",         &player.mdl.anim_walk  },
+         { "run",          &player.mdl.anim_run   },
+         { "idle_cycle",   &player.mdl.anim_idle  },
+         { "jump",         &player.mdl.anim_jump  }
+      };
+      
+      for( int i=0; i<vg_list_size(anims); i++ )
+      {
+         *anims[i].anim = skeleton_get_anim( &player.mdl.sk, anims[i].name );
+         
+         if( !(*anims[i].anim) )
+         {
+            vg_error( "Animation '%s' is missing from character '%s'\n",
+                        anims[i].name, name );
+            vg_free( src );
+            return;
+         }
+      }
 
-      if( !(*bones[i].bone_id) )
+      /* 
+       * Link bones
+       */
+      struct _load_bone
       {
-         vg_error( "Required bone '%s' is missing from character '%s'\n",
-                     bones[i].name, name );
-         vg_free( src );
-         return;
+         const char *name;
+         u32 *bone_id;
       }
+      bones[] = {
+         { "hips",      &player.mdl.id_hip },
+         { "hand.IK.L", &player.mdl.id_ik_hand_l },
+         { "hand.IK.R", &player.mdl.id_ik_hand_r },
+         { "elbow.L",   &player.mdl.id_ik_elbow_l },
+         { "elbow.R",   &player.mdl.id_ik_elbow_r },
+         { "head",      &player.mdl.id_head }
+      };
+
+      for( int i=0; i<vg_list_size(bones); i++ )
+      {
+         *bones[i].bone_id = skeleton_bone_id( &player.mdl.sk, bones[i].name );
+
+         if( !(*bones[i].bone_id) )
+         {
+            vg_error( "Required bone '%s' is missing from character '%s'\n",
+                        bones[i].name, name );
+            vg_free( src );
+            return;
+         }
+      }
+
+      player_init_ragdoll( src );
    }
 
-   /* swap temp into actual model */
-   mesh_free( &player.mdl.mesh );
-   player.mdl = temp;
-   player_init_ragdoll( src );
    vg_free( src );
 }
 
index 8d0b5b88ad3262f61da46b71804c3eaa9f616ec2..bc1434c66f801f8e37881ee4ab68c91634a4079f 100644 (file)
@@ -6,6 +6,7 @@
 #define PLAYER_PHYSICS_H
 
 #include "player.h"
+#include "camera.h"
 
 static void apply_gravity( v3f vel, float const timestep )
 {
@@ -730,8 +731,8 @@ static void player_freecam(void)
    v3f lookdir = { 0.0f, 0.0f, -1.0f },
        sidedir = { 1.0f, 0.0f,  0.0f };
    
-   m3x3_mulv( player.camera, lookdir, lookdir );
-   m3x3_mulv( player.camera, sidedir, sidedir );
+   m3x3_mulv( camera_mtx, lookdir, lookdir );
+   m3x3_mulv( camera_mtx, sidedir, sidedir );
    
    static v3f move_vel = { 0.0f, 0.0f, 0.0f };
    if( vg_get_button( "forward" ) )
@@ -747,20 +748,6 @@ static void player_freecam(void)
    v3_add( move_vel, player.camera_pos, player.camera_pos );
 }
 
-static void player_camera_update(void)
-{
-   /* Update camera matrices */
-   v4f qyaw, qpitch, qcam;
-   q_axis_angle( qyaw, (v3f){ 0.0f, 1.0f, 0.0f }, -player.angles[0] ); 
-   q_axis_angle( qpitch, (v3f){ 1.0f, 0.0f, 0.0f }, -player.angles[1] ); 
-
-   q_mul( qyaw, qpitch, qcam );
-   q_m3x3( qcam, player.camera );
-
-   v3_copy( player.camera_pos, player.camera[3] );
-   m4x3_invert_affine( player.camera, player.camera_inverse );
-}
-
 static int reset_player( int argc, char const *argv[] )
 {
    struct player_phys *phys = &player.phys;
index 4d78657f0a5a50f990ffd09ed81a49c548673687..f2ca0d41cb36dddb7887d7fe650188f7a443457c 100755 (executable)
@@ -26,7 +26,7 @@ shader gatelq gate.vs gate_lq.fs
 shader route standard.vs route.fs
 shader routeui routeui.vs routeui.fs
 shader viewchar standard_skinned.vs viewchar.fs
-shader menu standard.vs unlit.fs
+shader menu standard.vs menu.fs
 
 cd shaders
 ../bin/linux/tools/shader $target_shaders
index 67700e8e908482467dbbf64894f1a1038db42eac..d0cd493d75ab63ba6643b4bb30f452cff2fff98a 100644 (file)
@@ -40,7 +40,7 @@ static struct vg_shader _shader_menu = {
 ""},
    .fs = 
 {
-.orig_file = "../../shaders/unlit.fs",
+.orig_file = "../../shaders/menu.fs",
 .static_src = 
 "out vec4 FragColor;\n"
 "\n"
@@ -54,8 +54,12 @@ static struct vg_shader _shader_menu = {
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 diffuse = texture( uTexMain, aUv ).rgb;\n"
-"   FragColor = vec4( diffuse, 1.0 );\n"
+"   vec4 diffuse = texture( uTexMain, aUv );\n"
+"\n"
+"   if( diffuse.a < 0.5 )\n"
+"      discard;\n"
+"\n"
+"   FragColor = vec4( diffuse.rgb, 1.0 ) * uColour;\n"
 "}\n"
 ""},
 };