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;
+ }
+ }
+ }
}
/*
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';
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" );
}
}
}
+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 */
#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"
#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;
char foldername[ ADDON_FOLDERNAME_MAX ];
u32 foldername_hash;
- void *userdata;
+ u16 cache_id;
enum addon_state{
k_addon_state_none,
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;
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 */
return 0;
}
+#if 0
/*
* Get an existing cache instance, allocate a new one to be loaded, or NULL if
* there is no space
}
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 ){
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;
}
}
* -----------------------------------------------------------------------------
*/
-/*
- * 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
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 );
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 );
}
}
* 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 __)
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 ) ){
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;
*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 );
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;
}
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;
"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;
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;
global_skateshop.render.reg_id = global_skateshop.selected_board_id;
}
- addon_reg *reg = cache_ptr->reg_ptr;
-
/* Skin title
* ----------------------------------------------------------------- */
m3x3_zero( mlocal );
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)
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 );
#include "workshop.h"
#include "addon.h"
-#define SKATESHOP_VIEW_SLOT_MAX 6
+#define SKATESHOP_VIEW_SLOT_MAX 2
struct{
v3f look_target;
float factive;
struct shop_view_slot{
- struct cache_board *cache_ptr;
+ u16 cache_id;
float view_blend;
}
shop_view_slots[ SKATESHOP_VIEW_SLOT_MAX ];
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;
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 */
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 */
/* 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 );
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 ] ){
_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;
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();
_uniform_model_entity_uLightsIndex, 4 );
}
- mesh_bind( &board->mesh );
+ mesh_bind( &board->mdl.mesh );
m4x4f m4mdl;
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 );
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 */
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],
};
struct player_model{
- glmesh mesh;
- GLuint texture;
+ struct dynamic_model_1texture mdl;
};
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 );
#include "vg/vg_perlin.h"
#include "menu.h"
#include "ent_skateshop.h"
+#include "addon.h"
VG_STATIC void player__skate_bind( 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 */
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 ) ){
#ifndef SAVE_C
#define SAVE_C
+#include "save.h"
+#include "vg/vg_msg.h"
+
struct {
u8 buf[1024];
u32 len;
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 );
}
}
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!! */
}
#define VG_3D
#define VG_GAME
#define VG_MSG_V1_SUPPORT
+#define VG_LOG_SOURCE_INFO
#include "vg/vg.h"
#include "common.h"
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,