diff options
Diffstat (limited to 'src/simulation/Simulation.cpp')
| -rw-r--r-- | src/simulation/Simulation.cpp | 245 |
1 files changed, 149 insertions, 96 deletions
diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index b5e30f0..6d71b74 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -363,6 +363,143 @@ SimulationSample Simulation::Get(int x, int y) #define PMAP_CMP_CONDUCTIVE(pmap, t) (((pmap)&0xFF)==(t) || (((pmap)&0xFF)==PT_SPRK && parts[(pmap)>>8].ctype==(t))) +int Simulation::FloodINST(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] = (short unsigned int (*)[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 Simulation::FloodParts(int x, int y, int fullc, int cm, int bm, int flags) { int c = fullc&0xFF; @@ -375,9 +512,6 @@ int Simulation::FloodParts(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) @@ -437,112 +571,31 @@ int Simulation::FloodParts(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 (CreateParts(x, y, 0, 0, fullc, flags)) - created_something = 1; - } + if (CreateParts(x, y, 0, 0, fullc, flags)) + 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) + 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] = x1; - coord_stack[coord_stack_size][1] = y-2; + 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; } - } - 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) + if (y<YRES-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] = x1; - coord_stack[coord_stack_size][1] = y+2; + 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; } - } - 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) - { - 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) - 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; - } - } } while (coord_stack_size>0); free(coord_stack); return created_something; |
