diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-18 09:30:27 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-18 09:30:27 +0200 |
commit | 838c38045bef10fa893b6790fe42a5a649ccaeca (patch) | |
tree | 11c5529468498724e72d978b7779fff3eeefc852 | |
parent | 195f219514d02826571a89ff380debfbb2882872 (diff) | |
download | gba-link-cable-tester-838c38045bef10fa893b6790fe42a5a649ccaeca.tar.gz gba-link-cable-tester-838c38045bef10fa893b6790fe42a5a649ccaeca.zip |
Change dx >= dy mode 4 line drawing to be subpixel accurate
-rw-r--r-- | src/renderer_m4.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/renderer_m4.c b/src/renderer_m4.c index 4e8868a..a70cff9 100644 --- a/src/renderer_m4.c +++ b/src/renderer_m4.c | |||
@@ -118,6 +118,84 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
118 | MAYBE_SWAP(y0, y1); | 118 | MAYBE_SWAP(y0, y1); |
119 | draw_vline(x0, y0, y1, clr); | 119 | draw_vline(x0, y0, y1, clr); |
120 | } else { | 120 | } else { |
121 | #if 1 | ||
122 | // Fixed Precision constants. | ||
123 | const int fp_bit = 6; | ||
124 | const int fp_one = FP_NUM(1, fp_bit); | ||
125 | const int fp_half = fp_one >> 1; | ||
126 | |||
127 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; | ||
128 | int dy = y0 > y1 ? y0 - y1 : y1 - y0; | ||
129 | int dxf = (dx << fp_bit); | ||
130 | int dyf = (dy << fp_bit); | ||
131 | |||
132 | if ((dx >= dy && x0 > x1) || (dx < dy && y0 > y1)) { | ||
133 | SWAP(x0, x1); | ||
134 | SWAP(y0, y1); | ||
135 | } | ||
136 | |||
137 | int frac_x = x0 > x1 ? FP_NUM(x0 - x1, fp_bit) : FP_NUM(x1 - x0, 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; | ||
140 | int y_step = y0 > y1 ? -SCREEN_WIDTH : SCREEN_WIDTH; | ||
141 | int distance = (frac_y - fp_one) * dx - (frac_x - fp_half) * dy; | ||
142 | |||
143 | u16 *dst = NULL; | ||
144 | uintptr_t addr = ((uintptr_t)backbuf + y0 * SCREEN_WIDTH + x0); | ||
145 | u32 mask = x0 & 1 ? ~0xFF : 0xFF; | ||
146 | u32 color = (clr & 0xFF) | ((clr & 0xFF) << 8); | ||
147 | if (dx >= dy) { | ||
148 | // int step = dxf / dyf; | ||
149 | // int remaining = dx; | ||
150 | // int y_step = y0 > y1 ? -1 : 1; | ||
151 | // while (remaining > (step - 1)) { | ||
152 | // distance += step * 2 * dyf; | ||
153 | // if (distance >= 0) { | ||
154 | // draw_hline(x0, x0 + step - 1, y0, clr); | ||
155 | // x0 += x_step * step; | ||
156 | // remaining -= step; | ||
157 | // } else { | ||
158 | // if (remaining < step) { | ||
159 | // break; | ||
160 | // } | ||
161 | // draw_hline(x0, x0 + step, y0, clr); | ||
162 | // distance += 2 * dyf; | ||
163 | // x0 += x_step * (step + 1); | ||
164 | // remaining -= step + 1; | ||
165 | // } | ||
166 | // distance -= 2 * dxf; | ||
167 | // y0 += y_step; | ||
168 | // } | ||
169 | // if (remaining >= 0) { | ||
170 | // draw_hline(x0, x0 + remaining, y0, clr); | ||
171 | // } | ||
172 | // int distance = 2 * dy - dx; | ||
173 | for (int i = 0; i < dx + 1; i++) { | ||
174 | dst = (u16*)(addr - (mask >> 31)); | ||
175 | *dst = (*dst & ~mask) | (color & mask); | ||
176 | if (distance >= 0) { | ||
177 | distance -= 2 * dxf; | ||
178 | addr += y_step; | ||
179 | } | ||
180 | distance += 2 * dyf; | ||
181 | addr += x_step; | ||
182 | mask = ~mask; | ||
183 | } | ||
184 | } else { | ||
185 | int diff = 2 * dx - dy; | ||
186 | for (int i = 0; i < dy + 1; i++) { | ||
187 | dst = (u16*)(addr - (mask >> 31)); | ||
188 | *dst = (*dst & ~mask) | (color & mask); | ||
189 | if (diff >= 0) { | ||
190 | diff -= 2 * dy; | ||
191 | addr += x_step; | ||
192 | mask = ~mask; | ||
193 | } | ||
194 | diff += 2 * dx; | ||
195 | addr += y_step; | ||
196 | } | ||
197 | } | ||
198 | #else | ||
121 | // Diagonal line. | 199 | // Diagonal line. |
122 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; | 200 | int dx = x0 > x1 ? x0 - x1 : x1 - x0; |
123 | int dy = y0 > y1 ? y0 - y1 : y1 - y0; | 201 | int dy = y0 > y1 ? y0 - y1 : y1 - y0; |
@@ -155,6 +233,7 @@ draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
155 | addr += y_step; | 233 | addr += y_step; |
156 | } | 234 | } |
157 | } | 235 | } |
236 | #endif | ||
158 | } | 237 | } |
159 | } | 238 | } |
160 | 239 | ||