+ draw_mesh( filled_start, filled_count );
+ }
+
+ // Draw score
+ float const score_bright = 1.25f;
+ glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ),
+ 0.4f*score_bright, 0.39f*score_bright, 0.45f*score_bright, 1.0f );
+
+ use_mesh( &world.numbers );
+ draw_numbers( (v3f){ 2.0f, (float)world.h-1.875f, 0.3333f }, world.score );
+
+ // Level selection UI
+ use_mesh( &world.circle );
+ float ratio = ((float)vg_window_x/(float)vg_window_y);
+
+ m3x3f ui_view = M3X3_IDENTITY;
+ m3x3_scale( ui_view, (v3f){ 1.0f, ratio, 1.0f } );
+ glUniformMatrix3fv( SHADER_UNIFORM( shader_tile_colour, "uPv" ), 1, GL_FALSE, (float *)ui_view );
+
+ // Calculate mouse in UIsp
+ v3f mouse_ui_space = { ((float)vg_mouse[0] / (float)(vg_window_x)) * 2.0f - 1.0f,
+ (((float)vg_mouse[1] / (float)(vg_window_y)) * 2.0f - 1.0f)*(-1.0f/ratio), 0.0125f };
+
+ // Get selected level
+ const float selection_scale = 0.05f;
+ int const level_count = vg_list_size( level_pack_1 );
+ int level_select = -1;
+
+ if( mouse_ui_space[0] <= -0.8f )
+ {
+ float levels_range = (float)level_count*selection_scale*0.6f;
+ float level_offset = ((-mouse_ui_space[1] + levels_range) / levels_range) * 0.5f * (float)level_count;
+ level_select = ceilf( level_offset );
+
+ // Draw selector
+ if( level_select >= 0 && level_select < vg_list_size( level_pack_1 ) )
+ {
+ glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.369768f, 0.3654f, 0.42f, 1.0f );
+
+ use_mesh( &world.tile );
+ glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ),
+ -1.0f,
+ ((float)level_count - (float)level_select * 2.0f ) * selection_scale * 0.6f,
+ selection_scale
+ );
+ draw_mesh( 2, 2 );
+
+ use_mesh( &world.circle );
+
+ if( vg_get_button_down( "primary" ) )
+ {
+ console_changelevel( 1, level_pack_1 + level_select );
+ }
+ }
+ }
+ else mouse_ui_space[1] = INFINITY;
+
+ glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.4f, 0.39f, 0.45f, 1.0f );
+
+ // Draw levels
+ for( int i = 0; i < level_count; i ++ )
+ {
+ struct career_level *clevel = &career.levels[i];
+
+ v3f level_ui_space = {
+ -0.97f,
+ ((float)level_count - (float)i * 2.0f ) * selection_scale * 0.6f + selection_scale * 0.5f,
+ selection_scale * 0.5f
+ };
+
+ float scale = vg_clampf( 1.0f - fabsf(level_ui_space[1] - mouse_ui_space[1]) * 2.0f, 0.9f, 1.0f );
+ level_ui_space[2] *= scale;
+
+ glUniform3fv( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), 1, level_ui_space );
+
+ if( clevel->completed )
+ draw_mesh( filled_start, filled_count );
+ else
+ draw_mesh( empty_start, empty_count );
+ }
+
+ // Level scores
+ glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.4f*1.25f, 0.39f*1.25f, 0.45f*1.25f, 1.0f );
+
+ use_mesh( &world.numbers );
+ for( int i = 0; i < level_count; i ++ )
+ {
+ struct career_level *clevel = &career.levels[i];
+
+ v3f level_ui_space = {
+ -0.94f,
+ ((float)level_count - (float)i * 2.0f ) * selection_scale * 0.6f + selection_scale * 0.5f,
+ 0.02f
+ };
+
+ if( clevel->completed )
+ draw_numbers( level_ui_space, clevel->score );
+
+ level_ui_space[0] = -0.975f;
+ level_ui_space[1] -= 0.01f;
+ draw_numbers( level_ui_space, i );