remote items test
[carveJwlIkooP6JGAAIwe30JlM.git] / player_remote.c
index 4989b078c803cf77bc185bec583cfb04c6e8204f..3d674bcda2257d37a645b802818b39ee3006000b 100644 (file)
@@ -1,6 +1,8 @@
 #include "player_remote.h"
 #include "skeleton.h"
 #include "player_render.h"
+#include "network_common.h"
+#include "addon.h"
 
 static void player_remote_unwatch( struct network_player *player ){
    addon_cache_unwatch( k_addon_type_player, player->playermodel_view_slot );
@@ -14,14 +16,6 @@ static void player_remote_clear( struct network_player *player ){
    player->subsystem = k_player_subsystem_invalid;
 }
 
-static void player_remote_clear_interp( u32 index ){
-   struct interp_buffer *buf = &netplayers.interp_data[ index ];
-   buf->t = -99999999.9;
-   for( u32 i=0; i<vg_list_size(buf->frames); i ++ ){
-      buf->frames[i].active = 0;
-   }
-}
-
 static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){
    netmsg_blank *tmp = msg->m_pData;
 
@@ -37,13 +31,21 @@ static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){
          /* TODO: interpret the uids */
          player->board_view_slot = 0;
          player->playermodel_view_slot = 0;
-         player_remote_clear_interp( playerjoin->index );
-
-         vg_strncpy( playerjoin->username, player->username, 
-                     sizeof(player->username), k_strncpy_always_add_null );
+#if 0
+            addon_cache_create_viewer_from_uid( k_addon_type_board, 
+                                                playerjoin->board_uid );
+         player->playermodel_view_slot = 
+            addon_cache_create_viewer_from_uid( k_addon_type_player,
+                                                playerjoin->playermodel_uid );
+#endif
+
+         struct interp_buffer *buf = &netplayers.interp_data[playerjoin->index];
+         buf->t = -99999999.9;
+         for( u32 i=0; i<vg_list_size(buf->frames); i ++ ){
+            buf->frames[i].active = 0;
+         }
 
-         vg_info( "#%u joined with name: %s\n", 
-                  playerjoin->index, player->username );
+         vg_info( "#%u joined\n", playerjoin->index );
       }
       else {
          vg_error( "inetmsg_playerjoin: player index out of range\n" );
@@ -69,10 +71,11 @@ static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){
 
       if( update->index < vg_list_size(netplayers.list) ){
          struct network_player *player = &netplayers.list[ update->index ];
-         vg_strncpy( update->username, player->username, 
-                     sizeof(player->username), k_strncpy_always_add_null );
 
-         vg_info( "#%u changed username: %s\n", player->username );
+         network_msgstring( update->name, msg->m_cbSize, sizeof(*update),
+                            player->username, sizeof(player->username) );
+
+         vg_info( "#%u changed username to: %s\n", player->username );
       }
       else {
          vg_error( "inetmsg_playerleave: player index out of range\n" );
@@ -124,8 +127,36 @@ static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){
       player->subsystem = frame->subsystem;
       player->down_bytes += msg->m_cbSize;
    }
+   else if( tmp->inetmsg_id == k_inetmsg_playeritem ){
+      netmsg_playeritem *item = msg->m_pData;
+      if( !packet_minsize( msg, sizeof(*item)+1 )) return;
+
+      vg_info( "Client #%u equiped: [%u] %s\n", 
+               item->client, item->type, item->uid );
+
+      struct network_player *player = &netplayers.list[ item->client ];
+
+      char uid[ ADDON_UID_MAX ];
+      network_msgstring( item->uid, msg->m_cbSize, sizeof(*item),
+                         uid, ADDON_UID_MAX );
+
+      if( item->type == k_addon_type_board ){
+         addon_cache_unwatch( k_addon_type_board, player->board_view_slot );
+         player->board_view_slot = 
+            addon_cache_create_viewer_from_uid( k_addon_type_board, uid );
+      }
+      else if( item->type == k_addon_type_player ){
+         addon_cache_unwatch( k_addon_type_player, 
+                              player->playermodel_view_slot );
+         player->playermodel_view_slot =
+            addon_cache_create_viewer_from_uid( k_addon_type_player, uid );
+      }
+   }
 }
 
+/*
+ * Write localplayer pose to network
+ */
 static void remote_player_send_playerframe(void){
    u8 sysid = localplayer.subsystem;
    if( sysid >= k_player_subsystem_max ) return;
@@ -150,6 +181,9 @@ static void remote_player_send_playerframe(void){
    }
 }
 
+/*
+ * Updates network traffic stats
+ */
 static void remote_player_debug_update(void){
    if( (vg.time_real - netplayers.last_data_measurement) > 1.0 ){
       netplayers.last_data_measurement = vg.time_real;
@@ -170,6 +204,9 @@ static void remote_player_debug_update(void){
    }
 }
 
+/*
+ * Debugging information
+ */
 static void remote_player_network_imgui( m4x4f pv ){
    if( !network_client.network_info ) 
       return;
@@ -253,6 +290,9 @@ static void remote_player_network_imgui( m4x4f pv ){
    }
 }
 
+/*
+ * write the remote players final_mtx 
+ */
 static void pose_remote_player( u32 index, 
                                 struct interp_frame *f0,
                                 struct interp_frame *f1 ){
@@ -276,15 +316,7 @@ static void pose_remote_player( u32 index,
       sys1 = player_subsystems[f1->subsystem];
       sys1->pose( &f1->data, &pose1 );
 
-      if( pose0.type != pose1.type ){
-         /* it would be nice to apply IK pass in-keyframes. TOO BAD! */
-         skeleton_copy_pose( sk, pose0.keyframes, posed.keyframes );
-      }
-      else {
-         skeleton_lerp_pose( sk, pose0.keyframes, pose1.keyframes, t, 
-                             posed.keyframes );
-      }
-
+      lerp_player_pose( &pose0, &pose1, t, &posed );
       apply_full_skeleton_pose( &av->sk, &posed, final_mtx );
    }
    else {
@@ -292,10 +324,16 @@ static void pose_remote_player( u32 index,
    }
 }
 
+/* 
+ * animate remote player and store in final_mtx
+ */
 static void animate_remote_player( u32 index ){
 
-   f64 min_time =  999999999.9,
-       max_time = -999999999.9,
+   /*
+    * Trys to keep the cursor inside the buffer
+    */
+   f64 min_time = -999999999.9,
+       max_time =  999999999.9,
        abs_max_time = -999999999.9;
 
    struct interp_frame *minframe = NULL,
@@ -307,12 +345,12 @@ static void animate_remote_player( u32 index ){
       struct interp_frame *ifr = &buf->frames[i];
 
       if( ifr->active ){
-         if( (ifr->timestamp < min_time) && (ifr->timestamp > buf->t) ){
+         if( (ifr->timestamp > min_time) && (ifr->timestamp < buf->t) ){
             min_time = ifr->timestamp;
             minframe = ifr;
          }
 
-         if( (ifr->timestamp > max_time) && (ifr->timestamp < buf->t) ){
+         if( (ifr->timestamp < max_time) && (ifr->timestamp > buf->t) ){
             max_time = ifr->timestamp;
             maxframe = ifr;
          }
@@ -322,7 +360,7 @@ static void animate_remote_player( u32 index ){
             abs_max_frame = ifr;
          }
       }
-   }  
+   } 
    
    if( minframe && maxframe ){
       pose_remote_player( index, minframe, maxframe );
@@ -337,3 +375,52 @@ static void animate_remote_player( u32 index ){
          return;
    }
 }
+
+/*
+ * Update full final_mtx for all remote players
+ */
+static void animate_remote_players(void){
+   for( u32 i=0; i<vg_list_size(netplayers.list); i ++ ){
+      struct network_player *player = &netplayers.list[i];
+      if( !player->active ) continue;
+
+      animate_remote_player( i );
+   }
+}
+
+/*
+ * Draw remote players
+ */
+static void render_remote_players( world_instance *world, camera *cam ){
+
+   SDL_AtomicLock( &addon_system.sl_cache_using_resources );
+
+   for( u32 i=0; i<vg_list_size(netplayers.list); i ++ ){
+      struct network_player *player = &netplayers.list[i];
+      if( !player->active ) continue;
+      
+      struct player_avatar *av = localplayer.playeravatar;
+      m4x3f *final_mtx = &netplayers.final_mtx[ av->sk.bone_count*i ];
+
+      struct player_model *model = 
+         addon_cache_item_if_loaded( k_addon_type_player, 
+                                     player->playermodel_view_slot );
+
+      if( !model ) model = &localplayer.fallback_model;
+      render_playermodel( cam, world, 0, model, &av->sk, final_mtx );
+
+      struct player_board *board = 
+         addon_cache_item_if_loaded( k_addon_type_board,
+                                     player->board_view_slot );
+
+      /* TODO: Board pose */
+#if 0
+      render_board( cam, world, board, 
+                     final_mtx[localplayer.playeravatar->id_board],
+                     &localplayer.pose.board,
+                     k_board_shader_player );
+#endif
+   }
+
+   SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
+}