speed button
[fishladder.git] / fishladder.c
index becb812d88b5bb9b48a800ad8846962b2f7509f6..e90a8a527a1f89742bf31ee007545adb01ead367 100644 (file)
@@ -38,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
@@ -185,7 +185,7 @@ struct world
        
        int w, h;
        
-       struct mesh shapes, numbers;
+       struct mesh shapes;
        struct mesh_wire
        {
                GLuint vao, vbo, ebo;
@@ -346,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 ];
@@ -705,15 +701,30 @@ static int map_load( const char *str, const char *name )
                
                // Level selection area
                
-               for( int y = 16+2; y < 16+world.h-2; y ++ )
+               // 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 = 14; x < 16; x ++ )
+                       for( int x = 0; x < 3; x ++ )
                        {
-                               u8 *px = &info_buffer[((y*64)+x)*4];
+                               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;
 
@@ -1083,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;
@@ -1094,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 )
@@ -1195,11 +1211,11 @@ 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; 
+       size = ( r2 < r1? (float)(world.w+5) * 0.5f: ((float)world.h * 0.5f) / r1 ) + 2.5f;     
        m3x3_projection( m_projection, -size, size, -size*r1, size*r1 );
        
        v3f origin;
-       origin[0] = floorf( -0.5f * world.w );
+       origin[0] = floorf( -0.5f * ((float)world.w-3.0f) );
        origin[1] = floorf( -0.5f * world.h );
        origin[2] = 0.0f;
        
@@ -1914,33 +1930,12 @@ 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}
        };
 
@@ -1992,6 +1987,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;
@@ -2041,14 +2044,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+tex_offset), 
-               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 );
@@ -2249,9 +2384,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
        // ========================================================================================================
@@ -3175,19 +3312,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;
@@ -3283,7 +3407,6 @@ void vg_free(void)
        glDeleteBuffers( 1, &world.wire.ebo );
 
        free_mesh( &world.shapes );
-       free_mesh( &world.numbers );
        
        map_free();
 }