a mess but stable
[carveJwlIkooP6JGAAIwe30JlM.git] / world_routes_ui.c
1 #include "skaterift.h"
2 #include "world_routes_ui.h"
3 #include "world_routes.h"
4 #include "player.h"
5
6 static u32 v4_rgba( v4f colour ){
7 u32 r = vg_minf(1.0f,colour[0])*255.0f,
8 g = vg_minf(1.0f,colour[1])*255.0f,
9 b = vg_minf(1.0f,colour[2])*255.0f,
10 a = vg_minf(1.0f,colour[3])*255.0f;
11
12 return r | (g<<8) | (b<<16) | (a<<24);
13 }
14
15 static void ent_route_imgui( ui_context *ctx,
16 world_instance *world, ent_route *route,
17 ui_point inout_cursor ){
18 if( route->flags & k_ent_route_flag_out_of_zone )
19 return;
20
21 u32 last_version=0;
22 f64 last_time = 0.0;
23 ent_checkpoint *last_cp = NULL;
24
25 u32 valid_sections=0;
26
27 struct time_block{
28 f32 length, best;
29 int clean;
30 }
31 blocks[ route->checkpoints_count ];
32
33 for( u32 i=0; i<route->checkpoints_count; i++ ){
34 u32 cpid = i+route->active_checkpoint+1;
35 cpid %= route->checkpoints_count;
36 cpid += route->checkpoints_start;
37
38 ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, cpid );
39 ent_gate *rg = mdl_arritm( &world->ent_gate, cp->gate_index );
40 rg = mdl_arritm( &world->ent_gate, rg->target );
41
42 if( last_version+1 == rg->timing_version ) {
43 struct time_block *block = &blocks[ valid_sections ++ ];
44 block->clean = (rg->flags & k_ent_gate_clean_pass)? 1: 0;
45 block->length = rg->timing_time - last_time;
46 block->best = last_cp? last_cp->best_time: 0.0f;
47 }
48 else valid_sections = 0;
49
50 last_version = rg->timing_version;
51 last_time = rg->timing_time;
52 last_cp = cp;
53 }
54
55 if( last_version+1 == world_static.current_run_version ){
56 struct time_block *block = &blocks[ valid_sections ++ ];
57 block->clean = localplayer.rewinded_since_last_gate? 0: 1;
58 block->length = world_static.time - last_time;
59 block->best = last_cp->best_time;
60 }
61 else
62 valid_sections = 0;
63
64 u32 colour = v4_rgba( route->colour ) | 0xff000000;
65
66 ui_px x = 0,
67 h = route->factive * 16.0f,
68 base = inout_cursor[0];//(f32)vg.window_x*0.5f - route->ui_stopper;
69
70 if( route->ui_residual > 0.0f )
71 {
72 ui_px w = route->ui_residual_block_w,
73 total = w + 4;
74
75 f32 t = vg_smoothstepf(1.0f-route->ui_residual);
76
77 x -= (f32)total * t;
78
79 ui_rect rect = { base+x, inout_cursor[1], w, h };
80
81 v4f fadecolour;
82 v4_copy( route->colour, fadecolour );
83 fadecolour[3] *= route->ui_residual;
84
85 ui_fill( ctx, rect, v4_rgba(fadecolour) );
86
87 x += total;
88 }
89
90 int got_first = 0;
91
92 for( u32 i=0; i<valid_sections; i ++ )
93 {
94 struct time_block *block = &blocks[ i ];
95 ui_px w = 20 + (block->length * 6.0f);
96 ui_rect rect = { base+x, inout_cursor[1], w, h };
97 ui_fill( ctx, rect, colour );
98
99 if( block->clean )
100 ui_outline( ctx, rect, 1, 0xff00ffff, 0 );
101
102 if( block->best != 0.0f )
103 {
104 char buf[32];
105 vg_str str;
106 vg_strnull( &str, buf, 32 );
107
108 f32 diff = block->length - block->best,
109 as = fabsf(diff),
110 s = floorf( as ),
111 ds = floorf( vg_fractf( as ) * 10.0f );
112
113 if( (block->best != 0.0f) && (fabsf(diff) > 0.001f) )
114 {
115 if( diff > 0.0f )
116 vg_strcatch( &str, '+' );
117 else
118 vg_strcatch( &str, '-' );
119
120 vg_strcati32( &str, s );
121 vg_strcatch( &str, '.' );
122 vg_strcati32( &str, ds );
123
124 ui_text( ctx, rect, buf, 1, k_ui_align_middle_center, 0 );
125 }
126 }
127
128 x += w + 4;
129
130 if( !got_first ){
131 route->ui_first_block_width = w;
132 got_first = 1;
133 }
134 }
135
136 for( u32 i=0; i<route->checkpoints_count-valid_sections; i++ )
137 {
138 struct time_block *block = &blocks[ i ];
139
140 ui_px w = 20;
141 ui_rect rect = { base+x, inout_cursor[1], w, h };
142 ui_outline( ctx, rect, -1, colour, 0 );
143 x += w + 4;
144
145 if( !got_first )
146 {
147 route->ui_first_block_width = w;
148 got_first = 1;
149 }
150 }
151
152 inout_cursor[1] += h + 4;
153
154 vg_slewf( &route->ui_residual, 0.0f, vg.time_frame_delta );
155 route->ui_stopper = vg_lerpf( route->ui_stopper, (f32)x*0.5f,
156 vg.time_frame_delta );
157 }
158
159 void world_routes_imgui( ui_context *ctx, world_instance *world )
160 {
161 if( skaterift.activity == k_skaterift_menu ) return;
162
163 ui_point cursor = { 4, 4 };
164 for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ )
165 {
166 ent_route_imgui( ctx, world, mdl_arritm( &world->ent_route, i ), cursor );
167 }
168 }