refactor(1)
authorhgn <hgodden00@gmail.com>
Sat, 17 Jun 2023 13:45:38 +0000 (14:45 +0100)
committerhgn <hgodden00@gmail.com>
Sat, 17 Jun 2023 13:45:38 +0000 (14:45 +0100)
14 files changed:
addon.c
addon.h
ent_skateshop.c
ent_skateshop.h
player.h
player_common.c
player_common.h
player_render.c
player_render.h
player_skate.c
player_walk.c
save.c
skaterift.c
skaterift.h

diff --git a/addon.c b/addon.c
index d408654100b3d5c5a8a0d66c7e7a45993c59fe08..0346d01fc2d4b906fb915a6f7ded777220426ff0 100644 (file)
--- a/addon.c
+++ b/addon.c
@@ -73,6 +73,51 @@ static u32 addon_match( enum workshop_file_type type,
 static void addon_system_init( void ){
    u32 reg_size   = sizeof(addon_reg)*ADDON_MOUNTED_MAX;
    addon_system.registry = vg_linear_alloc( vg_mem.rtmemory, reg_size );
+
+   struct cache_inf {
+      size_t stride;
+      u32 count;
+   }
+   static cache_inf[] = {
+      [k_workshop_file_type_board] = { 
+         .stride = sizeof(struct player_board),
+         .count  = CACHE_BOARD_MAX 
+      },
+      [k_workshop_file_type_player] = {
+         .stride = sizeof(struct player_model),
+         .count  = CACHE_PLAYER_MAX
+      }
+   };
+
+   for( u32 i=0; i<vg_list_size(cache_inf); i++ ){
+      struct cache_inf *inf = &cache_inf[i];
+      struct addon_cache *cache = &addon_system.cache[i];
+
+      if( inf->count ){
+         /* create the allocations pool */
+         u32 alloc_size = sizeof(struct addon_cache_entry)*inf->count;
+         cache->allocs = vg_linear_alloc( vg_mem.rtmemory, alloc_size );
+         memset( cache->allocs, 0, alloc_size );
+
+         cache->pool.buffer = cache->allocs;
+         cache->pool.count  = inf->count;
+         cache->pool.stride = sizeof( struct addon_cache_entry );
+         cache->pool.offset = offsetof( struct addon_cache_entry, poolnode );
+         vg_pool_init( &cache->pool );
+
+         /* create the real memory */
+         u32 cache_size = inf->stride*inf->count;
+         cache->items = vg_linear_alloc( vg_mem.rtmemory, cache_size );
+         cache->stride = inf->stride;
+         memset( cache->items, 0, cache_size );
+
+         for( i32 j=0; j<inf->count; j++ ){
+            struct addon_cache_entry *alloc = &cache->allocs[j];
+            alloc->reg_ptr   = NULL;
+            alloc->reg_index = 0xffffffff;
+         }
+      }
+   }
 }
 
 /*
@@ -113,7 +158,7 @@ VG_STATIC addon_reg *addon_alloc_reg( PublishedFileId_t workshop_id,
 
    addon_reg *reg = &addon_system.registry[ addon_system.registry_count ];
    reg->metadata_len = 0;
-   reg->userdata = NULL;
+   reg->cache_id = 0;
    reg->state = k_addon_state_indexed;
    reg->workshop_id = workshop_id;
    reg->foldername[0] = '\0';
@@ -163,7 +208,7 @@ VG_STATIC void addon_print_info( addon_reg *reg ){
    vg_info( "  workshop_id: " PRINTF_U64 "\n", reg->workshop_id );
    vg_info( "  folder: [%u]%s\n", reg->foldername_hash, reg->foldername );
    vg_info( "  metadata_len: %u\n", reg->metadata_len );
-   vg_info( "  userdata: %p\n", reg->userdata );
+   vg_info( "  cache_id: %hu\n", reg->cache_id );
    vg_info( "}\n" );
 }
 
@@ -411,4 +456,63 @@ static int addon_get_content_folder( addon_reg *reg, vg_str *folder ){
    }
 }
 
+static u16 addon_cache_fetch( enum workshop_file_type type, u32 reg_index ){
+   vg_assert_thread( k_thread_purpose_main );
+
+   addon_reg *reg = NULL;
+
+   if( reg_index < addon_count( type ) ){
+      reg = get_addon_from_index( type, reg_index );
+      if( reg->cache_id ) 
+         return reg->cache_id;
+   }
+
+   return 0;
+}
+
+static u16 addon_cache_alloc( enum workshop_file_type type, u32 reg_index ){
+   struct addon_cache *cache = &addon_system.cache[ type ];
+
+   u16 new_id = vg_pool_lru( &cache->pool );
+   struct addon_cache_entry *new_entry = vg_pool_item( &cache->pool, new_id );
+
+   addon_reg *reg = NULL;
+   if( reg_index < addon_count( type ) )
+      reg = get_addon_from_index( type, reg_index );
+
+   if( new_entry ){
+      if( new_entry->reg_ptr )
+         new_entry->reg_ptr->cache_id = 0;
+
+      if( reg )
+         reg->cache_id = new_id;
+
+      new_entry->reg_ptr = reg;
+      new_entry->reg_index = reg_index;
+      return new_id;
+   }
+   else{
+      vg_error( "cache full (type: %u)!\n", type );
+      return 0;
+   }
+}
+
+static void *addon_cache_item( enum workshop_file_type type, u16 id ){
+   if( !id ) return NULL;
+
+   struct addon_cache *cache = &addon_system.cache[type];
+   return cache->items + ((size_t)(id-1) * cache->stride);
+}
+
+static void *addon_cache_item_if_loaded( enum workshop_file_type type, u16 id ){
+   if( !id ) return NULL;
+
+   struct addon_cache *cache = &addon_system.cache[type];
+   struct addon_cache_entry *entry = vg_pool_item( &cache->pool, id );
+
+   if( entry->state == k_addon_cache_state_loaded )
+      return addon_cache_item( type, id );
+   else return NULL;
+}
+
 #endif /* ADDON_C */
diff --git a/addon.h b/addon.h
index 7db6588515526217f779ba8e8b7cdbfcc59af58b..949a5d0678a29a10ec7cd76c0c9d4abac977aaba 100644 (file)
--- a/addon.h
+++ b/addon.h
@@ -1,7 +1,7 @@
 #ifndef ADDON_H
 #define ADDON_H
 
-#include "common.h"
+#include "skaterift.h"
 #include "vg/vg_steam_ugc.h"
 #include "workshop_types.h"
 #include "vg/vg_mem_pool.h"
@@ -19,6 +19,7 @@
 #define CACHE_PLAYER_MAX 10
 
 typedef struct addon_reg addon_reg;
+typedef struct addon_cache_entry addon_cache_entry;
 struct {
    struct addon_reg{
       PublishedFileId_t workshop_id;
@@ -29,7 +30,7 @@ struct {
 
       char foldername[ ADDON_FOLDERNAME_MAX ];
       u32 foldername_hash;
-      void *userdata;
+      u16 cache_id;
 
       enum addon_state{
          k_addon_state_none,
@@ -42,36 +43,59 @@ struct {
    u32 registry_count;
 
    /* deffered: updates in main thread */
-   u32 registry_type_counts[k_workshop_file_type_max]; 
+   u32 registry_type_counts[k_workshop_file_type_max];
+
+   struct addon_cache{
+      struct addon_cache_entry{
+         u32 reg_index;
+         addon_reg *reg_ptr;     /* TODO: only use reg_index? */
+
+         vg_pool_node poolnode;
+
+         enum addon_cache_state{
+            k_addon_cache_state_none,
+            k_addon_cache_state_loaded,
+            k_addon_cache_state_load_request
+         }
+         state;
+      }
+      *allocs;
+      vg_pool pool;
+
+      void *items;  /* the real data */
+      size_t stride;
+   }
+   cache[k_workshop_file_type_max];
+   SDL_SpinLock sl_cache_using_resources;
+
+
+
+#if 0
+
+
 
    /* caches */
    struct cache_board{
-      enum cache_board_state{
-         k_cache_board_state_none,
-         k_cache_board_state_loaded,
-         k_cache_board_state_load_request
-      }
-      state;
       struct player_board board;
+      
       u32 reg_index;
       addon_reg *reg_ptr;
-
       vg_pool_node cachenode;
    }
    *boards;
    vg_pool board_cache;
 
    struct cache_playermodel{
-      enum cache_board_state state;
       struct player_model model;
+
       u32 reg_index;
       addon_reg *reg_ptr;
       vg_pool_node cachenode;
    }
    *playermodels;
    vg_pool playermodel_cache;
+#endif
 
-   SDL_SpinLock sl_cache;
 }
 static addon_system;
 
@@ -90,5 +114,9 @@ VG_STATIC void async_addon_reg_update( void *data, u32 size );
 VG_STATIC addon_reg *addon_mount_local_addon( const char *folder,
                                               enum workshop_file_type type,
                                               const char *content_ext );
+static u16 addon_cache_fetch( enum workshop_file_type type, u32 reg_index );
+static u16 addon_cache_alloc( enum workshop_file_type type, u32 reg_index );
+static void *addon_cache_item( enum workshop_file_type type, u16 id );
+static void *addon_cache_item_if_loaded( enum workshop_file_type type, u16 id );
 
 #endif /* ADDON_H */
index 9bee505bc1412c124330ca33a9830d673f03b4ef..279512b7d124cb6dafdcbad865a603bc701e541e 100644 (file)
@@ -27,6 +27,7 @@ static inline int const_str_eq( u32 hash, const char *str, const char *cmp )
    return 0;
 }
 
+#if 0
 /*
  * Get an existing cache instance, allocate a new one to be loaded, or NULL if
  * there is no space
@@ -44,8 +45,7 @@ VG_STATIC struct cache_board *skateshop_cache_fetch_board( u32 registry_index )
    }
 
    SDL_AtomicLock( &addon_system.sl_cache );
-   struct cache_board *min_board = 
-      vg_pool_lru( &addon_system.board_cache );
+   struct cache_board *min_board = vg_pool_lru( &addon_system.board_cache );
 
    if( min_board ){
       if( min_board->state == k_cache_board_state_loaded ){
@@ -72,22 +72,49 @@ VG_STATIC struct cache_board *skateshop_cache_fetch_board( u32 registry_index )
    SDL_AtomicUnlock( &addon_system.sl_cache );
    return min_board;
 }
+#endif
 
-VG_STATIC void skateshop_update_viewpage(void)
-{
+VG_STATIC void skateshop_update_viewpage(void){
    u32 page = global_skateshop.selected_board_id/SKATESHOP_VIEW_SLOT_MAX;
+      
+   struct addon_cache *cache = &addon_system.cache[k_workshop_file_type_board];
+   vg_pool *pool = &cache->pool;
+
+   for( u32 i=0; i<SKATESHOP_VIEW_SLOT_MAX; i++ ){
+      u32 j = SKATESHOP_VIEW_SLOT_MAX-1-i;
+      struct shop_view_slot *slot = &global_skateshop.shop_view_slots[j];
+
+      if( slot->cache_id )
+         vg_pool_unwatch( pool, slot->cache_id );
+   }
    
    for( u32 i=0; i<SKATESHOP_VIEW_SLOT_MAX; i++ ){
       struct shop_view_slot *slot = &global_skateshop.shop_view_slots[i];
       u32 request_id = page*SKATESHOP_VIEW_SLOT_MAX + i;
-      
-      vg_pool *cache = &addon_system.board_cache;
-      if( slot->cache_ptr ) 
-         vg_pool_unwatch( cache, slot->cache_ptr );
 
-      slot->cache_ptr = skateshop_cache_fetch_board( request_id );
-      if( slot->cache_ptr ) 
-         vg_pool_watch( cache, slot->cache_ptr );
+      u16 id = addon_cache_fetch( k_workshop_file_type_board, request_id );
+      if( !id ){
+         id = addon_cache_alloc( k_workshop_file_type_board, request_id );
+
+         if( id ){
+            SDL_AtomicLock( &addon_system.sl_cache_using_resources );
+
+            addon_cache_entry *entry = vg_pool_item( &cache->pool, id );
+            struct player_board *board = 
+               addon_cache_item( k_workshop_file_type_board, id );
+
+            if( entry->state == k_addon_cache_state_loaded )
+               dynamic_model_unload( &board->mdl );
+
+            entry->state = k_addon_cache_state_load_request;
+            SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
+         }
+      }
+
+      if( id )
+         vg_pool_watch( pool, id );
+
+      slot->cache_id = id;
    }
 }
 
@@ -96,20 +123,6 @@ VG_STATIC void skateshop_update_viewpage(void)
  * -----------------------------------------------------------------------------
  */
 
-/*
- * Reciever for board completion; only promotes the status in the main thread
- */
-VG_STATIC void skateshop_async_board_loaded( void *payload, u32 size )
-{
-   SDL_AtomicLock( &addon_system.sl_cache );
-   struct cache_board *cache_ptr = payload;
-   cache_ptr->state = k_cache_board_state_loaded;
-
-   cache_ptr->reg_ptr->userdata = cache_ptr;
-   SDL_AtomicUnlock( &addon_system.sl_cache );
-   vg_success( "Async board loaded (%s)\n", cache_ptr->reg_ptr->foldername );
-}
-
 /*
  * Thread(or subroutine of thread), for checking view slots that weve installed.
  * Load the model if a view slot wants it
@@ -119,23 +132,32 @@ VG_STATIC void workshop_visibile_load_loop(void)
    vg_info( "Running load loop\n" );
    char path_buf[4096];
 
-   for( u32 i=0; i<CACHE_BOARD_MAX; i++ ){
-      struct cache_board *cache_ptr = &addon_system.boards[i];
+   /* boards */
+   struct addon_cache *cache = &addon_system.cache[k_workshop_file_type_board];
+
+   for( u32 id=1; id<=cache->pool.count; id++ ){
+      addon_cache_entry *entry = vg_pool_item( &cache->pool, id );
+      struct player_board *board = 
+         addon_cache_item( k_workshop_file_type_board, id );
+
+      SDL_AtomicLock( &addon_system.sl_cache_using_resources );
+      if( entry->state == k_addon_cache_state_load_request ){
+         vg_info( "process cache load request (type:%u#%u, reg:%u)\n",
+                     k_workshop_file_type_board, id, entry->reg_index );
 
-      SDL_AtomicLock( &addon_system.sl_cache );
-      if( cache_ptr->state == k_cache_board_state_load_request ){
-         if( cache_ptr->reg_index >= addon_count(k_workshop_file_type_board) ){
+         if( entry->reg_index >= addon_count(k_workshop_file_type_board) ){
             /* should maybe have a different value for this case */
-            cache_ptr->state = k_cache_board_state_none;
-            SDL_AtomicUnlock( &addon_system.sl_cache );
+            entry->state = k_addon_cache_state_none;
+            SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
             continue;
          }
 
+         SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
+
          /* continue with the request */
-         SDL_AtomicUnlock( &addon_system.sl_cache );
          addon_reg *reg = get_addon_from_index( k_workshop_file_type_board,
-                                                cache_ptr->reg_index );
-         cache_ptr->reg_ptr = reg;
+                                                entry->reg_index );
+         entry->reg_ptr = reg;
 
          vg_str folder;
          vg_strnull( &folder, path_buf, 4096 );
@@ -158,27 +180,36 @@ VG_STATIC void workshop_visibile_load_loop(void)
             vg_strcat( &content_path, kv_content );
          }
          else{
-            vg_error( "No content paths in metadata\n" );
+            vg_error( "   No content paths in metadata\n" );
             goto file_is_broken;
          }
 
          if( !vg_strgood( &content_path ) ) {
-            vg_error( "Metadata path too long\n" );
+            vg_error( "   Metadata path too long\n" );
             goto file_is_broken;
          }
          
-         vg_info( "Load content: %s\n", content_path.buffer );
-         player_board_load( &cache_ptr->board, content_path.buffer );
-         vg_async_call( skateshop_async_board_loaded, cache_ptr, 0 );
+         vg_info( "   Load content: %s\n", content_path.buffer );
+         
+         player_board_load( board, content_path.buffer );
+
+         /* WELL DONE */
+         vg_async_stall();
+
+         SDL_AtomicLock( &addon_system.sl_cache_using_resources );
+         entry->state = k_addon_cache_state_loaded;
+         SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
+
+         vg_success( "   loaded (%s)\n", entry->reg_ptr->foldername );
          continue;
 
 file_is_broken:;
-         SDL_AtomicLock( &addon_system.sl_cache );
-         cache_ptr->state = k_cache_board_state_none;
-         SDL_AtomicUnlock( &addon_system.sl_cache );
+         SDL_AtomicLock( &addon_system.sl_cache_using_resources );
+         entry->state = k_addon_cache_state_none;
+         SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
       }
       else
-         SDL_AtomicUnlock( &addon_system.sl_cache );
+         SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
    }
 }
 
@@ -230,43 +261,15 @@ VG_STATIC void skateshop_op_processview(void){
  * VG event init
  */
 VG_STATIC void skateshop_init(void){
-   u32 cache_size = sizeof(struct cache_board)*CACHE_BOARD_MAX;
-   addon_system.boards = vg_linear_alloc( vg_mem.rtmemory, cache_size );
-   memset( addon_system.boards, 0, cache_size );
-
-   for( i32 i=0; i<CACHE_BOARD_MAX; i++ ){
-      struct cache_board *board = &addon_system.boards[i];
-      board->state = k_cache_board_state_none;
-      board->reg_ptr= NULL;
-      board->reg_index = 0xffffffff;
-   }
-
-   vg_pool *cache = &addon_system.board_cache;
-   cache->buffer = addon_system.boards;
-   cache->count = CACHE_BOARD_MAX;
-   cache->stride = sizeof( struct cache_board );
-   cache->offset = offsetof( struct cache_board, cachenode );
-   vg_pool_init( cache );
 }
 
-VG_STATIC struct cache_board *skateshop_selected_cache_if_loaded(void)
-{
+static u16 skateshop_selected_cache_id(void){
    if( addon_count(k_workshop_file_type_board) ){
       addon_reg *reg = get_addon_from_index(k_workshop_file_type_board,
                                             global_skateshop.selected_board_id);
-
-      SDL_AtomicLock( &addon_system.sl_cache );
-      if( reg->userdata ){
-         struct cache_board *cache_ptr = reg->userdata;
-         if( cache_ptr->state == k_cache_board_state_loaded ){
-            SDL_AtomicUnlock( &addon_system.sl_cache );
-            return cache_ptr;
-         }
-      }
-      SDL_AtomicUnlock( &addon_system.sl_cache );
+      return reg->cache_id;
    }
-
-   return NULL;
+   else return 0;
 }
 
 VG_STATIC void pointcloud_async_end(void *_, u32 __)
@@ -383,19 +386,15 @@ VG_STATIC void global_skateshop_preupdate(void)
       gui_helper_action( axis_display_string( k_sraxis_mbrowse_h ), "browse" );
       gui_helper_action( button_display_string( k_srbind_mback ), "exit" );
 
-      struct cache_board *selected_cache = skateshop_selected_cache_if_loaded();
-
-      if( selected_cache ){
+      u16 cache_id = skateshop_selected_cache_id();
+      if( cache_id ){
          gui_helper_action( button_display_string( k_srbind_maccept ), "pick" );
       }
 
       /*
        * Controls
        * ----------------------
-       *
-       *  TODO: Crash if switch page too quick, delist browse if loading....
        */
-
       u32 opage = global_skateshop.selected_board_id/SKATESHOP_VIEW_SLOT_MAX;
 
       if( button_down( k_srbind_mleft ) ){
@@ -418,18 +417,20 @@ VG_STATIC void global_skateshop_preupdate(void)
          skateshop_update_viewpage();
          skateshop_op_processview();
       }
-      else if( selected_cache && button_down( k_srbind_maccept ) ){
+      else if( cache_id && button_down( k_srbind_maccept )){
          vg_info( "chose board from skateshop (%u)\n", 
                      global_skateshop.selected_board_id );
 
+         struct addon_cache *cache = 
+            &addon_system.cache[k_workshop_file_type_board];
+         addon_cache_entry *entry = vg_pool_item( &cache->pool, cache_id );
+
          if( localplayer.board_view_slot ){
-            vg_pool_unwatch( &addon_system.board_cache,
-                                 localplayer.board_view_slot );
+            vg_pool_unwatch( &cache->pool, localplayer.board_view_slot );
          }
 
-         localplayer.board_view_slot = selected_cache;
-         vg_pool_watch( &addon_system.board_cache,
-                             localplayer.board_view_slot );
+         localplayer.board_view_slot = cache_id;
+         vg_pool_watch( &cache->pool, cache_id );
          global_skateshop_exit();
          skaterift_write_savedata();
          return;
@@ -566,25 +567,24 @@ VG_STATIC void skateshop_render_boardshop(void)
               *mark_display = mdl_arritm( &world->ent_marker,
                                   mdl_entity_id_id(shop->boards.id_display));
 
-   int visibility[ SKATESHOP_VIEW_SLOT_MAX ];
-   SDL_AtomicLock( &addon_system.sl_cache );
-   for( u32 i=0; i<SKATESHOP_VIEW_SLOT_MAX; i++ ){
-      struct shop_view_slot *slot = &global_skateshop.shop_view_slots[i];
-
-      visibility[i] = 1;
-
-      if( slot->cache_ptr == NULL ) visibility[i] = 0;
-      else if( slot->cache_ptr->state != k_cache_board_state_loaded )
-         visibility[i] = 0;
-   }
-   SDL_AtomicUnlock( &addon_system.sl_cache );
+   SDL_AtomicLock( &addon_system.sl_cache_using_resources );
+   struct addon_cache *cache = &addon_system.cache[k_workshop_file_type_board];
    
    /* Render loaded boards in the view slots */
    for( u32 i=0; i<slot_count; i++ ){
       struct shop_view_slot *slot = &global_skateshop.shop_view_slots[i];
       float selected = 0.0f;
 
-      if( !visibility[i] ) goto fade_out;
+      if( !slot->cache_id ) 
+         goto fade_out;
+
+      addon_cache_entry *entry = vg_pool_item( &cache->pool, slot->cache_id );
+
+      if( entry->state != k_addon_cache_state_loaded )
+         goto fade_out;
+
+      struct player_board *board = 
+         addon_cache_item( k_workshop_file_type_board, slot->cache_id );
 
       mdl_transform xform;
       transform_identity( &xform );
@@ -592,7 +592,8 @@ VG_STATIC void skateshop_render_boardshop(void)
       xform.co[0] = -((float)i - ((float)slot_count)*0.5f)*0.45f;
       mdl_transform_mul( &mark_rack->transform, &xform, &xform );
 
-      if( slot->cache_ptr->reg_index == global_skateshop.selected_board_id ){
+
+      if( entry->reg_index == global_skateshop.selected_board_id ){
          selected = 1.0f;
       }
 
@@ -603,8 +604,7 @@ VG_STATIC void skateshop_render_boardshop(void)
 
       m4x3f mmdl;
       mdl_transform_m4x3( &xform, mmdl );
-      render_board( &main_camera, world, &slot->cache_ptr->board, mmdl,
-                    k_board_shader_entity );
+      render_board( &main_camera, world, board, mmdl, k_board_shader_entity );
 
 fade_out:;
       float rate = 5.0f*vg.time_delta;
@@ -656,9 +656,14 @@ fade_out:;
                           "Nothing installed", &main_camera, mmdl );
    }
 
-   struct cache_board *cache_ptr = skateshop_selected_cache_if_loaded();
+   u16 cache_id = skateshop_selected_cache_id();
+   struct addon_cache_entry *entry = vg_pool_item( &cache->pool, cache_id );
+   addon_reg *reg = NULL;
+
+   if( entry ) reg = entry->reg_ptr;
 
-   if( !cache_ptr ){
+   if( !reg ){
+      SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
       global_skateshop.render.item_title = "";
       global_skateshop.render.item_desc = "";
       return;
@@ -667,7 +672,6 @@ fade_out:;
    if( global_skateshop.render.reg_id != global_skateshop.selected_board_id ){
       global_skateshop.render.item_title = "";
       global_skateshop.render.item_desc = "";
-      addon_reg *reg = cache_ptr->reg_ptr;
       vg_msg root = {0};
       root.buf = reg->metadata;
       root.len = reg->metadata_len;
@@ -685,8 +689,6 @@ fade_out:;
       global_skateshop.render.reg_id = global_skateshop.selected_board_id;
    }
 
-   addon_reg *reg = cache_ptr->reg_ptr;
-
    /* Skin title
     * ----------------------------------------------------------------- */
    m3x3_zero( mlocal );
@@ -712,6 +714,8 @@ fade_out:;
    m4x3_mul( mtext, mlocal, mmdl );
    font3d_simple_draw( &gui.font, 0, global_skateshop.render.item_desc, 
                        &main_camera, mmdl );
+
+   SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
 }
 
 VG_STATIC void skateshop_render_charshop(void)
@@ -874,6 +878,9 @@ VG_STATIC void ent_skateshop_call( world_instance *world, ent_call *call )
       if( shop->type == k_skateshop_type_boardshop ){
          skateshop_update_viewpage();
          skateshop_op_board_scan();
+      }
+      else if( shop->type == k_skateshop_type_charshop ){
+         
       }
       else if( shop->type == k_skateshop_type_worldshop ){
          pointcloud_animate( k_pointcloud_anim_opening );
index ff52db0f1380530b4d0c9f6d2c86622dbddf35c7..70b327c6e10a36b8adbc03e17d5af5502bba14e2 100644 (file)
@@ -8,7 +8,7 @@
 #include "workshop.h"
 #include "addon.h"
 
-#define SKATESHOP_VIEW_SLOT_MAX    6
+#define SKATESHOP_VIEW_SLOT_MAX    2
 
 struct{
    v3f look_target;
@@ -18,7 +18,7 @@ struct{
    float factive;
 
    struct shop_view_slot{
-      struct cache_board *cache_ptr;
+      u16 cache_id;
       float view_blend;
    }
    shop_view_slots[ SKATESHOP_VIEW_SLOT_MAX ];
index 8db02de0f54568b3f40a3ad056e3b1fcb3fe5acf..8f1e3c6be4ae9ed96c3538b49294eeb6c440ffe5 100644 (file)
--- a/player.h
+++ b/player.h
@@ -75,10 +75,16 @@ struct player_instance
 
    struct player_avatar  *playeravatar;
    struct player_ragdoll  ragdoll;
+
+#if 0
    //struct player_model   *playermodel;
    //struct player_board   *board;
+   
    struct cache_board       *board_view_slot;
    struct cache_playermodel *playermodel_view_slot;
+#endif
+
+   u16 board_view_slot, playermodel_view_slot;
 
    player_pose            holdout_pose;
    float                  holdout_time;
index df219ef5423fe54fa8a8ecf13c647d3029dbc0f1..8696eab05c3bbaf7bf3830ccba6c9eab38fadc30 100644 (file)
@@ -306,26 +306,4 @@ VG_STATIC void player_look( player_instance *player, v3f angles )
    angles[1] = vg_clampf( angles[1], -VG_PIf*0.5f, VG_PIf*0.5f );
 }
 
-struct player_board *player_get_player_board( struct player_instance *player ){
-   if( localplayer.board_view_slot ){
-      struct cache_board *cache_view = localplayer.board_view_slot;
-      if( cache_view->state == k_cache_board_state_loaded ){
-         return &cache_view->board;
-      }
-   }
-
-   return NULL;
-}
-
-struct player_model *player_get_player_model( struct player_instance *player ){
-   if( localplayer.playermodel_view_slot ){
-      struct cache_playermodel *cache_view = localplayer.playermodel_view_slot;
-      if( cache_view->state == k_cache_board_state_loaded ){
-         return &cache_view->model;
-      }
-   }
-
-   return NULL;
-}
-
 #endif /* PLAYER_COMMON_C */
index 2be689e09c3d397b8a7b816926f5dc3a439cb685..129c335d172b6df606ff8851d5de16030ae3dd3b 100644 (file)
@@ -16,5 +16,6 @@ VG_STATIC void player_look( player_instance *player, v3f angles );
 VG_STATIC void player__cam_iterate( player_instance *player );
 VG_STATIC void player_vector_angles( v3f angles, v3f v, float C, float k );
 struct player_board *player_get_player_board( struct player_instance *player );
+struct player_model *player_get_player_model( struct player_instance *player );
 
 #endif /* PLAYER_COMMON_H */
index 20d9a706262e1b11e9515e95c155174e6f9e53d3..17eb34200aa3453053152b77587334e21de29091 100644 (file)
@@ -39,60 +39,45 @@ VG_STATIC void player_avatar_load( struct player_avatar *av, const char *path )
 
 /* TODO: Standard model load */
 
-VG_STATIC void player_model_load( struct player_model *mdl, const char *path )
+VG_STATIC void dynamic_model_load( mdl_context *ctx,
+                                   struct dynamic_model_1texture *mdl, 
+                                   const char *path )
 {
-   vg_linear_clear( vg_mem.scratch );
-
-   mdl_context ctx;
-   mdl_open( &ctx, path, vg_mem.scratch );
-   mdl_load_metadata_block( &ctx, vg_mem.scratch );
-
-   if( !mdl_arrcount( &ctx.textures ) )
-      vg_fatal_error( "No texture in player model" );
+   if( !mdl_arrcount( &ctx->textures ) )
+      vg_fatal_error( "No texture in model" );
 
-   mdl_texture *tex0 = mdl_arritm( &ctx.textures, 0 );
+   mdl_texture *tex0 = mdl_arritm( &ctx->textures, 0 );
    void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
-   mdl_fread_pack_file( &ctx, &tex0->file, data );
+   mdl_fread_pack_file( ctx, &tex0->file, data );
 
    vg_tex2d_load_qoi_async( data, tex0->file.pack_size,
                             VG_TEX2D_NEAREST|VG_TEX2D_CLAMP,
                             &mdl->texture );
 
-   mdl_async_load_glmesh( &ctx, &mdl->mesh );
-   mdl_close( &ctx );
+   mdl_async_load_glmesh( ctx, &mdl->mesh );
 }
 
 /* TODO: allow error handling */
-VG_STATIC void player_board_load( struct player_board *mdl, const char *path ){
+VG_STATIC void player_board_load( struct player_board *board, 
+                                  const char *path ){
+
    vg_linear_clear( vg_mem.scratch );
 
    mdl_context ctx;
    mdl_open( &ctx, path, vg_mem.scratch );
    mdl_load_metadata_block( &ctx, vg_mem.scratch );
 
+   dynamic_model_load( &ctx, &board->mdl, path );
+
    mdl_array_ptr markers;
    mdl_load_array( &ctx, &markers, "ent_marker", vg_mem.scratch );
 
-   if( !mdl_arrcount( &ctx.textures ) )
-      vg_fatal_error( "No texture in board model" );
-
-   mdl_texture *tex0 = mdl_arritm( &ctx.textures, 0 );
-   void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
-   mdl_fread_pack_file( &ctx, &tex0->file, data );
-
-   vg_tex2d_load_qoi_async( data, tex0->file.pack_size,
-                            VG_TEX2D_CLAMP|VG_TEX2D_NEAREST,
-                            &mdl->texture );
-
-   mdl_async_load_glmesh( &ctx, &mdl->mesh );
-   mdl_close( &ctx );
-
    /* TODO: you get put into a new section, the above is standard mdl loads. */
    for( int i=0; i<4; i++ )
-      mdl->wheels[i].indice_count = 0;
+      board->wheels[i].indice_count = 0;
    for( int i=0; i<2; i++ )
-      mdl->trucks[i].indice_count = 0;
-   mdl->board.indice_count = 0;
+      board->trucks[i].indice_count = 0;
+   board->board.indice_count = 0;
 
    for( u32 i=0; i<mdl_arrcount(&ctx.meshs); i++ ){
       mdl_mesh *mesh = mdl_arritm( &ctx.meshs, i );
@@ -111,26 +96,31 @@ VG_STATIC void player_board_load( struct player_board *mdl, const char *path ){
 
       if( !strcmp( alias, "wheel" ) ){
          u32 id = fb<<1 | lr;
-         mdl->wheels[ id ] = *sm0;
-         v3_copy( marker->transform.co, mdl->wheel_positions[ id ] );
+         board->wheels[ id ] = *sm0;
+         v3_copy( marker->transform.co, board->wheel_positions[ id ] );
       }
       else if( !strcmp( alias, "board" ) ){
-         mdl->board = *sm0;
-         v3_copy( marker->transform.co, mdl->board_position );
+         board->board = *sm0;
+         v3_copy( marker->transform.co, board->board_position );
       }
       else if( !strcmp( alias, "truck" ) ){
-         mdl->trucks[ fb ] = *sm0;
-         v3_copy( marker->transform.co, mdl->truck_positions[ fb ] );
+         board->trucks[ fb ] = *sm0;
+         v3_copy( marker->transform.co, board->truck_positions[ fb ] );
       }
    }
+
+   mdl_close( &ctx );
 }
 
-VG_STATIC void player_board_unload( struct player_board *mdl )
-{
+VG_STATIC void dynamic_model_unload( struct dynamic_model_1texture *mdl ){
    mesh_free( &mdl->mesh );
    glDeleteTextures( 1, &mdl->texture );
 }
 
+VG_STATIC void player_board_unload( struct player_board *board ){
+   dynamic_model_unload( &board->mdl );
+}
+
 VG_STATIC void player__pre_render( player_instance *player )
 {
    if( _player_animate[ player->subsystem ] ){
@@ -162,7 +152,9 @@ VG_STATIC void player__pre_render( player_instance *player )
       _player_post_animate[ player->subsystem ]( player );
 
    struct player_avatar *av = player->playeravatar;
-   struct player_board *board = player_get_player_board( player );
+   struct player_board *board = 
+      addon_cache_item_if_loaded( k_workshop_file_type_board,
+                                  player->board_view_slot );
 
    v3f vp0, vp1;
 
@@ -292,7 +284,7 @@ VG_STATIC void render_board( camera *cam, world_instance *world,
    v3f inverse;
 
    glActiveTexture( GL_TEXTURE0 );
-   glBindTexture( GL_TEXTURE_2D, board->texture );
+   glBindTexture( GL_TEXTURE_2D, board->mdl.texture );
 
    if( shader == k_board_shader_player ){
       shader_model_board_view_use();
@@ -334,7 +326,7 @@ VG_STATIC void render_board( camera *cam, world_instance *world,
                                  _uniform_model_entity_uLightsIndex, 4 );
    }
 
-   mesh_bind( &board->mesh );
+   mesh_bind( &board->mdl.mesh );
 
    m4x4f m4mdl;
 
@@ -408,7 +400,7 @@ VG_STATIC void render_playermodel( camera *cam, world_instance *world,
    shader_model_character_view_use();
 
        glActiveTexture( GL_TEXTURE0 );
-       glBindTexture( GL_TEXTURE_2D, model->texture );
+       glBindTexture( GL_TEXTURE_2D, model->mdl.texture );
    shader_model_character_view_uTexMain( 0 );
    shader_model_character_view_uCamera( cam->transform[3] );
    shader_model_character_view_uPv( cam->mtx.pv );
@@ -436,21 +428,28 @@ VG_STATIC void render_playermodel( camera *cam, world_instance *world,
                          0,
                          (float *)skeleton->final_mtx );
    
-   mesh_bind( &model->mesh );
-   mesh_draw( &model->mesh );
+   mesh_bind( &model->mdl.mesh );
+   mesh_draw( &model->mdl.mesh );
 }
 
 PLAYER_API void player__render( camera *cam, player_instance *player )
 {
    world_instance *world = world_current_instance();
+   SDL_AtomicLock( &addon_system.sl_cache_using_resources );
 
-   struct player_model *model = player_get_player_model( player );
+   struct player_model *model = 
+      addon_cache_item_if_loaded( k_workshop_file_type_player, 
+                                  player->playermodel_view_slot );
    render_playermodel( cam, world, model, &player->playeravatar->sk );
 
-   struct player_board *board = player_get_player_board( player );
+   struct player_board *board = 
+      addon_cache_item_if_loaded( k_workshop_file_type_board,
+                                  player->board_view_slot );
    render_board( cam, world, board, player->playeravatar->sk.final_mtx[
                                        player->playeravatar->id_board],
                                        k_board_shader_player );
+
+   SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
 }
 
 #endif /* PLAYER_RENDER_C */
index a31f19a86fe128f4c4c48952c3389ff75a2fbd5c..4d5145ffbc56e3dfbfb7d3ded88696c621ad01df 100644 (file)
@@ -38,11 +38,15 @@ enum eboard_wheel{
    k_board_wheel_br = 3,
 };
 
-struct player_board{
-   mdl_context model;
-
+/* TODO: Fully featured dynamic models
+ * This is FAR from the final system we want at all, but it will do for now */
+struct dynamic_model_1texture{
    glmesh mesh;
    GLuint texture;
+};
+
+struct player_board{
+   struct dynamic_model_1texture mdl;
 
    v4f wheel_positions[4],
        truck_positions[2],
@@ -54,8 +58,7 @@ struct player_board{
 };
 
 struct player_model{
-   glmesh mesh;
-   GLuint texture;
+   struct dynamic_model_1texture mdl;
 };
 
 enum board_shader{
@@ -65,6 +68,8 @@ enum board_shader{
 
 VG_STATIC void player_board_load( struct player_board *mdl, const char *path );
 VG_STATIC void player_board_unload( struct player_board *mdl );
+
+VG_STATIC void dynamic_model_unload( struct dynamic_model_1texture *mdl );
 VG_STATIC void render_board( camera *cam, world_instance *world,
                              struct player_board *board, m4x3f root,
                              enum board_shader shader );
index 551c2cc1d9d026db60f829c8a7a3b6b6d0716a22..3d01428748bdcf6e43a303b5bcb5be8c94db517c 100644 (file)
@@ -6,6 +6,7 @@
 #include "vg/vg_perlin.h"
 #include "menu.h"
 #include "ent_skateshop.h"
+#include "addon.h"
 
 VG_STATIC void player__skate_bind( player_instance *player )
 {
@@ -2995,7 +2996,9 @@ VG_STATIC void player__skate_animate( player_instance *player,
       q_mul( kf_board->q, qtrick, kf_board->q );
       q_normalize( kf_board->q );
 
-      struct player_board *board = player_get_player_board( player );
+      struct player_board *board = 
+         addon_cache_item_if_loaded( k_workshop_file_type_board,
+                                     player->board_view_slot );
       
       if( board ){
          /* foot weight distribution */
index 6a20b17f32855eb9bcd1924eb822ef431318fdcf..dbf0d026f3487efa251c19b8c2fa11123fea0690 100644 (file)
@@ -284,8 +284,11 @@ VG_STATIC void player__walk_pre_update( player_instance *player )
          player->subsystem = k_player_subsystem_drive;
       }
       else{
-         if( !player_get_player_board(player) )
-            return;
+         struct player_board *board = 
+            addon_cache_item_if_loaded( k_workshop_file_type_board,
+                                        player->board_view_slot );
+
+         if( !board ) return;
 
          if( w->state.activity == k_walk_activity_ground ){
             if( player_walk_scan_for_drop_in( player ) ){
diff --git a/save.c b/save.c
index b163cb46ed8fc903dab2ca91d83e2629246ecbd3..ad1b35e0414186b650596a4a094aed3e3b76c67b 100644 (file)
--- a/save.c
+++ b/save.c
@@ -1,6 +1,9 @@
 #ifndef SAVE_C
 #define SAVE_C
 
+#include "save.h"
+#include "vg/vg_msg.h"
+
 struct {
    u8  buf[1024];
    u32 len;
@@ -27,13 +30,17 @@ static void skaterift_write_savedata(void){
 
    vg_msg_frame( &sav, "player" );
 
+   struct addon_cache *cache = &addon_system.cache[k_workshop_file_type_board];
+
    if( localplayer.board_view_slot ){
-      struct cache_board *cache_ptr = localplayer.board_view_slot;
-      if( cache_ptr->reg_ptr ){
-         if( cache_ptr->reg_ptr->workshop_id ) 
-            vg_msg_wkvu64( &sav, "board", cache_ptr->reg_ptr->workshop_id );
+      addon_cache_entry *entry = vg_pool_item( &cache->pool, 
+                                               localplayer.board_view_slot );
+
+      if( entry->reg_ptr ){
+         if( entry->reg_ptr->workshop_id ) 
+            vg_msg_wkvu64( &sav, "board", entry->reg_ptr->workshop_id );
          else
-            vg_msg_wkvstr( &sav, "board", cache_ptr->reg_ptr->foldername );
+            vg_msg_wkvstr( &sav, "board", entry->reg_ptr->foldername );
       }
    }
 
index 4d65145bea75c893ffb0eb4efe2702a273da8d7b..8983f23f26cacb78fa0063c2306117a34320c86f 100644 (file)
@@ -249,14 +249,15 @@ VG_STATIC void vg_load(void)
       vg_error( "%u\n", sav.error );
    }
 
+#if 0
    vg_info( "search: %lu '%s'\n", query_workshop_id, query_local_folder );
-
    u32 reg_id = addon_match( k_workshop_file_type_board,
                              query_workshop_id, query_local_folder );
    if( reg_id != 0xffffffff ){
       localplayer.board_view_slot = skateshop_cache_fetch_board( reg_id );
       vg_pool_watch( &addon_system.board_cache, localplayer.board_view_slot );
    }
+#endif
 
    board_processview_thread(NULL); /* END_OP!! */
 }
index c13c78b7fb3d455a35955f9ffdb7a43243b83372..c9b3fae6d5eca5821f89fa8b852933479b4db1a7 100644 (file)
@@ -7,6 +7,7 @@
 #define VG_3D
 #define VG_GAME
 #define VG_MSG_V1_SUPPORT
+#define VG_LOG_SOURCE_INFO
 #include "vg/vg.h"
 
 #include "common.h"
@@ -22,6 +23,7 @@ struct{
       k_async_op_world_scan,
       k_async_op_world_load_preview,
       k_async_op_board_scan,
+      k_async_op_player_scan,
       k_async_op_board_load,
       k_async_op_write_savedata,
       k_workshop_form_op_loading_model,