}
void write_generic_addon_inf( u32 type, const char *title,
- const char *content, const char *dest )
+ const char *content, const char *dest, u32 flags )
{
u8 descriptor_buf[ 512 ];
vg_msg descriptor = {0};
vg_msg_wkvnum( &descriptor, "type", k_vg_msg_u32, 1, &type );
vg_msg_end_frame( &descriptor );
vg_msg_wkvstr( &descriptor, "content", content );
+ if( flags )
+ vg_msg_wkvnum( &descriptor, "flags", k_vg_msg_u32, 1, &flags );
write_msg( &descriptor, dest );
}
vg_info( "Building game metadata\n" );
write_generic_addon_inf( k_addon_type_board,
"Longboard", "board.mdl",
- "content_skaterift/boards/skaterift_long/addon.inf");
+ "content_skaterift/boards/skaterift_long/addon.inf", 0 );
write_generic_addon_inf( k_addon_type_board,
"Fractal", "board.mdl",
- "content_skaterift/boards/skaterift_fract/addon.inf");
+ "content_skaterift/boards/skaterift_fract/addon.inf", 0 );
write_generic_addon_inf( k_addon_type_board,
"Striped", "board.mdl",
- "content_skaterift/boards/skaterift_striped/addon.inf");
+ "content_skaterift/boards/skaterift_striped/addon.inf", 0 );
write_generic_addon_inf( k_addon_type_board,
"Licco", "board.mdl",
- "content_skaterift/boards/skaterift_licco/addon.inf");
+ "content_skaterift/boards/skaterift_licco/addon.inf", 0 );
write_generic_addon_inf( k_addon_type_board,
"Hypno", "board.mdl",
- "content_skaterift/boards/skaterift_spiral/addon.inf");
+ "content_skaterift/boards/skaterift_spiral/addon.inf", 0 );
write_generic_addon_inf( k_addon_type_board,
"Shark", "board.mdl",
- "content_skaterift/boards/skaterift_shark/addon.inf");
+ "content_skaterift/boards/skaterift_shark/addon.inf", 0 );
write_generic_addon_inf( k_addon_type_player,
"De'folde", "ch_new.mdl",
- "content_skaterift/playermodels/skaterift_new/addon.inf" );
+ "content_skaterift/playermodels/skaterift_new/addon.inf", 0 );
write_generic_addon_inf( k_addon_type_player,
"Jordan", "ch_jordan.mdl",
- "content_skaterift/playermodels/skaterift_jordan/addon.inf" );
+ "content_skaterift/playermodels/skaterift_jordan/addon.inf", 0 );
write_generic_addon_inf( k_addon_type_player,
"Outlaw", "ch_outlaw.mdl",
- "content_skaterift/playermodels/skaterift_outlaw/addon.inf" );
+ "content_skaterift/playermodels/skaterift_outlaw/addon.inf", 0 );
write_generic_addon_inf( k_addon_type_player,
"Chip", "ch_chip.mdl",
- "content_skaterift/playermodels/skaterift_chip/addon.inf" );
+ "content_skaterift/playermodels/skaterift_chip/addon.inf", 0 );
write_generic_addon_inf( k_addon_type_player,
"Aaron", "ch_aaron.mdl",
- "content_skaterift/playermodels/skaterift_aaron/addon.inf" );
+ "content_skaterift/playermodels/skaterift_aaron/addon.inf", 0 );
+ write_generic_addon_inf( k_addon_type_player,
+ "J", "ch_j.mdl",
+ "content_skaterift/playermodels/skaterift_j/addon.inf", 0 );
+ write_generic_addon_inf( k_addon_type_player,
+ "Ela", "ch_ela.mdl",
+ "content_skaterift/playermodels/skaterift_ela/addon.inf", 0 );
+
+ write_generic_addon_inf( k_addon_type_player,
+ "Jesus", "ch_jesus.mdl",
+ "content_skaterift/playermodels/skaterift_jesus/addon.inf", ADDON_REG_HIDDEN );
+ write_generic_addon_inf( k_addon_type_player,
+ "FBI", "ch_fbi.mdl",
+ "content_skaterift/playermodels/skaterift_fbi/addon.inf", ADDON_REG_HIDDEN );
+ write_generic_addon_inf( k_addon_type_player,
+ "FBI2", "ch_fbi2.mdl",
+ "content_skaterift/playermodels/skaterift_fbi2/addon.inf", ADDON_REG_HIDDEN );
+ write_generic_addon_inf( k_addon_type_player,
+ "President", "ch_president.mdl",
+ "content_skaterift/playermodels/skaterift_president/addon.inf", ADDON_REG_HIDDEN );
+
+
+ struct
+ {
+ const char *title, *location, *file;
+ u32 flags;
+ }
+ maps[] =
+ {
+ { "Mt.Zero Island", "Australia", "content_skaterift/maps/mp_mtzero/addon.inf", ADDON_REG_CAMPAIGN | ADDON_REG_MTZERO | ADDON_REG_PREMIUM },
+ { "Flat World", "...", "content_skaterift/maps/dev_flatworld/addon.inf", ADDON_REG_CAMPAIGN | ADDON_REG_HIDDEN },
+ { "Heaven", "...", "content_skaterift/maps/dev_heaven/addon.inf", ADDON_REG_CAMPAIGN | ADDON_REG_HIDDEN },
+ { "Valley", "Cambodia", "content_skaterift/maps/mp_line1/addon.inf", ADDON_REG_CAMPAIGN | ADDON_REG_PREMIUM },
+ { "Training Island", "Australia", "content_skaterift/maps/dev_tutorial/addon.inf", ADDON_REG_CAMPAIGN },
+ { "Center Island", "Australia", "content_skaterift/maps/dev_hub/addon.inf", ADDON_REG_CAMPAIGN },
+ { "Downtown", "USA, Georgia", "content_skaterift/maps/mp_spawn/addon.inf", ADDON_REG_CAMPAIGN | ADDON_REG_CITY | ADDON_REG_PREMIUM }
+ };
+
+ for( u32 i=0; i<VG_ARRAY_LEN(maps); i ++ )
+ {
+ u8 descriptor_buf[ 512 ];
+ vg_msg descriptor = {0};
+ descriptor.buf = descriptor_buf;
+ descriptor.max = sizeof(descriptor_buf);
+ vg_msg_frame( &descriptor, "workshop" );
+ {
+ vg_msg_wkvstr( &descriptor, "title", maps[i].title );
+ vg_msg_wkvstr( &descriptor, "author", "Skaterift" );
+ u32 type = k_addon_type_world;
+ vg_msg_wkvnum( &descriptor, "type", k_vg_msg_u32, 1, &type );
+ }
+ vg_msg_end_frame( &descriptor );
+ vg_msg_wkvstr( &descriptor, "content", "main.mdl" );
+ if( maps[i].flags )
+ vg_msg_wkvnum( &descriptor, "flags", k_vg_msg_u32, 1, &maps[i].flags );
+ write_msg( &descriptor, maps[i].file );
+ }
}
#define _S( NAME, VS, FS ) \
u32 get_index_from_addon( enum addon_type type, addon_reg *a, u32 whitelist, u32 blacklist )
{
- u32 count = 0;
- for( u32 i=0; count<addon_system.registry_type_counts[type]; i++ )
+ u32 typecount = 0, count = 0;
+ for( u32 i=0; typecount<addon_system.registry_type_counts[type]; i++ )
{
addon_reg *reg = &addon_system.registry[i];
if( reg->alias.type == type )
{
+ typecount ++;
+
if( addon_filter( reg, whitelist, blacklist ) )
{
if( reg == a )
/*
* If the addon.inf exists int the folder, load into the reg
*/
-static int addon_try_load_metadata( addon_reg *reg, vg_str folder_path ){
+static int addon_try_load_metadata( addon_reg *reg, vg_str folder_path )
+{
vg_str meta_path = folder_path;
vg_strcat( &meta_path, "/addon.inf" );
- if( !vg_strgood( &meta_path ) ){
+ if( !vg_strgood( &meta_path ) )
+ {
vg_error( "The metadata path is too long\n" );
return 0;
}
FILE *fp = fopen( meta_path.buffer, "rb" );
- if( !fp ){
+ if( !fp )
+ {
vg_error( "Could not open the '%s'\n", meta_path.buffer );
return 0;
}
reg->metadata_len = fread( reg->metadata, 1, 512, fp );
- if( reg->metadata_len != 512 ){
- if( !feof(fp) ){
+ if( reg->metadata_len != 512 )
+ {
+ if( !feof(fp) )
+ {
fclose(fp);
vg_error( "unknown error codition" );
reg->metadata_len = 0;
return 1;
}
-static void addon_print_info( addon_reg *reg ){
+static void addon_print_info( addon_reg *reg )
+{
vg_info( "addon_reg #%u{\n", addon_system.registry_count );
vg_info( " type: %d\n", reg->alias.type );
vg_info( " workshop_id: " PRINTF_U64 "\n", reg->alias.workshop_id );
vg_info( " folder: [%u]%s\n", reg->foldername_hash, reg->alias.foldername );
vg_info( " metadata_len: %u\n", reg->metadata_len );
vg_info( " cache_id: %hu\n", reg->cache_id );
+ vg_info( " flags: %hu\n", reg->flags );
vg_info( "}\n" );
}
/*
* Mount a local folder. may or may not have addon.inf
*/
-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;
addon_set_foldername( reg, folder_name );
addon_try_load_metadata( reg, folder_path );
- if( reg->metadata_len == 0 )
+ if( reg->metadata_len )
+ {
+ vg_msg msg;
+ vg_msg_init( &msg, reg->metadata, reg->metadata_len );
+
+ u32 flags = 0x00;
+ vg_msg_getkvintg( &msg, "flags", k_vg_msg_u32, &flags, NULL );
+ reg->flags |= flags;
+ }
+ else
{
/* create our own content commands */
vg_msg msg;
vg_warn( "Creating own metadata for: %s\n", folder_path.buffer );
vg_dir subdir;
- if( !vg_dir_open(&subdir, folder_path.buffer) ){
+ if( !vg_dir_open(&subdir, folder_path.buffer) )
+ {
vg_error( "Failed to open '%s'\n", folder_path.buffer );
return NULL;
}
- while( vg_dir_next_entry(&subdir) ){
- if( vg_dir_entry_type(&subdir) == k_vg_entry_type_file ){
+ while( vg_dir_next_entry(&subdir) )
+ {
+ if( vg_dir_entry_type(&subdir) == k_vg_entry_type_file )
+ {
const char *fname = vg_dir_entry_name(&subdir);
vg_str file = folder_path;
vg_strcat( &file, "/" );
if( !content_count ) return NULL;
if( msg.error == k_vg_msg_error_OK )
reg->metadata_len = msg.cur.co;
- else{
+ else
+ {
vg_error( "Error creating metadata: %d\n", msg.error );
return NULL;
}
*/
int addon_get_content_folder( addon_reg *reg, vg_str *folder, int async)
{
- if( reg->alias.workshop_id ){
+ if( reg->alias.workshop_id )
+ {
struct async_workshop_filepath_info *info = NULL;
vg_async_item *call = NULL;
- if( async ){
+ if( async )
+ {
call = vg_async_alloc( sizeof(struct async_workshop_filepath_info) );
info = call->payload;
}
info->id = reg->alias.workshop_id;
info->len = folder->len;
- if( async ){
+ if( async )
+ {
vg_async_dispatch( call, async_workshop_get_filepath );
vg_async_stall(); /* too bad! */
}
- else {
+ else
+ {
async_workshop_get_filepath( info, 0 );
}
- if( info->buf[0] == '\0' ){
- vg_error( "Failed SteamAPI_GetItemInstallInfo(" PRINTF_U64 ")\n",
- reg->alias.workshop_id );
+ if( folder->buffer[0] == '\0' )
+ {
+ vg_error( "Failed SteamAPI_GetItemInstallInfo(" PRINTF_U64 ")\n", reg->alias.workshop_id );
return 0;
}
folder->i = strlen( folder->buffer );
return 1;
}
- else{
+ else
+ {
folder->i = 0;
const char *local_folder =
char foldername[ ADDON_FOLDERNAME_MAX ];
};
-#define ADDON_REG_HIDDEN 0x1
-#define ADDON_REG_MTZERO 0x2
-#define ADDON_REG_CITY 0x4
-#define ADDON_REG_PREMIUM 0x8
-
-#define ADDON_REG_CAMPAIGN 0x10
-#define ADDON_REG_WORKSHOP 0x20
-#define ADDON_REG_VENUS 0x40
-#define ADDON_REG_INFINITE 0x80
-
struct addon_system
{
struct addon_reg
u8 metadata[512]; /* vg_msg buffer */
u32 metadata_len;
u32 flags;
-
u16 cache_id;
}
*registry;
#define ADDON_MOUNTED_MAX 128 /* total count that we have knowledge of */
#define ADDON_UID_MAX 76
+#define ADDON_REG_HIDDEN 0x1
+#define ADDON_REG_MTZERO 0x2
+#define ADDON_REG_CITY 0x4
+#define ADDON_REG_PREMIUM 0x8
+
+#define ADDON_REG_CAMPAIGN 0x10
+#define ADDON_REG_WORKSHOP 0x20
+#define ADDON_REG_VENUS 0x40
+#define ADDON_REG_INFINITE 0x80
+
#ifdef VG_ENGINE
struct addon_type_info
static void menu_update_world_filter(void)
{
menu.world_list_whitelist = 0;
- menu.world_list_blacklist = 0;//ADDON_REG_HIDDEN;
+ menu.world_list_blacklist = ADDON_REG_HIDDEN;
if( world_map.superworld_list_selected == k_superworld_campaign )
menu.world_list_whitelist = ADDON_REG_CAMPAIGN;
menu.world_list_whitelist, menu.world_list_blacklist );
menu.world_list_entries[ menu.world_list_display_count ] = reg;
+ const char *name = NULL;
+
vg_msg msg;
vg_msg_init( &msg, reg->metadata, reg->metadata_len );
- const char *name = vg_msg_getkvstr( &msg, "location" );
+ if( vg_msg_seekframe( &msg, "workshop" ) )
+ {
+ name = vg_msg_getkvstr( &msg, "title" );
+ }
if( !name )
name = reg->alias.foldername;
char buf[128];
vg_str str;
vg_strnull( &str, buf, sizeof(buf) );
- u32 colour;
+ u32 colour = 0;
network_status_string( &str, &colour );
menu_standard_widget( ctx, inner_online_panel, label_box, 1 );
ui_text( ctx, label_box, buf, 1, k_ui_align_middle_left, colour );
skaterift.override_load_world = arg;
}
-static addon_reg *skaterift_mount_world_unloadable( const char *path, u32 ext )
-{
- addon_reg *reg = addon_mount_local_addon( path, k_addon_type_world, ".mdl" );
- if( !reg ) vg_fatal_error( "world not found\n" );
- reg->flags |= (ext);
- return reg;
-}
-
-static void skaterift_load_world_content(void)
-{
- /* hub world */
- _world.default_hub_addon = skaterift_mount_world_unloadable( "maps/dev_hub", ADDON_REG_CAMPAIGN );
- skaterift_mount_world_unloadable( "maps/dev_heaven", ADDON_REG_CAMPAIGN | ADDON_REG_HIDDEN );
- skaterift_mount_world_unloadable( "maps/mp_spawn", ADDON_REG_CAMPAIGN | ADDON_REG_CITY|ADDON_REG_PREMIUM );
- skaterift_mount_world_unloadable( "maps/mp_mtzero", ADDON_REG_CAMPAIGN | ADDON_REG_MTZERO|ADDON_REG_PREMIUM );
- skaterift_mount_world_unloadable( "maps/dev_tutorial",ADDON_REG_CAMPAIGN );
- skaterift_mount_world_unloadable( "maps/dev_flatworld", ADDON_REG_HIDDEN );
- skaterift_mount_world_unloadable( "maps/mp_line1", ADDON_REG_CAMPAIGN | ADDON_REG_PREMIUM );
-}
-
static void skaterift_load_player_content(void)
{
particle_alloc( &particles_grind, 300 );
vg_loader_set_user_information( "Loading content files" );
vg_loader_step( audio_init, NULL );
- vg_loader_step( skaterift_load_world_content, NULL );
+
+ _world.default_hub_addon = addon_mount_local_addon( "maps/dev_hub", k_addon_type_world, ".mdl" );
+ if( !_world.default_hub_addon )
+ vg_fatal_error( "Hub world not found\n" );
+
vg_console_load_autos();
vg_loader_set_user_information( "Mounting addons" );
#endif
AF_LOAD_ARRAY_STRUCT( af, &world->ent_spawn, ent_spawn, heap );
+
+ if( af_arrcount( &world->ent_spawn ) == 0 )
+ {
+ vg_warn( "There are no spawn points in the world; defaulting to first non-local gate.\n" );
+ world->ent_spawn.data = vg_linear_alloc( heap, 1*sizeof(ent_spawn) );
+ world->ent_spawn.count = 1;
+ world->ent_spawn.stride = sizeof(ent_spawn);
+
+ ent_gate *found_gate = NULL;
+ for( u32 i=0; i<af_arrcount( &world->ent_gate ); i ++ )
+ {
+ ent_gate *gate = af_arritm( &world->ent_gate, i );
+ if( gate->flags & k_ent_gate_nonlocal )
+ {
+ found_gate = gate;
+ break;
+ }
+ }
+
+ ent_spawn *fallback_spawn = af_arritm( &world->ent_spawn, 0 );
+ fallback_spawn->pstr_name = 0;
+ q_identity( fallback_spawn->transform.q );
+ v3_copy( (v3f){1,1,1}, fallback_spawn->transform.s );
+
+ if( found_gate )
+ v3_copy( found_gate->co[0], fallback_spawn->transform.co );
+ else
+ {
+ vg_warn( "There are no non-local gates either. Defaulting to 0,0,0.\n" );
+ v3_zero( fallback_spawn->transform.co );
+ }
+ }
+
AF_LOAD_ARRAY_STRUCT( af, &world->ent_light, ent_light, heap );
AF_LOAD_ARRAY_STRUCT( af, &world->ent_route_node,ent_route_node, heap );
AF_LOAD_ARRAY_STRUCT( af, &world->ent_path_index,ent_path_index, heap );
f32 a = v3_dot(v0,v1);
cam.fov = acosf( a ) * 45.0f;
- cam.angles[0] -= 0.07f*a + ofs[0]*0.1f;
- cam.angles[1] += 0.03f*a + ofs[1]*0.1f;
+ cam.angles[0] -= /*0.07f*a*/ + ofs[0]*0.1f;
+ cam.angles[1] += /*0.03f*a*/ + ofs[1]*0.1f;
cam.angles[2] = ofs[2]*0.01f;
world_map_update_final_camera( &cam );
vg_framebuffer_bind( g_render.fb_workshop_preview, 1.0f );
glClearColor( 0.02f,0.02f,0.08f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
+ glDisable( GL_CULL_FACE );
vg_camera cam, *smooth_cam = &world_map.superworld_cam;
ent_camera *cam_temp = af_arritm( &world_map.ent_camera, world_map.superworld_list_selected );