mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-09-22 11:04:57 -04:00
avoid recursion floodfill exceeding stack limit (crashes on windows)
This commit is contained in:
parent
6989510924
commit
d3112ca416
69
finders.c
69
finders.c
@ -3697,47 +3697,65 @@ struct locate_info_t
|
|||||||
Generator *g;
|
Generator *g;
|
||||||
int *ids;
|
int *ids;
|
||||||
Range r;
|
Range r;
|
||||||
int match;
|
int match, tol;
|
||||||
int64_t sumx, sumz;
|
|
||||||
int n, dmax;
|
|
||||||
volatile char *stop;
|
volatile char *stop;
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
void floodFillGen(struct locate_info_t *info, int i, int j, int d)
|
int floodFillGen(struct locate_info_t *info, int i, int j, Pos *p)
|
||||||
{
|
{
|
||||||
if (i < 0 || j < 0 || i >= info->r.sx || j >= info->r.sz)
|
typedef struct { int i, j, d; } entry_t;
|
||||||
return;
|
entry_t *queue = (entry_t*) malloc(info->r.sx*info->r.sz * sizeof(*queue));
|
||||||
|
int qn = 1, d = 0;
|
||||||
|
queue->i = i;
|
||||||
|
queue->j = j;
|
||||||
|
int64_t sumx = 0;
|
||||||
|
int64_t sumz = 0;
|
||||||
|
int n = 0;
|
||||||
|
while (--qn >= 0)
|
||||||
|
{
|
||||||
if (info->stop && *info->stop)
|
if (info->stop && *info->stop)
|
||||||
return;
|
return 0;
|
||||||
int idx = j * info->r.sx + i;
|
i = queue[qn].i;
|
||||||
|
j = queue[qn].j;
|
||||||
|
d = queue[qn].d;
|
||||||
|
if (i < 0 || j < 0 || i >= info->r.sx || j >= info->r.sz)
|
||||||
|
continue;
|
||||||
|
int k, idx = j * info->r.sx + i;
|
||||||
int id = info->ids[idx];
|
int id = info->ids[idx];
|
||||||
if (id == INT_MAX)
|
if (id == INT_MAX)
|
||||||
return;
|
continue;
|
||||||
info->ids[idx] = INT_MAX;
|
info->ids[idx] = INT_MAX;
|
||||||
int x = info->r.x + i;
|
int x = info->r.x + i;
|
||||||
int z = info->r.z + j;
|
int z = info->r.z + j;
|
||||||
|
|
||||||
if (info->g->mc >= MC_1_18)
|
if (info->g->mc >= MC_1_18)
|
||||||
id = getBiomeAt(info->g, 4, x, info->r.y, z);
|
id = getBiomeAt(info->g, 4, x, info->r.y, z);
|
||||||
if (id == info->match)
|
if (id == info->match)
|
||||||
{
|
{
|
||||||
info->sumx += x;
|
sumx += x;
|
||||||
info->sumz += z;
|
sumz += z;
|
||||||
info->n += 1;
|
n++;
|
||||||
d = 0;
|
d = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (++d >= info->dmax)
|
if (++d >= info->tol)
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
floodFillGen(info, i, j-1, d);
|
entry_t next[] = { {i,j-1,d}, {i,j+1,d}, {i-1,j,d}, {i+1,j,d} };
|
||||||
floodFillGen(info, i, j+1, d);
|
for (k = 0; k < 4; k++)
|
||||||
floodFillGen(info, i-1, j, d);
|
queue[qn++] = next[k];
|
||||||
floodFillGen(info, i+1, j, d);
|
}
|
||||||
|
free(queue);
|
||||||
|
if (n)
|
||||||
|
{
|
||||||
|
p->x = (int) round(2.0 + 4.0*sumx / n);
|
||||||
|
p->z = (int) round(2.0 + 4.0*sumz / n);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int getBiomeCenters(Pos *pos, int *siz, int nmax, Generator *g, Range r,
|
int getBiomeCenters(Pos *pos, int *siz, int nmax, Generator *g, Range r,
|
||||||
int match, int minsiz, int tol, volatile char *stop)
|
int match, int minsiz, int tol, volatile char *stop)
|
||||||
{
|
{
|
||||||
@ -3760,7 +3778,7 @@ int getBiomeCenters(Pos *pos, int *siz, int nmax, Generator *g, Range r,
|
|||||||
info.r = r;
|
info.r = r;
|
||||||
info.stop = stop;
|
info.stop = stop;
|
||||||
info.match = match;
|
info.match = match;
|
||||||
info.dmax = tol;
|
info.tol = tol;
|
||||||
|
|
||||||
if (g->mc >= MC_1_18)
|
if (g->mc >= MC_1_18)
|
||||||
{
|
{
|
||||||
@ -3855,13 +3873,12 @@ int getBiomeCenters(Pos *pos, int *siz, int nmax, Generator *g, Range r,
|
|||||||
break;
|
break;
|
||||||
if (ids[j*r.sx + i] != match)
|
if (ids[j*r.sx + i] != match)
|
||||||
continue;
|
continue;
|
||||||
info.sumx = info.sumz = info.n = 0;
|
Pos center;
|
||||||
floodFillGen(&info, i, j, 0);
|
int area = floodFillGen(&info, i, j, ¢er);
|
||||||
if (info.n >= minsiz)
|
if (area >= minsiz)
|
||||||
{
|
{
|
||||||
pos[n].x = (int) round(2.0 + 4.0*info.sumx / info.n);
|
pos[n] = center;
|
||||||
pos[n].z = (int) round(2.0 + 4.0*info.sumz / info.n);
|
if (siz) siz[n] = area;
|
||||||
if (siz) siz[n] = info.n;
|
|
||||||
if (++n >= nmax)
|
if (++n >= nmax)
|
||||||
goto L_end;
|
goto L_end;
|
||||||
}
|
}
|
||||||
|
@ -549,7 +549,7 @@ int checkForTemps(LayerStack *g, uint64_t seed, int x, int z, int w, int h, cons
|
|||||||
* @r : area to examine, requires: scale = 4, sy = 1
|
* @r : area to examine, requires: scale = 4, sy = 1
|
||||||
* @match : biome id to find
|
* @match : biome id to find
|
||||||
* @minsiz : minimum size of output biomes
|
* @minsiz : minimum size of output biomes
|
||||||
* @tol : border tollerance
|
* @tol : border tolerance
|
||||||
* @stop : stopping flag (nullable)
|
* @stop : stopping flag (nullable)
|
||||||
* Returns the number of entries written to pos and siz.
|
* Returns the number of entries written to pos and siz.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user