+ // Reclassify world. TODO: Move into own function
+ for( int y = 2; y < world.h-2; y ++ )
+ {
+ for( int x = 2; x < world.w-2; x ++ )
+ {
+ v2i dirs[] = {{1,0},{0,1},{-1,0},{0,-1}};
+
+ u8 config = 0x00;
+
+ if( world.data[y*world.w+x].state & FLAG_CANAL )
+ {
+ 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->state & (FLAG_CANAL|FLAG_INPUT|FLAG_OUTPUT) )
+ config |= 0x1 << i;
+ }
+ } else config = 0xF;
+
+ world.data[ y*world.w+x ].config = config;
+ world.data[ y*world.w+x ].state &= ~(FLAG_DROP|FLAG_SPLIT);
+ }
+ }
+
+ for( int y = 2; y < world.h-2; y ++ )
+ for( int x = 2; x < world.w-2; x ++ )
+ {
+ // R,D,L,- 1110 (splitter, 1 drop created)
+
+ // R,-,L,U - 1011 (merger, 2 drop created)
+
+ u8 config = world.data[y*world.w+x].config;
+
+ if( config == 0x7 )
+ {
+ world.data[y*world.w+x ].state |= (FLAG_SPLIT | FLAG_DROP);
+ }
+ else if( config == 0xD )
+ {
+ world.data[y*world.w+x-1].state |= FLAG_DROP;
+ world.data[y*world.w+x+1].state |= FLAG_DROP;
+ }
+ }
+
+ /*
+ canals
+ x
+ xxxxx
+ x x
+ x xxx
+ x x x
+ x xxx
+ x x
+ xxxxx
+ x
+ x
+
+ configs (Downlevels marked)
+ x
+ xDxDx
+ x x
+ x DxD
+ x x x
+ x xDx
+ x x
+ xxxDx
+ x
+ x
+
+ Path tracing with min function
+ 0
+ 11011
+ 1 .
+ 1 D.D
+ 1 . .
+ 1 .D.
+ 1 .
+ 1112.
+ 2
+ 2
+
+ Path tracing with min function
+ 0
+ 11011
+ 1 1
+ 1 212
+ 1 2 2
+ 1 232
+ 1 3
+ 11143
+ 4
+ 4
+
+ L to R fill
+ 0000000
+ 1101111
+ 1111111
+ 1112122
+ 1112222
+ 1112322
+ 1111333
+ 1114333
+ 4444444
+ 4444444
+ */
+
+ // Simulate world
+ static int update_tick = 0;
+ update_tick ++;
+
+ if( update_tick > 5 )
+ {
+ update_tick = 0;
+
+ u32 buffer_id = world.frame & 0x1;
+ u32 buffer_next = buffer_id ^ 0x1;
+
+ for( int y = 1; y < world.h-1; y ++ )
+ {
+ for( int x = 1; x < world.w-1; x ++ )
+ {
+ struct cell *cell = &world.data[y*world.w+x];
+
+ if( cell->state & (FLAG_OUTPUT|FLAG_DROP) )
+ cell->water[ buffer_next ] = 16;
+ else
+ {
+ int has_source = 0;
+ cell->water[ buffer_next ] = 0;
+
+ if( cell->state & FLAG_CANAL )
+ {
+ 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;
+ }
+ }
+ }
+
+ world.frame ++;
+ }