X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=addon.c;h=34e16f8e42b995a3028bec2f655dd551d2475cd8;hb=0ba0bbe2da453f17f56a88521057e6514ae30b8f;hp=4d1e90342c0f35b6fb87081af3730c6af3fe2f4d;hpb=2c91a71533b4ce86b9e7fd708420ae05c74d8f52;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/addon.c b/addon.c index 4d1e903..34e16f8 100644 --- a/addon.c +++ b/addon.c @@ -1,22 +1,51 @@ -#ifndef ADDON_C -#define ADDON_C - +#include "vg/vg_engine.h" +#include "vg/vg_io.h" +#include "vg/vg_loader.h" #include "addon.h" #include "addon_types.h" #include "vg/vg_msg.h" #include "steam.h" #include "workshop.h" +#include + +struct addon_system addon_system; + +u32 addon_count( enum addon_type type, u32 ignoreflags ) +{ + if( ignoreflags ){ + u32 typecount = 0, count = 0; + for( u32 i=0; typecountalias.type == type ){ + typecount ++; + + if( reg->flags & ignoreflags ) + continue; + + count ++; + } + } -static u32 addon_count( enum addon_type type ){ - return addon_system.registry_type_counts[ type ]; + return count; + } + else + return addon_system.registry_type_counts[ type ]; } + /* these kind of suck, oh well. */ -static addon_reg *get_addon_from_index(enum addon_type type, u32 index){ - u32 count = 0; - for( u32 i=0; countalias.type == type ){ + typecount ++; + + if( reg->flags & ignoreflags ) + continue; + if( index == count ) return reg; @@ -27,7 +56,8 @@ static addon_reg *get_addon_from_index(enum addon_type type, u32 index){ return NULL; } -static u32 get_index_from_addon( enum addon_type type, addon_reg *a ){ +u32 get_index_from_addon( enum addon_type type, addon_reg *a ) +{ u32 count = 0; for( u32 i=0; counttype == k_addon_type_none ) return 0xffffffff; u32 foldername_djb2 = 0; @@ -76,7 +107,8 @@ static u32 addon_match( addon_alias *alias ){ /* * Create a string version of addon alias in buf */ -static void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] ){ +void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] ) +{ if( alias->workshop_id ){ snprintf( buf, 128, "sr%03d-steam-"PRINTF_U64, alias->type, alias->workshop_id ); @@ -90,7 +122,8 @@ static void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] ){ /* * equality check */ -static int addon_alias_eq( addon_alias *a, addon_alias *b ){ +int addon_alias_eq( addon_alias *a, addon_alias *b ) +{ if( a->type == b->type ){ if( a->workshop_id == b->workshop_id ){ if( a->workshop_id ) @@ -107,7 +140,8 @@ static int addon_alias_eq( addon_alias *a, addon_alias *b ){ /* * make alias represent NULL. */ -static void invalidate_addon_alias( addon_alias *alias ){ +void invalidate_addon_alias( addon_alias *alias ) +{ alias->type = k_addon_type_none; alias->workshop_id = 0; alias->foldername[0] = '\0'; @@ -116,7 +150,8 @@ static void invalidate_addon_alias( addon_alias *alias ){ /* * parse uid to alias. returns 1 if successful */ -static int addon_uid_to_alias( const char *uid, addon_alias *alias ){ +int addon_uid_to_alias( const char *uid, addon_alias *alias ) +{ /* 1 * 01234567890123 * sr&&&-@@@@@-#* @@ -157,7 +192,8 @@ static int addon_uid_to_alias( const char *uid, addon_alias *alias ){ return 1; } -static void addon_system_init( void ){ +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 ); @@ -200,7 +236,7 @@ static void addon_system_init( void ){ /* * Reciever for scan completion. copies the registry counts back into main fred */ -static void async_addon_reg_update( void *data, u32 size ) +void async_addon_reg_update( void *data, u32 size ) { vg_info( "Registry update notify\n" ); @@ -230,6 +266,7 @@ static addon_reg *addon_alloc_reg( PublishedFileId_t workshop_id, } addon_reg *reg = &addon_system.registry[ addon_system.registry_count ]; + reg->flags = 0; reg->metadata_len = 0; reg->cache_id = 0; reg->state = k_addon_state_indexed; @@ -309,11 +346,13 @@ static addon_reg *addon_mount_workshop_folder( PublishedFileId_t workshop_id, vg_msg msg; vg_msg_init( &msg, reg->metadata, reg->metadata_len ); - if( vg_msg_seekframe( &msg, "workshop" )){ - type = vg_msg_getkvu32( &msg, "type", 0 ); + if( vg_msg_seekframe( &msg, "workshop" )) + { + vg_msg_getkvintg( &msg, "type", k_vg_msg_u32, &type, NULL ); } - if( type == k_addon_type_none ){ + if( type == k_addon_type_none ) + { vg_error( "Cannot determine addon type\n" ); return NULL; } @@ -326,9 +365,9 @@ static addon_reg *addon_mount_workshop_folder( PublishedFileId_t workshop_id, /* * Mount a local folder. may or may not have addon.inf */ -static addon_reg *addon_mount_local_addon( const char *folder, - enum addon_type type, - const char *content_ext ) +addon_reg *addon_mount_local_addon( const char *folder, + enum addon_type type, + const char *content_ext ) { char folder_path_buf[4096]; vg_str folder_path; @@ -343,7 +382,7 @@ static addon_reg *addon_mount_local_addon( const char *folder, if( (reg->alias.type == type) && (reg->foldername_hash == folder_hash) ){ if( !strcmp( reg->alias.foldername, folder_name ) ){ reg->state = k_addon_state_indexed; - return NULL; + return reg; } } } @@ -403,8 +442,14 @@ static addon_reg *addon_mount_local_addon( const char *folder, /* * Check all subscribed items */ -static void addon_mount_workshop_items(void){ +void addon_mount_workshop_items(void) +{ + if( skaterift.demo_mode ){ + vg_info( "Won't load workshop items in demo mode\n" ); + return; + } if( !steam_ready ) return; + /* * Steam workshop scan */ @@ -455,9 +500,9 @@ next_file_workshop:; * Scan a local content folder for addons. It must find at least one file with * the specified content_ext to be considered. */ -static void addon_mount_content_folder( enum addon_type type, - const char *base_folder, - const char *content_ext ) +void addon_mount_content_folder( enum addon_type type, + const char *base_folder, + const char *content_ext ) { vg_info( "Mounting addons(type:%d) matching skaterift/%s/*/*%s\n", type, base_folder, content_ext ); @@ -497,16 +542,31 @@ static void addon_mount_content_folder( enum addon_type type, /* * write the full path of the addon's folder into the vg_str */ -static int addon_get_content_folder( addon_reg *reg, vg_str *folder ){ +int addon_get_content_folder( addon_reg *reg, vg_str *folder, int async) +{ if( reg->alias.workshop_id ){ - vg_async_item *call = - vg_async_alloc( sizeof(struct async_workshop_filepath_info) ); - struct async_workshop_filepath_info *info = call->payload; + struct async_workshop_filepath_info *info = NULL; + vg_async_item *call = NULL; + + if( async ){ + call = vg_async_alloc( sizeof(struct async_workshop_filepath_info) ); + info = call->payload; + } + else + info = alloca( sizeof(struct async_workshop_filepath_info) ); + info->buf = folder->buffer; info->id = reg->alias.workshop_id; info->len = folder->len; - vg_async_dispatch( call, async_workshop_get_filepath ); - vg_async_stall(); /* too bad! */ + + if( async ){ + vg_async_dispatch( call, async_workshop_get_filepath ); + vg_async_stall(); /* too bad! */ + } + else { + async_workshop_get_filepath( info, 0 ); + } + if( info->buf[0] == '\0' ){ vg_error( "Failed SteamAPI_GetItemInstallInfo(" PRINTF_U64 ")\n", reg->alias.workshop_id ); @@ -532,11 +592,12 @@ static int addon_get_content_folder( addon_reg *reg, vg_str *folder ){ * Return existing cache id if reg_index points to a registry with its cache * already set. */ -static u16 addon_cache_fetch( enum addon_type type, u32 reg_index ){ +u16 addon_cache_fetch( enum addon_type type, u32 reg_index ) +{ addon_reg *reg = NULL; - if( reg_index < addon_count( type ) ){ - reg = get_addon_from_index( type, reg_index ); + if( reg_index < addon_count( type, 0 ) ){ + reg = get_addon_from_index( type, reg_index, 0 ); if( reg->cache_id ) return reg->cache_id; } @@ -547,15 +608,16 @@ static u16 addon_cache_fetch( enum addon_type type, u32 reg_index ){ /* * Allocate a new cache item from the pool */ -static u16 addon_cache_alloc( enum addon_type type, u32 reg_index ){ +u16 addon_cache_alloc( enum addon_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( reg_index < addon_count( type, 0 ) ) + reg = get_addon_from_index( type, reg_index, 0 ); if( new_entry ){ if( new_entry->reg_ptr ) @@ -577,7 +639,8 @@ static u16 addon_cache_alloc( enum addon_type type, u32 reg_index ){ /* * Get the real item data for cache id */ -static void *addon_cache_item( enum addon_type type, u16 id ){ +void *addon_cache_item( enum addon_type type, u16 id ) +{ if( !id ) return NULL; struct addon_cache *cache = &addon_system.cache[type]; @@ -587,7 +650,8 @@ static void *addon_cache_item( enum addon_type type, u16 id ){ /* * Get the real item data for cache id ONLY if the item is completely loaded. */ -static void *addon_cache_item_if_loaded( enum addon_type type, u16 id ){ +void *addon_cache_item_if_loaded( enum addon_type type, u16 id ) +{ if( !id ) return NULL; struct addon_cache *cache = &addon_system.cache[type]; @@ -601,7 +665,8 @@ static void *addon_cache_item_if_loaded( enum addon_type type, u16 id ){ /* * Updates the item state from the main thread */ -static void async_addon_setstate( void *_entry, u32 _state ){ +void async_addon_setstate( void *_entry, u32 _state ) +{ addon_cache_entry *entry = _entry; SDL_AtomicLock( &addon_system.sl_cache_using_resources ); entry->state = _state; @@ -668,22 +733,27 @@ static void addon_cache_free_item( enum addon_type type, u16 id ){ /* * Goes over cache item load requests and calls the above ^ */ -static void addon_cache_load_loop(void){ +static void T1_addon_cache_load_loop(void *_) +{ vg_info( "Running load loop\n" ); char path_buf[4096]; - for( u32 type=0; typepool.count; id++ ){ + for( u32 id=1; id<=cache->pool.count; id++ ) + { addon_cache_entry *entry = vg_pool_item( &cache->pool, id ); SDL_AtomicLock( &addon_system.sl_cache_using_resources ); - if( entry->state == k_addon_cache_state_load_request ){ + if( entry->state == k_addon_cache_state_load_request ) + { vg_info( "process cache load request (%u#%u, reg:%u)\n", type, id, entry->reg_index ); - if( entry->reg_index >= addon_count(type) ){ + if( entry->reg_index >= addon_count(type,0) ) + { /* should maybe have a different value for this case */ entry->state = k_addon_cache_state_none; SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); @@ -693,13 +763,15 @@ static void addon_cache_load_loop(void){ SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); /* continue with the request */ - addon_reg *reg = get_addon_from_index( type, entry->reg_index ); + addon_reg *reg = get_addon_from_index( type, entry->reg_index, 0 ); entry->reg_ptr = reg; vg_str folder; vg_strnull( &folder, path_buf, 4096 ); - if( addon_get_content_folder( reg, &folder ) ){ - if( addon_cache_load_request( type, id, reg, folder ) ){ + if( addon_get_content_folder( reg, &folder, 1 ) ) + { + if( addon_cache_load_request( type, id, reg, folder ) ) + { vg_async_call( async_addon_setstate, entry, k_addon_cache_state_loaded ); continue; @@ -717,11 +789,35 @@ static void addon_cache_load_loop(void){ } } +void addon_system_pre_update(void) +{ + if( !vg_loader_availible() ) return; + + SDL_AtomicLock( &addon_system.sl_cache_using_resources ); + for( u32 type=0; typepool.count; id++ ) + { + addon_cache_entry *entry = vg_pool_item( &cache->pool, id ); + if( entry->state == k_addon_cache_state_load_request ) + { + SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); + vg_loader_start( T1_addon_cache_load_loop, NULL ); + return; + } + } + } + SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); +} + /* * Perform the cache interactions required to create a viewslot which will * eventually be loaded by other parts of the system. */ -static u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id ){ +u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id ) +{ struct addon_cache *cache = &addon_system.cache[type]; vg_pool *pool = &cache->pool; @@ -748,8 +844,9 @@ static u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id ){ return cache_id; } -static u16 addon_cache_create_viewer_from_uid( enum addon_type type, - char uid[ADDON_UID_MAX] ){ +u16 addon_cache_create_viewer_from_uid( enum addon_type type, + char uid[ADDON_UID_MAX] ) +{ addon_alias q; if( !addon_uid_to_alias( uid, &q ) ) return 0; if( q.type != type ) return 0; @@ -765,7 +862,8 @@ static u16 addon_cache_create_viewer_from_uid( enum addon_type type, } } -static void addon_cache_watch( enum addon_type type, u16 cache_id ){ +void addon_cache_watch( enum addon_type type, u16 cache_id ) +{ if( !cache_id ) return; struct addon_cache *cache = &addon_system.cache[type]; @@ -773,12 +871,11 @@ static void addon_cache_watch( enum addon_type type, u16 cache_id ){ vg_pool_watch( pool, cache_id ); } -static void addon_cache_unwatch( enum addon_type type, u16 cache_id ){ +void addon_cache_unwatch( enum addon_type type, u16 cache_id ) +{ if( !cache_id ) return; struct addon_cache *cache = &addon_system.cache[type]; vg_pool *pool = &cache->pool; vg_pool_unwatch( pool, cache_id ); } - -#endif /* ADDON_C */