From a11202313d5af4e6f88316743f54cba042e5d27c Mon Sep 17 00:00:00 2001 From: jacksonmj Date: Thu, 17 May 2012 01:01:48 +0100 Subject: [PATCH] New flood_parts function, should fix crashing due to too much recursion --- src/powder.c | 215 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 142 insertions(+), 73 deletions(-) diff --git a/src/powder.c b/src/powder.c index dfde2253a..6d92bc819 100644 --- a/src/powder.c +++ b/src/powder.c @@ -2918,11 +2918,18 @@ int flood_prop(int x, int y, size_t propoffset, void * propvalue, int proptype) 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 c = fullc&0xFF; int x1, x2, dy = (c=CELL) - { - if ((pmap[y][x1-1]&0xFF)!=cm || bmap[y/CELL][(x1-1)/CELL]!=bm) - { - break; - } - x1--; - } - while (x2=CELL) + { + if ((pmap[y][x1-1]&0xFF)!=cm || bmap[y/CELL][(x1-1)/CELL]!=bm) + { + break; + } + x1--; + } + // go right as far as possible + while (x2=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) { - if (create_part(-1,x, y, fullc)==-1) - return 0; + //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=coord_stack_limit) + return -1; + } + } + else if (y=coord_stack_limit) + return -1; + } + + } + } + } } - else if (!create_parts(x, y, 0, 0, fullc, flags, 1)) - return 0; - } - // fill children - if (cm==PT_INST&&co==PT_SPRK)//wire crossing for INST - { - 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++) - if ((pmap[y-1][x]&0xFF)!=PT_SPRK) - { - if (x==x1 || x==x2 || y>=YRES-CELL-1 || - (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) - flood_parts(x, y-dy, fullc, cm, bm, flags); - - } - - if (y=CELL+dy) - for (x=x1; x<=x2; x++) - 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; - if (y=CELL+dy) + for (x=x1; x<=x2; x++) + if ((pmap[y-dy][x]&0xFF)==cm && bmap[(y-dy)/CELL][x/CELL]==bm) + { + 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=coord_stack_limit) + 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)