summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-04-17 16:31:02 +0200
committerBad Diode <bd@badd10de.dev>2023-04-17 16:31:02 +0200
commit1d176dac4f3fc511693c5924affc553637b14879 (patch)
tree15d6ef0cabf1962c017e864c320070de773167a5
parent547d1c6bacb43fe14c285f8ae8d96a16e933ae3c (diff)
downloadgba-renderers-1d176dac4f3fc511693c5924affc553637b14879.tar.gz
gba-renderers-1d176dac4f3fc511693c5924affc553637b14879.zip
Clean up some bugs and add run slice bresenham for dy
-rw-r--r--src/main.c2
-rw-r--r--src/renderer_m0.c206
2 files changed, 41 insertions, 167 deletions
diff --git a/src/main.c b/src/main.c
index 2697b3c..6ea2619 100644
--- a/src/main.c
+++ b/src/main.c
@@ -163,7 +163,7 @@ int main(void) {
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 }
169 169
diff --git a/src/renderer_m0.c b/src/renderer_m0.c
index 2548fea..593dd10 100644
--- a/src/renderer_m0.c
+++ b/src/renderer_m0.c
@@ -146,7 +146,7 @@ draw_vline(size_t x0, size_t y0, size_t y1, u8 clr) {
146 u32 row = (0x11111111 * clr) & mask; 146 u32 row = (0x11111111 * clr) & mask;
147 u32 dty = tile_y1 - tile_y0; 147 u32 dty = tile_y1 - tile_y0;
148 if (dty < 1) { 148 if (dty < 1) {
149 for (size_t i = 0; i < (y1 - y0); i++, dst++) { 149 for (size_t i = 0; i <= (y1 - y0); i++, dst++) {
150 dst[0] = (dst[0] & ~mask) | row; 150 dst[0] = (dst[0] & ~mask) | row;
151 } 151 }
152 } else { 152 } else {
@@ -160,7 +160,7 @@ draw_vline(size_t x0, size_t y0, size_t y1, u8 clr) {
160 } 160 }
161 dst += 8 * 31; 161 dst += 8 * 31;
162 } 162 }
163 for (size_t i = 0; i < start_row1; i++, dst++) { 163 for (size_t i = 0; i <= start_row1; i++, dst++) {
164 dst[0] = (dst[0] & ~mask) | row; 164 dst[0] = (dst[0] & ~mask) | row;
165 } 165 }
166 } 166 }
@@ -179,12 +179,17 @@ 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 int fp_bit = 6; 182 // Fixed Precision constants.
183 int fp_one = FP_NUM(1, fp_bit); 183 const int fp_bit = 6;
184 int fp_half = fp_one >> 1; 184 const int fp_one = FP_NUM(1, fp_bit);
185 int dx = x0 > x1 ? x0 - x1 : x1 - x0; 185 const int fp_half = fp_one >> 1;
186 int dy = y0 > y1 ? y0 - y1 : y1 - y0; 186
187 if (dx >= dy && x0 > x1) { 187 int dx = x0 > x1 ? x0 - x1 : x1 - x0;
188 int dy = y0 > y1 ? y0 - y1 : y1 - y0;
189 int dxf = (dx << fp_bit);
190 int dyf = (dy << fp_bit);
191
192 if ((dx >= dy && x0 > x1) || (dx < dy && y0 > y1)) {
188 SWAP(x0, x1); 193 SWAP(x0, x1);
189 SWAP(y0, y1); 194 SWAP(y0, y1);
190 } 195 }
@@ -193,185 +198,54 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
193 int frac_y = y0 > y1 ? FP_NUM(y0 - y1, fp_bit) : FP_NUM(y1 - y0, fp_bit); 198 int frac_y = y0 > y1 ? FP_NUM(y0 - y1, fp_bit) : FP_NUM(y1 - y0, fp_bit);
194 int x_step = x0 > x1 ? -1 : 1; 199 int x_step = x0 > x1 ? -1 : 1;
195 int y_step = y0 > y1 ? -1 : 1; 200 int y_step = y0 > y1 ? -1 : 1;
196 int dxf = (dx << fp_bit);
197 int dyf = (dy << fp_bit);
198 int distance = (frac_y - fp_one) * dx - (frac_x - fp_half) * dy; 201 int distance = (frac_y - fp_one) * dx - (frac_x - fp_half) * dy;
199 if (dx >= dy) { 202 if (dx >= dy) {
200 int xp = x0; 203 int step = dx / dy;
201 int yp = y0;
202
203 //
204 // NOTE: REFERENCE
205 // for (int i = 0; i <= dx; i++) {
206 // if (distance >= 0) {
207 // distance -= 2 * dxf;
208 // yp += y_step;
209 // }
210 // draw_pixel(xp, yp, clr);
211 // distance += 2 * dyf;
212 // xp += x_step;
213 // }
214 // int step = dxf / dyf;
215 //
216 int step = dx;
217 if (dy > 0) {
218 step = dx / dy;
219 }
220 int remaining = dx; 204 int remaining = dx;
221 int big_step = step; 205 while (remaining > (step - 1)) {
222 int small_step = step - 1;
223 while (remaining > small_step) {
224 distance += step * 2 * dyf; 206 distance += step * 2 * dyf;
225 if (distance >= 0) { 207 if (distance >= 0) {
226 draw_hline(xp, xp + small_step, yp, clr); 208 draw_hline(x0, x0 + step - 1, y0, clr);
227 xp += x_step * step; 209 x0 += x_step * step;
228 remaining -= step; 210 remaining -= step;
229 } else { 211 } else {
230 if (remaining < big_step) { 212 if (remaining < step) {
231 break; 213 break;
232 } 214 }
233 draw_hline(xp, xp + big_step, yp, clr); 215 draw_hline(x0, x0 + step, y0, clr);
234 distance += 2 * dyf; 216 distance += 2 * dyf;
235 xp += x_step * (step + 1); 217 x0 += x_step * (step + 1);
236 remaining -= step + 1; 218 remaining -= step + 1;
237 } 219 }
238 distance -= 2 * dxf; 220 distance -= 2 * dxf;
239 yp += y_step; 221 y0 += y_step;
240 } 222 }
241 if (remaining >= 0) { 223 if (remaining >= 0) {
242 draw_hline(xp, xp + remaining, yp, clr); 224 draw_hline(x0, x0 + remaining, y0, clr);
243 }
244
245 // for (int i = 0; i <= remaining; i++) {
246 // if (distance >= 0) {
247 // distance -= 2 * dxf;
248 // y0 += y_step;
249 // }
250 // draw_pixel(xp, yp, clr);
251 // distance += 2 * dyf;
252 // xp += x_step;
253 // }
254
255 // txt_printf("steps: %d\n", step);
256 // if (step == 1) {
257 // // If the line is mostly diagonal, default to regular Bresenham.
258 // for (int i = 0; i <= dx; i++) {
259 // if (distance >= 0) {
260 // distance -= 2 * dxf;
261 // y0 += y_step;
262 // }
263 // draw_pixel(x0, y0, clr);
264 // distance += 2 * dyf;
265 // x0 += x_step;
266 // }
267 // } else {
268 // // Run slice Bresenham.
269 // int remaining = dx;
270 // while (remaining > (step - 1)) {
271 // distance += step * 2 * dyf;
272 // if (distance >= 0) {
273 // draw_hline(x0, x0 + step - 1, y0, clr);
274 // x0 += x_step * (step + 0);
275 // remaining -= step;
276 // } else {
277 // draw_hline(x0, x0 + step, y0, clr);
278 // distance += 2 * dyf;
279 // x0 += x_step * (step + 1);
280 // remaining -= step + 1;
281 // }
282 // distance -= 2 * dxf;
283 // y0 += y_step;
284 // }
285 // // Default to regular Bresenham for the final segment.
286 // for (int i = 0; i <= remaining; i++) {
287 // if (distance >= 0) {
288 // distance -= 2 * dxf;
289 // y0 += y_step;
290 // }
291 // draw_pixel(x0, y0, clr);
292 // distance += 2 * dyf;
293 // x0 += x_step;
294 // }
295 // }
296 } else {
297 // int step = dy / dx;
298 // int distance = (frac_x - fp_one) * dy - (frac_y - fp_half) * dx;
299 // if (step == 1) {
300 // for (int i = 0; i <= dy; i++) {
301 // draw_pixel(x0, y0, clr);
302 // if (distance >= 0) {
303 // distance -= 2 * dyf;
304 // x0 += x_step;
305 // }
306 // distance += 2 * dxf;
307 // y0 += y_step;
308 // }
309 // } else {
310 // // Run slice Bresenham.
311 // int remaining = dy;
312 // while (remaining > (step)) {
313 // distance += step * 2 * dxf;
314 // if (distance >= 0) {
315 // draw_vline(x0, y0, y0 + step, 2);
316 // y0 += y_step * (step + 0);
317 // remaining -= step;
318 // } else {
319 // draw_vline(x0, y0, y0 + step + 1, 3);
320 // distance += 2 * dxf;
321 // y0 += y_step * (step + 1);
322 // remaining -= step + 1;
323 // }
324 // distance -= 2 * dyf;
325 // x0 += x_step;
326 // }
327 // // Default to regular Bresenham for the final segment.
328 // for (int i = 0; i <= dy; i++) {
329 // draw_pixel(x0, y0, 6);
330 // if (distance >= 0) {
331 // distance -= 2 * dyf;
332 // x0 += x_step;
333 // }
334 // distance += 2 * dxf;
335 // y0 += y_step;
336 // }
337 // }
338 }
339#elif 0
340 int fp_bit = 6;
341 int fp_one = FP_NUM(1, fp_bit);
342 int fp_half = fp_one >> 1;
343 int dx = x0 > x1 ? x0 - x1 : x1 - x0;
344 int dy = y0 > y1 ? y0 - y1 : y1 - y0;
345 int frac_x = x0 > x1 ? FP_NUM(x0 - x1, fp_bit) : FP_NUM(x1 - x0, fp_bit);
346 int frac_y = y0 > y1 ? FP_NUM(y0 - y1, fp_bit) : FP_NUM(y1 - y0, fp_bit);
347 int x_step = x0 > x1 ? -1 : 1;
348 int y_step = y0 > y1 ? -1 : 1;
349 int dxf = (dx << fp_bit);
350 int dyf = (dy << fp_bit);
351 if (dx >= dy) {
352 int distance = (frac_y - fp_one) * dx - (frac_x - fp_half) * dy;
353 for (int i = 0; i <= dx; i++) {
354 if (distance >= 0) {
355 distance -= 2 * dxf;
356 y0 += y_step;
357 }
358 draw_pixel(x0, y0, clr);
359 distance += 2 * dyf;
360 x0 += x_step;
361 } 225 }
362 } else { 226 } else {
363 int distance = (frac_x - fp_one) * dy - (frac_y - fp_half) * dx; 227 int step = dy / dx;
364 for (int i = 0; i <= dy; i++) { 228 int remaining = dy;
365 draw_pixel(x0, y0, clr); 229 while (remaining > (step - 1)) {
366 if (distance >= 0) { 230 distance += step * 2 * dxf;
231 if (distance >= 0) {
232 draw_vline(x0, y0, y0 + step - 1, clr);
233 y0 += y_step * step;
234 remaining -= step;
235 } else {
236 draw_vline(x0, y0, y0 + step, clr);
237 distance += 2 * dxf;
238 y0 += y_step * (step + 1);
239 remaining -= step + 1;
240 }
367 distance -= 2 * dyf; 241 distance -= 2 * dyf;
368 x0 += x_step; 242 x0 += x_step;
369 } 243 }
370 distance += 2 * dxf; 244 if (remaining >= 0) {
371 y0 += y_step; 245 draw_vline(x0, y0, y0 + remaining, clr);
372 } 246 }
373 } 247 }
374#elif 0 248#else
375 int dx = x0 > x1 ? x0 - x1 : x1 - x0; 249 int dx = x0 > x1 ? x0 - x1 : x1 - x0;
376 int dy = y0 > y1 ? y0 - y1 : y1 - y0; 250 int dy = y0 > y1 ? y0 - y1 : y1 - y0;
377 int x_step = x0 > x1 ? -1 : 1; 251 int x_step = x0 > x1 ? -1 : 1;