#ifndef ROUTES_H
#define ROUTES_H
-#include "common.h"
-#include "model.h"
-#include "gate.h"
+#include "world.h"
+#include "world_info.h"
#include "shaders/vblend.h"
#include "shaders/route.h"
k_route_special_type_collector = 2
};
-enum { k_max_ui_segments = 32 };
-enum { k_route_ui_max_verts = 2000 };
-enum { k_route_ui_max_indices = 3000 };
-
-struct subworld_routes
-{
- struct route_node
- {
- v3f co, right, up, h;
- u32 next[2];
-
- u32 special_type, special_id, current_refs, ref_count;
- u32 route_ids[4]; /* Gates can be linked into up to four routes */
- }
- *nodes;
-
- u32 node_count,
- node_cap;
-
- struct route
- {
- const char *name;
- v4f colour;
-
- u32 start;
- mdl_submesh sm;
-
- int active;
- float factive;
-
- double best_lap, latest_pass; /* Session */
-
- struct
- {
- GLuint vao, vbo, ebo;
-
- u32 indices_head;
- u32 vertex_head;
-
- float last_notch;
-
- struct route_ui_segment
- {
- float length;
- u32 vertex_start, vertex_count,
- index_start, index_count;
- }
- segments[k_max_ui_segments];
-
- u32 segment_start, segment_count, fade_start, fade_count;
- double fade_timer_start;
- float xpos;
- }
- ui;
- }
- *routes;
-
- u32 route_count,
- route_cap;
-
- struct route_gate
- {
- teleport_gate gate;
-
- u32 node_id;
-
- struct route_timing
- {
- u32 version; /* Incremented on every teleport */
- double time;
- }
- timing;
- }
- *gates;
-
- struct route_collector
- {
- struct route_timing timing;
- }
- *collectors;
-
- u32 gate_count,
- gate_cap,
- collector_count,
- collector_cap;
-
- u32 active_gate,
- current_run_version;
-
- scene scene_lines;
-};
-
-static struct subworld_routes *subworld_routes(void);
-
static void debug_sbpath( struct route_node *rna, struct route_node *rnb,
u32 colour, float xoffset )
{
*/
static u32 world_routes_get_path( u32 starter, u32 stack[64] )
{
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
u32 stack_i[64];
stack[0] = starter;
*/
static void world_routes_ui_popfirst( u32 route )
{
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
struct route *pr = &r->routes[route];
if( pr->ui.segment_count )
*/
static void world_routes_ui_clear( u32 route )
{
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
struct route *pr = &r->routes[route];
pr->ui.segment_start = (pr->ui.segment_start + pr->ui.segment_count) %
k_max_ui_segments;
*/
static void world_routes_ui_newseg( u32 route )
{
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
struct route *pr = &r->routes[route];
pr->ui.last_notch = 0.0;
*/
static void world_routes_ui_updatetime( u32 route, float time )
{
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
struct route *pr = &r->routes[route];
v2f verts[2];
*/
static void world_routes_ui_notch( u32 route, float time )
{
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
struct route *pr = &r->routes[route];
if( (time - pr->ui.last_notch) > 1.0 )
float const k_bar_height = 0.05f,
k_bar_scale_x = 0.005f;
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
struct route *pr = &r->routes[route];
float cx = pr->ui.xpos;
pr->ui.xpos = vg_lerpf( pr->ui.xpos, -main_block_size * 0.5f, 0.03f );
}
+static void world_routes_local_set_record( u32 route, double lap_time )
+{
+ vg_success( " NEW LAP TIME: %f\n", lap_time );
+
+ struct subworld_routes *r = &world.routes;
+ struct route *pr = &r->routes[route];
+
+ if( pr->track_id != 0xffffffff )
+ {
+ double time_centiseconds = lap_time * 100.0;
+ if( time_centiseconds > (float)0xfffe )
+ return;
+
+ highscore_record temp;
+ temp.trackid = pr->track_id;
+ temp.datetime = time(NULL);
+ temp.playerid = 0;
+ temp.points = 0;
+ temp.time = time_centiseconds;
+
+ highscores_push_record( &temp );
+ track_infos[ pr->track_id ].push = 1;
+ }
+ else
+ {
+ vg_warn( "There is no associated track for this record...\n" );
+ }
+}
+
/*
* Will scan the whole run for two things;
* 1: we set a new record for the total, complete loop around the course
*/
static void world_routes_verify_run( u32 route )
{
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
struct route *pr = &r->routes[route];
u32 stack[64];
if( verified )
{
- vg_success( " NEW LAP TIME: %f\n", lap_time );
+ world_routes_local_set_record( route, lap_time );
world_routes_ui_popfirst(route);
pr->ui.fade_count ++;
}
*/
static void world_routes_activate_gate( u32 id )
{
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
struct route_gate *rg = &r->gates[id];
struct route_node *pnode = &r->nodes[rg->node_id],
*pdest = &r->nodes[pnode->next[0]];
*/
static void world_routes_notify_reset(void)
{
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
for( int i=0; i<r->route_count; i++ )
{
static void world_routes_debug(void)
{
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
for( int i=0; i<r->node_count; i++ )
{
}
}
-static void world_routes_free(void)
-{
- struct subworld_routes *r = subworld_routes();
-
- free( r->nodes );
- free( r->routes );
- free( r->gates );
-}
-
static void world_id_fixup( u32 *uid, mdl_header *mdl )
{
if( *uid )
*/
static void world_routes_gen_meshes(void)
{
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
scene_init( &r->scene_lines );
for( int i=0; i<r->route_count; i++ )
v3_muladds( hb.pos, up, 0.06f, vb.co );
v3_copy( up, va.norm );
v3_copy( up, vb.norm );
- v3_zero( va.colour );
- v3_zero( vb.colour );
v2_zero( va.uv );
v2_zero( vb.uv );
scene_free_offline_buffers( &r->scene_lines );
}
-static void world_routes_update(void)
-{
- struct subworld_routes *r = subworld_routes();
-
- for( int i=0; i<r->route_count; i++ )
- {
- struct route *route = &r->routes[i];
- route->factive = vg_lerpf( route->factive, route->active, 0.01f );
-
- if( route->active )
- {
- world_routes_ui_updatetime( i, vg_time - route->latest_pass );
- }
- }
-}
-
-static void bind_terrain_textures(void);
-static void render_world_routes( m4x4f projection, v3f camera )
-{
- struct subworld_routes *r = subworld_routes();
-
- m4x3f identity_matrix;
- m4x3_identity( identity_matrix );
-
- shader_route_use();
- shader_route_uTexGarbage(0);
- shader_link_standard_ub( _shader_route.id, 2 );
- bind_terrain_textures();
-
- shader_route_uPv( projection );
- shader_route_uMdl( identity_matrix );
- shader_route_uCamera( camera );
-
- scene_bind( &r->scene_lines );
-
- for( int i=0; i<r->route_count; i++ )
- {
- struct route *route = &r->routes[i];
-
- v4f colour;
- v3_lerp( (v3f){0.7f,0.7f,0.7f}, route->colour, route->factive, colour );
- colour[3] = 1.0f;
-
- shader_route_uColour( colour );
- mdl_draw_submesh( &route->sm );
- }
-}
-
-static void render_world_routes_ui(void)
-{
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBlendEquation(GL_FUNC_ADD);
-
- struct subworld_routes *r = subworld_routes();
-
- float active_offset = 0.0f;
- for( int i=0; i<r->route_count; i++ )
- {
- struct route *route = &r->routes[i];
- world_routes_ui_draw( i, route->colour, active_offset );
- active_offset += route->factive;
- }
-
- glDisable(GL_BLEND);
-}
-
-static void world_routes_register(void)
-{
- struct subworld_routes *r = subworld_routes();
- r->current_run_version = 2;
-
- shader_route_register();
- shader_routeui_register();
-}
static void world_routes_loadfrom( mdl_header *mdl )
{
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
r->nodes = NULL;
r->node_count = 0;
r->node_cap = 0;
v3_copy( inf->colour, route->colour );
route->colour[3] = 1.0f;
- route->name = NULL;
+
+ route->track_id = 0xffffffff;
+ for( u32 j=0; j<vg_list_size(track_infos); j++ )
+ {
+ if( !strcmp( mdl_pstr(mdl,pnode->pstr_name), track_infos[j].name ))
+ {
+ route->track_id = j;
+ break;
+ }
+ }
+
route->start = inf->id_start;
route->active = 0;
route->factive = 0.0f;
+ mdl_node_transform( pnode, route->scoreboard_transform );
/* OpenGL strips */
glGenVertexArrays( 1, &route->ui.vao );
world_routes_gen_meshes();
}
+/*
+ * -----------------------------------------------------------------------------
+ * Events
+ * -----------------------------------------------------------------------------
+ */
+
+static void world_routes_register(void)
+{
+ struct subworld_routes *r = &world.routes;
+ r->current_run_version = 2;
+
+ shader_route_register();
+ shader_routeui_register();
+}
+
+static void world_routes_free(void)
+{
+ struct subworld_routes *r = &world.routes;
+
+ free( r->nodes );
+ free( r->routes );
+ free( r->gates );
+}
+
+static void world_routes_update(void)
+{
+ struct subworld_routes *r = &world.routes;
+
+ for( int i=0; i<r->route_count; i++ )
+ {
+ struct route *route = &r->routes[i];
+ route->factive = vg_lerpf( route->factive, route->active, 0.01f );
+
+ if( route->active )
+ {
+ world_routes_ui_updatetime( i, vg_time - route->latest_pass );
+ }
+ }
+}
+
+static void bind_terrain_textures(void);
+static void render_world_routes( m4x4f projection, v3f camera )
+{
+ struct subworld_routes *r = &world.routes;
+
+ m4x3f identity_matrix;
+ m4x3_identity( identity_matrix );
+
+ shader_route_use();
+ shader_route_uTexGarbage(0);
+ shader_link_standard_ub( _shader_route.id, 2 );
+ bind_terrain_textures();
+
+ shader_route_uPv( projection );
+ shader_route_uMdl( identity_matrix );
+ shader_route_uCamera( camera );
+
+ scene_bind( &r->scene_lines );
+
+ for( int i=0; i<r->route_count; i++ )
+ {
+ struct route *route = &r->routes[i];
+
+ v4f colour;
+ v3_lerp( (v3f){0.7f,0.7f,0.7f}, route->colour, route->factive, colour );
+ colour[3] = 1.0f;
+
+ shader_route_uColour( colour );
+ mdl_draw_submesh( &route->sm );
+ }
+}
+
+static void render_world_routes_ui(void)
+{
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendEquation(GL_FUNC_ADD);
+
+ struct subworld_routes *r = &world.routes;
+
+ float active_offset = 0.0f;
+ for( int i=0; i<r->route_count; i++ )
+ {
+ struct route *route = &r->routes[i];
+ world_routes_ui_draw( i, route->colour, active_offset );
+ active_offset += route->factive;
+ }
+
+ glDisable(GL_BLEND);
+}
+
#endif /* ROUTES_H */