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;
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
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;