diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-17 16:31:02 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-17 16:31:02 +0200 |
commit | 1d176dac4f3fc511693c5924affc553637b14879 (patch) | |
tree | 15d6ef0cabf1962c017e864c320070de773167a5 | |
parent | 547d1c6bacb43fe14c285f8ae8d96a16e933ae3c (diff) | |
download | gba-renderers-1d176dac4f3fc511693c5924affc553637b14879.tar.gz gba-renderers-1d176dac4f3fc511693c5924affc553637b14879.zip |
Clean up some bugs and add run slice bresenham for dy
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/renderer_m0.c | 206 |
2 files changed, 41 insertions, 167 deletions
@@ -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; |