mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-02-03 18:14:01 +00:00
Fix obstruction grid edge rendering.
This patch adds the functionality of the removed hack added in 07bc370c1680, but without the runtime performance impact. OT_* obstruction types are now a bitmask; as a side effect, Game::baseGrid is no longer needed, which reduces memory usage by 4 MB.
This commit is contained in:
parent
ed767d150b
commit
9e675be651
6 changed files with 83 additions and 86 deletions
106
Aquaria/Game.cpp
106
Aquaria/Game.cpp
|
@ -2176,15 +2176,29 @@ std::string Game::getNoteName(int n, const std::string &pre)
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::clearDynamicGrid()
|
||||||
|
{
|
||||||
|
// just to be sure in case the grid/type sizes change,
|
||||||
|
// otherwise there is a chance to write a few bytes over the end of the buffer -- FG
|
||||||
|
compile_assert(sizeof(grid) % sizeof(uint32) == 0);
|
||||||
|
|
||||||
|
signed char *gridstart = &grid[0][0];
|
||||||
|
uint32 *gridend = (uint32*)(gridstart + sizeof(grid));
|
||||||
|
uint32 *gridptr = (uint32*)gridstart;
|
||||||
|
// mask out non-black bytes (which are those set by entites or tiles),
|
||||||
|
// use full uint32 rounds instead of single-bytes to speed things up.
|
||||||
|
const unsigned int mask = OT_MASK_BLACK | (OT_MASK_BLACK << 8) | (OT_MASK_BLACK << 16) | (OT_MASK_BLACK << 24);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*gridptr &= mask;
|
||||||
|
++gridptr;
|
||||||
|
}
|
||||||
|
while(gridptr < gridend);
|
||||||
|
}
|
||||||
|
|
||||||
void Game::reconstructEntityGrid()
|
void Game::reconstructEntityGrid()
|
||||||
{
|
{
|
||||||
for (int x = 0; x < MAX_GRID; x++)
|
clearDynamicGrid();
|
||||||
{
|
|
||||||
for (int y = 0; y < MAX_GRID; y++)
|
|
||||||
{
|
|
||||||
grid[x][y] = baseGrid[x][y];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FOR_ENTITIES(i)
|
FOR_ENTITIES(i)
|
||||||
{
|
{
|
||||||
|
@ -2203,37 +2217,6 @@ void Game::reconstructGrid(bool force)
|
||||||
{
|
{
|
||||||
Element *e = dsq->getElement(i);
|
Element *e = dsq->getElement(i);
|
||||||
e->fillGrid();
|
e->fillGrid();
|
||||||
/*
|
|
||||||
Element *e = dsq->getElement(i);
|
|
||||||
if (e->getElementType() == Element::BOX)
|
|
||||||
{
|
|
||||||
int w = e->getWidth()/TILE_SIZE;
|
|
||||||
int h = e->getHeight()/TILE_SIZE;
|
|
||||||
TileVector t(e->position);
|
|
||||||
|
|
||||||
if (h <= 1)
|
|
||||||
{
|
|
||||||
for (int tx = t.x-w/2; tx < t.x+w/2; tx++)
|
|
||||||
{
|
|
||||||
setGrid(TileVector(tx, t.y), 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int tx = t.x-w/2; tx < t.x+w/2; tx++)
|
|
||||||
{
|
|
||||||
for (int ty = t.y-h/2; ty < t.y+h/2; ty++)
|
|
||||||
{
|
|
||||||
setGrid(TileVector(tx, ty), 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (e->templateIdx != -1 && e->bgLayer == 0)
|
|
||||||
{
|
|
||||||
setGrid(&elementTemplates[e->templateIdx], e->position, e->rotation.z);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObsRow *o;
|
ObsRow *o;
|
||||||
|
@ -2246,23 +2229,37 @@ void Game::reconstructGrid(bool force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 0; x < MAX_GRID; x++)
|
|
||||||
{
|
|
||||||
for (int y = 0; y < MAX_GRID; y++)
|
|
||||||
{
|
|
||||||
baseGrid[x][y] = grid[x][y];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FOR_ENTITIES(i)
|
FOR_ENTITIES(i)
|
||||||
{
|
{
|
||||||
Entity *e = *i;
|
Entity *e = *i;
|
||||||
e->fillGrid();
|
e->fillGrid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trimGrid();
|
||||||
|
|
||||||
dsq->pathFinding.generateZones();
|
dsq->pathFinding.generateZones();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::trimGrid()
|
||||||
|
{
|
||||||
|
// Prevent the left- and rightmost column of black tiles
|
||||||
|
// from beeing drawn. (The maps were designed with this mind...)
|
||||||
|
for (int x = 0; x < MAX_GRID; x++)
|
||||||
|
{
|
||||||
|
const signed char *curCol = dsq->game->getGridColumn(x);
|
||||||
|
const signed char *leftCol = dsq->game->getGridColumn(x-1);
|
||||||
|
const signed char *rightCol = dsq->game->getGridColumn(x+1);
|
||||||
|
for (int y = 0; y < MAX_GRID; y++)
|
||||||
|
{
|
||||||
|
if (curCol[y] & OT_MASK_BLACK)
|
||||||
|
{
|
||||||
|
if (!(leftCol[y] & OT_MASK_BLACK) || !(rightCol[y] & OT_MASK_BLACK))
|
||||||
|
setGrid(TileVector(x, y), OT_BLACKINVIS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float Game::getCoverage(Vector pos, int sampleArea)
|
float Game::getCoverage(Vector pos, int sampleArea)
|
||||||
{
|
{
|
||||||
TileVector t(pos);
|
TileVector t(pos);
|
||||||
|
@ -6773,6 +6770,10 @@ void Game::applyState()
|
||||||
addRenderObject(gridRender3, LR_DEBUG_TEXT);
|
addRenderObject(gridRender3, LR_DEBUG_TEXT);
|
||||||
gridRender3->alpha = 0;
|
gridRender3->alpha = 0;
|
||||||
|
|
||||||
|
edgeRender = new GridRender(OT_BLACKINVIS);
|
||||||
|
addRenderObject(edgeRender, LR_DEBUG_TEXT);
|
||||||
|
edgeRender->alpha = 0;
|
||||||
|
|
||||||
waterSurfaceRender = new WaterSurfaceRender();
|
waterSurfaceRender = new WaterSurfaceRender();
|
||||||
//waterSurfaceRender->setRenderPass(-1);
|
//waterSurfaceRender->setRenderPass(-1);
|
||||||
addRenderObject(waterSurfaceRender, LR_WATERSURFACE);
|
addRenderObject(waterSurfaceRender, LR_WATERSURFACE);
|
||||||
|
@ -8786,12 +8787,14 @@ void Game::toggleGridRender()
|
||||||
gridRender->alpha.interpolateTo(0.5, t);
|
gridRender->alpha.interpolateTo(0.5, t);
|
||||||
gridRender2->alpha.interpolateTo(0.5, t);
|
gridRender2->alpha.interpolateTo(0.5, t);
|
||||||
gridRender3->alpha.interpolateTo(0.5, t);
|
gridRender3->alpha.interpolateTo(0.5, t);
|
||||||
|
edgeRender->alpha.interpolateTo(0.5, t);
|
||||||
}
|
}
|
||||||
else if (gridRender->alpha == 0.5)
|
else if (gridRender->alpha == 0.5)
|
||||||
{
|
{
|
||||||
gridRender->alpha.interpolateTo(0, t);
|
gridRender->alpha.interpolateTo(0, t);
|
||||||
gridRender2->alpha.interpolateTo(0, t);
|
gridRender2->alpha.interpolateTo(0, t);
|
||||||
gridRender3->alpha.interpolateTo(0, t);
|
gridRender3->alpha.interpolateTo(0, t);
|
||||||
|
edgeRender->alpha.interpolateTo(0, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10872,13 +10875,10 @@ void Game::loadElementTemplates(std::string pack)
|
||||||
|
|
||||||
void Game::clearGrid(int v)
|
void Game::clearGrid(int v)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < MAX_GRID; x++)
|
// ensure that grid is really a byte-array
|
||||||
{
|
compile_assert(sizeof(grid) == MAX_GRID * MAX_GRID);
|
||||||
for (int y = 0; y < MAX_GRID; y++)
|
|
||||||
{
|
memset(grid, v, sizeof(grid));
|
||||||
grid[x][y] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::resetFromTitle()
|
void Game::resetFromTitle()
|
||||||
|
|
|
@ -596,13 +596,20 @@ typedef std::vector<QuadList> QuadArray;
|
||||||
|
|
||||||
typedef std::list<Element*> ElementUpdateList;
|
typedef std::list<Element*> ElementUpdateList;
|
||||||
|
|
||||||
|
// Note: although this is a bitmask, only one of these values may be set at a time!
|
||||||
enum ObsType
|
enum ObsType
|
||||||
{
|
{
|
||||||
OT_EMPTY = 0,
|
OT_EMPTY = 0x00,
|
||||||
OT_INVISIBLE = 1,
|
|
||||||
OT_BLACK = 2,
|
// immutable
|
||||||
OT_INVISIBLEIN = 3,
|
OT_BLACK = 0x01,
|
||||||
OT_HURT = 4
|
OT_BLACKINVIS = 0x02, // same as OT_BLACK, but not drawn
|
||||||
|
OT_MASK_BLACK = OT_BLACK | OT_BLACKINVIS,
|
||||||
|
|
||||||
|
// set by entities or tiles
|
||||||
|
OT_INVISIBLE = 0x04,
|
||||||
|
OT_INVISIBLEIN = 0x08,
|
||||||
|
OT_HURT = 0x10,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EntitySaveData
|
struct EntitySaveData
|
||||||
|
@ -641,6 +648,7 @@ public:
|
||||||
const signed char *getGridColumn(int tileX);
|
const signed char *getGridColumn(int tileX);
|
||||||
void setGrid(const TileVector &tile, int v);
|
void setGrid(const TileVector &tile, int v);
|
||||||
bool isObstructed(const TileVector &tile, int t = -1) const;
|
bool isObstructed(const TileVector &tile, int t = -1) const;
|
||||||
|
void trimGrid();
|
||||||
|
|
||||||
void clearPointers();
|
void clearPointers();
|
||||||
|
|
||||||
|
@ -652,6 +660,7 @@ public:
|
||||||
bool loadScene(std::string scene);
|
bool loadScene(std::string scene);
|
||||||
|
|
||||||
void clearGrid(int v = 0);
|
void clearGrid(int v = 0);
|
||||||
|
void clearDynamicGrid();
|
||||||
|
|
||||||
void toggleWorldMap();
|
void toggleWorldMap();
|
||||||
|
|
||||||
|
@ -976,7 +985,7 @@ public:
|
||||||
void createGradient();
|
void createGradient();
|
||||||
|
|
||||||
std::string saveMusic;
|
std::string saveMusic;
|
||||||
GridRender *gridRender, *gridRender2, *gridRender3;
|
GridRender *gridRender, *gridRender2, *gridRender3, *edgeRender;
|
||||||
void toggleGridRender();
|
void toggleGridRender();
|
||||||
ElementUpdateList elementUpdateList;
|
ElementUpdateList elementUpdateList;
|
||||||
|
|
||||||
|
@ -1189,7 +1198,6 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
signed char grid[MAX_GRID][MAX_GRID];
|
signed char grid[MAX_GRID][MAX_GRID];
|
||||||
signed char baseGrid[MAX_GRID][MAX_GRID];
|
|
||||||
|
|
||||||
|
|
||||||
Quad *bg, *bg2;
|
Quad *bg, *bg2;
|
||||||
|
@ -1223,7 +1231,7 @@ int Game::getGridRaw(unsigned int x, unsigned int y) const
|
||||||
inline
|
inline
|
||||||
int Game::getGrid(const TileVector &tile) const
|
int Game::getGrid(const TileVector &tile) const
|
||||||
{
|
{
|
||||||
if (tile.x < 0 || tile.x >= MAX_GRID || tile.y < 0 || tile.y >= MAX_GRID) return 1;
|
if (tile.x < 0 || tile.x >= MAX_GRID || tile.y < 0 || tile.y >= MAX_GRID) return OT_INVISIBLE;
|
||||||
return grid[tile.x][tile.y];
|
return grid[tile.x][tile.y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,10 +1254,7 @@ void Game::setGrid(const TileVector &tile, int v)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool Game::isObstructed(const TileVector &tile, int t) const
|
bool Game::isObstructed(const TileVector &tile, int t /* = -1 */) const
|
||||||
{
|
{
|
||||||
if (t == -1)
|
return (getGrid(tile) & t);
|
||||||
return (getGrid(tile) != 0);
|
|
||||||
return getGrid(tile) == t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,9 @@ void GridRender::onRender()
|
||||||
case OT_BLACK:
|
case OT_BLACK:
|
||||||
core->setColor(0, 0, 0, 1);
|
core->setColor(0, 0, 0, 1);
|
||||||
break;
|
break;
|
||||||
|
case OT_BLACKINVIS:
|
||||||
|
core->setColor(0.3, 0, 0.6, alpha.getValue());
|
||||||
|
break;
|
||||||
case OT_HURT:
|
case OT_HURT:
|
||||||
core->setColor(1, 1, 0, alpha.getValue());
|
core->setColor(1, 1, 0, alpha.getValue());
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -518,7 +518,7 @@ void SceneEditor::openMainMenu()
|
||||||
addMainMenuItem("EDIT TILES (F5)", 106);
|
addMainMenuItem("EDIT TILES (F5)", 106);
|
||||||
addMainMenuItem("EDIT ENTITIES (F6)", 107);
|
addMainMenuItem("EDIT ENTITIES (F6)", 107);
|
||||||
addMainMenuItem("EDIT NODES (F7)", 108);
|
addMainMenuItem("EDIT NODES (F7)", 108);
|
||||||
addMainMenuItem("REGEN COLLISIONS (SHIFT-R)", 103);
|
addMainMenuItem("REGEN COLLISIONS (ALT-R)", 103);
|
||||||
addMainMenuItem("RECACHE TEXTURES (CTRL-R)", 130);
|
addMainMenuItem("RECACHE TEXTURES (CTRL-R)", 130);
|
||||||
// addMainMenuItem("REFRESH DATAFILES (F11)", 117);
|
// addMainMenuItem("REFRESH DATAFILES (F11)", 117);
|
||||||
addMainMenuItem("REGEN ROCK FROM MAPTEMPLATE (F11+F12)", 116);
|
addMainMenuItem("REGEN ROCK FROM MAPTEMPLATE (F11+F12)", 116);
|
||||||
|
@ -1949,12 +1949,12 @@ void SceneEditor::skinLevel(pngRawInfo *png, int minX, int minY, int maxX, int m
|
||||||
float rot=0;
|
float rot=0;
|
||||||
bool addTile = false;
|
bool addTile = false;
|
||||||
TileVector t(x,y);
|
TileVector t(x,y);
|
||||||
if (dsq->game->isObstructed(t,OT_BLACK)
|
if (dsq->game->isObstructed(t, OT_MASK_BLACK)
|
||||||
&& (
|
&& (
|
||||||
!dsq->game->isObstructed(TileVector(x+1,y),OT_BLACK) ||
|
!dsq->game->isObstructed(TileVector(x+1,y), OT_MASK_BLACK) ||
|
||||||
!dsq->game->isObstructed(TileVector(x-1,y),OT_BLACK) ||
|
!dsq->game->isObstructed(TileVector(x-1,y), OT_MASK_BLACK) ||
|
||||||
!dsq->game->isObstructed(TileVector(x,y-1),OT_BLACK) ||
|
!dsq->game->isObstructed(TileVector(x,y-1), OT_MASK_BLACK) ||
|
||||||
!dsq->game->isObstructed(TileVector(x,y+1),OT_BLACK)
|
!dsq->game->isObstructed(TileVector(x,y+1), OT_MASK_BLACK)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -1967,7 +1967,7 @@ void SceneEditor::skinLevel(pngRawInfo *png, int minX, int minY, int maxX, int m
|
||||||
{
|
{
|
||||||
*/
|
*/
|
||||||
float dist=0;
|
float dist=0;
|
||||||
wallNormal = dsq->game->getWallNormal(t.worldVector(), 5, &dist, OT_BLACK);
|
wallNormal = dsq->game->getWallNormal(t.worldVector(), 5, &dist, OT_MASK_BLACK);
|
||||||
offset = wallNormal*(-TILE_SIZE*0.6f);
|
offset = wallNormal*(-TILE_SIZE*0.6f);
|
||||||
MathFunctions::calculateAngleBetweenVectorsInDegrees(Vector(0,0,0), wallNormal, rot);
|
MathFunctions::calculateAngleBetweenVectorsInDegrees(Vector(0,0,0), wallNormal, rot);
|
||||||
rot = 180-(360-rot);
|
rot = 180-(360-rot);
|
||||||
|
@ -3919,22 +3919,12 @@ void SceneEditor::prevEntityType()
|
||||||
void SceneEditor::dumpObs()
|
void SceneEditor::dumpObs()
|
||||||
{
|
{
|
||||||
TileVector tv;
|
TileVector tv;
|
||||||
const uint32 A = 0xFF000000;
|
|
||||||
#define COL(c) (((0x ## c)) | A)
|
|
||||||
const uint32 coltab[5] =
|
|
||||||
{
|
|
||||||
COL(FFFFFF),
|
|
||||||
COL(FFFFFF),
|
|
||||||
COL(000000),
|
|
||||||
COL(FFFFFF),
|
|
||||||
COL(FFFFFF),
|
|
||||||
};
|
|
||||||
unsigned char *data = new unsigned char[MAX_GRID * MAX_GRID * sizeof(uint32)];
|
unsigned char *data = new unsigned char[MAX_GRID * MAX_GRID * sizeof(uint32)];
|
||||||
uint32 *ptr = (uint32*)data;
|
uint32 *ptr = (uint32*)data;
|
||||||
for(tv.y = MAX_GRID - 1; ; --tv.y)
|
for(tv.y = MAX_GRID - 1; ; --tv.y)
|
||||||
{
|
{
|
||||||
for(tv.x = 0; tv.x < MAX_GRID; ++tv.x)
|
for(tv.x = 0; tv.x < MAX_GRID; ++tv.x)
|
||||||
*ptr++ = coltab[game->getGrid(tv)];
|
*ptr++ = game->isObstructed(tv, OT_MASK_BLACK) ? 0xFF000000 : 0xFFFFFFFF;
|
||||||
if(tv.y == 0)
|
if(tv.y == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,7 +349,6 @@ static void scriptDebug(lua_State *L, const std::string& msg)
|
||||||
void compile_time_assertions()
|
void compile_time_assertions()
|
||||||
{
|
{
|
||||||
#define oo(cls) offsetof(cls, _objtype)
|
#define oo(cls) offsetof(cls, _objtype)
|
||||||
#define compile_assert(pred) switch(0){case 0:case (pred):;}
|
|
||||||
compile_assert(oo(Path) == oo(RenderObject));
|
compile_assert(oo(Path) == oo(RenderObject));
|
||||||
compile_assert(oo(Path) == oo(Entity));
|
compile_assert(oo(Path) == oo(Entity));
|
||||||
compile_assert(oo(Path) == oo(Ingredient));
|
compile_assert(oo(Path) == oo(Ingredient));
|
||||||
|
@ -364,7 +363,6 @@ void compile_time_assertions()
|
||||||
compile_assert(oo(Path) == oo(Avatar));
|
compile_assert(oo(Path) == oo(Avatar));
|
||||||
compile_assert(oo(Path) == oo(BaseText));
|
compile_assert(oo(Path) == oo(BaseText));
|
||||||
#undef oo
|
#undef oo
|
||||||
#undef compile_assert
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -97,6 +97,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "glext.h"
|
#include "glext.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define compile_assert(pred) switch(0){case 0:case (pred):;}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable:4786)
|
#pragma warning(disable:4786)
|
||||||
|
|
Loading…
Add table
Reference in a new issue