diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-17 13:20:52 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-17 13:20:52 +0200 |
commit | cb73b66dc43672f18c0fcf75ab1e20691673ba05 (patch) | |
tree | 49a9ba882315b91bb284bfc3218b4fbba09cd473 | |
parent | 2c8000b2bd04d31e9de356ca60bafdf648dd420b (diff) | |
download | gba-renderers-cb73b66dc43672f18c0fcf75ab1e20691673ba05.tar.gz gba-renderers-cb73b66dc43672f18c0fcf75ab1e20691673ba05.zip |
Add initial run slice bresengham implementation
-rw-r--r-- | src/main.c | 12 | ||||
-rw-r--r-- | src/renderer_m0.c | 70 |
2 files changed, 76 insertions, 6 deletions
@@ -126,15 +126,17 @@ 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, 100, 31, 2); | 129 | // draw_line(0, 0, 100, 50, 2); |
130 | // draw_line(0, 0, 100, 21, 5); | ||
131 | // draw_line(0, 0, 15, 7, 2); | ||
130 | // draw_line(0, 31, 100, 0, 5); | 132 | // draw_line(0, 31, 100, 0, 5); |
131 | // txt_render(); | 133 | // txt_render(); |
132 | // txt_clear(); | 134 | // txt_clear(); |
133 | PROF(test_lines(), test_lines_cycles); | 135 | PROF(test_lines(), test_lines_cycles); |
134 | // PROF(test_rect(), test_rect_cycles); | 136 | PROF(test_rect(), test_rect_cycles); |
135 | // PROF(test_fill_rect(), test_fill_rect_cycles); | 137 | PROF(test_fill_rect(), test_fill_rect_cycles); |
136 | // PROF(test_chr(), test_chr_cycles); | 138 | PROF(test_chr(), test_chr_cycles); |
137 | // PROF(test_icn(), test_icn_cycles); | 139 | PROF(test_icn(), test_icn_cycles); |
138 | draw_filled_rect(0, 0, 140, 60, 0); | 140 | draw_filled_rect(0, 0, 140, 60, 0); |
139 | PROF_SHOW(); | 141 | PROF_SHOW(); |
140 | PROF(flip_buffer(), flip_cycles); | 142 | PROF(flip_buffer(), flip_cycles); |
diff --git a/src/renderer_m0.c b/src/renderer_m0.c index 904c2a1..02f1e31 100644 --- a/src/renderer_m0.c +++ b/src/renderer_m0.c | |||
@@ -179,6 +179,74 @@ 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 | // NOTE: WIP run slice bresenham | ||
183 | int fp_bit = 6; | ||
184 | int fp_one = FP_NUM(1, fp_bit); | ||
185 | int fp_half = fp_one >> 1; | ||
186 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; | ||
187 | int dy = y0 > y1 ? y0 - y1 : y1 - y0; | ||
188 | int frac_x = x0 > x1 ? FP_NUM(x0 - x1, fp_bit) : FP_NUM(x1 - x0, fp_bit); | ||
189 | int frac_y = y0 > y1 ? FP_NUM(y0 - y1, fp_bit) : FP_NUM(y1 - y0, fp_bit); | ||
190 | int x_step = x0 > x1 ? -1 : 1; | ||
191 | int y_step = y0 > y1 ? -1 : 1; | ||
192 | int dxf = (dx << fp_bit); | ||
193 | int dyf = (dy << fp_bit); | ||
194 | if (dx >= dy) { | ||
195 | int step = dx / dy; | ||
196 | if (step == 1) { | ||
197 | // If the line is mostly diagonal, default to regular bresengham. | ||
198 | int distance = (frac_y - fp_one) * dx - (frac_x - fp_half) * dy; | ||
199 | for (int i = 0; i <= dx; i++) { | ||
200 | if (distance >= 0) { | ||
201 | distance -= 2 * dxf; | ||
202 | y0 += y_step; | ||
203 | } | ||
204 | draw_pixel(x0, y0, clr); | ||
205 | distance += 2 * dyf; | ||
206 | x0 += x_step; | ||
207 | } | ||
208 | } else { | ||
209 | int distance = (frac_y - fp_one) * dx - (frac_x - fp_half) * dy; | ||
210 | int remaining = dx; | ||
211 | while (remaining > (step - 1)) { | ||
212 | distance += step * 2 * dyf; | ||
213 | if (distance >= 0) { | ||
214 | draw_hline(x0, x0 + step - 1, y0, clr); | ||
215 | x0 += x_step * (step + 0); | ||
216 | remaining -= step; | ||
217 | } else { | ||
218 | draw_hline(x0, x0 + step, y0, clr); | ||
219 | distance += 2 * dyf; | ||
220 | x0 += x_step * (step + 1); | ||
221 | remaining -= step + 1; | ||
222 | } | ||
223 | distance -= 2 * dxf; | ||
224 | y0 += y_step; | ||
225 | } | ||
226 | // Default to regular bresengham for the final segment. | ||
227 | for (int i = 0; i <= remaining; i++) { | ||
228 | if (distance >= 0) { | ||
229 | distance -= 2 * dxf; | ||
230 | y0 += y_step; | ||
231 | } | ||
232 | draw_pixel(x0, y0, clr); | ||
233 | distance += 2 * dyf; | ||
234 | x0 += x_step; | ||
235 | } | ||
236 | } | ||
237 | } else { | ||
238 | int distance = (frac_x - fp_one) * dy - (frac_y - fp_half) * dx; | ||
239 | for (int i = 0; i <= dy; i++) { | ||
240 | draw_pixel(x0, y0, clr); | ||
241 | if (distance >= 0) { | ||
242 | distance -= 2 * dyf; | ||
243 | x0 += x_step; | ||
244 | } | ||
245 | distance += 2 * dxf; | ||
246 | y0 += y_step; | ||
247 | } | ||
248 | } | ||
249 | #elif 0 | ||
182 | int fp_bit = 6; | 250 | int fp_bit = 6; |
183 | int fp_one = FP_NUM(1, fp_bit); | 251 | int fp_one = FP_NUM(1, fp_bit); |
184 | int fp_half = fp_one >> 1; | 252 | int fp_half = fp_one >> 1; |
@@ -213,7 +281,7 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
213 | y0 += y_step; | 281 | y0 += y_step; |
214 | } | 282 | } |
215 | } | 283 | } |
216 | #else | 284 | #elif 0 |
217 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; | 285 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; |
218 | int dy = y0 > y1 ? y0 - y1 : y1 - y0; | 286 | int dy = y0 > y1 ? y0 - y1 : y1 - y0; |
219 | int x_step = x0 > x1 ? -1 : 1; | 287 | int x_step = x0 > x1 ? -1 : 1; |