aboutsummaryrefslogtreecommitdiffstats
path: root/src/renderer.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-06-06 10:58:09 +0200
committerBad Diode <bd@badd10de.dev>2021-06-06 10:58:09 +0200
commit96c4179094b229c67701f0f36abd5e118a4331c9 (patch)
tree14d2734ca425f4770b96bcb84baa3c5a97741670 /src/renderer.c
parent8feaf2dc269dd0cb81de87be90d2b2c7f28bcbea (diff)
downloadstepper-96c4179094b229c67701f0f36abd5e118a4331c9.tar.gz
stepper-96c4179094b229c67701f0f36abd5e118a4331c9.zip
Add diagonal line implementation
Diffstat (limited to 'src/renderer.c')
-rw-r--r--src/renderer.c103
1 files changed, 37 insertions, 66 deletions
diff --git a/src/renderer.c b/src/renderer.c
index d247d06..2b1f0d2 100644
--- a/src/renderer.c
+++ b/src/renderer.c
@@ -47,65 +47,6 @@ draw_pixel(size_t x, size_t y, u8 color) {
47IWRAM_CODE 47IWRAM_CODE
48void 48void
49draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { 49draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
50 // Pointer to the initial position of the screen buffer where we will start
51 // writing our data.
52 // vu16 *destination = (u16*)(SCREEN_BUFFER + y0 * SCREEN_WIDTH + x0);
53
54// // Adjust the step direction and calculate deltas.
55// size_t x_step;
56// size_t y_step;
57// size_t dx;
58// size_t dy;
59// if (x0 > x1) {
60// x_step = -1;
61// dx = x0 - x1;
62// } else {
63// x_step = 1;
64// dx = x1 - x0;
65// }
66// if (y0 > y1) {
67// y_step = -SCREEN_WIDTH;
68// dy = y0 - y1;
69// } else {
70// y_step = +SCREEN_WIDTH;
71// dy = y1 - y0;
72// }
73
74// if(dy == 0) {
75// // Horizontal line.
76// for(int i = 0; i <= dx; i++) {
77// draw_pixel(x0 + i, y0, clr);
78// }
79// } else if(dx == 0) {
80// // Vertical line.
81// for(int i = 0; i <= dy; i++) {
82// draw_pixel(x0, y0 + i, clr);
83// }
84// } else if (dx >= dy){
85// // Positive slope.
86// int diff = 2 * dy - dx;
87// for (int i = 0; i <= dx; ++i) {
88// // *destination = clr;
89// if (diff >= 0) {
90// // destination += y_step;
91// diff -= 2 * dx;
92// }
93// // destination += x_step;
94// diff += 2 * dy;
95// }
96// } else {
97// // Negative slope.
98// int diff = 2 * dx - dy;
99// for (int i = 0; i <= dy; ++i) {
100// // *destination = clr;
101// if (diff >= 0) {
102// // destination += x_step;
103// diff -= 2 * dy;
104// }
105// // destination += y_step;
106// diff += 2 * dx;
107// }
108// }
109 BOUNDCHECK_SCREEN(x0, y0); 50 BOUNDCHECK_SCREEN(x0, y0);
110 BOUNDCHECK_SCREEN(x1, y1); 51 BOUNDCHECK_SCREEN(x1, y1);
111 52
@@ -122,15 +63,13 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
122 // Get a pointer to the backbuffer and the tile row. 63 // Get a pointer to the backbuffer and the tile row.
123 u32 *backbuffer = &BACKBUF[start_row0 + (tile_x0 + tile_y0 * 32) * 8]; 64 u32 *backbuffer = &BACKBUF[start_row0 + (tile_x0 + tile_y0 * 32) * 8];
124 65
125 size_t dx = tile_x1 - tile_x0;
126 size_t dy = tile_y1 - tile_y0;
127
128 if (y0 == y1) { 66 if (y0 == y1) {
129 // There are 3 cases: 67 // Horizontal line. There are 3 cases:
130 // 1. Lines fit on a single tile. 68 // 1. Lines fit on a single tile.
131 // 2. Lines go through 2 tiles, both require partial row updates. 69 // 2. Lines go through 2 tiles, both require partial row updates.
132 // 3. Lines go through 3 or more tiles, first and last tiles use 70 // 3. Lines go through 3 or more tiles, first and last tiles use
133 // partial row updates, rows in the middle can write the. 71 // partial row updates, rows in the middle can write the.
72 size_t dx = tile_x1 - tile_x0;
134 if (dx < 1) { 73 if (dx < 1) {
135 u32 row_mask = 0xFFFFFFFF; 74 u32 row_mask = 0xFFFFFFFF;
136 row_mask >>= (7 - start_col1 - dx) * 4; 75 row_mask >>= (7 - start_col1 - dx) * 4;
@@ -155,7 +94,8 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
155 dirty_tiles[tile_y0] |= 1 << (tile_x0 + dx); 94 dirty_tiles[tile_y0] |= 1 << (tile_x0 + dx);
156 } 95 }
157 } else if (x0 == x1) { 96 } else if (x0 == x1) {
158 //The vertical line cases are analogous to the horizontal ones. 97 // Vertical line. The cases are analogous to the horizontal ones.
98 size_t dy = tile_y1 - tile_y0;
159 u32 row_mask = 0xF << start_col0 * 4; 99 u32 row_mask = 0xF << start_col0 * 4;
160 u32 row_left = (0x11111111 * clr) & row_mask; 100 u32 row_left = (0x11111111 * clr) & row_mask;
161 if (dy < 1) { 101 if (dy < 1) {
@@ -178,9 +118,40 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
178 backbuffer[0] = (backbuffer[0] & ~row_mask) | row_left; 118 backbuffer[0] = (backbuffer[0] & ~row_mask) | row_left;
179 } 119 }
180 } 120 }
121 } else {
122 // Diagonal line.
123 int x_step = x0 > x1 ? -1 : 1;
124 int y_step = y0 > y1 ? -1 : 1;
125 size_t dx = x0 > x1 ? x0 - x1 : x1 - x0;
126 size_t dy = y0 > y1 ? y0 - y1 : y1 - y0;
127 size_t x = x0;
128 size_t y = y0;
129 if (dx >= dy) {
130 // Positive slope.
131 int diff = 2 * dy - dx;
132 for (int i = 0; i <= dx; ++i) {
133 draw_pixel(x, y, clr);
134 if (diff >= 0) {
135 y += y_step;
136 diff -= 2 * dx;
137 }
138 x += x_step;
139 diff += 2 * dy;
140 }
141 } else {
142 // Negative slope.
143 int diff = 2 * dx - dy;
144 for (int i = 0; i <= dy; ++i) {
145 draw_pixel(x, y, clr);
146 if (diff >= 0) {
147 x += x_step;
148 diff -= 2 * dy;
149 }
150 y -= y_step;
151 diff += 2 * dx;
152 }
153 }
181 } 154 }
182
183 // TODO: Add slope line drawing.
184} 155}
185 156
186IWRAM_CODE 157IWRAM_CODE