diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-17 12:02:35 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-17 12:02:35 +0200 |
commit | 579f18c54565728c6efb50edee40ca27f86d2fcc (patch) | |
tree | 63afac7181eceecab15df2c0c6130fc123f906da | |
parent | 70d6b8a2cbe4c7343297f466132ac2d7ce1a652d (diff) | |
download | gba-link-cable-tester-579f18c54565728c6efb50edee40ca27f86d2fcc.tar.gz gba-link-cable-tester-579f18c54565728c6efb50edee40ca27f86d2fcc.zip |
Implement subpixel precision for line drawing
-rw-r--r-- | src/main.c | 13 | ||||
-rw-r--r-- | src/renderer_m0.c | 39 |
2 files changed, 25 insertions, 27 deletions
@@ -126,12 +126,15 @@ 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, 50, 20, 2); | 129 | // draw_line(0, 0, 100, 31, 2); |
130 | // draw_line(0, 31, 100, 0, 5); | ||
131 | // txt_render(); | ||
132 | // txt_clear(); | ||
130 | PROF(test_lines(), test_lines_cycles); | 133 | PROF(test_lines(), test_lines_cycles); |
131 | PROF(test_rect(), test_rect_cycles); | 134 | // PROF(test_rect(), test_rect_cycles); |
132 | PROF(test_fill_rect(), test_fill_rect_cycles); | 135 | // PROF(test_fill_rect(), test_fill_rect_cycles); |
133 | PROF(test_chr(), test_chr_cycles); | 136 | // PROF(test_chr(), test_chr_cycles); |
134 | PROF(test_icn(), test_icn_cycles); | 137 | // PROF(test_icn(), test_icn_cycles); |
135 | draw_filled_rect(0, 0, 140, 60, 0); | 138 | draw_filled_rect(0, 0, 140, 60, 0); |
136 | PROF_SHOW(); | 139 | PROF_SHOW(); |
137 | PROF(flip_buffer(), flip_cycles); | 140 | PROF(flip_buffer(), flip_cycles); |
diff --git a/src/renderer_m0.c b/src/renderer_m0.c index 94a3d9d..36ed01b 100644 --- a/src/renderer_m0.c +++ b/src/renderer_m0.c | |||
@@ -179,42 +179,37 @@ 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 precision_bits = 6; | ||
183 | int precision_one = (1 << precision_bits); | ||
184 | int precision_half = precision_one >> 1; | ||
182 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; | 185 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; |
183 | int dy = y0 > y1 ? y0 - y1 : y1 - y0; | 186 | int dy = y0 > y1 ? y0 - y1 : y1 - y0; |
187 | int frac_x = x0 > x1 ? ((x0 - x1) << precision_bits) : ((x1 - x0) << precision_bits); | ||
188 | int frac_y = y0 > y1 ? ((y0 - y1) << precision_bits) : ((y1 - y0) << precision_bits); | ||
184 | int x_step = x0 > x1 ? -1 : 1; | 189 | int x_step = x0 > x1 ? -1 : 1; |
185 | int y_step = y0 > y1 ? -1 : 1; | 190 | int y_step = y0 > y1 ? -1 : 1; |
191 | int dxf = (dx << precision_bits); | ||
192 | int dyf = (dy << precision_bits); | ||
186 | if (dx >= dy) { | 193 | if (dx >= dy) { |
187 | // int diff = 2 * dy - dx; | 194 | int distance = (frac_y - precision_one) * dx - (frac_x - precision_half) * dy; |
188 | // int distance = dx * dy - (y1 - y0) * dx; | 195 | for (int i = 0; i <= dx; i++) { |
189 | int distance = (dy - dx) / 2; | 196 | if (distance >= 0) { |
190 | for (int i = 0; i < dx + 1; i++) { | 197 | distance -= 2 * dxf; |
191 | // Previous implementation (Tom Forsyth). | ||
192 | if (distance > dx / 2) { | ||
193 | distance -= dx; | ||
194 | y0 += y_step; | 198 | y0 += y_step; |
195 | } | 199 | } |
196 | draw_pixel(x0, y0, clr); | 200 | draw_pixel(x0, y0, clr); |
197 | distance += dy; | 201 | distance += 2 * dyf; |
198 | x0 += x_step; | 202 | x0 += x_step; |
199 | |||
200 | // Previous implementation, slightly faster. | ||
201 | // draw_pixel(x0, y0, clr); | ||
202 | // if (diff >= 0) { | ||
203 | // diff -= 2 * dx; | ||
204 | // y0 += y_step; | ||
205 | // } | ||
206 | // diff += 2 * dy; | ||
207 | // x0 += x_step; | ||
208 | } | 203 | } |
209 | } else { | 204 | } else { |
210 | int diff = 2 * dx - dy; | 205 | int distance = (frac_x - precision_one) * dy - (frac_y - precision_half) * dx; |
211 | for (int i = 0; i < dy + 1; i++) { | 206 | for (int i = 0; i <= dy; i++) { |
212 | draw_pixel(x0, y0, clr); | 207 | draw_pixel(x0, y0, clr); |
213 | if (diff >= 0) { | 208 | if (distance >= 0) { |
214 | diff -= 2 * dy; | 209 | distance -= 2 * dyf; |
215 | x0 += x_step; | 210 | x0 += x_step; |
216 | } | 211 | } |
217 | diff += 2 * dx; | 212 | distance += 2 * dxf; |
218 | y0 += y_step; | 213 | y0 += y_step; |
219 | } | 214 | } |
220 | } | 215 | } |