summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-04-17 22:16:18 +0200
committerBad Diode <bd@badd10de.dev>2023-04-17 22:16:18 +0200
commit45b083b8b0aca089df7dde2b194f942ae50d8e21 (patch)
treebcd5f7e3010887fc0a818a52cee52e43328fa988
parent4b5be795ea7f177d5e343b9f75eff781667cd301 (diff)
downloadgba-renderers-45b083b8b0aca089df7dde2b194f942ae50d8e21.tar.gz
gba-renderers-45b083b8b0aca089df7dde2b194f942ae50d8e21.zip
Add example run-slice bresenham using a buf pointer
This is thus far slower than the previous run-slice approach, but not by much. There could still be some savings by reducing the number of ops but doubt it's worth it at this point.
-rw-r--r--src/main.c7
-rw-r--r--src/renderer_m0.c143
2 files changed, 131 insertions, 19 deletions
diff --git a/src/main.c b/src/main.c
index 44e8fdb..29e420d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -130,7 +130,8 @@ int main(void) {
130 130
131 // DX is bigger 131 // DX is bigger
132 // left -> right && top -> bot 132 // left -> right && top -> bot
133 //PROF(draw_line(0, 0, 239, 159, 1), test_lines_cycles); 133 // PROF(draw_line(0, 0, 64, 32, 1), test_lines_cycles);
134 // PROF(draw_line(0, 0, 239, 159, 1), test_lines_cycles);
134 ////// draw_line(10, 0, 229, 159, 1); 135 ////// draw_line(10, 0, 229, 159, 1);
135 ////// left -> right && bot -> top 136 ////// left -> right && bot -> top
136 //draw_line(0, 159, 239, 0, 2); 137 //draw_line(0, 159, 239, 0, 2);
@@ -142,8 +143,8 @@ int main(void) {
142 //draw_line(239, 81, 0, 129, 3); 143 //draw_line(239, 81, 0, 129, 3);
143 ////// right -> left && bot -> top 144 ////// right -> left && bot -> top
144 //draw_line(239, 129, 0, 40, 5); 145 //draw_line(239, 129, 0, 40, 5);
145 // txt_render(); 146 txt_render();
146 // txt_clear(); 147 txt_clear();
147 148
148 // draw_line(239, 149, 0, 10, 3); 149 // draw_line(239, 149, 0, 10, 3);
149 150
diff --git a/src/renderer_m0.c b/src/renderer_m0.c
index ce9cfc8..ece7dbb 100644
--- a/src/renderer_m0.c
+++ b/src/renderer_m0.c
@@ -222,27 +222,117 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
222 222
223 // Update backbuffer. 223 // Update backbuffer.
224 if (dx >= dy) { 224 if (dx >= dy) {
225 for (int i = 0; i <= dx; i++) { 225 int step = dxf / dyf;
226 start_col = x0 % 8; 226 int remaining = dx;
227 start_row = y0 % 8; 227
228 size_t shift = start_col * sizeof(u32); 228 //
229 u32 mask = 0xF << shift; 229 // NOTE: Reference with pointers.
230 u32 row = clr << shift; 230 // for (int i = 0; i <= dx; i++) {
231 // start_col = x0 % 8;
232 // start_row = y0 % 8;
233 // size_t shift = start_col * sizeof(u32);
234 // u32 mask = 0xF << shift;
235 // u32 row = clr << shift;
236 // if (distance >= 0) {
237 // distance -= 2 * dxf;
238 // y0 += y_step;
239 // if (((int)start_row + y_step) >= 8 || ((int)start_row + y_step) < 0) {
240 // dst += 8 * 31 * y_step;
241 // }
242 // dst += y_step;
243 // }
244 // *dst = (*dst & ~mask) | row;
245 // distance += 2 * dyf;
246 // if ((int)(start_col + x_step) >= 8 ||(int)(start_col + x_step) < 0) {
247 // dst += 8;
248 // }
249 // x0 += x_step;
250 // }
251 //
252
253 while (remaining > (step - 1)) {
254 distance += step * 2 * dyf;
255 size_t start_row = y0 % 8;
256 u32 a = x0;
257 size_t start_col = a % 8;
258 size_t tile_x0 = a / 8;
259 size_t shift_left = start_col * 4;
231 if (distance >= 0) { 260 if (distance >= 0) {
232 distance -= 2 * dxf; 261 u32 b = x0 + step - 1;
233 y0 += y_step; 262 size_t tile_x1 = b / 8;
234 if (((int)start_row + y_step) >= 8 || ((int)start_row + y_step) < 0) { 263 size_t end_col = b % 8;
235 dst += 8 * 31 * y_step; 264 size_t shift_right = (7 - end_col) * 4;
265 size_t dtx = tile_x1 - tile_x0;
266 if (dtx < 1) {
267 u32 mask = (0xFFFFFFFF >> shift_right) & (0xFFFFFFFF << shift_left);
268 u32 row = (0x11111111 * clr) & mask;
269 *dst = (*dst & ~mask) | row;
270 if ((start_col + x_step) >= 8 || end_col == 7) {
271 dst += 8 * x_step;
272 }
273 } else {
274 u32 mask = 0xFFFFFFFF;
275 u32 row = 0x11111111 * clr;
276 *dst = (*dst & ~(mask << shift_left)) | (row << shift_left);
277 dst += 8 * x_step;
278 for (size_t i = 1; i < dtx; i++) {
279 *dst = row;
280 dst += 8 * x_step;
281 }
282 *dst = (*dst & ~(mask >> shift_right)) | (row >> shift_right);
283 if (end_col == 7) {
284 dst += 8 * x_step;
285 }
286 }
287 // draw_hline(a, b, y0, clr);
288 x0 += step;
289 remaining -= step;
290 } else {
291 if (remaining < step) {
292 break;
236 } 293 }
237 dst += y_step; 294 u32 b = x0 + step;
295 size_t tile_x1 = b / 8;
296 size_t end_col = b % 8;
297 size_t dtx = tile_x1 - tile_x0;
298 size_t shift_right = (7 - end_col) * 4;
299 if (dtx < 1) {
300 u32 mask = (0xFFFFFFFF >> shift_right) & (0xFFFFFFFF << shift_left);
301 u32 row = (0x11111111 * clr) & mask;
302 *dst = (*dst & ~mask) | row;
303 if ((start_col + x_step) >= 8 || end_col == 7) {
304 dst += 8 * x_step;
305 }
306 } else {
307 u32 mask = 0xFFFFFFFF;
308 u32 row = 0x11111111 * clr;
309 *dst = (*dst & ~(mask << shift_left)) | (row << shift_left);
310 dst += 8 * x_step;
311 for (size_t i = 1; i < dtx; i++) {
312 *dst = row;
313 dst += 8 * x_step;
314 }
315 *dst = (*dst & ~(mask >> shift_right)) | (row >> shift_right);
316 if (end_col == 7) {
317 dst += 8 * x_step;
318 }
319 }
320 // draw_hline(a, b, y0, clr);
321 distance += 2 * dyf;
322 x0 += (step + 1);
323 remaining -= step + 1;
238 } 324 }
239 *dst = (*dst & ~mask) | row; 325 if (((int)start_row + y_step) >= 8 || ((int)start_row + y_step) < 0) {
240 distance += 2 * dyf; 326 dst += 8 * 31 * y_step;
241 if ((int)(start_col + x_step) >= 8 ||(int)(start_col + x_step) < 0) {
242 dst += 8;
243 } 327 }
244 x0 += x_step; 328 dst += y_step;
329 distance -= 2 * dxf;
330 y0 += y_step;
245 } 331 }
332 if (remaining >= 0) {
333 draw_hline(x0, x0 + remaining, y0, clr);
334 }
335
246 // for (int i = 0; i <= dx; i++) { 336 // for (int i = 0; i <= dx; i++) {
247 // if (distance >= 0) { 337 // if (distance >= 0) {
248 // distance -= 2 * dxf; 338 // distance -= 2 * dxf;
@@ -252,6 +342,27 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
252 // distance += 2 * dyf; 342 // distance += 2 * dyf;
253 // x0 += x_step; 343 // x0 += x_step;
254 // } 344 // }
345 } else {
346 // int step = dyf / dxf;
347 // int remaining = dy;
348 // while (remaining > (step - 1)) {
349 // distance += step * 2 * dxf;
350 // if (distance >= 0) {
351 // draw_vline(x0, y0, y0 + step - 1, clr);
352 // y0 += y_step * step;
353 // remaining -= step;
354 // } else {
355 // draw_vline(x0, y0, y0 + step, clr);
356 // distance += 2 * dxf;
357 // y0 += y_step * (step + 1);
358 // remaining -= step + 1;
359 // }
360 // distance -= 2 * dyf;
361 // x0 += x_step;
362 // }
363 // if (remaining >= 0) {
364 // draw_vline(x0, y0, y0 + remaining, clr);
365 // }
255 } 366 }
256#else 367#else
257 // Fixed Precision constants. 368 // Fixed Precision constants.