diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-17 08:45:27 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-17 08:45:27 +0200 |
commit | fc83417ad04f19bfea4313cd811facf21d8dec9b (patch) | |
tree | 8cc86bb9338abc774fffe43bea24999d1a929c9b | |
parent | aa04adf0d2068fb1ef96ac64edc07a92fedf6025 (diff) | |
download | gba-link-cable-tester-fc83417ad04f19bfea4313cd811facf21d8dec9b.tar.gz gba-link-cable-tester-fc83417ad04f19bfea4313cd811facf21d8dec9b.zip |
Add improved version of simple bresenham line drawing
-rw-r--r-- | src/main.c | 1 | ||||
-rw-r--r-- | src/renderer_m0.c | 176 |
2 files changed, 39 insertions, 138 deletions
@@ -126,6 +126,7 @@ int main(void) { | |||
126 | bios_vblank_wait(); | 126 | bios_vblank_wait(); |
127 | 127 | ||
128 | PROF(test_clear(), test_clear_cycles); | 128 | PROF(test_clear(), test_clear_cycles); |
129 | // draw_line(0, 0, 50, 20, 2); | ||
129 | PROF(test_lines(), test_lines_cycles); | 130 | PROF(test_lines(), test_lines_cycles); |
130 | PROF(test_rect(), test_rect_cycles); | 131 | PROF(test_rect(), test_rect_cycles); |
131 | PROF(test_fill_rect(), test_fill_rect_cycles); | 132 | PROF(test_fill_rect(), test_fill_rect_cycles); |
diff --git a/src/renderer_m0.c b/src/renderer_m0.c index 2cb7675..d66785a 100644 --- a/src/renderer_m0.c +++ b/src/renderer_m0.c | |||
@@ -99,11 +99,11 @@ draw_hline(size_t x0, size_t x1, size_t y0, u8 clr) { | |||
99 | // 3. Lines go through 3 or more tiles, first and last tiles use | 99 | // 3. Lines go through 3 or more tiles, first and last tiles use |
100 | // partial row updates, rows in the middle can write the entire | 100 | // partial row updates, rows in the middle can write the entire |
101 | // row. | 101 | // row. |
102 | size_t dx = tile_x1 - tile_x0; | 102 | size_t dtx = tile_x1 - tile_x0; |
103 | u32 *dst = &backbuf[tile_x0 * 8 + tile_y * 8 * 32 + start_row]; | 103 | u32 *dst = &backbuf[tile_x0 * 8 + tile_y * 8 * 32 + start_row]; |
104 | if (dx < 1) { | 104 | if (dtx < 1) { |
105 | u32 mask = 0xFFFFFFFF; | 105 | u32 mask = 0xFFFFFFFF; |
106 | mask >>= (7 - end_col - dx) * 4; | 106 | mask >>= (7 - end_col - dtx) * 4; |
107 | mask &= 0xFFFFFFFF << start_col * 4; | 107 | mask &= 0xFFFFFFFF << start_col * 4; |
108 | u32 row = (0x11111111 * clr) & mask; | 108 | u32 row = (0x11111111 * clr) & mask; |
109 | *dst = (*dst & ~mask) | row; | 109 | *dst = (*dst & ~mask) | row; |
@@ -114,7 +114,7 @@ draw_hline(size_t x0, size_t x1, size_t y0, u8 clr) { | |||
114 | u32 row = 0x11111111 * clr; | 114 | u32 row = 0x11111111 * clr; |
115 | *dst = (*dst & ~(mask << shift_left)) | (row << shift_left); | 115 | *dst = (*dst & ~(mask << shift_left)) | (row << shift_left); |
116 | dst += 8; | 116 | dst += 8; |
117 | for (size_t i = 1; i < dx; i++) { | 117 | for (size_t i = 1; i < dtx; i++) { |
118 | *dst = row; | 118 | *dst = row; |
119 | dst += 8; | 119 | dst += 8; |
120 | } | 120 | } |
@@ -142,9 +142,9 @@ draw_vline(size_t x0, size_t y0, size_t y1, u8 clr) { | |||
142 | u32 *dst = &backbuf[tile_x * 8 + tile_y * 8 * 32 + start_row0]; | 142 | u32 *dst = &backbuf[tile_x * 8 + tile_y * 8 * 32 + start_row0]; |
143 | u32 mask = 0x0000000F << shift_left; | 143 | u32 mask = 0x0000000F << shift_left; |
144 | u32 row = (0x11111111 * clr) & mask; | 144 | u32 row = (0x11111111 * clr) & mask; |
145 | u32 dy = tile_y1 - tile_y0; | 145 | u32 dty = tile_y1 - tile_y0; |
146 | if (dy < 1) { | 146 | if (dty < 1) { |
147 | for (size_t i = 0; i < y1 - y0; i++, dst++) { | 147 | for (size_t i = 0; i < (y1 - y0); i++, dst++) { |
148 | dst[0] = (dst[0] & ~mask) | row; | 148 | dst[0] = (dst[0] & ~mask) | row; |
149 | } | 149 | } |
150 | } else { | 150 | } else { |
@@ -152,7 +152,7 @@ draw_vline(size_t x0, size_t y0, size_t y1, u8 clr) { | |||
152 | dst[0] = (dst[0] & ~mask) | row; | 152 | dst[0] = (dst[0] & ~mask) | row; |
153 | } | 153 | } |
154 | dst += 8 * 31; | 154 | dst += 8 * 31; |
155 | for (size_t j = 1; j < dy; j++) { | 155 | for (size_t j = 1; j < dty; j++) { |
156 | for (size_t i = 0; i < 8; i++, dst++) { | 156 | for (size_t i = 0; i < 8; i++, dst++) { |
157 | dst[0] = (dst[0] & ~mask) | row; | 157 | dst[0] = (dst[0] & ~mask) | row; |
158 | } | 158 | } |
@@ -176,7 +176,7 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
176 | MAYBE_SWAP(y0, y1); | 176 | MAYBE_SWAP(y0, y1); |
177 | draw_vline(x0, y0, y1, clr); | 177 | draw_vline(x0, y0, y1, clr); |
178 | } else { | 178 | } else { |
179 | #if 1 | 179 | #if 0 |
180 | // Diagonal line. | 180 | // Diagonal line. |
181 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; | 181 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; |
182 | int dy = y0 > y1 ? y1 - y0 : y0 - y1; | 182 | int dy = y0 > y1 ? y1 - y0 : y0 - y1; |
@@ -196,135 +196,35 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
196 | } | 196 | } |
197 | } | 197 | } |
198 | #else | 198 | #else |
199 | // int dx = x0 > x1 ? x0 - x1 : x1 - x0; | 199 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; |
200 | // int dy = y0 > y1 ? y0 - y1 : y1 - y0; | 200 | int dy = y0 > y1 ? y0 - y1 : y1 - y0; |
201 | // int x_step = x0 > x1 ? -1 : 1; | 201 | int x_step = x0 > x1 ? -1 : 1; |
202 | // int y_step = y0 > y1 ? -SCREEN_WIDTH : SCREEN_WIDTH; | 202 | int y_step = y0 > y1 ? -1 : 1; |
203 | 203 | if (dx >= dy) { | |
204 | // u16 *dst = NULL; | 204 | int diff = 2 * dy - dx; |
205 | // uintptr_t addr = ((uintptr_t)backbuf + y0 * SCREEN_WIDTH + x0); | 205 | for (int i = 0; i < dx + 1; i++) { |
206 | // u32 mask = x0 & 1 ? ~0xFF : 0xFF; | 206 | draw_pixel(x0, y0, clr); |
207 | // u32 color = (clr & 0xFF) | ((clr & 0xFF) << 8); | 207 | if (diff >= 0) { |
208 | // if (dx >= dy) { | 208 | diff -= 2 * dx; |
209 | // int diff = 2 * dy - dx; | 209 | y0 += y_step; |
210 | // for (int i = 0; i < dx + 1; i++) { | 210 | } |
211 | // dst = (u16 *)(addr - (mask >> 31)); | 211 | diff += 2 * dy; |
212 | // *dst = (*dst & ~mask) | (color & mask); | 212 | x0 += x_step; |
213 | // if (diff >= 0) { | 213 | } |
214 | // diff -= 2 * dx; | 214 | } else { |
215 | // addr += y_step; | 215 | int diff = 2 * dx - dy; |
216 | // } | 216 | for (int i = 0; i < dy + 1; i++) { |
217 | // diff += 2 * dy; | 217 | draw_pixel(x0, y0, clr); |
218 | // addr += x_step; | 218 | if (diff >= 0) { |
219 | // mask = ~mask; | 219 | diff -= 2 * dy; |
220 | // } | 220 | x0 += x_step; |
221 | // } else { | 221 | } |
222 | // int diff = 2 * dx - dy; | 222 | diff += 2 * dx; |
223 | // for (int i = 0; i < dy + 1; i++) { | 223 | y0 += y_step; |
224 | // dst = (u16 *)(addr - (mask >> 31)); | 224 | } |
225 | // *dst = (*dst & ~mask) | (color & mask); | 225 | } |
226 | // if (diff >= 0) { | ||
227 | // diff -= 2 * dy; | ||
228 | // addr += x_step; | ||
229 | // mask = ~mask; | ||
230 | // } | ||
231 | // diff += 2 * dx; | ||
232 | // addr += y_step; | ||
233 | // } | ||
234 | // } | ||
235 | #endif | 226 | #endif |
236 | } | 227 | } |
237 | |||
238 | // // Find row positions for the given x/y coordinates. | ||
239 | // size_t tile_x0 = x0 / 8; | ||
240 | // size_t tile_y0 = y0 / 8; | ||
241 | // size_t tile_x1 = x1 / 8; | ||
242 | // size_t tile_y1 = y1 / 8; | ||
243 | // size_t start_col0 = x0 % 8; | ||
244 | // size_t start_col1 = x1 % 8; | ||
245 | // size_t start_row0 = y0 % 8; | ||
246 | // size_t start_row1 = y1 % 8; | ||
247 | |||
248 | // // Get a pointer to the backbuffer and the tile row. | ||
249 | // u32 *backbuffer = &BACKBUF[start_row0 + (tile_x0 + tile_y0 * 32) * 8]; | ||
250 | |||
251 | // if (y0 == y1) { | ||
252 | // // Horizontal line. There are 3 cases: | ||
253 | // // 1. Lines fit on a single tile. | ||
254 | // // 2. Lines go through 2 tiles, both require partial row updates. | ||
255 | // // 3. Lines go through 3 or more tiles, first and last tiles use | ||
256 | // // partial row updates, rows in the middle can write the. | ||
257 | // size_t dx = tile_x1 - tile_x0; | ||
258 | // if (dx < 1) { | ||
259 | // u32 row_mask = 0xFFFFFFFF; | ||
260 | // row_mask >>= (7 - start_col1 - dx) * 4; | ||
261 | // row_mask &= 0xFFFFFFFF << start_col0 * 4; | ||
262 | // u32 row = (0x11111111 * clr) & row_mask; | ||
263 | // backbuffer[0] = (backbuffer[0] & ~row_mask) | row; | ||
264 | // dirty_tiles[tile_y0] |= 1 << tile_x0; | ||
265 | // } else { | ||
266 | // size_t shift_left = start_col0 * 4; | ||
267 | // size_t shift_right = (7 - start_col1) * 4; | ||
268 | // u32 row_mask = 0xFFFFFFFF; | ||
269 | // u32 row = 0x11111111 * clr; | ||
270 | // backbuffer[0] = backbuffer[0] & ~(row_mask << shift_left); | ||
271 | // backbuffer[0] |= row << shift_left; | ||
272 | // dirty_tiles[tile_y0] |= 1 << tile_x0; | ||
273 | // for (size_t i = 1; i < dx; i++) { | ||
274 | // backbuffer[i * 8] = row; | ||
275 | // dirty_tiles[tile_y0] |= 1 << (tile_x0 + i); | ||
276 | // } | ||
277 | // backbuffer[dx * 8] = backbuffer[dx * 8] & ~(row_mask >> shift_right); | ||
278 | // backbuffer[dx * 8] |= row >> shift_right; | ||
279 | // dirty_tiles[tile_y0] |= 1 << (tile_x0 + dx); | ||
280 | // } | ||
281 | // } else if (x0 == x1) { | ||
282 | // // Vertical line. The cases are analogous to the horizontal ones. | ||
283 | // size_t dy = tile_y1 - tile_y0; | ||
284 | // u32 row_mask = 0xF << start_col0 * 4; | ||
285 | // u32 row_left = (0x11111111 * clr) & row_mask; | ||
286 | // if (dy < 1) { | ||
287 | // for (size_t i = 0; i <= y1 - y0; i++, backbuffer++) { | ||
288 | // backbuffer[0] = (backbuffer[0] & ~row_mask) | row_left; | ||
289 | // } | ||
290 | // } else { | ||
291 | // for (size_t i = 0; i < (8 - start_row0); i++, backbuffer++) { | ||
292 | // backbuffer[0] = (backbuffer[0] & ~row_mask) | row_left; | ||
293 | // } | ||
294 | // dirty_tiles[tile_y0] |= 1 << tile_x0; | ||
295 | // backbuffer += 8 * 31; | ||
296 | // for (size_t j = 1; j < dy; j++) { | ||
297 | // for (size_t i = 0; i < 8; i++, backbuffer++) { | ||
298 | // backbuffer[0] = (backbuffer[0] & ~row_mask) | row_left; | ||
299 | // } | ||
300 | // backbuffer += 8 * 31; | ||
301 | // dirty_tiles[tile_y0 + j] |= 1 << tile_x0; | ||
302 | // } | ||
303 | // for (size_t i = 0; i <= start_row1; i++, backbuffer++) { | ||
304 | // backbuffer[0] = (backbuffer[0] & ~row_mask) | row_left; | ||
305 | // } | ||
306 | // dirty_tiles[tile_y1] |= 1 << tile_x0; | ||
307 | // } | ||
308 | // } else { | ||
309 | // // Diagonal line. | ||
310 | // int dx = x0 > x1 ? x0 - x1 : x1 - x0; | ||
311 | // int dy = y0 > y1 ? y1 - y0 : y0 - y1; | ||
312 | // int x_step = x0 < x1 ? 1 : -1; | ||
313 | // int y_step = y0 < y1 ? 1 : -1; | ||
314 | // int err = dx + dy; | ||
315 | // while (!(x0 == x1 && y0 == y1)) { | ||
316 | // draw_pixel(x0, y0, clr); | ||
317 | // int diff = 2 * err; | ||
318 | // if (diff >= dy) { | ||
319 | // err += dy; | ||
320 | // x0 += x_step; | ||
321 | // } | ||
322 | // if (diff <= dx) { | ||
323 | // err += dx; | ||
324 | // y0 += y_step; | ||
325 | // } | ||
326 | // } | ||
327 | // } | ||
328 | } | 228 | } |
329 | 229 | ||
330 | IWRAM_CODE | 230 | IWRAM_CODE |
@@ -399,7 +299,7 @@ draw_rect(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
399 | // u32 cur_row = start_row0; | 299 | // u32 cur_row = start_row0; |
400 | // dst0 = &backbuf[start_row0 + (tile_x0 + tile_y0 * 32) * 8]; | 300 | // dst0 = &backbuf[start_row0 + (tile_x0 + tile_y0 * 32) * 8]; |
401 | // dst1 = &backbuf[start_row0 + (tile_x1 + tile_y0 * 32) * 8]; | 301 | // dst1 = &backbuf[start_row0 + (tile_x1 + tile_y0 * 32) * 8]; |
402 | // for (size_t i = 0; i <= y1 - y0; i++) { | 302 | // for (size_t i = 0; i <= (y1 - y0); i++) { |
403 | // *dst0 = (*dst0 & ~mask_left) | row_left; | 303 | // *dst0 = (*dst0 & ~mask_left) | row_left; |
404 | // *dst1 = (*dst1 & ~mask_right) | row_right; | 304 | // *dst1 = (*dst1 & ~mask_right) | row_right; |
405 | // if (cur_row == 7) { | 305 | // if (cur_row == 7) { |
@@ -413,7 +313,7 @@ draw_rect(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
413 | // } | 313 | // } |
414 | // } | 314 | // } |
415 | if (dy < 1) { | 315 | if (dy < 1) { |
416 | for (size_t i = 1; i < y1 - y0; i++, dst0++) { | 316 | for (size_t i = 1; i < (y1 - y0); i++, dst0++) { |
417 | dst0[1] = (dst0[1] & ~mask_left) | row_left; | 317 | dst0[1] = (dst0[1] & ~mask_left) | row_left; |
418 | dst0[1 + 8 * dx] = (dst0[1 + 8 * dx] & ~mask_right) | row_right; | 318 | dst0[1 + 8 * dx] = (dst0[1 + 8 * dx] & ~mask_right) | row_right; |
419 | } | 319 | } |