X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=world_routes.c;h=52c2c2aa76ad4afad3d10211fcca13afb1e99c5b;hb=1d8d9366022c064ef56d80d463c90a79721c6243;hp=8567cdb7cc580513f120737f6bb78d5a3bf8cf75;hpb=73adac381b2c72f08293416a960942dc40db3c7f;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/world_routes.c b/world_routes.c index 8567cdb..52c2c2a 100644 --- a/world_routes.c +++ b/world_routes.c @@ -6,34 +6,38 @@ #define ROUTES_C #include +#include "entity.h" #include "world_routes.h" #include "world_gate.h" #include "world_load.h" #include "highscores.h" +#include "network.h" #include "font.h" #include "pointcloud.h" #include "gui.h" #include "steam.h" +#include "network_msg.h" +#include "network_common.h" #include "shaders/scene_route.h" #include "shaders/routeui.h" - -VG_STATIC +#if 0 +static void world_routes_local_set_record( world_instance *world, ent_route *route, f64 lap_time ) { vg_success( " NEW LAP TIME: %f\n", lap_time ); - if( route->official_track_id != 0xffffffff ){ + if( route->anon.official_track_id != 0xffffffff ){ double time_centiseconds = lap_time * 100.0; if( time_centiseconds > (float)0xfffe ) /* skill issue */ return; - struct track_info *ti = &track_infos[ route->official_track_id ]; + struct track_info *ti = &track_infos[ route->anon.official_track_id ]; highscore_record *record = &ti->record; - record->trackid = route->official_track_id; + record->trackid = route->anon.official_track_id; record->datetime = time(NULL); record->playerid = 0; record->points = 0; @@ -49,9 +53,9 @@ void world_routes_local_set_record( world_instance *world, ent_route *route, vg_warn( "There is no associated track for this record...\n" ); } } +#endif - -VG_STATIC void world_routes_clear( world_instance *world ) +static void world_routes_clear( world_instance *world ) { for( u32 i=0; ient_route ); i++ ){ ent_route *route = mdl_arritm( &world->ent_route, i ); @@ -68,7 +72,7 @@ VG_STATIC void world_routes_clear( world_instance *world ) world_static.last_use = 0.0; } -VG_STATIC void world_routes_time_lap( world_instance *world, ent_route *route ) +static void world_routes_time_lap( world_instance *world, ent_route *route ) { vg_info( "------- time lap %s -------\n", mdl_pstr(&world->meta,route->pstr_name) ); @@ -113,8 +117,25 @@ VG_STATIC void world_routes_time_lap( world_instance *world, ent_route *route ) vg_info( "%u %f\n", world_static.current_run_version, world_static.time ); if( valid_count==route->checkpoints_count ){ - double lap_time = world_static.time - start_time; - world_routes_local_set_record( world, route, lap_time ); + f64 lap_time = world_static.time - start_time; + //world_routes_local_set_record( world, route, lap_time ); + + if( route->anon.official_track_id != 0xffffffff ){ + struct track_info *ti = &track_infos[ route->anon.official_track_id ]; + if( ti->achievement_id ){ + steam_set_achievement( ti->achievement_id ); + steam_store_achievements(); + } + } + + addon_alias *alias = + &world_static.instance_addons[ world_static.active_instance ]->alias; + + char mod_uid[ ADDON_UID_MAX ]; + addon_alias_uid( alias, mod_uid ); + network_publish_laptime( mod_uid, + mdl_pstr( &world->meta, route->pstr_name ), + lap_time ); } route->valid_checkpoints = valid_count+1; @@ -126,13 +147,13 @@ VG_STATIC void world_routes_time_lap( world_instance *world, ent_route *route ) /* * When going through a gate this is called for bookkeeping purposes */ -VG_STATIC void world_routes_activate_entry_gate( world_instance *world, +static void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg ) { world_static.last_use = world_static.time; /* disable all routes and leave the world */ - if( rg->type == k_gate_type_nonlocel ){ + if( rg->flags & k_ent_gate_nonlocal ){ for( u32 i=0; ient_route); i++ ){ ent_route *route = mdl_arritm( &world->ent_route, i ); route->active_checkpoint = 0xffff; @@ -174,7 +195,7 @@ VG_STATIC void world_routes_activate_entry_gate( world_instance *world, } /* draw lines along the paths */ -VG_STATIC void world_routes_debug( world_instance *world ) +static void world_routes_debug( world_instance *world ) { for( u32 i=0; ient_route_node); i++ ){ ent_route_node *rn = mdl_arritm(&world->ent_route_node,i); @@ -223,7 +244,7 @@ VG_STATIC void world_routes_debug( world_instance *world ) } } -VG_STATIC +static void world_routes_pointcloud_spot( world_instance *world, pointcloud_buffer *pcbuf, v3f co, f32 radius, u32 samples, v4f colour ) @@ -250,15 +271,12 @@ void world_routes_pointcloud_spot( world_instance *world, v3_sub( point, pcbuf->boundary[0], pos ); v3_mul( pos, inv_ext, pos ); - for( u32 i=0; i<3; i++ ){ - vert->pos[i] = (pos[i]-0.5f) * 32767.0f; - } - float dist = 1.0f-(v3_length(jitter)); - for( u32 i=0; i<4; i++ ){ - vert->colour[i] = colour[i] * 255.0f * dist*dist; - } + v4f final_colour; + v4_muls( colour, dist*dist, final_colour ); + + pointcloud_packvert( vert, pos, final_colour ); } } @@ -270,7 +288,7 @@ void world_routes_pointcloud_spot( world_instance *world, * /#\ * -'###`- */ -VG_STATIC +static void world_routes_pointcloud_tower( world_instance *world, pointcloud_buffer *pcbuf, v3f co, f32 radius, f32 height, @@ -302,18 +320,11 @@ void world_routes_pointcloud_tower( world_instance *world, v3_sub( point, pcbuf->boundary[0], point ); v3_mul( point, inv_ext, point ); - /* TODO....... */ - for( u32 i=0; i<3; i++ ){ - vert->pos[i] = (point[i]-0.5f) * 32767.0f; - } - - for( u32 i=0; i<4; i++ ){ - vert->colour[i] = colour[i] * 255.0f; - } + pointcloud_packvert( vert, point, colour ); } } -VG_STATIC +static void world_routes_place_curve( world_instance *world, ent_route *route, v4f h[3], v3f n0, v3f n2, scene_context *scene, pointcloud_buffer *pcbuf ) @@ -374,8 +385,8 @@ void world_routes_place_curve( world_instance *world, ent_route *route, ha.dist = 8.0f; hb.dist = 8.0f; - int resa = ray_world( world, sa, down, &ha ), - resb = ray_world( world, sb, down, &hb ); + int resa = ray_world( world, sa, down, &ha, k_material_flag_ghosts ), + resb = ray_world( world, sb, down, &hb, k_material_flag_ghosts ); if( pcbuf && resa ){ world_routes_pointcloud_spot( world, pcbuf, ha.pos, @@ -435,7 +446,7 @@ void world_routes_place_curve( world_instance *world, ent_route *route, } } -VG_STATIC void world_routes_gen_meshes( world_instance *world, u32 route_id, +static void world_routes_gen_meshes( world_instance *world, u32 route_id, scene_context *sc, pointcloud_buffer *pcbuf ) { @@ -558,11 +569,11 @@ VG_STATIC void world_routes_gen_meshes( world_instance *world, u32 route_id, scene_copy_slice( sc, &route->sm ); } -VG_STATIC +static struct world_surface *world_tri_index_surface( world_instance *world, u32 index ); -VG_STATIC f64 world_routes_scatter_surface_points( world_instance *world, +static f64 world_routes_scatter_surface_points( world_instance *world, pointcloud_buffer *pcbuf, f32 rate ) { @@ -662,10 +673,6 @@ VG_STATIC f64 world_routes_scatter_surface_points( world_instance *world, v3_sub( pt, pcbuf->boundary[0], pos ); v3_mul( pos, inv_ext, pos ); - for( u32 i=0; i<3; i++ ){ - vert->pos[i] = (pos[i]-0.5f) * 32767.0f; - } - static v4f colours[] = { [k_surface_prop_concrete] = { 0.13, 0.15, 0.17, 1.0 }, [k_surface_prop_grass] = { 0.07, 0.1, 0.14, 1.0 }, @@ -675,23 +682,20 @@ VG_STATIC f64 world_routes_scatter_surface_points( world_instance *world, }; v4f col = {0.0f,0.0f,0.0f,0.0f}; - if( surf->info.surface_prop < vg_list_size(colours) ){ + if( surf->info.surface_prop < vg_list_size(colours) ) v4_copy( colours[surf->info.surface_prop], col ); - } f32 brightness = v3_dot(vn,light_dir)*0.5f+0.5f; v3_muls( col, brightness, col ); - for( u32 j=0; j<4; j++ ){ - vert->colour[j] = col[j] * 255.0f; - } + pointcloud_packvert( vert, pos, col ); } } return total_area; } -VG_STATIC void world_routes_surface_grid( world_instance *world, +static void world_routes_surface_grid( world_instance *world, pointcloud_buffer *pcbuf ) { i32 const k_gridlines = 32, @@ -728,6 +732,10 @@ VG_STATIC void world_routes_surface_grid( world_instance *world, u32 *tri = &world->scene_geo.arrindices[ idx*3 ]; v3f vs[3]; + u16 mask = k_material_flag_preview_visibile; + if( !(world->scene_geo.arrvertices[tri[0]].flags & mask) ) + continue; + for( u32 i=0; i<3; i++ ){ v3_copy( world->scene_geo.arrvertices[tri[i]].co, vs[i] ); } @@ -735,11 +743,6 @@ VG_STATIC void world_routes_surface_grid( world_instance *world, f32 t; if( ray_tri( vs, ro, dir, &t ) ){ v3_muladds( ro, dir, t, hit ); - struct world_surface *m1 = - world_tri_index_surface( world, tri[0] ); - - if( !(m1->info.flags & k_material_flag_preview_visibile) ) - continue; if( world->water.enabled ) if( hit[1] < world->water.height ) @@ -753,13 +756,7 @@ VG_STATIC void world_routes_surface_grid( world_instance *world, v3_sub( hit, pcbuf->boundary[0], co ); v3_mul( co, inv_ext, co ); - for( u32 i=0; i<3; i++ ){ - vert->pos[i] = (co[i]-0.5f) * 32767.0f; - } - - for( u32 i=0; i<4; i++ ){ - vert->colour[i] = colour[i] * 255.0f; - } + pointcloud_packvert( vert, co, colour ); } } } @@ -767,22 +764,20 @@ VG_STATIC void world_routes_surface_grid( world_instance *world, } } -VG_STATIC void world_write_preview( pointcloud_buffer *pcbuf ){ +static void world_write_preview( addon_reg *reg, pointcloud_buffer *pcbuf ){ + if( reg->alias.workshop_id ) return; + + /* + * FIXME: BUG: cannot correctly handle workshop because there is a stalling + * call below, which deadlocks the scene upload. TODO: improve the async + * stack to handle out of order execution. MAYBE + */ + char path_buf[4096]; vg_str path; vg_strnull( &path, path_buf, 4096 ); - if( world_loader.reg ){ - /* Don't want to override the one we get from the workshop */ - if( world_loader.reg->alias.workshop_id ) return; - - addon_get_content_folder( world_loader.reg, &path ); - } - else{ - vg_strcat( &path, "maps/" ); - vg_strcat( &path, world_loader.override_name ); - } - + addon_get_content_folder( reg, &path ); vg_strcat( &path, "/preview.bin" ); if( !vg_strgood( &path ) ) vg_fatal_error( "Path too long\n" ); @@ -792,14 +787,14 @@ VG_STATIC void world_write_preview( pointcloud_buffer *pcbuf ){ fwrite( pcbuf, sizeof(struct pointcloud_buffer) + sizeof(struct pointcloud_vert)*pcbuf->count, 1, fp ); fclose( fp ); + vg_info( "written %s\n", path_buf ); } /* * Create the strips of colour that run through the world along course paths */ -VG_STATIC void world_gen_routes_generate(void) -{ - world_instance *world = world_loading_instance(); +static void world_gen_routes_generate( u32 instance_id ){ + world_instance *world = &world_static.instances[ instance_id ]; vg_info( "Generating route meshes\n" ); vg_async_stall(); @@ -811,7 +806,7 @@ VG_STATIC void world_gen_routes_generate(void) vg_async_item *call_pointcloud = NULL; pointcloud_buffer *pcbuf = NULL; - if( world_loader.generate_point_cloud ){ + if( instance_id <= 1 /*world_loader.generate_point_cloud*/ ){ call_pointcloud = vg_async_alloc( sizeof(pointcloud_buffer) + sizeof(pointcloud_vert)*POINTCLOUD_POINTS ); @@ -872,8 +867,10 @@ VG_STATIC void world_gen_routes_generate(void) world_routes_gen_meshes( world, i, &world->scene_lines, pcbuf ); } - if( world_loader.generate_point_cloud ){ + if( instance_id <= 1 /*world_loader.generate_point_cloud*/ ){ f64 area = 0.0; + +#if VG_RELEASE area = world_routes_scatter_surface_points( world, pcbuf, 16.0f ); world_routes_surface_grid( world, pcbuf ); @@ -884,11 +881,12 @@ VG_STATIC void world_gen_routes_generate(void) 2.0f, 50.0f, 128, (v4f){0.2f,0.2f,0.2f,1.0f} ); } +#endif - vg_info( "Distrubuted %u points over %fkm^2!\n", + vg_info( "Distributed %u points over %fkm^2!\n", pcbuf->count, area/1e6f ); - world_write_preview( pcbuf ); + world_write_preview( world_static.instance_addons[ instance_id ], pcbuf ); vg_async_dispatch( call_pointcloud, async_pointcloud_sub ); } @@ -897,9 +895,7 @@ VG_STATIC void world_gen_routes_generate(void) } /* load all routes from model header */ -VG_STATIC void world_gen_routes_ent_init(void) -{ - world_instance *world = world_loading_instance(); +static void world_gen_routes_ent_init( world_instance *world ){ vg_info( "Initializing routes\n" ); for( u32 i=0; ient_gate); i++ ){ @@ -911,13 +907,13 @@ VG_STATIC void world_gen_routes_ent_init(void) for( u32 i=0; ient_route); i++ ){ ent_route *route = mdl_arritm(&world->ent_route,i); - mdl_transform_m4x3( &route->transform, route->board_transform ); + mdl_transform_m4x3( &route->anon.transform, route->board_transform ); - route->official_track_id = 0xffffffff; + route->anon.official_track_id = 0xffffffff; for( u32 j=0; jmeta,route->pstr_name))){ - route->official_track_id = j; + route->anon.official_track_id = j; } } @@ -934,7 +930,8 @@ VG_STATIC void world_gen_routes_ent_init(void) } } - if( gate->type == k_gate_type_teleport ){ + if( (gate->flags & k_ent_gate_linked) & + !(gate->flags & k_ent_gate_nonlocal) ){ gate = mdl_arritm(&world->ent_gate, gate->target ); for( u32 k=0; k<4; k++ ){ @@ -958,14 +955,37 @@ VG_STATIC void world_gen_routes_ent_init(void) world_routes_clear( world ); } +static void world_routes_recv_scoreboard( world_instance *world, + vg_msg *body, u32 route_id, + enum request_status status ){ + if( route_id >= mdl_arrcount( &world->ent_route ) ){ + vg_error( "Scoreboard route_id out of range (%u)\n", route_id ); + return; + } + + struct leaderboard_cache *board = &world->leaderboard_cache[ route_id ]; + board->status = status; + + if( body == NULL ) + board->data_len = 0; + + if( body->max > NETWORK_LEADERBOARD_MAX_SIZE ){ + vg_error( "Scoreboard leaderboard too big (%u>%u)\n", body->max, + NETWORK_LEADERBOARD_MAX_SIZE ); + return; + } + + memcpy( board->data, body->buf, body->max ); + board->data_len = body->max; +} + /* * ----------------------------------------------------------------------------- * Events * ----------------------------------------------------------------------------- */ -VG_STATIC void world_routes_init(void) -{ +static void world_routes_init(void){ world_static.current_run_version = 200; world_static.time = 300.0; world_static.last_use = 0.0; @@ -974,15 +994,16 @@ VG_STATIC void world_routes_init(void) shader_routeui_register(); } -VG_STATIC void world_routes_update( world_instance *world ) -{ +static void world_routes_update( world_instance *world ){ world_static.time += vg.time_delta; for( u32 i=0; ient_route); i++ ){ ent_route *route = mdl_arritm( &world->ent_route, i ); - int target = route->active_checkpoint == 0xffff? 0: 1; - route->factive = vg_lerpf( route->factive, target, 0.6f*vg.time_delta ); + int target = (route->active_checkpoint == 0xffff? 0: 1) || + skaterift.activity == k_skaterift_respawning; + route->factive = vg_lerpf( route->factive, target, + 0.6f*vg.time_frame_delta ); } for( u32 i=0; iobj.rb.to_world, &particle->obj.inf.sphere, - NULL, &world->rb_geo.inf.scene, buf ); + NULL, &world->rb_geo.inf.scene, buf, + k_material_flag_ghosts ); for( int j=0; jobj.rb; @@ -1035,16 +1056,15 @@ VG_STATIC void world_routes_fixedupdate( world_instance *world ) } } -VG_STATIC void bind_terrain_noise(void); -VG_STATIC void world_bind_light_array( world_instance *world, +static void bind_terrain_noise(void); +static void world_bind_light_array( world_instance *world, GLuint shader, GLuint location, int slot ); -VG_STATIC void world_bind_light_index( world_instance *world, +static void world_bind_light_index( world_instance *world, GLuint shader, GLuint location, int slot ); -VG_STATIC void world_routes_update_timer_texts( world_instance *world ) -{ +static void world_routes_update_timer_texts( world_instance *world ){ world_render.timer_text_count = 0; for( u32 i=0; ient_route); i++ ){ @@ -1116,8 +1136,9 @@ VG_STATIC void world_routes_update_timer_texts( world_instance *world ) highscore_intr( text->text+2, route->checkpoints_count+1, 1, ' ' ); text->text[3] = '\0'; } - - float align_r = font3d_string_width( &gui.font, 0, text->text ); + + gui_font3d.font = &gui.font; + float align_r = font3d_string_width( 0, text->text ); align_r *= size; v3f positions[] = { @@ -1132,17 +1153,20 @@ VG_STATIC void world_routes_update_timer_texts( world_instance *world ) positions[0][1] = h1; } - m3x3_copy( gate->to_world, text->transform ); + m4x3f mmdl; + ent_gate_get_mdl_mtx( gate, mmdl ); + + m3x3_copy( mmdl, text->transform ); float ratio = v3_length(text->transform[0]) / v3_length(text->transform[1]); m3x3_scale( text->transform, (v3f){ size, size*ratio, 0.1f } ); - m4x3_mulv( gate->to_world, positions[j], text->transform[3] ); + m4x3_mulv( mmdl, positions[j], text->transform[3] ); } } } -VG_STATIC void world_routes_fracture( world_instance *world, ent_gate *gate, +static void world_routes_fracture( world_instance *world, ent_gate *gate, v3f imp_co, v3f imp_v ) { world_render.text_particle_count = 0; @@ -1216,9 +1240,20 @@ VG_STATIC void world_routes_fracture( world_instance *world, ent_gate *gate, } } -VG_STATIC void render_world_routes( world_instance *world, camera *cam, - int layer_depth ) -{ +static void render_gate_markers( int run_id, ent_gate *gate ){ + for( u32 j=0; j<4; j++ ){ + if( gate->routes[j] == run_id ){ + m4x3f mmdl; + ent_gate_get_mdl_mtx( gate, mmdl ); + shader_model_gate_uMdl( mmdl ); + mdl_draw_submesh( &world_gates.sm_marker[j] ); + break; + } + } +} + +static void render_world_routes( world_instance *world, camera *cam, + int layer_depth ){ m4x3f identity_matrix; m4x3_identity( identity_matrix ); @@ -1254,7 +1289,7 @@ VG_STATIC void render_world_routes( world_instance *world, camera *cam, /* timers * ---------------------------------------------------- */ if( layer_depth == 0 ){ - font3d_bind( &gui.font, cam ); + font3d_bind( &gui.font, k_font_shader_default, 0, world, cam ); for( u32 i=0; iroute->factive; shader_model_font_uColour( colour ); - font3d_simple_draw( &gui.font, 0, text->text, cam, text->transform ); + font3d_simple_draw( 0, text->text, cam, text->transform ); } shader_model_font_uOffset( (v4f){0.0f,0.0f,0.0f,1.0f} ); @@ -1309,34 +1344,48 @@ VG_STATIC void render_world_routes( world_instance *world, camera *cam, /* skip writing into the motion vectors for this */ glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } ); + glDisable( GL_CULL_FACE ); - for( u32 i=0; ient_route); i++ ){ - ent_route *route = mdl_arritm( &world->ent_route, i ); + if( skaterift.activity == k_skaterift_respawning ){ + for( u32 i=0; ient_route); i++ ){ + ent_route *route = mdl_arritm( &world->ent_route, i ); - if( route->active_checkpoint != 0xffff ){ v4f colour; - float brightness = 0.3f + world->ub_lighting.g_day_phase; - v3_muls( route->colour, brightness, colour ); - colour[3] = 1.0f-route->factive; + v3_muls( route->colour, 1.6666f, colour ); + colour[3] = 0.0f; shader_model_gate_uColour( colour ); - u32 next = route->active_checkpoint+1+layer_depth; - next = next % route->checkpoints_count; - next += route->checkpoints_start; + for( u32 j=0; jent_gate); j ++ ){ + ent_gate *gate = mdl_arritm( &world->ent_gate, j ); + if( !(gate->flags & k_ent_gate_nonlocal) ) + render_gate_markers( i, gate ); + } + } + } + else{ + for( u32 i=0; ient_route); i++ ){ + ent_route *route = mdl_arritm( &world->ent_route, i ); - ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, next ); - ent_gate *gate = mdl_arritm( &world->ent_gate, cp->gate_index ); - shader_model_gate_uMdl( gate->to_world ); + if( route->active_checkpoint != 0xffff ){ + v4f colour; + float brightness = 0.3f + world->ub_lighting.g_day_phase; + v3_muls( route->colour, brightness, colour ); + colour[3] = 1.0f-route->factive; - for( u32 j=0; j<4; j++ ){ - if( gate->routes[j] == i ){ - mdl_draw_submesh( &world_gates.sm_marker[j] ); - break; - } + shader_model_gate_uColour( colour ); + + u32 next = route->active_checkpoint+1+layer_depth; + next = next % route->checkpoints_count; + next += route->checkpoints_start; + + ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, next ); + ent_gate *gate = mdl_arritm( &world->ent_gate, cp->gate_index ); + render_gate_markers( i, gate ); } } } + glEnable( GL_CULL_FACE ); glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 } ); }