diff --git a/src/simulation/CoordStack.h b/src/simulation/CoordStack.h new file mode 100644 index 000000000..32625a24f --- /dev/null +++ b/src/simulation/CoordStack.h @@ -0,0 +1,74 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef Simulation_CoordStack_h +#define Simulation_CoordStack_h + +#include "Config.h" // for XRES and YRES +#include + +class CoordStackOverflowException: public std::exception +{ +public: + CoordStackOverflowException() { } + virtual const char* what() const throw() + { + return "Maximum number of entries in the coordinate stack was exceeded"; + } + ~CoordStackOverflowException() throw() {}; +}; + +class CoordStack +{ +private: + unsigned short (*stack)[2]; + int stack_size; + const static int stack_limit = XRES*YRES; +public: + CoordStack() : + stack(NULL), + stack_size(0) + { + stack = (unsigned short(*)[2])(malloc(sizeof(unsigned short)*2*stack_limit)); + } + ~CoordStack() + { + if (stack) free(stack); + } + void push(int x, int y) + { + if (stack_size>=stack_limit) + throw CoordStackOverflowException(); + stack[stack_size][0] = x; + stack[stack_size][1] = y; + stack_size++; + } + void pop(int& x, int& y) + { + stack_size--; + x = stack[stack_size][0]; + y = stack[stack_size][1]; + } + int getSize() const + { + return stack_size; + } + void clear() + { + stack_size = 0; + } +}; + +#endif diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index c0de378d2..5fefc0304 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -13,6 +13,7 @@ #include "Air.h" #include "Gravity.h" #include "elements/Element.h" +#include "CoordStack.h" //#include "graphics/Renderer.h" //#include "graphics/Graphics.h" @@ -379,78 +380,85 @@ bool Simulation::FloodFillPmapCheck(int x, int y, int type) return (pmap[y][x]&0xFF) == type; } -int Simulation::flood_prop_2(int x, int y, size_t propoffset, PropertyValue propvalue, StructProperty::PropertyType proptype, int parttype, char * bitmap) -{ - int x1, x2, i, dy = 1; - x1 = x2 = x; - while (x1>=CELL) - { - if (!FloodFillPmapCheck(x1-1, y, parttype) || bitmap[(y*XRES)+x1-1]) - { - break; - } - x1--; - } - while (x2>8])+propoffset)) = propvalue.Float; - break; - - case StructProperty::ParticleType: - case StructProperty::Integer: - *((int*)(((char*)&parts[i>>8])+propoffset)) = propvalue.Integer; - break; - - case StructProperty::UInteger: - *((unsigned int*)(((char*)&parts[i>>8])+propoffset)) = propvalue.UInteger; - break; - - default: - break; - } - bitmap[(y*XRES)+x] = 1; - } - if (y>=CELL+dy) - for (x=x1; x<=x2; x++) - if (FloodFillPmapCheck(x, y-dy, parttype) && !bitmap[((y-dy)*XRES)+x]) - if (!flood_prop_2(x, y-dy, propoffset, propvalue, proptype, parttype, bitmap)) - return 0; - if (y=CELL) + { + if (!FloodFillPmapCheck(x1-1, y, parttype) || bitmap[(y*XRES)+x1-1]) + break; + x1--; + } + while (x2>8])+propoffset)) = propvalue.Float; + break; + + case StructProperty::ParticleType: + case StructProperty::Integer: + *((int*)(((char*)&parts[i>>8])+propoffset)) = propvalue.Integer; + break; + + case StructProperty::UInteger: + *((unsigned int*)(((char*)&parts[i>>8])+propoffset)) = propvalue.UInteger; + break; + + default: + break; + } + bitmap[(y*XRES)+x] = 1; + did_something = 1; + } + if (y>=CELL+dy) + for (x=x1; x<=x2; x++) + if (FloodFillPmapCheck(x, y-dy, parttype) && !bitmap[((y-dy)*XRES)+x]) + cs.push(x, y-dy); + if (y0); + } + catch (std::exception& e) + { + std::cerr << e.what() << std::endl; + free(bitmap); + return -1; + } free(bitmap); - return 0; + return did_something; } SimulationSample Simulation::GetSample(int x, int y) diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h index 5933619a5..93d92a63b 100644 --- a/src/simulation/Simulation.h +++ b/src/simulation/Simulation.h @@ -135,7 +135,6 @@ public: void kill_part(int i); bool FloodFillPmapCheck(int x, int y, int type); int flood_prop(int x, int y, size_t propoffset, PropertyValue propvalue, StructProperty::PropertyType proptype); - int flood_prop_2(int x, int y, size_t propoffset, PropertyValue propvalue, StructProperty::PropertyType proptype, int parttype, char * bitmap); int flood_water(int x, int y, int i, int originaly, int check); int FloodINST(int x, int y, int fullc, int cm); void detach(int i);