New flood_parts function, should fix crashing due to too much recursion
This commit is contained in:
parent
9a30a580d2
commit
a11202313d
143
src/powder.c
143
src/powder.c
@ -2918,11 +2918,18 @@ int flood_prop(int x, int y, size_t propoffset, void * propvalue, int proptype)
|
|||||||
free(bitmap);
|
free(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PMAP_CMP_CONDUCTIVE(pmap, t) (((pmap)&0xFF)==(t) || (((pmap)&0xFF)==PT_SPRK && parts[(pmap)>>8].ctype==(t)))
|
||||||
|
|
||||||
int flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
|
int flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
|
||||||
{
|
{
|
||||||
int c = fullc&0xFF;
|
int c = fullc&0xFF;
|
||||||
int x1, x2, dy = (c<PT_NUM)?1:CELL;
|
int x1, x2, dy = (c<PT_NUM)?1:CELL;
|
||||||
int co = c;
|
int co = c;
|
||||||
|
int coord_stack_limit = XRES*YRES;
|
||||||
|
unsigned short (*coord_stack)[2] = malloc(sizeof(unsigned short)*2*coord_stack_limit);
|
||||||
|
int coord_stack_size = 0;
|
||||||
|
int created_something = 0;
|
||||||
|
|
||||||
if (c==SPC_PROP)
|
if (c==SPC_PROP)
|
||||||
return 0;
|
return 0;
|
||||||
if (cm==PT_INST&&co==PT_SPRK)
|
if (cm==PT_INST&&co==PT_SPRK)
|
||||||
@ -2958,8 +2965,17 @@ int flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
|
|||||||
if (((pmap[y][x]&0xFF)!=cm || bmap[y/CELL][x/CELL]!=bm )||( (flags&BRUSH_SPECIFIC_DELETE) && cm!=SLALT))
|
if (((pmap[y][x]&0xFF)!=cm || bmap[y/CELL][x/CELL]!=bm )||( (flags&BRUSH_SPECIFIC_DELETE) && cm!=SLALT))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// go left as far as possible
|
coord_stack[coord_stack_size][0] = x;
|
||||||
|
coord_stack[coord_stack_size][1] = y;
|
||||||
|
coord_stack_size++;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
coord_stack_size--;
|
||||||
|
x = coord_stack[coord_stack_size][0];
|
||||||
|
y = coord_stack[coord_stack_size][1];
|
||||||
x1 = x2 = x;
|
x1 = x2 = x;
|
||||||
|
// go left as far as possible
|
||||||
while (x1>=CELL)
|
while (x1>=CELL)
|
||||||
{
|
{
|
||||||
if ((pmap[y][x1-1]&0xFF)!=cm || bmap[y/CELL][(x1-1)/CELL]!=bm)
|
if ((pmap[y][x1-1]&0xFF)!=cm || bmap[y/CELL][(x1-1)/CELL]!=bm)
|
||||||
@ -2968,6 +2984,7 @@ int flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
|
|||||||
}
|
}
|
||||||
x1--;
|
x1--;
|
||||||
}
|
}
|
||||||
|
// go right as far as possible
|
||||||
while (x2<XRES-CELL)
|
while (x2<XRES-CELL)
|
||||||
{
|
{
|
||||||
if ((pmap[y][x2+1]&0xFF)!=cm || bmap[y/CELL][(x2+1)/CELL]!=bm)
|
if ((pmap[y][x2+1]&0xFF)!=cm || bmap[y/CELL][(x2+1)/CELL]!=bm)
|
||||||
@ -2976,66 +2993,118 @@ int flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
|
|||||||
}
|
}
|
||||||
x2++;
|
x2++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill span
|
// fill span
|
||||||
for (x=x1; x<=x2; x++)
|
for (x=x1; x<=x2; x++)
|
||||||
{
|
{
|
||||||
if (cm==PT_INST&&co==PT_SPRK)
|
if (cm==PT_INST&&co==PT_SPRK)
|
||||||
{
|
{
|
||||||
if (create_part(-1,x, y, fullc)==-1)
|
if (create_part(-1, x, y, fullc)>=0)
|
||||||
return 0;
|
created_something = 1;
|
||||||
}
|
}
|
||||||
else if (!create_parts(x, y, 0, 0, fullc, flags, 1))
|
else
|
||||||
return 0;
|
{
|
||||||
}
|
if (create_parts(x, y, 0, 0, fullc, flags, 1))
|
||||||
// fill children
|
created_something = 1;
|
||||||
if (cm==PT_INST&&co==PT_SPRK)//wire crossing for INST
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add vertically adjacent pixels to stack
|
||||||
|
if (cm==PT_INST&&co==PT_SPRK)
|
||||||
|
{
|
||||||
|
//wire crossing for INST
|
||||||
|
if (y>=CELL+1 && x1==x2 &&
|
||||||
|
PMAP_CMP_CONDUCTIVE(pmap[y-1][x1-1], PT_INST) && PMAP_CMP_CONDUCTIVE(pmap[y-1][x1], PT_INST) && PMAP_CMP_CONDUCTIVE(pmap[y-1][x1+1], PT_INST) &&
|
||||||
|
!PMAP_CMP_CONDUCTIVE(pmap[y-2][x1-1], PT_INST) && PMAP_CMP_CONDUCTIVE(pmap[y-2][x1], PT_INST) && !PMAP_CMP_CONDUCTIVE(pmap[y-2][x1+1], PT_INST))
|
||||||
|
{
|
||||||
|
// travelling vertically up, skipping a horizontal line
|
||||||
|
if ((pmap[y-2][x1]&0xFF)==PT_INST)
|
||||||
|
{
|
||||||
|
coord_stack[coord_stack_size][0] = x1;
|
||||||
|
coord_stack[coord_stack_size][1] = y-2;
|
||||||
|
coord_stack_size++;
|
||||||
|
if (coord_stack_size>=coord_stack_limit)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (y>=CELL+1)
|
||||||
{
|
{
|
||||||
if (y>=CELL+dy && x1==x2 &&
|
|
||||||
((pmap[y-1][x1-1]&0xFF)==PT_INST||(pmap[y-1][x1-1]&0xFF)==PT_SPRK) && ((pmap[y-1][x1]&0xFF)==PT_INST||(pmap[y-1][x1]&0xFF)==PT_SPRK) && ((pmap[y-1][x1+1]&0xFF)==PT_INST || (pmap[y-1][x1+1]&0xFF)==PT_SPRK) &&
|
|
||||||
(pmap[y-2][x1-1]&0xFF)!=PT_INST && ((pmap[y-2][x1]&0xFF)==PT_INST ||(pmap[y-2][x1]&0xFF)==PT_SPRK) && (pmap[y-2][x1+1]&0xFF)!=PT_INST)
|
|
||||||
flood_parts(x1, y-2, fullc, cm, bm, flags);
|
|
||||||
else if (y>=CELL+dy)
|
|
||||||
for (x=x1; x<=x2; x++)
|
for (x=x1; x<=x2; x++)
|
||||||
if ((pmap[y-1][x]&0xFF)!=PT_SPRK)
|
|
||||||
{
|
{
|
||||||
if (x==x1 || x==x2 || y>=YRES-CELL-1 ||
|
if ((pmap[y-1][x]&0xFF)==PT_INST)
|
||||||
(pmap[y-1][x-1]&0xFF)==PT_INST || (pmap[y-1][x+1]&0xFF)==PT_INST ||
|
{
|
||||||
(pmap[y+1][x-1]&0xFF)==PT_INST || ((pmap[y+1][x]&0xFF)!=PT_INST&&(pmap[y+1][x]&0xFF)!=PT_SPRK) || (pmap[y+1][x+1]&0xFF)==PT_INST)
|
if (x==x1 || x==x2 || y>=YRES-CELL-1 || !PMAP_CMP_CONDUCTIVE(pmap[y+1][x], PT_INST))
|
||||||
flood_parts(x, y-dy, fullc, cm, bm, flags);
|
{
|
||||||
|
// if at the end of a horizontal section, or if it's a T junction
|
||||||
|
coord_stack[coord_stack_size][0] = x;
|
||||||
|
coord_stack[coord_stack_size][1] = y-1;
|
||||||
|
coord_stack_size++;
|
||||||
|
if (coord_stack_size>=coord_stack_limit)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y<YRES-CELL-dy && x1==x2 &&
|
if (y<YRES-CELL-1 && x1==x2 &&
|
||||||
((pmap[y+1][x1-1]&0xFF)==PT_INST||(pmap[y+1][x1-1]&0xFF)==PT_SPRK) && ((pmap[y+1][x1]&0xFF)==PT_INST||(pmap[y+1][x1]&0xFF)==PT_SPRK) && ((pmap[y+1][x1+1]&0xFF)==PT_INST || (pmap[y+1][x1+1]&0xFF)==PT_SPRK) &&
|
PMAP_CMP_CONDUCTIVE(pmap[y+1][x1-1], PT_INST) && PMAP_CMP_CONDUCTIVE(pmap[y+1][x1], PT_INST) && PMAP_CMP_CONDUCTIVE(pmap[y+1][x1+1], PT_INST) &&
|
||||||
(pmap[y+2][x1-1]&0xFF)!=PT_INST && ((pmap[y+2][x1]&0xFF)==PT_INST ||(pmap[y+2][x1]&0xFF)==PT_SPRK) && (pmap[y+2][x1+1]&0xFF)!=PT_INST)
|
!PMAP_CMP_CONDUCTIVE(pmap[y+2][x1-1], PT_INST) && PMAP_CMP_CONDUCTIVE(pmap[y+2][x1], PT_INST) && !PMAP_CMP_CONDUCTIVE(pmap[y+2][x1+1], PT_INST))
|
||||||
flood_parts(x1, y+2, fullc, cm, bm, flags);
|
|
||||||
else if (y<YRES-CELL-dy)
|
|
||||||
for (x=x1; x<=x2; x++)
|
|
||||||
if ((pmap[y+1][x]&0xFF)!=PT_SPRK)
|
|
||||||
{
|
{
|
||||||
if (x==x1 || x==x2 || y<0 ||
|
// travelling vertically down, skipping a horizontal line
|
||||||
(pmap[y+1][x-1]&0xFF)==PT_INST || (pmap[y+1][x+1]&0xFF)==PT_INST ||
|
if ((pmap[y+2][x1]&0xFF)==PT_INST)
|
||||||
(pmap[y-1][x-1]&0xFF)==PT_INST || ((pmap[y-1][x]&0xFF)!=PT_INST&&(pmap[y-1][x]&0xFF)!=PT_SPRK) || (pmap[y-1][x+1]&0xFF)==PT_INST)
|
{
|
||||||
flood_parts(x, y+dy, fullc, cm, bm, flags);
|
coord_stack[coord_stack_size][0] = x1;
|
||||||
|
coord_stack[coord_stack_size][1] = y+2;
|
||||||
|
coord_stack_size++;
|
||||||
|
if (coord_stack_size>=coord_stack_limit)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (y<YRES-CELL-1)
|
||||||
|
{
|
||||||
|
for (x=x1; x<=x2; x++)
|
||||||
|
{
|
||||||
|
if ((pmap[y+1][x]&0xFF)==PT_INST)
|
||||||
|
{
|
||||||
|
if (x==x1 || x==x2 || y<0 || !PMAP_CMP_CONDUCTIVE(pmap[y-1][x], PT_INST))
|
||||||
|
{
|
||||||
|
// if at the end of a horizontal section, or if it's a T junction
|
||||||
|
coord_stack[coord_stack_size][0] = x;
|
||||||
|
coord_stack[coord_stack_size][1] = y+1;
|
||||||
|
coord_stack_size++;
|
||||||
|
if (coord_stack_size>=coord_stack_limit)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (y>=CELL+dy)
|
if (y>=CELL+dy)
|
||||||
for (x=x1; x<=x2; x++)
|
for (x=x1; x<=x2; x++)
|
||||||
if ((pmap[y-dy][x]&0xFF)==cm && bmap[(y-dy)/CELL][x/CELL]==bm)
|
if ((pmap[y-dy][x]&0xFF)==cm && bmap[(y-dy)/CELL][x/CELL]==bm)
|
||||||
if (!flood_parts(x, y-dy, fullc, cm, bm, flags))
|
{
|
||||||
return 0;
|
coord_stack[coord_stack_size][0] = x;
|
||||||
|
coord_stack[coord_stack_size][1] = y-dy;
|
||||||
|
coord_stack_size++;
|
||||||
|
if (coord_stack_size>=coord_stack_limit)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (y<YRES-CELL-dy)
|
if (y<YRES-CELL-dy)
|
||||||
for (x=x1; x<=x2; x++)
|
for (x=x1; x<=x2; x++)
|
||||||
if ((pmap[y+dy][x]&0xFF)==cm && bmap[(y+dy)/CELL][x/CELL]==bm)
|
if ((pmap[y+dy][x]&0xFF)==cm && bmap[(y+dy)/CELL][x/CELL]==bm)
|
||||||
if (!flood_parts(x, y+dy, fullc, cm, bm, flags))
|
{
|
||||||
return 0;
|
coord_stack[coord_stack_size][0] = x;
|
||||||
|
coord_stack[coord_stack_size][1] = y+dy;
|
||||||
|
coord_stack_size++;
|
||||||
|
if (coord_stack_size>=coord_stack_limit)
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
if (!(cm==PT_INST&&co==PT_SPRK))
|
}
|
||||||
return 1;
|
} while (coord_stack_size>0);
|
||||||
|
free(coord_stack);
|
||||||
|
return created_something;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flood_water(int x, int y, int i, int originaly, int check)
|
int flood_water(int x, int y, int i, int originaly, int check)
|
||||||
|
Reference in New Issue
Block a user