aboutsummaryrefslogtreecommitdiff
path: root/src/sandbox.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2025-05-18 11:10:09 -0700
committerrtk0c <[email protected]>2025-05-18 11:10:09 -0700
commit838792fca41b9bccce260e9500d75549433bbe6a (patch)
treea6552fa2d9dbfeebc69f13d7cffca6d29b219c7c /src/sandbox.cpp
parent3af71b8aa4976d2eb6ed9eb61e9e8ac5bd6d309a (diff)
Add bounds check to set_sand()HEADmaster
Previously, painting didn't do it (simulation did) so there were buffer overruns
Diffstat (limited to 'src/sandbox.cpp')
-rw-r--r--src/sandbox.cpp31
1 files changed, 22 insertions, 9 deletions
diff --git a/src/sandbox.cpp b/src/sandbox.cpp
index 2c09d77..64bf1db 100644
--- a/src/sandbox.cpp
+++ b/src/sandbox.cpp
@@ -60,8 +60,8 @@ static void simulate_sand_tile(Sandbox& self, int x, int y) {
case Tile::Ti_Sand: {
const auto below = self.gs(x, y - 1);
if (below.so == Tile::Ti_Air) {
- self.set_sand(x, y, below);
- self.set_sand(x, y - 1, at0);
+ self.ss(x, y, below);
+ self.ss(x, y - 1, at0);
} else {
Pt loc1[]{ Pt(x - 1, y - 1), Pt(x + 1, y - 1) };
auto bound = 2;
@@ -70,8 +70,8 @@ static void simulate_sand_tile(Sandbox& self, int x, int y) {
// Try going to a side
auto at1 = self.gs(loc1[i].x, loc1[i].y);
if (at1.so == Tile::Ti_Air) {
- self.set_sand(x, y, at1);
- self.set_sand(loc1[i].x, loc1[i].y, at0);
+ self.ss(x, y, at1);
+ self.ss(loc1[i].x, loc1[i].y, at0);
}
which = (which + 1) % bound;
}
@@ -123,19 +123,32 @@ void Sandbox::simulate_step() {
++ncycle;
}
+#define BOUNDS_CHECK(x, y) if (x < 0 || x >= width || y < 0 || y >= height)
+
Tile& Sandbox::gs(int x, int y) {
- if (x < 0 || x >= width || y < 0 || y >= height)
+ BOUNDS_CHECK(x, y) {
return _wall_tile;
+ }
+
return tiles[y * width + x];
}
-void Sandbox::set_sand(int x, int y, Tile sand) {
+void Sandbox::ss(int x, int y, Tile sand) {
+ BOUNDS_CHECK(x, y) {
+ return;
+ }
+
+ // Update tile
auto& target = tiles[y * width + x];
target = sand;
- // Set update bit if the target is after cursor
- if (y < _y || x > _x)
- target.updated = true;
+ target.updated = true;
+ // Update visuals
bitmap[y * width + x] = sand.get_color();
+
+ mark_dirty(x, y);
+}
+
+void Sandbox::mark_dirty(int x, int y) {
if (dirty_writeto == Rect())
dirty_writeto = Rect(x, y, x, y);
else