summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-04-17 18:08:39 +0200
committerBad Diode <bd@badd10de.dev>2023-04-17 18:08:39 +0200
commit4b5be795ea7f177d5e343b9f75eff781667cd301 (patch)
treea27e2068facadfbe794afcb46a07ad6427f205c5
parent1d176dac4f3fc511693c5924affc553637b14879 (diff)
downloadgba-renderers-4b5be795ea7f177d5e343b9f75eff781667cd301.tar.gz
gba-renderers-4b5be795ea7f177d5e343b9f75eff781667cd301.zip
Experiment with a more performant basic bresenham
-rw-r--r--src/main.c20
-rw-r--r--src/renderer_m0.c107
2 files changed, 87 insertions, 40 deletions
diff --git a/src/main.c b/src/main.c
index 6ea2619..44e8fdb 100644
--- a/src/main.c
+++ b/src/main.c
@@ -130,17 +130,17 @@ int main(void) {
130 130
131 // DX is bigger 131 // DX is bigger
132 // left -> right && top -> bot 132 // left -> right && top -> bot
133 //draw_line(0, 0, 239, 159, 1); 133 //PROF(draw_line(0, 0, 239, 159, 1), test_lines_cycles);
134 //// draw_line(10, 0, 229, 159, 1); 134 ////// draw_line(10, 0, 229, 159, 1);
135 //// left -> right && bot -> top 135 ////// left -> right && bot -> top
136 //draw_line(0, 159, 239, 0, 2); 136 //draw_line(0, 159, 239, 0, 2);
137 //// draw_line(10, 159, 229, 0, 2); 137 ////// draw_line(10, 159, 229, 0, 2);
138 //// 138 //////
139 //draw_line(0, 0, 239, 159, 1); 139 ////draw_line(0, 0, 239, 159, 1);
140 //draw_line(0, 129, 239, 40, 2); 140 ////draw_line(0, 129, 239, 40, 2);
141 //// right -> left && top -> bot 141 ////// right -> left && top -> bot
142 //draw_line(239, 81, 0, 129, 3); 142 //draw_line(239, 81, 0, 129, 3);
143 //// right -> left && bot -> top 143 ////// right -> left && bot -> top
144 //draw_line(239, 129, 0, 40, 5); 144 //draw_line(239, 129, 0, 40, 5);
145 // txt_render(); 145 // txt_render();
146 // txt_clear(); 146 // txt_clear();
@@ -162,7 +162,7 @@ int main(void) {
162 // PROF(test_fill_rect(), test_fill_rect_cycles); 162 // PROF(test_fill_rect(), test_fill_rect_cycles);
163 // PROF(test_chr(), test_chr_cycles); 163 // PROF(test_chr(), test_chr_cycles);
164 // PROF(test_icn(), test_icn_cycles); 164 // PROF(test_icn(), test_icn_cycles);
165 // draw_filled_rect(0, 0, 140, 60, 0); 165 draw_filled_rect(0, 0, 140, 60, 0);
166 PROF_SHOW(); 166 PROF_SHOW();
167 PROF(flip_buffer(), flip_cycles); 167 PROF(flip_buffer(), flip_cycles);
168 } 168 }
diff --git a/src/renderer_m0.c b/src/renderer_m0.c
index 593dd10..ce9cfc8 100644
--- a/src/renderer_m0.c
+++ b/src/renderer_m0.c
@@ -179,6 +179,81 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
179 draw_vline(x0, y0, y1, clr); 179 draw_vline(x0, y0, y1, clr);
180 } else { 180 } else {
181#if 1 181#if 1
182
183 // Fixed Precision constants.
184 const int fp_bit = 6;
185 const int fp_one = FP_NUM(1, fp_bit);
186 const int fp_half = fp_one >> 1;
187
188 int dx = x0 > x1 ? x0 - x1 : x1 - x0;
189 int dy = y0 > y1 ? y0 - y1 : y1 - y0;
190 int dxf = (dx << fp_bit);
191 int dyf = (dy << fp_bit);
192
193 if ((dx >= dy && x0 > x1) || (dx < dy && y0 > y1)) {
194 SWAP(x0, x1);
195 SWAP(y0, y1);
196 }
197
198 int frac_x = x0 > x1 ? FP_NUM(x0 - x1, fp_bit) : FP_NUM(x1 - x0, fp_bit);
199 int frac_y = y0 > y1 ? FP_NUM(y0 - y1, fp_bit) : FP_NUM(y1 - y0, fp_bit);
200 int x_step = x0 > x1 ? -1 : 1;
201 int y_step = y0 > y1 ? -1 : 1;
202 int distance = (frac_y - fp_one) * dx - (frac_x - fp_half) * dy;
203
204 //
205 // DEBUG: reference
206 // for (int i = 0; i <= dx; i++) {
207 // if (distance >= 0) {
208 // distance -= 2 * dxf;
209 // y0 += y_step;
210 // }
211 // draw_pixel(x0, y0, clr);
212 // distance += 2 * dyf;
213 // x0 += x_step;
214 // }
215 //
216
217 size_t tile_x = x0 / 8;
218 size_t tile_y = y0 / 8;
219 size_t start_col = x0 % 8;
220 size_t start_row = y0 % 8;
221 u32 *dst = &backbuf[start_row + (tile_x + tile_y * 32) * 8];
222
223 // Update backbuffer.
224 if (dx >= dy) {
225 for (int i = 0; i <= dx; i++) {
226 start_col = x0 % 8;
227 start_row = y0 % 8;
228 size_t shift = start_col * sizeof(u32);
229 u32 mask = 0xF << shift;
230 u32 row = clr << shift;
231 if (distance >= 0) {
232 distance -= 2 * dxf;
233 y0 += y_step;
234 if (((int)start_row + y_step) >= 8 || ((int)start_row + y_step) < 0) {
235 dst += 8 * 31 * y_step;
236 }
237 dst += y_step;
238 }
239 *dst = (*dst & ~mask) | row;
240 distance += 2 * dyf;
241 if ((int)(start_col + x_step) >= 8 ||(int)(start_col + x_step) < 0) {
242 dst += 8;
243 }
244 x0 += x_step;
245 }
246 // for (int i = 0; i <= dx; i++) {
247 // if (distance >= 0) {
248 // distance -= 2 * dxf;
249 // y0 += y_step;
250 // }
251 // draw_pixel(x0, y0, clr);
252 // distance += 2 * dyf;
253 // x0 += x_step;
254 // }
255 }
256#else
182 // Fixed Precision constants. 257 // Fixed Precision constants.
183 const int fp_bit = 6; 258 const int fp_bit = 6;
184 const int fp_one = FP_NUM(1, fp_bit); 259 const int fp_one = FP_NUM(1, fp_bit);
@@ -200,7 +275,7 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
200 int y_step = y0 > y1 ? -1 : 1; 275 int y_step = y0 > y1 ? -1 : 1;
201 int distance = (frac_y - fp_one) * dx - (frac_x - fp_half) * dy; 276 int distance = (frac_y - fp_one) * dx - (frac_x - fp_half) * dy;
202 if (dx >= dy) { 277 if (dx >= dy) {
203 int step = dx / dy; 278 int step = dxf / dyf;
204 int remaining = dx; 279 int remaining = dx;
205 while (remaining > (step - 1)) { 280 while (remaining > (step - 1)) {
206 distance += step * 2 * dyf; 281 distance += step * 2 * dyf;
@@ -224,7 +299,7 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
224 draw_hline(x0, x0 + remaining, y0, clr); 299 draw_hline(x0, x0 + remaining, y0, clr);
225 } 300 }
226 } else { 301 } else {
227 int step = dy / dx; 302 int step = dyf / dxf;
228 int remaining = dy; 303 int remaining = dy;
229 while (remaining > (step - 1)) { 304 while (remaining > (step - 1)) {
230 distance += step * 2 * dxf; 305 distance += step * 2 * dxf;
@@ -245,34 +320,6 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
245 draw_vline(x0, y0, y0 + remaining, clr); 320 draw_vline(x0, y0, y0 + remaining, clr);
246 } 321 }
247 } 322 }
248#else
249 int dx = x0 > x1 ? x0 - x1 : x1 - x0;
250 int dy = y0 > y1 ? y0 - y1 : y1 - y0;
251 int x_step = x0 > x1 ? -1 : 1;
252 int y_step = y0 > y1 ? -1 : 1;
253 if (dx >= dy) {
254 int diff = 2 * dy - dx;
255 for (int i = 0; i < dx + 1; i++) {
256 draw_pixel(x0, y0, clr);
257 if (diff >= 0) {
258 diff -= 2 * dx;
259 y0 += y_step;
260 }
261 diff += 2 * dy;
262 x0 += x_step;
263 }
264 } else {
265 int diff = 2 * dx - dy;
266 for (int i = 0; i < dy + 1; i++) {
267 draw_pixel(x0, y0, clr);
268 if (diff >= 0) {
269 diff -= 2 * dy;
270 x0 += x_step;
271 }
272 diff += 2 * dx;
273 y0 += y_step;
274 }
275 }
276#endif 323#endif
277 } 324 }
278} 325}