Index: simworld.cc =================================================================== --- simworld.cc (revision 9143) +++ simworld.cc (working copy) @@ -211,7 +211,7 @@ world_thread_param[t].welt = this; world_thread_param[t].thread_num = t; - world_thread_param[t].x_step = min( 64, max_x / env_t::num_threads ); + world_thread_param[t].x_step = sync_x_steps ? min( 64, max_x / env_t::num_threads ) : max_x; world_thread_param[t].x_world_max = max_x; world_thread_param[t].y_min = (t * max_y) / env_t::num_threads; world_thread_param[t].y_max = ((t + 1) * max_y) / env_t::num_threads; @@ -356,7 +356,6 @@ for( int y = y_min; y < y_max; y++ ) { for( int x = x_min; x < x_max; x++ ) { planquadrat_t *pl = access_nocheck(x,y); - grund_t *gr = pl->get_kartenboden(); koord k(x,y); slope_t::type slope = calc_natural_slope(k); sint8 height = min_hgt_nocheck(k); @@ -371,17 +370,13 @@ slope = encode_corners(disp_hn_sw - height, disp_hn_se - height, disp_hn_ne - height, disp_hn_nw - height); } - gr->set_pos( koord3d( k, height) ); - if( gr->get_typ() != grund_t::wasser && max_hgt_nocheck(k) <= water_hgt ) { - // below water but ground => convert - pl->kartenboden_setzen( new wasser_t(gr->get_pos()), true /* do not calc_image for water tiles */ ); + if( max_hgt_nocheck(k) <= water_hgt ) { + // create water + pl->kartenboden_setzen( new wasser_t(koord3d( k, height)), true /* do not calc_image for water tiles */ ); } - else if( gr->get_typ() == grund_t::wasser && max_hgt_nocheck(k) > water_hgt ) { - // water above ground => to ground - pl->kartenboden_setzen( new boden_t(gr->get_pos(), slope ) ); - } else { - gr->set_grund_hang( slope ); + // create ground + pl->kartenboden_setzen( new boden_t(koord3d( k, height), slope ) ); } if( max_hgt_nocheck(k) > water_hgt ) { @@ -416,7 +411,8 @@ } if( xoff==0 && yoff==0 ) { - world_xy_loop(&karte_t::cleanup_grounds_loop, 0); +// world_xy_loop(&karte_t::cleanup_grounds_loop, 0); + cleanup_grounds_loop( 0, get_size().x, 0, get_size().y ); } else { cleanup_grounds_loop( 0, get_size().x, yoff, get_size().y ); @@ -1353,54 +1349,62 @@ * To start with every tile in the map is checked - but when we fail for * a tile then it is excluded from subsequent checks */ -void karte_t::create_lakes( int xoff, int yoff ) +sint8 *stage; +sint8 *new_stage; +sint8 *local_stage; +sint8 *max_water_hgt; +bool need_to_flood; +sint8 h; + +void karte_t::create_lakes_loop( sint16 x_min, sint16 x_max, sint16 y_min, sint16 y_max ) { - if( xoff > 0 || yoff > 0 ) { - // too complicated to add lakes to an already existing world... - return; - } - const sint8 max_lake_height = groundwater + 8; const uint16 size_x = get_size().x; const uint16 size_y = get_size().y; - sint8 *max_water_hgt = new sint8[size_x * size_y]; - memset( max_water_hgt, 1, sizeof(sint8) * size_x * size_y ); + if( x_min < 1 ) x_min = 1; + //if( y_min < 1 ) y_min = 1; + y_min++; // first row is barrier even if not at world edge + if( x_max > size_x-1 ) x_max = size_x-1; + if( y_max > size_y-1 ) y_max = size_y-1; - sint8 *stage = new sint8[size_x * size_y]; - sint8 *new_stage = new sint8[size_x * size_y]; - sint8 *local_stage = new sint8[size_x * size_y]; + for( uint16 y = y_min; y < y_max; y++ ) { + for( uint16 x = x_min; x < x_max; x++ ) { + uint32 offset = array_koord(x,y); + if( max_water_hgt[offset]==1 && stage[offset]==-1 ) { - for( sint8 h = groundwater+1; hmax_lake_height ) { + max_water_hgt[offset] = 0; + } + else if( h>new_water_hgt ) { + koord k(x,y); + if( env_t::num_threads == 1 ) { + memcpy( new_stage, stage, sizeof(sint8) * size_x * size_y ); + } + else { + memcpy( new_stage + sizeof(sint8) * array_koord(0,y_min), stage + sizeof(sint8) * array_koord(0,y_min), sizeof(sint8) * size_x * (y_max-y_min) ); + } - sint8 hgt = lookup_hgt_nocheck( x, y ); - const sint8 water_hgt = water_hgts[offset]; // optimised <- get_water_hgt_nocheck(x, y); - const sint8 new_water_hgt = max(hgt, water_hgt); - if( new_water_hgt>max_lake_height ) { - max_water_hgt[offset] = 0; - } - else if( h>new_water_hgt ) { - koord k(x,y); - memcpy( new_stage, stage, sizeof(sint8) * size_x * size_y ); - if(can_flood_to_depth( k, h, new_stage, local_stage )) { - sint8 *tmp_stage = new_stage; - new_stage = stage; - stage = tmp_stage; - need_to_flood = true; + if( can_flood_to_depth( k, h, new_stage, local_stage, x_min, x_max, y_min, y_max ) ) { + if( env_t::num_threads == 1 ) { + sint8 *tmp_stage = new_stage; + new_stage = stage; + stage = tmp_stage; } else { - for( uint16 iy = 1; iy -1 ) { - max_water_hgt[local_offset] = 0; - } + memcpy( stage + sizeof(sint8) * array_koord(0,y_min), new_stage + sizeof(sint8) * array_koord(0,y_min), sizeof(sint8) * size_x * (y_max-y_min) ); + } + need_to_flood = true; + } + else { + for( uint16 iy = y_min; iy -1 ) { + max_water_hgt[local_offset] = 0; } } } @@ -1408,10 +1412,51 @@ } } } + } +} + +void karte_t::create_lakes( int xoff, int yoff ) +{ + if( xoff > 0 || yoff > 0 ) { + // too complicated to add lakes to an already existing world... + return; + } + + const sint8 max_lake_height = groundwater + 8; + const uint16 size_x = get_size().x; + const uint16 size_y = get_size().y; + + max_water_hgt = new sint8[size_x * size_y]; + memset( max_water_hgt, 1, sizeof(sint8) * size_x * size_y ); + + stage = new sint8[size_x * size_y]; + new_stage = new sint8[size_x * size_y]; + local_stage = new sint8[size_x * size_y]; + + for( h = groundwater+1; h= x_min && k_neighbour.x= y_min && k_neighbour.y 0 && old_y > 0 ) { - // create grounds on new part - for (sint16 iy = 0; iy=old_y)?0:old_x; ixkartenboden_setzen( new boden_t( koord3d( ix, iy, max( min_hgt_nocheck(k), get_water_hgt_nocheck(k) ) ), 0 ) ); - } - } - } - else { - world_xy_loop(&karte_t::create_grounds_loop, 0); + // smooth the new part, reassign slopes on new part + cleanup_karte( old_x, old_y ); + if ( old_x == 0 && old_y == 0 ) { ls.set_progress(10); } @@ -1833,12 +1871,6 @@ } if ( old_x == 0 && old_y == 0 ) { - ls.set_progress(11); - } - - // smooth the new part, reassign slopes on new part - cleanup_karte( old_x, old_y ); - if ( old_x == 0 && old_y == 0 ) { ls.set_progress(12); } @@ -6044,17 +6076,6 @@ } -void karte_t::create_grounds_loop( sint16 x_min, sint16 x_max, sint16 y_min, sint16 y_max ) -{ - for( int y = y_min; y < y_max; y++ ) { - for( int x = x_min; x < x_max; x++ ) { - koord k(x,y); - access_nocheck(k)->kartenboden_setzen( new boden_t( koord3d( x, y, max(min_hgt_nocheck(k),get_water_hgt_nocheck(k)) ), 0 ) ); - } - } -} - - uint8 karte_t::sp2num(player_t *player) { if( player==NULL ) { Index: simworld.h =================================================================== --- simworld.h (revision 9143) +++ simworld.h (working copy) @@ -649,6 +649,11 @@ void create_rivers(sint16 number); /** + * Will create lakes (multithreaded). + */ + void create_lakes_loop(sint16, sint16, sint16, sint16); + + /** * Will create lakes. */ void create_lakes( int xoff, int yoff ); @@ -1117,7 +1122,7 @@ * lakes are left where there is no drainage */ void drain_tile(koord k, sint8 water_height); - bool can_flood_to_depth(koord k, sint8 new_water_height, sint8 *stage, sint8 *our_stage) const; + bool can_flood_to_depth(koord k, sint8 new_water_height, sint8 *stage, sint8 *our_stage, sint16, sint16, sint16, sint16) const; public: void flood_to_depth(sint8 new_water_height, sint8 *stage); @@ -1632,11 +1637,6 @@ void recalc_transitions_loop(sint16, sint16, sint16, sint16); /** - * Loop creating grounds on all plans from height and water height - suitable for multithreading - */ - void create_grounds_loop(sint16, sint16, sint16, sint16); - - /** * Loop cleans grounds so that they have correct boden and slope - suitable for multithreading */ void cleanup_grounds_loop(sint16, sint16, sint16, sint16);