Move INST flood fill into a separate function

Since there were so many if statements for INST in flood_parts. Also, allow
INST inside walls to be sparked.
This commit is contained in:
jacksonmj 2012-06-15 13:45:55 +01:00
parent e7fabd8601
commit 36de2f19f5
3 changed files with 152 additions and 97 deletions

View File

@ -834,6 +834,8 @@ void create_box(int x1, int y1, int x2, int y2, int c, int flags);
int flood_parts(int x, int y, int c, int cm, int bm, int flags);
int flood_INST(int x, int y, int fullc, int cm);
int create_parts(int x, int y, int rx, int ry, int c, int flags, int fill);
void create_line(int x1, int y1, int x2, int y2, int rx, int ry, int c, int flags);

View File

@ -210,7 +210,7 @@ int update_SPRK(UPDATE_FUNC_ARGS) {
else if (rt==PT_INST) {
if (parts[r>>8].life==0 && parts[i].life<4)
{
flood_parts(x+rx,y+ry,PT_SPRK,PT_INST,-1, 0);//spark the wire
flood_INST(x+rx,y+ry,PT_SPRK,PT_INST);//spark the wire
}
}
else if (parts[r>>8].life==0 && parts[i].life<4) {

View File

@ -3010,6 +3010,143 @@ int flood_prop(int x, int y, size_t propoffset, void * propvalue, int proptype)
#define PMAP_CMP_CONDUCTIVE(pmap, t) (((pmap)&0xFF)==(t) || (((pmap)&0xFF)==PT_SPRK && parts[(pmap)>>8].ctype==(t)))
int flood_INST(int x, int y, int fullc, int cm)
{
int c = fullc&0xFF;
int x1, x2, dy = (c<PT_NUM)?1:CELL;
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>=PT_NUM)
return 0;
if (cm==-1)
{
if (c==0)
{
cm = pmap[y][x]&0xFF;
if (!cm)
return 0;
}
else
cm = 0;
}
if ((pmap[y][x]&0xFF)!=cm)
return 1;
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;
// go left as far as possible
while (x1>=CELL)
{
if ((pmap[y][x1-1]&0xFF)!=cm)
{
break;
}
x1--;
}
// go right as far as possible
while (x2<XRES-CELL)
{
if ((pmap[y][x2+1]&0xFF)!=cm)
{
break;
}
x2++;
}
// fill span
for (x=x1; x<=x2; x++)
{
if (create_part(-1, x, y, fullc)>=0)
created_something = 1;
}
// add vertically adjacent pixels to stack
// (wire crossing for INST)
if (y>=CELL+1 && x1==x2 &&
PMAP_CMP_CONDUCTIVE(pmap[y-1][x1-1], cm) && PMAP_CMP_CONDUCTIVE(pmap[y-1][x1], cm) && PMAP_CMP_CONDUCTIVE(pmap[y-1][x1+1], cm) &&
!PMAP_CMP_CONDUCTIVE(pmap[y-2][x1-1], cm) && PMAP_CMP_CONDUCTIVE(pmap[y-2][x1], cm) && !PMAP_CMP_CONDUCTIVE(pmap[y-2][x1+1], cm))
{
// travelling vertically up, skipping a horizontal line
if ((pmap[y-2][x1]&0xFF)==cm)
{
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)
{
for (x=x1; x<=x2; x++)
{
if ((pmap[y-1][x]&0xFF)==cm)
{
if (x==x1 || x==x2 || y>=YRES-CELL-1 || !PMAP_CMP_CONDUCTIVE(pmap[y+1][x], cm))
{
// 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-1 && x1==x2 &&
PMAP_CMP_CONDUCTIVE(pmap[y+1][x1-1], cm) && PMAP_CMP_CONDUCTIVE(pmap[y+1][x1], cm) && PMAP_CMP_CONDUCTIVE(pmap[y+1][x1+1], cm) &&
!PMAP_CMP_CONDUCTIVE(pmap[y+2][x1-1], cm) && PMAP_CMP_CONDUCTIVE(pmap[y+2][x1], cm) && !PMAP_CMP_CONDUCTIVE(pmap[y+2][x1+1], cm))
{
// travelling vertically down, skipping a horizontal line
if ((pmap[y+2][x1]&0xFF)==cm)
{
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)==cm)
{
if (x==x1 || x==x2 || y<0 || !PMAP_CMP_CONDUCTIVE(pmap[y-1][x], cm))
{
// 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;
}
}
}
}
} while (coord_stack_size>0);
free(coord_stack);
return created_something;
}
int flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
{
int c = fullc&0xFF;
@ -3022,9 +3159,6 @@ int flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
if (c==SPC_PROP)
return 0;
if (cm==PT_INST&&co==PT_SPRK)
if ((pmap[y][x]&0xFF)==PT_SPRK)
return 0;
if (cm==-1)
{
if (c==0)
@ -3085,92 +3219,12 @@ int flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
}
// fill span
for (x=x1; x<=x2; x++)
{
if (cm==PT_INST&&co==PT_SPRK)
{
if (create_part(-1, x, y, fullc)>=0)
created_something = 1;
}
else
{
if (create_parts(x, y, 0, 0, fullc, flags, 1))
created_something = 1;
}
}
// 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)
{
for (x=x1; x<=x2; x++)
{
if ((pmap[y-1][x]&0xFF)==PT_INST)
{
if (x==x1 || x==x2 || y>=YRES-CELL-1 || !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;
}
}
}
}
if (y<YRES-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 down, 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<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
{
if (y>=CELL+dy)
for (x=x1; x<=x2; x++)
if ((pmap[y-dy][x]&0xFF)==cm && bmap[(y-dy)/CELL][x/CELL]==bm)
@ -3191,7 +3245,6 @@ int flood_parts(int x, int y, int fullc, int cm, int bm, int flags)
if (coord_stack_size>=coord_stack_limit)
return -1;
}
}
} while (coord_stack_size>0);
free(coord_stack);
return created_something;