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 "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<XRES-CELL)
|
||||
{
|
||||
if (!FloodFillPmapCheck(x2+1, y, parttype) || bitmap[(y*XRES)+x2+1])
|
||||
{
|
||||
break;
|
||||
}
|
||||
x2++;
|
||||
}
|
||||
for (x=x1; x<=x2; x++)
|
||||
{
|
||||
i = pmap[y][x];
|
||||
if (!i)
|
||||
i = photons[y][x];
|
||||
if (!i)
|
||||
continue;
|
||||
switch (proptype) {
|
||||
case StructProperty::Float:
|
||||
*((float*)(((char*)&parts[i>>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<YRES-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;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Simulation::flood_prop(int x, int y, size_t propoffset, PropertyValue propvalue, StructProperty::PropertyType proptype)
|
||||
{
|
||||
int r = 0;
|
||||
char * bitmap = (char *)malloc(XRES*YRES); //Bitmap for checking
|
||||
memset(bitmap, 0, XRES*YRES);
|
||||
r = pmap[y][x];
|
||||
int i, x1, x2, dy = 1;
|
||||
int did_something = 0;
|
||||
int 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);
|
||||
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;
|
||||
while (x1>=CELL)
|
||||
{
|
||||
if (!FloodFillPmapCheck(x1-1, y, parttype) || bitmap[(y*XRES)+x1-1])
|
||||
break;
|
||||
x1--;
|
||||
}
|
||||
while (x2<XRES-CELL)
|
||||
{
|
||||
if (!FloodFillPmapCheck(x2+1, y, parttype) || bitmap[(y*XRES)+x2+1])
|
||||
break;
|
||||
x2++;
|
||||
}
|
||||
for (x=x1; x<=x2; x++)
|
||||
{
|
||||
i = pmap[y][x];
|
||||
if (!i)
|
||||
i = photons[y][x];
|
||||
if (!i)
|
||||
continue;
|
||||
switch (proptype) {
|
||||
case StructProperty::Float:
|
||||
*((float*)(((char*)&parts[i>>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 (y<YRES-CELL-dy)
|
||||
for (x=x1; x<=x2; x++)
|
||||
if (FloodFillPmapCheck(x, y+dy, parttype) && !bitmap[((y+dy)*XRES)+x])
|
||||
cs.push(x, y+dy);
|
||||
} while (cs.getSize()>0);
|
||||
}
|
||||
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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user