From cbeec2e44e93ab43ccde54c2dd9cd02f559ebef8 Mon Sep 17 00:00:00 2001 From: hgn Date: Sat, 17 Jun 2023 14:45:38 +0100 Subject: [PATCH] refactor(1) --- addon.c | 108 ++++++++++++++++++++++- addon.h | 52 ++++++++--- ent_skateshop.c | 223 +++++++++++++++++++++++++----------------------- ent_skateshop.h | 4 +- player.h | 6 ++ player_common.c | 22 ----- player_common.h | 1 + player_render.c | 93 ++++++++++---------- player_render.h | 15 ++-- player_skate.c | 5 +- player_walk.c | 7 +- save.c | 17 ++-- skaterift.c | 3 +- skaterift.h | 2 + 14 files changed, 351 insertions(+), 207 deletions(-) diff --git a/addon.c b/addon.c index d408654..0346d01 100644 --- 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; icount ){ + /* 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; jcount; 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 7db6588..949a5d0 100644 --- 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 */ diff --git a/ent_skateshop.c b/ent_skateshop.c index 9bee505..279512b 100644 --- a/ent_skateshop.c +++ b/ent_skateshop.c @@ -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; icache_id ) + vg_pool_unwatch( pool, slot->cache_id ); + } for( u32 i=0; icache_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; ipool.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; istate = 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; icache_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; icache_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 ); diff --git a/ent_skateshop.h b/ent_skateshop.h index ff52db0..70b327c 100644 --- a/ent_skateshop.h +++ b/ent_skateshop.h @@ -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 ]; diff --git a/player.h b/player.h index 8db02de..8f1e3c6 100644 --- 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; diff --git a/player_common.c b/player_common.c index df219ef..8696eab 100644 --- a/player_common.c +++ b/player_common.c @@ -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 */ diff --git a/player_common.h b/player_common.h index 2be689e..129c335 100644 --- a/player_common.h +++ b/player_common.h @@ -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 */ diff --git a/player_render.c b/player_render.c index 20d9a70..17eb342 100644 --- a/player_render.c +++ b/player_render.c @@ -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; iwheels[ 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 */ diff --git a/player_render.h b/player_render.h index a31f19a..4d5145f 100644 --- a/player_render.h +++ b/player_render.h @@ -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 ); diff --git a/player_skate.c b/player_skate.c index 551c2cc..3d01428 100644 --- a/player_skate.c +++ b/player_skate.c @@ -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 */ diff --git a/player_walk.c b/player_walk.c index 6a20b17..dbf0d02 100644 --- a/player_walk.c +++ b/player_walk.c @@ -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 b163cb4..ad1b35e 100644 --- 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 ); } } diff --git a/skaterift.c b/skaterift.c index 4d65145..8983f23 100644 --- a/skaterift.c +++ b/skaterift.c @@ -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!! */ } diff --git a/skaterift.h b/skaterift.h index c13c78b..c9b3fae 100644 --- a/skaterift.h +++ b/skaterift.h @@ -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, -- 2.25.1