The International Simutrans Forum

Development => Patches & Projects => Incorporated Patches and Solved Bug Reports => Topic started by: hreintke on July 01, 2013, 12:36:20 PM

Title: Drain tile (within simworld) koord usage
Post by: hreintke on July 01, 2013, 12:36:20 PM
LS,

I don't know have I got into this issue but :

I updated my local development source to latest trunk 6570.
After that I was not able anymore to start simutrans due to "endless loop behavior".

Detailed investigation showed that the issue is in the "Drain tile" routine where the end of the do-loop


} while(  from_dir[array_koord( k.x, k.y )] != -1  );


had a k.x value of 64, while maximum should be 63 (welt->get_size().x = 64).

After updating the internal array declarations to add one more row


sint8 *from_dir = new sint8[(welt->get_size().x +1)* (welt->get_size().y+1)];
sint8 *stage = new sint8[(welt->get_size().x +1)* (welt->get_size().y+1)];
memset( from_dir, -1, sizeof(sint8) * ((welt->get_size().x+1) * (welt->get_size().y+1)) );
memset( stage, 0, sizeof(sint8) * ((welt->get_size().x+1) * (welt->get_size().y+1)) );


it seems to work.

I did not have the behavior with the non-patched version but nothing in my own patches is doing anything with this part of the code so I am puzzled whether this is a generic bug or just something I have to sort out in my configuration.

Any hints appreciated.


I found the issue in my patches : I have/had a patch in the routine perlin_hoehe to create absolute flat maps.
see the last line in the code


sint32 karte_t::perlin_hoehe(settings_t const* const sets, koord k, koord const size)
{
switch( sets->get_rotation() ) {
// 0: do nothing
case 1: k = koord(k.y,size.x-k.x); break;
case 2: k = koord(size.x-k.x,size.y-k.y); break;
case 3: k = koord(size.y-k.y,k.x); break;
}
//    double perlin_noise_2D(double x, double y, double persistence);
//    return ((int)(perlin_noise_2D(x, y, 0.6)*160.0)) & 0xFFFFFFF0;
k = k + koord(sets->get_origin_x(), sets->get_origin_y());
// return ((int)(perlin_noise_2D(k.x, k.y, sets->get_map_roughness())*(double)sets->get_max_mountain_height())) / 16;
    return (0);
}


That means I created a very specific case to start the initial map creation/elargement with.

Still think that also the "standard code" can get this issue with specific settings.

Herman 
Title: Re: Drain tile (within simworld) koord usage
Post by: Dwachs on July 01, 2013, 06:53:11 PM
Thanks for the report. Seems to be fixed in r5761. It was caused imho by a faulty bounds check for the water_hgts array.
Title: Re: Drain tile (within simworld) koord usage
Post by: hreintke on July 02, 2013, 02:15:22 PM
Dwachs,

The issue is still present in R6751.
I will investigate further but have some trouble understanding what we want to achieve in drain_tile so maybe it will take some time.

Herman
Title: Re: Drain tile (within simworld) koord usage
Post by: kierongreen on July 02, 2013, 03:59:56 PM
Drain tile is used to create lakes above sea level. The map is flooded above the level of all land, then the water is drained away with an iterative algorithm until the only water remaining is that which is trapped in basins above sea level forming lakes, or that below sea level forming the sea.
Title: Re: Drain tile (within simworld) koord usage
Post by: Dwachs on July 02, 2013, 07:04:19 PM
I am still convinced that the size of the arrays is right. Here is my try:

Index: simworld.cc
===================================================================
--- simworld.cc (revision 6573)
+++ simworld.cc (working copy)
@@ -1570,7 +1571,7 @@
                                }
                        }
                        //return back to previous tile
-                       if(  i == 7  ) {
+                       if(  i == 7  &&  from_dir[array_koord( k.x, k.y )] != -1) {
                                k = k - koord::neighbours[from_dir[array_koord( k.x, k.y )]];
                                water_height = welt->get_water_hgt(k);
                        }

If the method reaches the starting tile then from_dir[array_koord( k.x, k.y )]== -1, this branch will access koord::neighbours[-1], which is out-of-bounds ofc.
Title: Re: Drain tile (within simworld) koord usage
Post by: hreintke on July 02, 2013, 07:57:52 PM
Yes,

That looks like to have solved it. Thanks for looking into this.

Herman