aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay <[email protected]>2021-04-07 14:37:46 +0100
committerAkshay <[email protected]>2021-04-07 14:37:46 +0100
commitb90c2c4bc61248d5ea2e894fc70b84bc00582406 (patch)
tree5e361a095a5745ba4944e55d12d5e73090cdd54c
parentf57f03cd87d205d8304008d08c05f53c34b44435 (diff)
implement iso grids; lisp primitives to manipulate grids
-rw-r--r--src/grid.rs107
-rw-r--r--src/lisp/prelude.rs11
2 files changed, 118 insertions, 0 deletions
diff --git a/src/grid.rs b/src/grid.rs
new file mode 100644
index 0000000..38efaba
--- /dev/null
+++ b/src/grid.rs
@@ -0,0 +1,107 @@
1// most of this module was written out of frustration
2// TODO: make all this less messy
3
4use sdl2::{pixels::Color, rect::Point, render::Canvas, video::Window};
5
6use crate::{
7 consts::{colors::*, ANGLE},
8 rect,
9};
10
11#[derive(Debug, Copy, Clone)]
12pub enum GridKind {
13 Rectangle,
14 Isometric,
15}
16
17pub struct Grid {
18 pub enabled: bool,
19 pub color: Color,
20 pub kind: GridKind,
21}
22
23impl Grid {
24 pub fn new() -> Self {
25 Self {
26 enabled: true,
27 color: GRID_COLOR,
28 kind: GridKind::Rectangle,
29 }
30 }
31
32 pub fn draw(
33 &self,
34 canvas: &mut Canvas<Window>,
35 zoom: u8,
36 start: &Point,
37 width: u32,
38 height: u32,
39 ) {
40 let cs = zoom as u32;
41 let (x, y) = (start.x(), start.y());
42 canvas.set_draw_color(self.color);
43
44 match self.kind {
45 GridKind::Rectangle => {
46 let mut vertical_tuples = (1..width)
47 .map(|i| {
48 let x = (i * cs) as i32;
49 let y = (height * cs) as i32;
50 if i % 2 == 0 {
51 (*start + Point::new(x, 0), *start + Point::new(x, y))
52 } else {
53 (*start + Point::new(x, y), *start + Point::new(x, 0))
54 }
55 })
56 .collect::<Vec<_>>();
57
58 // SAFETY
59 // The mem space occupied by a [(T, T); N] is the same as twice the mem space of a
60 // [T; 2 * N], where T is not a dynamically sized type.
61 let verticals: Vec<Point> = unsafe {
62 vertical_tuples.set_len(vertical_tuples.len() * 2);
63 std::mem::transmute(vertical_tuples)
64 };
65
66 let mut horizontal_tuples = (1..height)
67 .map(|j| {
68 let x = (width * cs) as i32;
69 let y = (j * cs) as i32;
70 if j % 2 == 0 {
71 (*start + Point::new(0, y), *start + Point::new(x, y))
72 } else {
73 (*start + Point::new(x, y), *start + Point::new(0, y))
74 }
75 })
76 .collect::<Vec<_>>();
77 let horizontals: Vec<Point> = unsafe {
78 horizontal_tuples.set_len(horizontal_tuples.len() * 2);
79 std::mem::transmute(horizontal_tuples)
80 };
81
82 canvas.draw_lines(&verticals[..]).unwrap();
83 canvas.draw_lines(&horizontals[..]).unwrap();
84 }
85 GridKind::Isometric => {
86 // tan 26.525 ~= 0.5
87 canvas.set_clip_rect(Some(rect!(x, y, width * cs, height * cs)));
88 for i in (0..2 * height + width).step_by(4) {
89 let begin = Point::from(((i * cs) as i32, 0i32));
90 let end = Point::from((0i32, ((i * cs) as f64 * 0.5).floor() as i32));
91 canvas.draw_line(*start + begin, *start + end).unwrap();
92 }
93 for j in (0..height + width / 2).step_by(2) {
94 let idx = (j as i32 - (width as i32 / 2)) * cs as i32;
95 let begin = Point::from((-100i32, idx));
96 let end = Point::from((
97 (width * cs) as i32,
98 (idx as f64 + (width * cs) as f64 * ANGLE.to_radians().tan()).floor()
99 as i32,
100 ));
101 canvas.draw_line(*start + begin, *start + end).unwrap();
102 }
103 canvas.set_clip_rect(None);
104 }
105 }
106 }
107}
diff --git a/src/lisp/prelude.rs b/src/lisp/prelude.rs
index fee787e..d0667d8 100644
--- a/src/lisp/prelude.rs
+++ b/src/lisp/prelude.rs
@@ -1,6 +1,7 @@
1use crate::{ 1use crate::{
2 bitmap::MapPoint, 2 bitmap::MapPoint,
3 brush::Brush, 3 brush::Brush,
4 grid::{Grid, GridKind},
4 guide::Guide, 5 guide::Guide,
5 lisp::{ 6 lisp::{
6 error::{EvalError, LispError}, 7 error::{EvalError, LispError},
@@ -257,6 +258,16 @@ pub fn new_env() -> Result<Environment, LispError> {
257 Ok(LispExpr::Unit) 258 Ok(LispExpr::Unit)
258 }); 259 });
259 260
261 primitive!(env, Arity::Exact(0), "grid-rectangle", |_, app| {
262 app.grid.kind = GridKind::Rectangle;
263 Ok(LispExpr::Unit)
264 });
265
266 primitive!(env, Arity::Exact(0), "grid-isometric", |_, app| {
267 app.grid.kind = GridKind::Isometric;
268 Ok(LispExpr::Unit)
269 });
270
260 primitive!(env, Arity::Exact(0), "brush-fill", |_, app| { 271 primitive!(env, Arity::Exact(0), "brush-fill", |_, app| {
261 app.brush = Brush::Fill; 272 app.brush = Brush::Fill;
262 Ok(LispExpr::Unit) 273 Ok(LispExpr::Unit)