switch to multiple runs conditions
authorhgn <hgodden00@gmail.com>
Sat, 20 Nov 2021 11:30:02 +0000 (11:30 +0000)
committerhgn <hgodden00@gmail.com>
Sat, 20 Nov 2021 11:30:02 +0000 (11:30 +0000)
fishladder.c
maps/level6.map [new file with mode: 0644]
maps/xor.map [new file with mode: 0644]

index de9da68cac28ba2d7dc9acff593111af255e80ae..1d93a6088e15d24f782e55fb63b274140aa102d9 100644 (file)
@@ -10,7 +10,8 @@ const char *level_pack_1[] = {
        "level2", 
        "level3", 
        "level4",
-       "level5"
+       "level5",
+       "level6"
 };
 
 #pragma pack(push,1)
@@ -57,7 +58,7 @@ static void career_load(void)
                u32 const size_levels = sizeof(struct career_state)-size_header;
                u32 const size_levels_input = sz - size_header;
                
-               memcpy( (void*)career.levels, (void*)cr->levels, size_levels );
+               memcpy( (void*)career.levels, (void*)cr->levels, size_levels_input );
                
                if( sz < sizeof( struct career_state ) )
                {
@@ -190,20 +191,31 @@ struct world
        u32 sim_frame;
        float sim_start;
        int simulating;
+       u32 sim_run;
        
        float frame_lerp;
        
        struct cell_terminal
        {
-               // TODO: Split into input/output structures
-               char *conditions;
-               char recv[12];
-               int recv_count;
+               //char *conditions;
+               //char recv[12];
+               
+               struct terminal_run
+               {
+                       char conditions[8];
+                       char recieved[8];
+                       
+                       int condition_count, recv_count;
+               }
+               runs[8];
+               
+               int run_count;
+               
                int id;
        }
        *io;
        
-       u32 w, h;
+       int w, h;
        
        struct mesh tile, circle, numbers;
        
@@ -237,10 +249,7 @@ struct world
 } world = {};
 
 static void map_free(void)
-{
-       for( int i = 0; i < arrlen( world.io ); i ++ )
-               arrfree( world.io[ i ].conditions );
-       
+{      
        arrfree( world.data );
        arrfree( world.io );
        
@@ -292,9 +301,12 @@ static int map_load( const char *str, const char *name )
                                {
                                        if( reg_start < reg_end )
                                        {
+                                               struct cell_terminal *terminal = &world.io[ reg_start ];
+                                               struct terminal_run *run = &terminal->runs[ terminal->run_count-1 ];
+
                                                if( *c >= 'a' && *c <= 'z' )
-                                               {
-                                                       arrpush( world.io[ reg_start ].conditions, *c );
+                                               {                                                       
+                                                       run->conditions[ run->condition_count ++ ] = *c;
                                                }
                                                else
                                                {
@@ -305,6 +317,11 @@ static int map_load( const char *str, const char *name )
                                                                if( *c == '\n' )
                                                                        break;
                                                        }
+                                                       else if( *c == ':' )
+                                                       {
+                                                               terminal->runs[ terminal->run_count ].condition_count = 0;
+                                                               terminal->run_count ++;
+                                                       }
                                                        else
                                                        {
                                                                vg_error( "Unkown attribute '%c' (row: %u)\n", *c, world.h );
@@ -353,8 +370,11 @@ static int map_load( const char *str, const char *name )
                        
                        if( *c == '+' || *c == '-' )
                        {
-                               struct cell_terminal term = { .id = cx + world.h*world.w };
-                               arrpush( world.io, term );
+                               struct cell_terminal *term = arraddnptr( world.io, 1 );
+                               term->id = cx + world.h*world.w;
+                               term->run_count = 1;
+                               term->runs[0].condition_count = 0;
+
                                cell->state = *c == '+'? FLAG_INPUT: FLAG_OUTPUT;
                                reg_end ++;
                        }
@@ -426,8 +446,16 @@ static void map_serialize( FILE *stream )
                                                fputc( ',', stream );
                                        terminal_write_count ++;
                                
-                                       for( int j = 0; j < arrlen( term->conditions ); j ++ )
-                                               fputc( term->conditions[j], stream );
+                                       for( int j = 0; j < term->run_count; j ++ )
+                                       {
+                                               struct terminal_run *run = &term->runs[j];
+                                               
+                                               for( int k = 0; k < run->condition_count; k ++ )
+                                                       fputc( run->conditions[k], stream );
+                                                       
+                                               if( j < term->run_count-1 )
+                                                       fputc( ':', stream );
+                                       }
                                }
                        }
                }
@@ -488,7 +516,9 @@ static int console_load_map( int argc, char const *argv[] )
                
                if( text_source )
                {
-                       map_load( text_source, argv[0] );
+                       if( !map_load( text_source, argv[0] ) )
+                               map_free();
+                       
                        free( text_source );
                        
                        // Update career link
@@ -518,14 +548,24 @@ static int console_load_map( int argc, char const *argv[] )
        }
 }
 
+static void io_reset(void)
+{
+       for( int i = 0; i < arrlen( world.io ); i ++ )
+       {
+               struct cell_terminal *term = &world.io[i];
+               
+               for( int j = 0; j < term->run_count; j ++ )
+                       term->runs[j].recv_count = 0;
+       }
+}
+
 static void simulation_stop(void)
 {
        world.simulating = 0;
        world.num_fishes = 0;
        world.sim_frame = 0;
        
-       for( int i = 0; i < arrlen( world.io ); i ++ )
-               world.io[i].recv_count = 0;
+       io_reset();
        
        sfx_system_fadeout( &audio_system_balls_rolling, 44100 );
        
@@ -872,11 +912,21 @@ void vg_update(void)
                {
                        world.selected = world.tile_y * world.w + world.tile_x;
                        
+                       static u32 modify_state = 0;
+                       
+                       struct cell *cell_ptr = &world.data[world.selected];
+                       
                        if( vg_get_button_down("primary") )
                        {
-                               world.data[ world.selected ].state ^= FLAG_CANAL;
-                                                               
-                               if( world.data[ world.selected ].state & FLAG_CANAL )
+                               modify_state = (cell_ptr->state & FLAG_CANAL) ^ FLAG_CANAL;
+                       }
+                       
+                       if( vg_get_button("primary") && ((cell_ptr->state & FLAG_CANAL) != modify_state) )
+                       {
+                               cell_ptr->state &= ~FLAG_CANAL;
+                               cell_ptr->state |= modify_state;
+                       
+                               if( cell_ptr->state & FLAG_CANAL )
                                {
                                        sfx_set_playrnd( &audio_tile_mod, &audio_system_sfx, 3, 6 );
                                        world.score ++;
@@ -915,12 +965,9 @@ void vg_update(void)
                        world.sim_start = vg_time;
                        
                        for( int i = 0; i < world.w*world.h; i ++ )
-                       {
                                world.data[ i ].state &= ~FLAG_FLIP_FLOP;
-                       }
                        
-                       for( int i = 0; i < arrlen( world.io ); i ++ )
-                               world.io[i].recv_count = 0;
+                       io_reset();
                }
        }
 
@@ -965,7 +1012,10 @@ void vg_update(void)
                                                
                                                if( term->id == fish->pos[1]*world.w + fish->pos[0] )
                                                {
-                                                       term->recv[ term->recv_count ++ ] = fish->payload;
+                                                       struct terminal_run *run = &term->runs[ world.sim_run ];
+                                                       if( run->recv_count < vg_list_size( run->recieved ) )
+                                                               run->recieved[ run->recv_count ++ ] = fish->payload;
+                                                       
                                                        break;
                                                }
                                        }
@@ -1077,13 +1127,13 @@ void vg_update(void)
                                
                                if( is_input )
                                {
-                                       if( world.sim_frame < arrlen( term->conditions ) )
+                                       if( world.sim_frame < term->runs[ world.sim_run ].condition_count )
                                        {
                                                struct fish *fish = &world.fishes[world.num_fishes++];
                                                fish->pos[0] = posx;
                                                fish->pos[1] = posy;
                                                fish->alive = 1;
-                                               fish->payload = term->conditions[world.sim_frame];
+                                               fish->payload = term->runs[ world.sim_run ].conditions[ world.sim_frame ];
                                                
                                                int can_spawn = 0;
                                                
@@ -1116,11 +1166,13 @@ void vg_update(void)
                                        
                                        if( !is_input )
                                        {
-                                               if( term->recv_count == arrlen( term->conditions ) )
+                                               struct terminal_run *run = &term->runs[ world.sim_run ];
+                                       
+                                               if( run->recv_count == run->condition_count )
                                                {
-                                                       for( int j = 0; j < arrlen( term->conditions ); j ++ )
+                                                       for( int j = 0; j < run->condition_count; j ++ )
                                                        {
-                                                               if( term->recv[j] != term->conditions[j] )
+                                                               if( run->recieved[j] != run->conditions[j] )
                                                                {
                                                                        world.completed = 0;
                                                                        break;
@@ -1509,14 +1561,15 @@ void vg_render(void)
 
                v4f dot_colour = { 0.0f, 0.0f, 0.0f, 1.0f };
                
-               for( int j = 0; j < arrlen( term->conditions ); j ++ )
+               // TODO: Iterate runs
+               for( int j = 0; j < term->runs[0].condition_count; j ++ )
                {
                        float y_offset = is_input? 1.2f: -0.2f;
                        glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), (float)posx + 0.2f + 0.2f * (float)j, (float)posy + y_offset, 0.1f );
                        
                        if( is_input )
                        {
-                               colour_code_v3( term->conditions[j], dot_colour );
+                               colour_code_v3( term->runs[0].conditions[j], dot_colour );
                                glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour );
                        
                                // Draw filled if tick not passed, draw empty if empty
@@ -1527,16 +1580,16 @@ void vg_render(void)
                        }
                        else
                        {
-                               if( term->recv_count > j )
+                               if( term->runs[0].recv_count > j )
                                {
-                                       colour_code_v3( term->recv[j], dot_colour );
+                                       colour_code_v3( term->runs[0].recieved[j], dot_colour );
                                        v3_muls( dot_colour, 0.8f, dot_colour );
                                        glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour );
                                        
                                        draw_mesh( filled_start, filled_count );
                                }
                                
-                               colour_code_v3( term->conditions[j], dot_colour );
+                               colour_code_v3( term->runs[0].conditions[j], dot_colour );
                                glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour );
                                
                                draw_mesh( empty_start, empty_count );
@@ -1629,6 +1682,24 @@ void vg_render(void)
                        draw_mesh( empty_start, empty_count );
        }
        
+       // Level scores
+       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 );
+               }
+       }
+       
        //use_mesh( &world.numbers );
        //draw_numbers( (v3f){ 0.0f, -0.5f, 0.1f }, 128765 );
 }
diff --git a/maps/level6.map b/maps/level6.map
new file mode 100644 (file)
index 0000000..a9802d1
--- /dev/null
@@ -0,0 +1,15 @@
+#################;
+##-###########-##;acac,acac
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+########+########;aaaacccc
+#################;
diff --git a/maps/xor.map b/maps/xor.map
new file mode 100644 (file)
index 0000000..ca66c87
--- /dev/null
@@ -0,0 +1,15 @@
+#################;
+########-########;c:c:
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+##             ##;
+#####+##+#####+##;:a:,a::a,c:c:c
+#################;