[VID] flowing water
authorhgn <hgodden00@gmail.com>
Wed, 22 Sep 2021 13:32:04 +0000 (14:32 +0100)
committerhgn <hgodden00@gmail.com>
Wed, 22 Sep 2021 13:32:04 +0000 (14:32 +0100)
fishladder.c

index b19f58523b2161207c4d370156aaeb9e35e82ddf..19340148d341e34cfb4756979f440df540443578 100644 (file)
@@ -41,10 +41,12 @@ struct world
        struct cell
        {
                u32 state;
-               u8 water;
+               u8 water[2];
        }
        *data;
        
+       u32 frame;
+       
        struct cell_terminal
        {
                char *conditions;
@@ -169,7 +171,8 @@ static int map_load( const char *str )
                        
                        // Tile initialization
                        // row[ cx ] .. etc
-                       row[ cx ].water = 0;
+                       row[ cx ].water[0] = 0;
+                       row[ cx ].water[1] = 0;
                        
                        if( *c == '+' || *c == '-' )
                        {
@@ -296,35 +299,53 @@ void vg_update(void)
        else
                world.selected = -1;
        
-       for( int y = 1; y < world.h-1; y ++ )
+       // Simulate world
+       static int update_tick = 0;
+       update_tick ++;
+       
+       if( update_tick > 5 )
        {
-               for( int x = 1; x < world.w-1; x ++ )
+               update_tick = 0;
+               
+               u32 buffer_id = world.frame & 0x1;
+               u32 buffer_next = buffer_id ^ 0x1;
+               
+               for( int y = 1; y < world.h-1; y ++ )
                {
-                       struct cell *cell = &world.data[y*world.w+x];
-
-                       if( !(cell->state & FLAG_CANAL) )
-                               cell->water = 0;
-                       
-                       if( cell->state & FLAG_INPUT )
-                               cell->water = 8;
-                       
-                       if( cell->water )
+                       for( int x = 1; x < world.w-1; x ++ )
                        {
-                               v2i dirs[] = {{1,0},{0,1},{-1,0},{0,-1}};
-                               
-                               for( int i = 0; i < vg_list_size( dirs ); i ++ )
+                               struct cell *cell = &world.data[y*world.w+x];
+
+                               if( cell->state & FLAG_INPUT )
+                                       cell->water[ buffer_next ] = 8;
+                               else
                                {
-                                       struct cell *neighbour = &world.data[(y+dirs[i][1])*world.w+x+dirs[i][0]];
+                                       int has_source = 0;
+                                       cell->water[ buffer_next ] = 0; 
                                        
-                                       if( neighbour->state & FLAG_CANAL )
+                                       if( cell->state & FLAG_CANAL )
                                        {
-                                               neighbour->water = vg_max( neighbour->water, cell->water-1 );
+                                               v2i dirs[] = {{1,0},{0,1},{-1,0},{0,-1}};
+                                               
+                                               for( int i = 0; i < vg_list_size( dirs ); i ++ )
+                                               {
+                                                       struct cell *neighbour = &world.data[(y+dirs[i][1])*world.w+x+dirs[i][0]];
+                                                       
+                                                       if( neighbour->water[ buffer_id ] > cell->water[ buffer_next ]+1 )
+                                                       {
+                                                               has_source = 1;
+                                                               cell->water[ buffer_next ] = neighbour->water[ buffer_id ]-1;
+                                                       }
+                                               }
                                        }
+                                       
+                                       if( !has_source && cell->water[ buffer_id ] )
+                                               cell->water[ buffer_next ] = cell->water[ buffer_id ]-1;
                                }
-                               
-                               cell->water --;
                        }
                }
+               
+               world.frame ++;
        }
 }
 
@@ -356,8 +377,8 @@ void vg_render(void)
                        else if( cell->state & FLAG_OUTPUT ) { v4_copy( (v4f){ 0.2f, 0.7f, 0.3f, 1.0f }, colour ); }
                        else v4_copy( (v4f){ 0.9f, 0.9f, 0.9f, 1.0f }, colour );
                        
-                       if( cell->water )
-                               v4_copy( (v4f){ 0.2f, 0.3f, 0.7f * (float)(cell->water) * (1.0f/8.0f), 1.0f }, colour );
+                       if( cell->water[world.frame&0x1] )
+                               v4_copy( (v4f){ 0.2f, 0.3f, 0.7f * (float)(cell->water[world.frame&0x1]) * (1.0f/8.0f), 1.0f }, colour );
                        
                        if( world.selected == y*world.w + x )
                                v3_muls( colour, sinf( vg_time )*0.25f + 0.5f, colour );