Use stack on the heap for roof fill
This commit is contained in:
parent
e23b39abaa
commit
bdf515c755
91
src/tile.cc
91
src/tile.cc
|
@ -18,6 +18,7 @@
|
||||||
#include "platform_compat.h"
|
#include "platform_compat.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "svga.h"
|
#include "svga.h"
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
namespace fallout {
|
namespace fallout {
|
||||||
|
|
||||||
|
@ -52,8 +53,6 @@ typedef struct UpsideDownTriangle {
|
||||||
static void tileSetBorder(int windowWidth, int windowHeight, int hexGridWidth, int hexGridHeight);
|
static void tileSetBorder(int windowWidth, int windowHeight, int hexGridWidth, int hexGridHeight);
|
||||||
static void tileRefreshMapper(Rect* rect, int elevation);
|
static void tileRefreshMapper(Rect* rect, int elevation);
|
||||||
static void tileRefreshGame(Rect* rect, int elevation);
|
static void tileRefreshGame(Rect* rect, int elevation);
|
||||||
static void roof_fill_on(int x, int y, int elevation);
|
|
||||||
static void roof_fill_off(int x, int y, int elevation);
|
|
||||||
static void tileRenderRoof(int fid, int x, int y, Rect* rect, int light);
|
static void tileRenderRoof(int fid, int x, int y, Rect* rect, int light);
|
||||||
static void _draw_grid(int tile, int elevation, Rect* rect);
|
static void _draw_grid(int tile, int elevation, Rect* rect);
|
||||||
static void tileRenderFloor(int fid, int x, int y, Rect* rect);
|
static void tileRenderFloor(int fid, int x, int y, Rect* rect);
|
||||||
|
@ -1258,63 +1257,59 @@ void tileRenderRoofsInRect(Rect* rect, int elevation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4B22D0
|
|
||||||
static void roof_fill_on(int x, int y, int elevation)
|
struct roof_fill_task {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
||||||
|
void roof_fill_push_task_if_in_bounds(std::stack<roof_fill_task> &tasks_stack, int x, int y) {
|
||||||
|
if (x >= 0 && x < gSquareGridWidth && y >= 0 && y < gSquareGridHeight) {
|
||||||
|
tasks_stack.push(roof_fill_task{x,y});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static void roof_fill_off_process_task(std::stack<roof_fill_task> &tasks_stack, int elevation, bool on)
|
||||||
{
|
{
|
||||||
if (x >= 0 && x < gSquareGridWidth && y >= 0 && y < gSquareGridHeight) {
|
|
||||||
int squareTileIndex = gSquareGridWidth * y + x;
|
|
||||||
int squareTile = gTileSquares[elevation]->field_0[squareTileIndex];
|
|
||||||
int roof = (squareTile >> 16) & 0xFFFF;
|
|
||||||
|
|
||||||
int id = roof & 0xFFF;
|
auto [x, y] = tasks_stack.top();
|
||||||
if (buildFid(OBJ_TYPE_TILE, id, 0, 0, 0) != buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
tasks_stack.pop();
|
||||||
int flag = (roof & 0xF000) >> 12;
|
|
||||||
if ((flag & 0x01) != 0) {
|
int squareTileIndex = gSquareGridWidth * y + x;
|
||||||
|
int squareTile = gTileSquares[elevation]->field_0[squareTileIndex];
|
||||||
|
int roof = (squareTile >> 16) & 0xFFFF;
|
||||||
|
|
||||||
|
int id = roof & 0xFFF;
|
||||||
|
if (buildFid(OBJ_TYPE_TILE, id, 0, 0, 0) != buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
||||||
|
int flag = (roof & 0xF000) >> 12;
|
||||||
|
|
||||||
|
if (on ? ((flag & 0x01) != 0) : ((flag & 0x03) == 0)) {
|
||||||
|
if (on) {
|
||||||
flag &= ~0x01;
|
flag &= ~0x01;
|
||||||
|
} else {
|
||||||
gTileSquares[elevation]->field_0[squareTileIndex] = (squareTile & 0xFFFF) | (((flag << 12) | id) << 16);
|
flag |= 0x01;
|
||||||
|
|
||||||
roof_fill_on(x - 1, y, elevation);
|
|
||||||
roof_fill_on(x + 1, y, elevation);
|
|
||||||
roof_fill_on(x, y - 1, elevation);
|
|
||||||
roof_fill_on(x, y + 1, elevation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gTileSquares[elevation]->field_0[squareTileIndex] = (squareTile & 0xFFFF) | (((flag << 12) | id) << 16);
|
||||||
|
|
||||||
|
roof_fill_push_task_if_in_bounds(tasks_stack, x - 1, y);
|
||||||
|
roof_fill_push_task_if_in_bounds(tasks_stack, x + 1, y);
|
||||||
|
roof_fill_push_task_if_in_bounds(tasks_stack, x, y - 1);
|
||||||
|
roof_fill_push_task_if_in_bounds(tasks_stack, x, y + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 0x4B23D4
|
// 0x4B23D4
|
||||||
void tile_fill_roof(int x, int y, int elevation, bool on)
|
void tile_fill_roof(int x, int y, int elevation, bool on)
|
||||||
{
|
{
|
||||||
if (on) {
|
std::stack<roof_fill_task> tasks_stack;
|
||||||
roof_fill_on(x, y, elevation);
|
|
||||||
} else {
|
roof_fill_push_task_if_in_bounds(tasks_stack, x, y);
|
||||||
roof_fill_off(x, y, elevation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0x4B23DC
|
while(!tasks_stack.empty()) {
|
||||||
static void roof_fill_off(int x, int y, int elevation)
|
roof_fill_off_process_task(tasks_stack, elevation, on);
|
||||||
{
|
|
||||||
if (x >= 0 && x < gSquareGridWidth && y >= 0 && y < gSquareGridHeight) {
|
|
||||||
int squareTileIndex = gSquareGridWidth * y + x;
|
|
||||||
int squareTile = gTileSquares[elevation]->field_0[squareTileIndex];
|
|
||||||
int roof = (squareTile >> 16) & 0xFFFF;
|
|
||||||
|
|
||||||
int id = roof & 0xFFF;
|
|
||||||
if (buildFid(OBJ_TYPE_TILE, id, 0, 0, 0) != buildFid(OBJ_TYPE_TILE, 1, 0, 0, 0)) {
|
|
||||||
int flag = (roof & 0xF000) >> 12;
|
|
||||||
if ((flag & 0x03) == 0) {
|
|
||||||
flag |= 0x01;
|
|
||||||
|
|
||||||
gTileSquares[elevation]->field_0[squareTileIndex] = (squareTile & 0xFFFF) | (((flag << 12) | id) << 16);
|
|
||||||
|
|
||||||
roof_fill_off(x - 1, y, elevation);
|
|
||||||
roof_fill_off(x + 1, y, elevation);
|
|
||||||
roof_fill_off(x, y - 1, elevation);
|
|
||||||
roof_fill_off(x, y + 1, elevation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue