level smooth transition camera
[fishladder.git] / fishladder.c
index d6f3ef007f2ff57ec0b95bc5f2dfef04e151a0a5..fcdd58d4fe014c5d4ae3de204315e036e7a29af6 100644 (file)
@@ -1,38 +1,12 @@
 // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
 
+//#define VG_CAPTURE_MODE
 #define VG_STEAM
 #define VG_STEAM_APPID 1218140U
 #include "vg/vg.h"
 #include "fishladder_resources.h"
 
-/*
-       Todo for release:
-               Tutorial levels:
-                       1. Transport
-                       2. Split
-                       3. Merge (and explode)
-                       4. Principle 1 (divide colours)
-                       5. Principle 2 (combine colours)
-                       
-               Trainee levels:
-                       Simple maths                    (x3)
-                       Colour ordering                 (x2)
-                       Routing problems                (x2)
-                       
-               Medium levels:
-                       Reverse order
-               
-               New things to program:
-                       UI text element renderer (SDF)                          DONE(sorta)
-                       Particle system thing for ball collision        
-                       Level descriptions / titles                                     HALF
-                       Row Gridlines for I/O                                                   DONE
-                       Play button / Speed controller                          PLAY/PAUSED.. todo: speed, wire connecty
-                       
-                       
-       After release:
-               
-*/
+// #define STEAM_LEADERBOARDS
 
 // CONSTANTS
 // ===========================================================================================================
@@ -64,7 +38,7 @@ enum e_world_button
        k_world_button_none = -1,
        k_world_button_sim = 0,
        k_world_button_pause = 1,
-       k_world_button_wire_mode = 2
+       k_world_button_speedy = 2
 };
 
 #define FLAG_CANAL             0x1
@@ -211,7 +185,7 @@ struct world
        
        int w, h;
        
-       struct mesh shapes, numbers;
+       struct mesh shapes;
        struct mesh_wire
        {
                GLuint vao, vbo, ebo;
@@ -372,10 +346,6 @@ static void use_mesh( struct mesh *m )
        glBindVertexArray( m->vao );
 }
 
-
-
-
-
 static struct cell_button *get_wbutton( enum e_world_button btn )
 {
        return &world.buttons[ btn ];
@@ -728,6 +698,35 @@ static int map_load( const char *str, const char *name )
                                px[3] = 0;
                        }
                }
+               
+               // Level selection area
+               
+               // Beginner
+               for( int y = 16+2; y < 16+2+4; y ++ )
+               {
+                       u8 *px = &info_buffer[((y*64)+16-1)*4];
+                       px[0] = 0x10;
+               }
+               
+               // Intermediate
+               for( int y = 16+2; y < 16+2+6; y ++ )
+               {
+                       for( int x = 0; x < 3; x ++ )
+                       {
+                               u8 *px = &info_buffer[((y*64)+16-5+x)*4];
+                               px[0] = 0x10;
+                       }
+               }
+               
+               // Expert
+               for( int x = 1; x < 5; x ++ )
+               {
+                       u8 *px = &info_buffer[((16*64)+16-5+x)*4];
+                       px[0] = 0x10;
+               }
+               
+               info_buffer[(((16+world.h-3)*64)+world.w+16-1)*4] = 0x30;
+               info_buffer[(((16+world.h-2)*64)+world.w+16-1)*4] = 0x30;
 
                // Random walks.. kinda
                for( int i = 0; i < arrlen(world.io); i ++ )
@@ -1095,7 +1094,7 @@ static void simulation_start(void)
        world.sim_frame = 0;
        world.sim_run = 0;
        
-       world.sim_delta_speed = 2.5f;
+       world.sim_delta_speed = world.buttons[ k_world_button_speedy ].pressed? 10.0f: 2.5f;
        world.sim_delta_ref = vg_time;
        world.sim_internal_ref = 0.0f;
        world.sim_internal_time = 0.0f;
@@ -1106,6 +1105,11 @@ static void simulation_start(void)
        clear_animation_flags();
        
        io_reset();
+       
+       if( world.pCmpLevel )
+       {
+               world.pCmpLevel->completed_score = 0;
+       }
 }
 
 static int world_check_pos_ok( v2i co )
@@ -1207,16 +1211,23 @@ void vg_update(void)
                        r2 = (float)world.h / (float)world.w,
                        size;
        
-       size = ( r2 < r1? (float)world.w * 0.5f: ((float)world.h * 0.5f) / r1 ) + 2.5f; 
-       m3x3_projection( m_projection, -size, size, -size*r1, size*r1 );
+       static float size_current = 2.0f;
+       static v3f origin_current = { 0.0f, 0.0f, 0.0f };
+       
+       size = ( r2 < r1? (float)(world.w+5) * 0.5f: ((float)(world.h+5) * 0.5f) / r1 ) + 0.5f; 
        
        v3f origin;
-       origin[0] = floorf( -0.5f * world.w );
+       origin[0] = floorf( -0.5f * ((float)world.w-4.5f) );
        origin[1] = floorf( -0.5f * world.h );
        origin[2] = 0.0f;
        
+       // Lerp towards target
+       size_current = vg_lerpf( size_current, size, vg_time_delta * 6.0f );
+       v2_lerp( origin_current, origin, vg_time_delta * 6.0f, origin_current ); 
+       
+       m3x3_projection( m_projection, -size_current, size_current, -size_current*r1, size_current*r1 );
        m3x3_identity( m_view );
-       m3x3_translate( m_view, origin );
+       m3x3_translate( m_view, origin_current );
        m3x3_mul( m_projection, m_view, vg_pv );
        vg_projection_update();
        
@@ -1279,7 +1290,7 @@ void vg_update(void)
                        
                        if( vg_get_button_up("secondary") && world.id_drag_from == world.selected )
                        {
-                               u32 link_id = local_x > 0.5f? 1: 0;
+                               u32 link_id = cell_ptr->links[ 0 ]? 0: 1;
                                
                                // break existing connection off
                                if( cell_ptr->links[ link_id ] )
@@ -1297,7 +1308,7 @@ void vg_update(void)
                                world.id_drag_from = 0;
                        }
                        
-                       if( world.id_drag_from && (cell_ptr->state & FLAG_CANAL) && (cell_ptr->config == k_cell_type_split) )
+                       else if( world.id_drag_from && (cell_ptr->state & FLAG_CANAL) && (cell_ptr->config == k_cell_type_split) )
                        {
                                world.drag_to_co[0] = (float)world.tile_x + (local_x > 0.5f? 0.75f: 0.25f);
                                world.drag_to_co[1] = (float)world.tile_y + 0.25f;
@@ -1369,6 +1380,9 @@ void vg_update(void)
                
                world.sim_target = (int)floorf(world.sim_internal_time);
                
+               int success_this_frame = 0;
+               int failure_this_frame = 0;
+               
                while( world.sim_frame < world.sim_target )
                {
                        sfx_set_playrnd( &audio_random, &audio_system_balls_switching, 0, 8 );
@@ -1416,7 +1430,16 @@ void vg_update(void)
                                                        {
                                                                struct terminal_run *run = &term->runs[ world.sim_run ];
                                                                if( run->recv_count < vg_list_size( run->recieved ) )
+                                                               {
+                                                                       if( fish->payload == run->conditions[ run->recv_count ] )
+                                                                               success_this_frame = 1;
+                                                                       else
+                                                                               failure_this_frame = 1;
+                                                               
                                                                        run->recieved[ run->recv_count ++ ] = fish->payload;
+                                                               }
+                                                               else
+                                                                       failure_this_frame = 1;
                                                                
                                                                break;
                                                        }
@@ -1762,6 +1785,21 @@ void vg_update(void)
                        world.sim_frame ++;
                }
                
+               // Sounds
+               if( failure_this_frame )
+               {
+                       sfx_set_play( &audio_tones, &audio_system_balls_extra, 0 );
+               }
+               else if( success_this_frame )
+               {
+                       static int succes_counter = 0;
+                       
+                       sfx_set_play( &audio_tones, &audio_system_balls_extra, 1+(succes_counter++) );
+                       
+                       if( succes_counter == 7 )
+                               succes_counter = 0;
+               }
+               
                // Position update
                // =====================================================================================================
                
@@ -1899,39 +1937,19 @@ static void render_tiles( v2i start, v2i end, v4f const regular_colour, v4f cons
        }
 }
 
-/*
-static void draw_numbers( v3f coord, int number )
-{
-       v3f pos;
-       v3_copy( coord, pos );
-       int digits[8]; int i = 0;
-       
-       while( number > 0 && i < 8 )
-       {               
-               digits[i ++] = number % 10;
-               number = number / 10;
-       }
-       
-       for( int j = 0; j < i; j ++ )
-       {
-               glUniform3fv( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), 1, pos );
-               draw_mesh( MESH_NUMBERS_OFFSETS[digits[i-j-1]][0], MESH_NUMBERS_OFFSETS[digits[i-j-1]][1] );
-               pos[0] += pos[2] * 0.75f;
-       }
-}*/
-
-static void wbutton_run( enum e_world_button btn_name )
+static void wbutton_run( enum e_world_button btn_name, v2f btn_tex )
 {
        static v3f button_colours[] = {
                {0.204f, 0.345f, 0.553f},
                {0.204f, 0.345f, 0.553f},
-               {0.741f, 0.513f, 0.078f},
+               {0.553f, 0.345f, 0.204f},
                {1.0f, 0.0f, 0.0f}
        };
 
        struct cell_button *btn = &world.buttons[btn_name];
        
        // Interaction
+       int tex_offset = 0;
        
        int is_hovering = (world.tile_x == world.w-1 && world.tile_y == world.h-btn_name-2)?1:0;        
        if( vg_get_button_up( "primary" ) && is_hovering )
@@ -1976,6 +1994,14 @@ static void wbutton_run( enum e_world_button btn_name )
                        else
                                world.pause_offset_target = 0.0f;
                }
+               else if( btn_name == k_world_button_speedy )
+               {
+                       btn->pressed ^= 0x1;
+                       
+                       world.sim_delta_speed = btn->pressed? 10.0f: 2.5f;
+                       world.sim_delta_ref = vg_time;
+                       world.sim_internal_ref = world.sim_internal_time;
+               }
                else
                {
                        btn->pressed ^= 0x1;
@@ -2010,6 +2036,13 @@ static void wbutton_run( enum e_world_button btn_name )
        btn->light = vg_lerpf( btn->light, btn->light_target, vg_time_delta*26.0f );
        
        // Draw
+       if( btn_name == k_world_button_sim && world.buttons[ k_world_button_sim ].pressed )
+       {
+               if( world.buttons[ k_world_button_pause ].pressed )
+                       tex_offset = 3;
+               else
+                       tex_offset = 2;
+       }
        
        v4f final_colour;
        v3_copy( button_colours[ btn_name ], final_colour );
@@ -2018,14 +2051,146 @@ static void wbutton_run( enum e_world_button btn_name )
        glUniform4f( SHADER_UNIFORM( shader_buttons, "uOffset" ), 
                world.w-1, 
                world.h-btn_name-2, 
-               (float)btn_name
-               3.0f 
+               (float)(btn_tex[0]+tex_offset)
+               btn_tex[1]
        );
        glUniform4fv( SHADER_UNIFORM( shader_buttons, "uColour" ), 1, final_colour );
        
        draw_mesh( 0, 2 );
 }
 
+static void wbutton_draw( v2i pos, v2f tex, v4f colour )
+{
+       glUniform4f( SHADER_UNIFORM( shader_buttons, "uOffset" ), 
+               pos[0], 
+               pos[1], 
+               tex[0], 
+               tex[1] 
+       );
+       glUniform4fv( SHADER_UNIFORM( shader_buttons, "uColour" ), 1, colour );
+       draw_mesh( 0, 2 );
+}
+
+static void level_selection_buttons(void)
+{
+       v3f tutorial_colour = { 0.204f, 0.345f, 0.553f };
+       v3f locked_colour = { 0.2f, 0.2f, 0.2f };
+
+       struct button_grid
+       {
+               v3f primary_colour;
+               v2i origin;
+               v2i dims;
+               struct cmp_level *levels;
+               int count;
+       }
+       grids[] = 
+       {
+               {
+                       .primary_colour = { 0.204f, 0.345f, 0.553f },
+                       .origin = { -1, 2 },
+                       .dims = { 1, 4 },
+                       .levels = cmp_levels_tutorials,
+                       .count = vg_list_size( cmp_levels_tutorials )
+               },
+               {
+                       .primary_colour = { 0.304f, 0.245f, 0.553f },
+                       .origin = { -5, 2 },
+                       .dims = { 3, 6 },
+                       .levels = cmp_levels_basic,
+                       .count = vg_list_size( cmp_levels_basic )
+               },
+               {
+                       .primary_colour = { 0.553f, 0.345f, 0.204f },
+                       .origin = { -4, 0 },
+                       .dims = { 4, 1 },
+                       .levels = cmp_levels_grad,
+                       .count = vg_list_size( cmp_levels_grad )
+               }
+       };
+       
+       v2f tex_coord = { 0.0f, 0.0f };
+       v4f final_colour = { 0.0f, 0.0f, 0.0f, 0.2f };
+       v2i button_pos;
+       static struct cmp_level *select_from = NULL;
+       struct cmp_level *switch_level_to = NULL;
+       
+       if( vg_get_button_down( "primary" ) )
+               select_from = NULL;
+       
+       for( int i = 0; i < vg_list_size( grids ); i ++ )
+       {
+               struct button_grid *grid = &grids[i];
+               
+               int j = 0;
+               
+               for( int x = 0; x < grid->dims[0]; x ++ )
+               {
+                       for( int y = 0; y < grid->dims[1]; y ++ )
+                       {
+                               if( j < grid->count )
+                               {
+                                       struct cmp_level *lvl = &grid->levels[ j ];
+                                       
+                                       // Determine colour
+                                       if( lvl->unlocked )
+                                       {
+                                               if( lvl->is_tutorial )
+                                                       v3_copy( tutorial_colour, final_colour );
+                                               else
+                                                       v3_copy( grid->primary_colour, final_colour );
+                                                       
+                                               if( lvl->completed_score )
+                                                       final_colour[3] = 0.8f;
+                                               else
+                                                       final_colour[3] = 0.2f;
+                                       }
+                                       else v3_copy( locked_colour, final_colour );
+                                       
+                                       v2i_add( grid->origin, (v2i){ x,y }, button_pos );
+                                       int is_hovering = v2i_eq( (v2i){world.tile_x, world.tile_y}, button_pos );
+                               
+                                       if( is_hovering )
+                                       {
+                                               final_colour[3] += 0.1f;
+                                               
+                                               // Up click
+                                               if( vg_get_button_up( "primary" ) )
+                                                       if( select_from == lvl && lvl->unlocked )
+                                                       {
+                                                               switch_level_to = lvl;
+                                                               sfx_set_play( &audio_clicks, &audio_system_ui, 1 );
+                                                       }
+                                               
+                                               // Start click
+                                               if( vg_get_button_down( "primary" ) )
+                                                       select_from = lvl;
+                                               
+                                               if( vg_get_button( "primary" ) )
+                                                       final_colour[3] += 0.2f;
+                                       }
+                                       
+                                       if( world.pCmpLevel == lvl )
+                                               final_colour[3] += fabsf(sinf( vg_time * 2.0f )) * 0.2f;
+                                       
+                                       wbutton_draw( (v2i){ grid->origin[0] + x, grid->origin[1] + y }, tex_coord, final_colour );
+                               }
+                               else break;
+                               
+                               j ++;
+                       }
+               }
+       }
+       
+       if( switch_level_to )
+       {
+               if( console_changelevel( 1, &switch_level_to->map_name ) )
+               {
+                       world.pCmpLevel = switch_level_to;
+               }
+       }
+}
+
 void vg_render(void)
 {
        glViewport( 0,0, vg_window_x, vg_window_y );
@@ -2043,6 +2208,9 @@ void vg_render(void)
        int const empty_start = circle_base+32;
        int const empty_count = circle_base+32*2;
        
+       if( !world.initialzed )
+               return;
+       
        // BACKGROUND
        // ========================================================================================================
        use_mesh( &world.shapes );
@@ -2223,9 +2391,11 @@ void vg_render(void)
        vg_tex2d_bind( &tex_buttons, 0 );
        glUniform1i( SHADER_UNIFORM( shader_buttons, "uTexMain" ), 0 );
        
-       wbutton_run( k_world_button_sim );
-       wbutton_run( k_world_button_pause );
-       //wbutton_run( k_world_button_wire_mode );
+       wbutton_run( k_world_button_sim, (v2f){ 0.0f, 3.0f } );
+       wbutton_run( k_world_button_pause, (v2f){ 1.0f, 3.0f } );
+       wbutton_run( k_world_button_speedy, (v2f){ 0.0f, 2.0f } );
+       
+       level_selection_buttons();
        
        // WIRES
        // ========================================================================================================
@@ -2540,6 +2710,7 @@ ui_data;
 
 void vg_ui(void)
 {
+       /*
        // UI memory
        static int pack_selection = 0;
        static struct pack_info
@@ -2581,7 +2752,7 @@ void vg_ui(void)
                gui_capture_mouse( 9999 );
                gui_fill_rect( ui_global_ctx.cursor, 0xff5a4e4d );
                
-               gui_text( "ASSIGNMENTS", 8, 0 );
+               gui_text( "ASSIGNMENTS", 32, 0 );
                
                ui_global_ctx.cursor[1] += 30;
                ui_global_ctx.cursor[3] = 25;
@@ -2602,7 +2773,7 @@ void vg_ui(void)
                                        pack_selection = i;
                                
                                ui_global_ctx.cursor[1] += 2;
-                               gui_text( pack_is_unlocked? pack_infos[i].name: "???", 4, 0 );
+                               gui_text( pack_is_unlocked? pack_infos[i].name: "???", 24, 0 );
                                gui_end_right();
                                
                                gui_reset_colours();
@@ -2674,18 +2845,18 @@ void vg_ui(void)
                                                }
                                                
                                                ui_global_ctx.override_colour = 0xffffffff;
-                                               gui_text( lvl_info->title, 6, 0 );
+                                               gui_text( lvl_info->title, 24, 0 );
                                                ui_global_ctx.cursor[1] += 18;
-                                               gui_text( lvl_info->completed_score>0? "passed": "incomplete", 4, 0 );
+                                               gui_text( lvl_info->completed_score>0? "passed": "incomplete", 24, 0 );
                                        }
                                        else
                                        {
                                                gui_button( 2 + i );
                                                
                                                ui_global_ctx.override_colour = 0xff786f6f;
-                                               gui_text( "???", 6, 0 );
+                                               gui_text( "???", 24, 0 );
                                                ui_global_ctx.cursor[1] += 18;
-                                               gui_text( "locked", 4, 0 );
+                                               gui_text( "locked", 24, 0 );
                                        }
                                        
                                        gui_end_down();
@@ -2715,7 +2886,7 @@ void vg_ui(void)
                        
                        gui_fill_rect( ui_global_ctx.cursor, 0xff5a4e4d );
                        ui_global_ctx.cursor[1] += 4;
-                       gui_text( ui_data.level_selected->title, 6, 0 );
+                       gui_text( ui_data.level_selected->title, 24, 0 );
                        
                        ui_global_ctx.cursor[1] += 30;
                        ui_rect_pad( ui_global_ctx.cursor, 8 );
@@ -2727,11 +2898,11 @@ void vg_ui(void)
                        }
                        gui_end_down();
                        
-                       ui_text_use_paragraph( &ui_global_ctx );
+                       //ui_text_use_paragraph( &ui_global_ctx );
                        ui_global_ctx.cursor[1] += 2;
                        
-                       gui_text( ui_data.level_selected->description, 5, 0 );
-                       ui_text_use_title( &ui_global_ctx );
+                       gui_text( ui_data.level_selected->description, 16, 0 );
+                       //ui_text_use_title( &ui_global_ctx );
                        
                        // Buttons at the bottom
                        ui_global_ctx.cursor[3] = 25;
@@ -2744,7 +2915,7 @@ void vg_ui(void)
                        {
                                ui_data.level_selected = NULL;
                        }
-                       gui_text( "BACK", 6, k_text_alignment_center );
+                       gui_text( "BACK", 24, k_text_alignment_center );
                        gui_end();
                        
                        gui_align_right();
@@ -2758,7 +2929,7 @@ void vg_ui(void)
                                
                                ui_global_ctx.override_colour = 0xff888888;
                                
-                               gui_text( "RESTORE SOLUTION", 6, k_text_alignment_center );
+                               gui_text( "RESTORE SOLUTION", 24, k_text_alignment_center );
                                gui_end_right();
                                ui_global_ctx.override_colour = 0xffffffff;
                        }
@@ -2778,7 +2949,7 @@ void vg_ui(void)
                                                ui_data.leaderboard_show = 0;
                                        }
                                }
-                               gui_text( "PLAY", 6, k_text_alignment_center );
+                               gui_text( "PLAY", 24, k_text_alignment_center );
                                gui_end();
                        }
                        
@@ -2796,7 +2967,7 @@ void vg_ui(void)
                        gui_new_node();
                        {
                                gui_fill_rect( ui_global_ctx.cursor, 0xff5a4e4d );
-                               gui_text( "FRIEND LEADERBOARD", 6, 0 );
+                               gui_text( "FRIEND LEADERBOARD", 24, 0 );
                        }
                        gui_end_down();
                        
@@ -2817,7 +2988,7 @@ void vg_ui(void)
                                                
                                                // 1,2,3 ...
                                                static const char *places[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
-                                               gui_text( places[i], 7, 0 );
+                                               gui_text( places[i], 24, 0 );
                                                ui_global_ctx.cursor[0] += 32;
                                                
                                                struct leaderboard_player *player = &ui_data.leaderboard_players[i];
@@ -2833,12 +3004,12 @@ void vg_ui(void)
                                                gui_end_right();
                                                
                                                // Players name
-                                               gui_text( player->player_name, 7, 0 );
+                                               gui_text( player->player_name, 24, 0 );
                                                
                                                ui_global_ctx.cursor[2] = 50;
                                                gui_align_right();
                                                
-                                               gui_text( player->score_text, 7, k_text_alignment_right );
+                                               gui_text( player->score_text, 24, k_text_alignment_right );
                                        }
                                        gui_end_down();
                                        
@@ -2848,10 +3019,12 @@ void vg_ui(void)
                        gui_end();
                }
        }
+       */
 }
 
 void leaderboard_dispatch_score(void)
 {
+#if STEAM_LEADERBOARDS
        sw_upload_leaderboard_score( 
                ui_data.upload_request.level->steam_leaderboard, 
                k_ELeaderboardUploadScoreMethodKeepBest,
@@ -2863,10 +3036,12 @@ void leaderboard_dispatch_score(void)
        ui_data.upload_request.is_waiting = 0;
        
        vg_success( "Dispatched leaderboard score\n" );
+#endif
 }
 
 void leaderboard_found( LeaderboardFindResult_t *pCallback )
 {
+#ifdef STEAM_LEADERBOARDS
        if( !pCallback->m_bLeaderboardFound )
        {
                vg_error( "Leaderboard could not be found\n" );
@@ -2896,10 +3071,12 @@ void leaderboard_found( LeaderboardFindResult_t *pCallback )
                        }
                }
        }
+#endif
 }
 
 void leaderboard_downloaded( LeaderboardScoresDownloaded_t *pCallback )
 {
+#ifdef STEAM_LEADERBOARDS
        // Update UI if this leaderboard matches what we currently have in view
        if( ui_data.level_selected->steam_leaderboard == pCallback->m_hSteamLeaderboard )
        {
@@ -2934,10 +3111,12 @@ void leaderboard_downloaded( LeaderboardScoresDownloaded_t *pCallback )
                        ui_data.leaderboard_show = 0;
        }
        else vg_warn( "Downloaded leaderboard does not match requested!\n" );
+#endif
 }
 
 void leaderboard_set_score( struct cmp_level *cmp_level, u32 score )
 {
+#ifdef STEAM_LEADERBOARDS
        if( ui_data.upload_request.is_waiting )
                vg_warn( "You are uploading leaderboard entries too quickly!\n" );
                
@@ -2950,6 +3129,7 @@ void leaderboard_set_score( struct cmp_level *cmp_level, u32 score )
                leaderboard_dispatch_score();
        else
                sw_find_leaderboard( cmp_level->map_name );
+#endif
 }
 
 // CONSOLE COMMANDS
@@ -3073,8 +3253,10 @@ static int console_changelevel( int argc, char const *argv[] )
 void vg_start(void)
 {
        // Steamworks callbacks
+       #ifdef STEAM_LEADERBOARDS
        sw_leaderboard_found = &leaderboard_found;
        sw_leaderboard_downloaded = &leaderboard_downloaded;
+       #endif
 
        vg_function_push( (struct vg_cmd){
                .name = "_map_write",
@@ -3137,19 +3319,6 @@ void vg_start(void)
                init_mesh( &world.shapes, combined_mesh, vg_list_size( combined_mesh ) );
        }
        
-       // Numbers mesh
-       {
-               init_mesh( &world.numbers,
-                       MESH_NUMBERS_BUFFER,
-                       vg_list_size( MESH_NUMBERS_BUFFER )
-               );
-               
-               for( int i = 0; i < 10; i ++ )
-               {
-                       vg_info( "offset: %u, length: %u\n", MESH_NUMBERS_OFFSETS[i][0], MESH_NUMBERS_OFFSETS[i][1] );
-               }
-       }
-       
        // Create wire mesh
        {
                int const num_segments = 64;
@@ -3245,7 +3414,6 @@ void vg_free(void)
        glDeleteBuffers( 1, &world.wire.ebo );
 
        free_mesh( &world.shapes );
-       free_mesh( &world.numbers );
        
        map_free();
 }