create tile validator
authorhgn <hgodden00@gmail.com>
Wed, 22 Sep 2021 17:22:42 +0000 (18:22 +0100)
committerhgn <hgodden00@gmail.com>
Wed, 22 Sep 2021 17:22:42 +0000 (18:22 +0100)
fishladder.c

index 19340148d341e34cfb4756979f440df540443578..e8f801489ec3b89ec31664f9f8249530899e9eb4 100644 (file)
@@ -257,6 +257,91 @@ void vg_free(void)
        map_free();
 }
 
+static int cell_interactive( v2i co )
+{
+       // Bounds check
+       if( co[0] < 2 || co[0] >= world.w-2 || co[1] < 2 || co[1] >= world.h-2 )
+               return 0;
+
+       // Flags check
+       if( world.data[ world.w*co[1] + co[0] ].state & (FLAG_WALL|FLAG_INPUT|FLAG_OUTPUT) )
+               return 0;
+
+       // List of 3x3 configurations that we do not allow
+       static u32 invalid_src[][9] = 
+       { 
+               { 0,1,0,
+                 1,1,1,
+                 0,1,0 
+               },
+               { 0,0,0,
+                 0,1,1,
+                 0,1,1
+               },
+               { 0,0,0,
+                 1,1,0,
+                 1,1,0
+               },
+               { 0,1,1,
+                 0,1,1,
+                 0,0,0
+               },
+               { 1,1,0,
+                 1,1,0,
+                 0,0,0
+               },
+               { 0,1,0,
+                 0,1,1,
+                 0,1,0
+               },
+               { 0,1,0,
+                 1,1,0,
+                 0,1,0
+               }
+       };
+       
+       // Statically compile invalid configurations into bitmasks
+       static u32 invalid[ vg_list_size(invalid_src) ];
+       
+       for( int i = 0; i < vg_list_size(invalid_src); i ++ )
+       {
+               u32 comped = 0x00;
+       
+               for( int j = 0; j < 3; j ++ )
+                       for( int k = 0; k < 3; k ++ )
+                               comped |= invalid_src[i][ j*3+k ] << ((j*5)+k);
+               
+               invalid[i] = comped;
+       }
+
+       // Extract 5x5 grid surrounding tile
+       u32 blob = 0x1000;
+       for( int y = co[1]-2; y < co[1]+3; y ++ )
+               for( int x = co[0]-2; x < co[0]+3; x ++ )
+               {                
+                       struct cell *cell = &world.data[ world.w*y + x ];
+
+                       if( cell && (cell->state & (FLAG_CANAL|FLAG_INPUT|FLAG_OUTPUT)) )
+                               blob |= 0x1 << ((y-(co[1]-2))*5 + x-(co[0]-2));
+               }
+
+       // Run filter over center 3x3 grid to check for invalid configurations
+       int kernel[] = { 0, 1, 2, 5, 6, 7, 10, 11, 12 };
+       for( int i = 0; i < vg_list_size(kernel); i ++ )
+       {
+               if( blob & (0x1 << (6+kernel[i])) )
+               {
+                       u32 window = blob >> kernel[i];
+
+                       for( int j = 0; j < vg_list_size(invalid); j ++ )
+                               if((window & invalid[j]) == invalid[j])
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
 void vg_update(void)
 {
        float ratio = (float)vg_window_y / (float)vg_window_x;
@@ -279,21 +364,13 @@ void vg_update(void)
        int tile_x = floorf( tile_pos[0] );
        int tile_y = floorf( tile_pos[1] );
        
-       if( tile_x >= 2 && tile_x < world.w-2 && tile_y >= 2 && tile_y <= world.h-2 )
+       if( cell_interactive( (v2i){ tile_x, tile_y } ))// tile_x >= 2 && tile_x < world.w-2 && tile_y >= 2 && tile_y <= world.h-2 )
        {
                world.selected = tile_y * world.w + tile_x;
                
-               struct cell *cell = &world.data[tile_y*world.w+tile_x];
-               if( cell->state & (FLAG_WALL|FLAG_INPUT|FLAG_OUTPUT) )
+               if( vg_get_button_down("primary") )
                {
-                       world.selected = -1;
-               }
-               else
-               {
-                       if( vg_get_button_down("primary") )
-                       {
-                               cell->state ^= FLAG_CANAL;
-                       }
+                       world.data[ world.selected ].state ^= FLAG_CANAL;
                }
        }
        else
@@ -317,7 +394,7 @@ void vg_update(void)
                                struct cell *cell = &world.data[y*world.w+x];
 
                                if( cell->state & FLAG_INPUT )
-                                       cell->water[ buffer_next ] = 8;
+                                       cell->water[ buffer_next ] = 16;
                                else
                                {
                                        int has_source = 0;