News:

Want to praise Simutrans?
Your feedback is important for us ;D.

Drain tile (within simworld) koord usage

Started by hreintke, July 01, 2013, 12:36:20 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

hreintke

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 

Dwachs

Thanks for the report. Seems to be fixed in r5761. It was caused imho by a faulty bounds check for the water_hgts array.
Parsley, sage, rosemary, and maggikraut.

hreintke

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

kierongreen

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.

Dwachs

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.
Parsley, sage, rosemary, and maggikraut.

hreintke

Yes,

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

Herman