Fix TNT floodfill crash
This commit is contained in:
parent
91b4d1bf23
commit
5e02073a2f
74
src/simulation/CoordStack.h
Normal file
74
src/simulation/CoordStack.h
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Simulation_CoordStack_h
|
||||||
|
#define Simulation_CoordStack_h
|
||||||
|
|
||||||
|
#include "Config.h" // for XRES and YRES
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
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
|
@ -13,6 +13,7 @@
|
|||||||
#include "Air.h"
|
#include "Air.h"
|
||||||
#include "Gravity.h"
|
#include "Gravity.h"
|
||||||
#include "elements/Element.h"
|
#include "elements/Element.h"
|
||||||
|
#include "CoordStack.h"
|
||||||
|
|
||||||
//#include "graphics/Renderer.h"
|
//#include "graphics/Renderer.h"
|
||||||
//#include "graphics/Graphics.h"
|
//#include "graphics/Graphics.h"
|
||||||
@ -379,24 +380,38 @@ bool Simulation::FloodFillPmapCheck(int x, int y, int type)
|
|||||||
return (pmap[y][x]&0xFF) == 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 Simulation::flood_prop(int x, int y, size_t propoffset, PropertyValue propvalue, StructProperty::PropertyType proptype)
|
||||||
{
|
{
|
||||||
int x1, x2, i, dy = 1;
|
int i, x1, x2, dy = 1;
|
||||||
|
int did_something = 0;
|
||||||
|
int r = pmap[y][x];
|
||||||
|
if (!r)
|
||||||
|
r = photons[y][x];
|
||||||
|
if (!r)
|
||||||
|
return 0;
|
||||||
|
int parttype = (r&0xFF);
|
||||||
|
char * bitmap = (char*)malloc(XRES*YRES); //Bitmap for checking
|
||||||
|
if (!bitmap) return -1;
|
||||||
|
memset(bitmap, 0, XRES*YRES);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CoordStack cs;
|
||||||
|
cs.push(x, y);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
cs.pop(x, y);
|
||||||
|
x1 = x2 = x;
|
||||||
x1 = x2 = x;
|
x1 = x2 = x;
|
||||||
while (x1>=CELL)
|
while (x1>=CELL)
|
||||||
{
|
{
|
||||||
if (!FloodFillPmapCheck(x1-1, y, parttype) || bitmap[(y*XRES)+x1-1])
|
if (!FloodFillPmapCheck(x1-1, y, parttype) || bitmap[(y*XRES)+x1-1])
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
x1--;
|
x1--;
|
||||||
}
|
}
|
||||||
while (x2<XRES-CELL)
|
while (x2<XRES-CELL)
|
||||||
{
|
{
|
||||||
if (!FloodFillPmapCheck(x2+1, y, parttype) || bitmap[(y*XRES)+x2+1])
|
if (!FloodFillPmapCheck(x2+1, y, parttype) || bitmap[(y*XRES)+x2+1])
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
x2++;
|
x2++;
|
||||||
}
|
}
|
||||||
for (x=x1; x<=x2; x++)
|
for (x=x1; x<=x2; x++)
|
||||||
@ -424,33 +439,26 @@ int Simulation::flood_prop_2(int x, int y, size_t propoffset, PropertyValue prop
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bitmap[(y*XRES)+x] = 1;
|
bitmap[(y*XRES)+x] = 1;
|
||||||
|
did_something = 1;
|
||||||
}
|
}
|
||||||
if (y>=CELL+dy)
|
if (y>=CELL+dy)
|
||||||
for (x=x1; x<=x2; x++)
|
for (x=x1; x<=x2; x++)
|
||||||
if (FloodFillPmapCheck(x, y-dy, parttype) && !bitmap[((y-dy)*XRES)+x])
|
if (FloodFillPmapCheck(x, y-dy, parttype) && !bitmap[((y-dy)*XRES)+x])
|
||||||
if (!flood_prop_2(x, y-dy, propoffset, propvalue, proptype, parttype, bitmap))
|
cs.push(x, y-dy);
|
||||||
return 0;
|
|
||||||
if (y<YRES-CELL-dy)
|
if (y<YRES-CELL-dy)
|
||||||
for (x=x1; x<=x2; x++)
|
for (x=x1; x<=x2; x++)
|
||||||
if (FloodFillPmapCheck(x, y+dy, parttype) && !bitmap[((y+dy)*XRES)+x])
|
if (FloodFillPmapCheck(x, y+dy, parttype) && !bitmap[((y+dy)*XRES)+x])
|
||||||
if (!flood_prop_2(x, y+dy, propoffset, propvalue, proptype, parttype, bitmap))
|
cs.push(x, y+dy);
|
||||||
return 0;
|
} while (cs.getSize()>0);
|
||||||
return 1;
|
}
|
||||||
}
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
int Simulation::flood_prop(int x, int y, size_t propoffset, PropertyValue propvalue, StructProperty::PropertyType proptype)
|
std::cerr << e.what() << std::endl;
|
||||||
{
|
|
||||||
int r = 0;
|
|
||||||
char * bitmap = (char *)malloc(XRES*YRES); //Bitmap for checking
|
|
||||||
memset(bitmap, 0, XRES*YRES);
|
|
||||||
r = pmap[y][x];
|
|
||||||
if (!r)
|
|
||||||
r = photons[y][x];
|
|
||||||
if (!r)
|
|
||||||
return 1;
|
|
||||||
flood_prop_2(x, y, propoffset, propvalue, proptype, r&0xFF, bitmap);
|
|
||||||
free(bitmap);
|
free(bitmap);
|
||||||
return 0;
|
return -1;
|
||||||
|
}
|
||||||
|
free(bitmap);
|
||||||
|
return did_something;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulationSample Simulation::GetSample(int x, int y)
|
SimulationSample Simulation::GetSample(int x, int y)
|
||||||
|
@ -135,7 +135,6 @@ public:
|
|||||||
void kill_part(int i);
|
void kill_part(int i);
|
||||||
bool FloodFillPmapCheck(int x, int y, int type);
|
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(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 flood_water(int x, int y, int i, int originaly, int check);
|
||||||
int FloodINST(int x, int y, int fullc, int cm);
|
int FloodINST(int x, int y, int fullc, int cm);
|
||||||
void detach(int i);
|
void detach(int i);
|
||||||
|
Loading…
Reference in New Issue
Block a user