summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-04-18 14:08:22 +0200
committerBad Diode <bd@badd10de.dev>2023-04-18 14:08:22 +0200
commit04af30b7fcb1abc2702f6b01ccf7f9d9ead86af1 (patch)
tree124c16370bef74a229eabb6d5b3d947f9ac62779
parent838c38045bef10fa893b6790fe42a5a649ccaeca (diff)
downloadgba-renderers-04af30b7fcb1abc2702f6b01ccf7f9d9ead86af1.tar.gz
gba-renderers-04af30b7fcb1abc2702f6b01ccf7f9d9ead86af1.zip
Add line movement test
-rw-r--r--src/main.c54
-rw-r--r--src/renderer_m0.c32
-rw-r--r--src/renderer_m4.c87
3 files changed, 151 insertions, 22 deletions
diff --git a/src/main.c b/src/main.c
index fa4457a..88ca24e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -122,11 +122,51 @@ int main(void) {
122 122
123 // Main loop. 123 // Main loop.
124 PROF_INIT(); 124 PROF_INIT();
125 int x = 0;
126 int y = 0;
127 int inc_x = 1;
128 int inc_y = 0;
125 while (true) { 129 while (true) {
126 bios_vblank_wait(); 130 bios_vblank_wait();
127 131
128 PROF(test_clear(), test_clear_cycles); 132 PROF(test_clear(), test_clear_cycles);
133 draw_line(x, y, 239 - x, 159 - y, 2);
134 x += inc_x;
135 y += inc_y;
136 if (x == 239 && inc_x == 1) {
137 inc_x = 0;
138 inc_y = 1;
139 }
140 if (y == 159 && inc_y == 1) {
141 x = 0;
142 y = 0;
143 inc_x = 1;
144 inc_y = 0;
145 }
146
147 // draw_line(x, 229 - x, y, 129 - y, 2);
129 // screen_fill(0); 148 // screen_fill(0);
149 // draw_pixel(0, 100 + 0, 5);
150 // draw_pixel(1, 100 + 0, 6);
151 // draw_pixel(2, 100 + 0, 5);
152 // draw_pixel(3, 100 + 0, 6);
153 // draw_pixel(4, 100 + 0, 5);
154 // draw_pixel(5, 100 + 0, 6);
155 // draw_pixel(6, 100 + 0, 5);
156 // draw_pixel(7, 100 + 0, 6);
157 // draw_pixel(8, 100 + 0, 5);
158 // draw_pixel(9, 100 + 0, 6);
159 // draw_pixel(10, 100 + 0, 5);
160 // draw_pixel(11, 100 + 0, 6);
161 // draw_pixel(12, 100 + 0, 5);
162 // draw_pixel(13, 100 + 0, 6);
163 // draw_pixel(14, 100 + 0, 5);
164 // draw_pixel(15, 100 + 0, 6);
165
166 // draw_hline(0, 10 + 4, 100 + 1, 2);
167 // draw_hline(0, 10 + 5, 100 + 2, 2);
168 // draw_hline(1, 10 + 4, 100 + 3, 5);
169 // draw_hline(1, 10 + 5, 100 + 4, 5);
130 170
131 // DX is bigger 171 // DX is bigger
132 // left -> right && top -> bot 172 // left -> right && top -> bot
@@ -134,7 +174,7 @@ int main(void) {
134 // PROF(draw_line(0, 0, 239, 159, 1), test_lines_cycles); 174 // PROF(draw_line(0, 0, 239, 159, 1), test_lines_cycles);
135 ////// draw_line(10, 0, 229, 159, 1); 175 ////// draw_line(10, 0, 229, 159, 1);
136 ////// left -> right && bot -> top 176 ////// left -> right && bot -> top
137 //draw_line(0, 159, 239, 0, 2); 177 // draw_line(0, 159, 239, 0, 2);
138 ////// draw_line(10, 159, 229, 0, 2); 178 ////// draw_line(10, 159, 229, 0, 2);
139 ////// 179 //////
140 ////draw_line(0, 0, 239, 159, 1); 180 ////draw_line(0, 0, 239, 159, 1);
@@ -158,12 +198,12 @@ int main(void) {
158 // draw_line(0, 0, 19, 159, 6); 198 // draw_line(0, 0, 19, 159, 6);
159 // txt_render(); 199 // txt_render();
160 // txt_clear(); 200 // txt_clear();
161 PROF(test_lines(), test_lines_cycles); 201 // PROF(test_lines(), test_lines_cycles);
162 PROF(test_rect(), test_rect_cycles); 202 // PROF(test_rect(), test_rect_cycles);
163 PROF(test_fill_rect(), test_fill_rect_cycles); 203 // PROF(test_fill_rect(), test_fill_rect_cycles);
164 PROF(test_chr(), test_chr_cycles); 204 // PROF(test_chr(), test_chr_cycles);
165 PROF(test_icn(), test_icn_cycles); 205 // PROF(test_icn(), test_icn_cycles);
166 draw_filled_rect(0, 0, 140, 60, 0); 206 // draw_filled_rect(0, 0, 140, 60, 0);
167 PROF_SHOW(); 207 PROF_SHOW();
168 PROF(flip_buffer(), flip_cycles); 208 PROF(flip_buffer(), flip_cycles);
169 } 209 }
diff --git a/src/renderer_m0.c b/src/renderer_m0.c
index 6be01a4..c9aa7ae 100644
--- a/src/renderer_m0.c
+++ b/src/renderer_m0.c
@@ -173,14 +173,41 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
173 173
174 int dx = x0 > x1 ? x0 - x1 : x1 - x0; 174 int dx = x0 > x1 ? x0 - x1 : x1 - x0;
175 int dy = y0 > y1 ? y0 - y1 : y1 - y0; 175 int dy = y0 > y1 ? y0 - y1 : y1 - y0;
176 int dxf = (dx << fp_bit);
177 int dyf = (dy << fp_bit);
178 176
179 if ((dx >= dy && x0 > x1) || (dx < dy && y0 > y1)) { 177 if ((dx >= dy && x0 > x1) || (dx < dy && y0 > y1)) {
180 SWAP(x0, x1); 178 SWAP(x0, x1);
181 SWAP(y0, y1); 179 SWAP(y0, y1);
182 } 180 }
183 181
182#if 0
183 int x_step = x0 > x1 ? -1 : 1;
184 int y_step = y0 > y1 ? -1 : 1;
185 if (dx >= dy) {
186 int diff = 2 * dy - dx;
187 for (int i = 0; i < dx + 1; i++) {
188 draw_pixel(x0, y0, clr);
189 if (diff >= 0) {
190 diff -= 2 * dx;
191 y0 += y_step;
192 }
193 diff += 2 * dy;
194 x0 += x_step;
195 }
196 } else {
197 int diff = 2 * dx - dy;
198 for (int i = 0; i < dy + 1; i++) {
199 draw_pixel(x0, y0, clr);
200 if (diff >= 0) {
201 diff -= 2 * dy;
202 x0 += x_step;
203 }
204 diff += 2 * dx;
205 y0 += y_step;
206 }
207 }
208#else
209 int dxf = (dx << fp_bit);
210 int dyf = (dy << fp_bit);
184 int frac_x = x0 > x1 ? FP_NUM(x0 - x1, fp_bit) : FP_NUM(x1 - x0, fp_bit); 211 int frac_x = x0 > x1 ? FP_NUM(x0 - x1, fp_bit) : FP_NUM(x1 - x0, fp_bit);
185 int frac_y = y0 > y1 ? FP_NUM(y0 - y1, fp_bit) : FP_NUM(y1 - y0, fp_bit); 212 int frac_y = y0 > y1 ? FP_NUM(y0 - y1, fp_bit) : FP_NUM(y1 - y0, fp_bit);
186 int x_step = x0 > x1 ? -1 : 1; 213 int x_step = x0 > x1 ? -1 : 1;
@@ -232,6 +259,7 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
232 draw_vline(x0, y0, y0 + remaining, clr); 259 draw_vline(x0, y0, y0 + remaining, clr);
233 } 260 }
234 } 261 }
262#endif
235 } 263 }
236} 264}
237 265
diff --git a/src/renderer_m4.c b/src/renderer_m4.c
index a70cff9..de052df 100644
--- a/src/renderer_m4.c
+++ b/src/renderer_m4.c
@@ -138,39 +138,86 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
138 int frac_y = y0 > y1 ? FP_NUM(y0 - y1, fp_bit) : FP_NUM(y1 - y0, fp_bit); 138 int frac_y = y0 > y1 ? FP_NUM(y0 - y1, fp_bit) : FP_NUM(y1 - y0, fp_bit);
139 int x_step = x0 > x1 ? -1 : 1; 139 int x_step = x0 > x1 ? -1 : 1;
140 int y_step = y0 > y1 ? -SCREEN_WIDTH : SCREEN_WIDTH; 140 int y_step = y0 > y1 ? -SCREEN_WIDTH : SCREEN_WIDTH;
141 int distance = (frac_y - fp_one) * dx - (frac_x - fp_half) * dy;
142 141
143 u16 *dst = NULL; 142 u16 *dst = NULL;
144 uintptr_t addr = ((uintptr_t)backbuf + y0 * SCREEN_WIDTH + x0); 143 uintptr_t addr = ((uintptr_t)backbuf + y0 * SCREEN_WIDTH + x0);
145 u32 mask = x0 & 1 ? ~0xFF : 0xFF; 144 u32 mask = x0 & 1 ? ~0xFF : 0xFF;
146 u32 color = (clr & 0xFF) | ((clr & 0xFF) << 8); 145 u32 color = (clr & 0xFF) | ((clr & 0xFF) << 8);
147 if (dx >= dy) { 146 if (dx >= dy) {
147 // u64 *dst = ((u64*)addr);
148 // int step = dxf / dyf; 148 // int step = dxf / dyf;
149 // int remaining = dx; 149 // int remaining = dx;
150 // int y_step = y0 > y1 ? -1 : 1; 150 // int y_step = y0 > y1 ? -1 : 1;
151 // y_step /= 8;
151 // while (remaining > (step - 1)) { 152 // while (remaining > (step - 1)) {
152 // distance += step * 2 * dyf; 153 // distance += step * 2 * dyf;
154 // size_t a = x0;
155 // size_t b;
153 // if (distance >= 0) { 156 // if (distance >= 0) {
154 // draw_hline(x0, x0 + step - 1, y0, clr); 157 // b = a + step - 1;
155 // x0 += x_step * step; 158 // x0 += step;
156 // remaining -= step; 159 // remaining -= step;
157 // } else { 160 // } else {
158 // if (remaining < step) { 161 // if (remaining < step) {
159 // break; 162 // break;
160 // } 163 // }
161 // draw_hline(x0, x0 + step, y0, clr); 164 // b = a + step;
162 // distance += 2 * dyf; 165 // distance += 2 * dyf;
163 // x0 += x_step * (step + 1); 166 // x0 += (step + 1);
164 // remaining -= step + 1; 167 // remaining -= step + 1;
165 // } 168 // }
169 // draw_hline(a, b, y0, 8); // DEBUG: reference
170
171 // // size_t tile_x0 = a / 8;
172 // // size_t tile_x1 = b / 8;
173 // // size_t start_col = a % 8;
174 // // size_t end_col = b % 8;
175 // // size_t dtx = tile_x1 - tile_x0;
176 // // size_t shift_left = start_col * 8;
177 // // size_t shift_right = (7 - end_col) * 8;
178 // // // size_t dtx = b/8 - a/8;
179 // // u64 mask = 0xFFFFFFFFFFFFFFFF;
180 // // u64 row = 0x0101010101010101 * clr;
181 // // if (dtx < 1) {
182 // // mask = (mask >> shift_right) & (mask << shift_left);
183 // // *dst = (*dst & ~mask) | (row & mask);
184 // // } else {
185 // // *dst = (*dst & ~(mask << shift_left)) | row << shift_left;
186 // // if (dtx != 1) {
187 // // dma_fill(&dst[1], 0x01010101 * clr, (dtx - 1) * 8, 3);
188 // // }
189 // // dst += dtx;
190 // // *dst = (*dst & ~(mask >> shift_right)) | row >> shift_right;
191 // // }
192 // // if (end_col == 7) {
193 // // dst++;
194 // // }
195
196 // dst += y_step;
166 // distance -= 2 * dxf; 197 // distance -= 2 * dxf;
167 // y0 += y_step;
168 // } 198 // }
169 // if (remaining >= 0) { 199 // if (remaining >= 0) {
170 // draw_hline(x0, x0 + remaining, y0, clr); 200 // draw_hline(x0, x0 + remaining, y0, clr);
171 // } 201 // }
172 // int distance = 2 * dy - dx; 202 // Subpixel accurate version.
173 for (int i = 0; i < dx + 1; i++) { 203 // int distance = (frac_y - fp_half) * dx - (frac_x - fp_half) * dy;
204 // int distance = ( dx * ( frac_y - fp_half ) ) - ( dy * ( frac_x - fp_half ) );
205 // distance -= ( dx << ( fp_bit - 1 ) );
206 //
207 int distance = (frac_y - fp_one) * dx - (frac_x - fp_half) * dy;
208 int remaining = dx;
209 while (distance <= 0 && remaining > 0) {
210 dst = (u16*)(addr - (mask >> 31));
211 *dst = (*dst & ~mask) | (color & mask);
212 distance += 2 * dyf;
213 addr += x_step;
214 remaining--;
215 mask = ~mask;
216 }
217 distance -= 2 * dxf;
218 addr += y_step;
219
220 while (remaining >= 0) {
174 dst = (u16*)(addr - (mask >> 31)); 221 dst = (u16*)(addr - (mask >> 31));
175 *dst = (*dst & ~mask) | (color & mask); 222 *dst = (*dst & ~mask) | (color & mask);
176 if (distance >= 0) { 223 if (distance >= 0) {
@@ -180,19 +227,33 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
180 distance += 2 * dyf; 227 distance += 2 * dyf;
181 addr += x_step; 228 addr += x_step;
182 mask = ~mask; 229 mask = ~mask;
230 remaining--;
183 } 231 }
184 } else { 232 } else {
185 int diff = 2 * dx - dy; 233 int distance = (frac_x - fp_one) * dy - (frac_y - fp_half) * dx;
186 for (int i = 0; i < dy + 1; i++) { 234 int remaining = dy;
235 while (distance <= 0 && remaining > 0) {
187 dst = (u16*)(addr - (mask >> 31)); 236 dst = (u16*)(addr - (mask >> 31));
188 *dst = (*dst & ~mask) | (color & mask); 237 *dst = (*dst & ~mask) | (color & mask);
189 if (diff >= 0) { 238 distance += 2 * dxf;
190 diff -= 2 * dy; 239 addr += y_step;
240 remaining--;
241 }
242 distance -= 2 * dyf;
243 addr += x_step;
244 mask = ~mask;
245
246 while (remaining >= 0) {
247 dst = (u16*)(addr - (mask >> 31));
248 *dst = (*dst & ~mask) | (color & mask);
249 if (distance >= 0) {
250 distance -= 2 * dyf;
191 addr += x_step; 251 addr += x_step;
192 mask = ~mask; 252 mask = ~mask;
193 } 253 }
194 diff += 2 * dx; 254 distance += 2 * dxf;
195 addr += y_step; 255 addr += y_step;
256 remaining--;
196 } 257 }
197 } 258 }
198#else 259#else