diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-15 00:26:17 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-15 18:29:26 +0200 |
commit | a6859fa5c780878a92fbfcd1f12a815fcb1961d6 (patch) | |
tree | 09c43083036148d52bde8d120b0798b4fd84530c | |
parent | dd009eb124cf929bee0233b7323b448319e25665 (diff) | |
download | gba-renderers-a6859fa5c780878a92fbfcd1f12a815fcb1961d6.tar.gz gba-renderers-a6859fa5c780878a92fbfcd1f12a815fcb1961d6.zip |
Speed up line drawing algorithm
-rw-r--r-- | src/main.c | 13 | ||||
-rw-r--r-- | src/renderer_m4.c | 45 |
2 files changed, 58 insertions, 0 deletions
@@ -128,6 +128,19 @@ int main(void) { | |||
128 | bios_vblank_wait(); | 128 | bios_vblank_wait(); |
129 | 129 | ||
130 | PROF(test_clear(), test_clear_cycles); | 130 | PROF(test_clear(), test_clear_cycles); |
131 | // draw_line(0, 0, 100, 50, 1); | ||
132 | // // draw_line(0, 0, 100, 100, 2); | ||
133 | // // draw_line(0, 0, 50, 100, 3); | ||
134 | // // draw_line(5, 0, 0, 5, 2); | ||
135 | // draw_line(100, 0, 0, 50, 1); | ||
136 | // // draw_line(100, 0, 0, 100, 2); | ||
137 | // // draw_line(50, 0, 0, 100, 3); | ||
138 | // txt_render(); | ||
139 | // txt_clear(); | ||
140 | // txt_printf("dx: %d\n", dx); | ||
141 | // txt_printf("dy: %d\n", dy); | ||
142 | // txt_render(); | ||
143 | // txt_clear(); | ||
131 | PROF(test_lines(), test_lines_cycles); | 144 | PROF(test_lines(), test_lines_cycles); |
132 | PROF(test_rect(), test_rect_cycles); | 145 | PROF(test_rect(), test_rect_cycles); |
133 | PROF(test_fill_rect(), test_fill_rect_cycles); | 146 | PROF(test_fill_rect(), test_fill_rect_cycles); |
diff --git a/src/renderer_m4.c b/src/renderer_m4.c index cbf3c3f..c950763 100644 --- a/src/renderer_m4.c +++ b/src/renderer_m4.c | |||
@@ -131,6 +131,8 @@ draw_vline(size_t x0, size_t y0, size_t y1, u8 clr) { | |||
131 | } | 131 | } |
132 | } | 132 | } |
133 | 133 | ||
134 | #define SWAP(A,B) do {size_t tmp = (A); (A) = (B); (B) = (tmp);} while(0) | ||
135 | |||
134 | IWRAM_CODE | 136 | IWRAM_CODE |
135 | void | 137 | void |
136 | draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | 138 | draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { |
@@ -144,7 +146,49 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
144 | MAYBE_SWAP(y0, y1); | 146 | MAYBE_SWAP(y0, y1); |
145 | draw_vline(x0, y0, y1, clr); | 147 | draw_vline(x0, y0, y1, clr); |
146 | } else { | 148 | } else { |
149 | #if 1 | ||
147 | // Diagonal line. | 150 | // Diagonal line. |
151 | if (x0 > x1) { | ||
152 | SWAP(x0, x1); | ||
153 | SWAP(y0, y1); | ||
154 | } | ||
155 | int dx = x1 - x0; | ||
156 | int dy = y0 > y1 ? y0 - y1 : y1 - y0; | ||
157 | int x_step = 1; | ||
158 | int y_step = y0 > y1 ? -1 : 1; | ||
159 | y_step *= SCREEN_WIDTH / 2; | ||
160 | |||
161 | // Mini-LUT for M4 byte decoding. | ||
162 | u16 mask[] = { ~0xFF, 0xFF }; | ||
163 | u16 color[] = { clr, (clr << 8) }; | ||
164 | u8 advance[] = { 0, x_step }; | ||
165 | u16 *dst = &backbuf[(x0 + y0 * SCREEN_WIDTH) / 2]; | ||
166 | if (dx >= dy) { | ||
167 | int diff = 2 * dy - dx; | ||
168 | for (int i = dx; i >= 0; i--) { | ||
169 | *dst = (*dst & mask[x0 & 1]) | color[x0 & 1]; | ||
170 | if (diff >= 0) { | ||
171 | diff -= 2 * dx; | ||
172 | dst = dst + y_step; | ||
173 | } | ||
174 | diff += 2 * dy; | ||
175 | dst = dst + advance[x0 & 1]; | ||
176 | x0 += x_step; | ||
177 | } | ||
178 | } else { | ||
179 | int diff = 2 * dx - dy; | ||
180 | for (int i = dy; i >= 0; i--) { | ||
181 | *dst = (*dst & mask[x0 & 1]) | color[x0 & 1]; | ||
182 | if (diff >= 0) { | ||
183 | diff -= 2 * dy; | ||
184 | dst = dst + advance[x0 & 1]; | ||
185 | x0 += x_step; | ||
186 | } | ||
187 | diff += 2 * dx; | ||
188 | dst = dst + y_step; | ||
189 | } | ||
190 | } | ||
191 | #else | ||
148 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; | 192 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; |
149 | int dy = y0 > y1 ? y1 - y0 : y0 - y1; | 193 | int dy = y0 > y1 ? y1 - y0 : y0 - y1; |
150 | int x_step = x0 < x1 ? 1 : -1; | 194 | int x_step = x0 < x1 ? 1 : -1; |
@@ -162,6 +206,7 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
162 | y0 += y_step; | 206 | y0 += y_step; |
163 | } | 207 | } |
164 | } | 208 | } |
209 | #endif | ||
165 | } | 210 | } |
166 | screen_updated = true; | 211 | screen_updated = true; |
167 | } | 212 | } |