#ifndef ROUTES_H
#define ROUTES_H
-#include "common.h"
-#include "model.h"
-#include "gate.h"
+#include "world.h"
#include "world_info.h"
-#include "highscores.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
- {
- u32 track_id;
- 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;
-
- m4x3f scoreboard_transform;
- }
- *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;
{
vg_success( " NEW LAP TIME: %f\n", lap_time );
- struct subworld_routes *r = subworld_routes();
+ struct subworld_routes *r = &world.routes;
struct route *pr = &r->routes[route];
if( pr->track_id != 0xffffffff )
*/
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];
*/
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++ )
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;
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 */