... |
... |
@@ -22,6 +22,12 @@ |
22
|
22
|
#define UPSCALE( x ) ( ( x ) * ( ONE_PIXEL >> 6 ) )
|
23
|
23
|
#define DOWNSCALE( x ) ( ( x ) >> ( PIXEL_BITS - 6 ) )
|
24
|
24
|
|
|
25
|
+// TODO: Fix types
|
|
26
|
+#define FT_UDIVPREP( c, b ) \
|
|
27
|
+ FT26D6 b ## _r = c ? (FT26D6)0xFFFFFFFF / ( b ) : 0
|
|
28
|
+#define FT_UDIV( a, b ) \
|
|
29
|
+ (FT26D6)( ( (FT26D6)( a ) * (FT26D6)( b ## _r ) ) >> 32 )
|
|
30
|
+
|
25
|
31
|
typedef struct dense_TRaster_
|
26
|
32
|
{
|
27
|
33
|
void* memory;
|
... |
... |
@@ -119,6 +125,11 @@ dense_render_line( dense_worker* worker, TPos tox, TPos toy ) |
119
|
125
|
deltax = to_x - from_x;
|
120
|
126
|
deltay = to_y - from_y;
|
121
|
127
|
|
|
128
|
+ FT_UDIVPREP(from_x != to_x, deltax);
|
|
129
|
+
|
|
130
|
+ FT_UDIVPREP(from_y != to_y, deltay);
|
|
131
|
+
|
|
132
|
+
|
122
|
133
|
if ( from_y < 0 )
|
123
|
134
|
{
|
124
|
135
|
from_x -= from_y * deltax/deltay;
|
... |
... |
@@ -133,6 +144,51 @@ dense_render_line( dense_worker* worker, TPos tox, TPos toy ) |
133
|
144
|
}
|
134
|
145
|
|
135
|
146
|
|
|
147
|
+ if(deltax == 0){
|
|
148
|
+ FT26D6 x = from_x;
|
|
149
|
+ int x0i = x>>6;
|
|
150
|
+ FT26D6 x0floor = x0i<<6;
|
|
151
|
+
|
|
152
|
+ // y-coordinate of first pixel of line
|
|
153
|
+ int y0 = from_y>>6;
|
|
154
|
+
|
|
155
|
+ // y-coordinate of last pixel of line
|
|
156
|
+ int y_limit = (to_y + 0x3f)>>6;
|
|
157
|
+ FT20D12* m_a = worker->m_a;
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+ for ( int y = y0; y < y_limit; y++ )
|
|
162
|
+ {
|
|
163
|
+ int linestart = y * worker->m_w;
|
|
164
|
+
|
|
165
|
+ FT26D6 dy = min( (y + 1)<<6, to_y ) - max( y<<6, from_y );
|
|
166
|
+
|
|
167
|
+ m_a[linestart + x0i] += dir*dy*(64 - x + x0floor);
|
|
168
|
+ m_a[linestart + ( x0i + 1 )] += dir*dy*(x-x0floor);
|
|
169
|
+
|
|
170
|
+ }
|
|
171
|
+
|
|
172
|
+ // int y = y0;
|
|
173
|
+
|
|
174
|
+ // int linestart = y * worker->m_w;
|
|
175
|
+
|
|
176
|
+ // FT26D6 dy1 = min( (y + 1)<<6, to_y ) - max( y<<6, from_y );
|
|
177
|
+ // m_a[linestart + x0i] += dir*dy1*(64 - x + x0floor);
|
|
178
|
+ // m_a[linestart + ( x0i + 1 )] += dir*dy1*(x-x0floor);
|
|
179
|
+
|
|
180
|
+ // y = y_limit -1;
|
|
181
|
+
|
|
182
|
+ // linestart = y * worker->m_w;
|
|
183
|
+
|
|
184
|
+ // FT26D6 dy2 = min( (y + 1)<<6, to_y ) - max( y<<6, from_y );
|
|
185
|
+ // m_a[linestart + x0i] += dir*dy2*(64 - x + x0floor);
|
|
186
|
+ // m_a[linestart + ( x0i + 1 )] += dir*dy2*(x-x0floor);
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+ }else{
|
|
191
|
+
|
136
|
192
|
FT26D6 x = from_x;
|
137
|
193
|
|
138
|
194
|
// y-coordinate of first pixel of line
|
... |
... |
@@ -142,6 +198,7 @@ dense_render_line( dense_worker* worker, TPos tox, TPos toy ) |
142
|
198
|
int y_limit = (to_y + 0x3f)>>6;
|
143
|
199
|
FT20D12* m_a = worker->m_a;
|
144
|
200
|
|
|
201
|
+
|
145
|
202
|
for ( int y = y0; y < y_limit; y++ )
|
146
|
203
|
{
|
147
|
204
|
int linestart = y * worker->m_w;
|
... |
... |
@@ -150,7 +207,8 @@ dense_render_line( dense_worker* worker, TPos tox, TPos toy ) |
150
|
207
|
FT26D6 dy = min( (y + 1)<<6, to_y ) - max( y<<6, from_y );
|
151
|
208
|
|
152
|
209
|
// x coordinate where the line leaves the current scanline
|
153
|
|
- FT26D6 xnext = x + dy * deltax/deltay;
|
|
210
|
+ FT26D6 xnext = x + FT_UDIV((dy*deltax), deltay);
|
|
211
|
+
|
154
|
212
|
|
155
|
213
|
// height with sign
|
156
|
214
|
FT26D6 d = dy * dir;
|
... |
... |
@@ -190,46 +248,52 @@ dense_render_line( dense_worker* worker, TPos tox, TPos toy ) |
190
|
248
|
}
|
191
|
249
|
else
|
192
|
250
|
{
|
193
|
|
-
|
194
|
251
|
// total horizontal length of line in current scanline, might be replaced by deltax
|
195
|
252
|
FT26D6 oneOverS = x1 - x0;
|
|
253
|
+
|
|
254
|
+ FT_UDIVPREP(x1 != x0, oneOverS);
|
|
255
|
+
|
196
|
256
|
FT26D6 x0f = x0 - x0floor;
|
197
|
257
|
|
198
|
258
|
// 64 - x0f is the horizontal length of line in first pixel
|
199
|
259
|
FT26D6 oneMinusX0f = (1<<6) - x0f;
|
200
|
260
|
|
201
|
261
|
// Stores area of triangle in first pixel divided by d
|
202
|
|
- FT26D6 a0 = ((oneMinusX0f * oneMinusX0f) >> 1) / oneOverS;
|
|
262
|
+ FT26D6 a0 = FT_UDIV(((oneMinusX0f * oneMinusX0f) >> 1), oneOverS);
|
203
|
263
|
|
204
|
264
|
// x1f is the horizontal length in the last pixel
|
205
|
265
|
FT26D6 x1f = x1 - x1ceil + (1<<6);
|
206
|
|
- FT26D6 am = ((x1f * x1f) >> 1) / oneOverS;
|
|
266
|
+ FT26D6 am = FT_UDIV(((x1f * x1f) >> 1) , oneOverS);
|
207
|
267
|
|
208
|
268
|
// d * a0 is area of triangle in first pixel
|
209
|
269
|
m_a[linestart + x0i] += d * a0;
|
210
|
|
-
|
211
|
270
|
if ( x1i == x0i + 2 )
|
212
|
271
|
m_a[linestart + ( x0i + 1 )] += d * ( (1<<6) - a0 - am );
|
213
|
272
|
else
|
214
|
273
|
{
|
215
|
|
- FT26D6 a1 = (((1<<6) + (1<<5) - x0f) << 6) / oneOverS;
|
|
274
|
+
|
|
275
|
+ FT26D6 a1 = FT_UDIV((((1<<6) + (1<<5) - x0f) << 6) , oneOverS);
|
|
276
|
+
|
216
|
277
|
m_a[linestart + ( x0i + 1 )] += d * ( a1 - a0 );
|
217
|
278
|
|
218
|
|
- FT26D6 dTimesS = (d << 12) / oneOverS;
|
219
|
|
-
|
|
279
|
+ FT26D6 dTimesS = FT_UDIV((d << 12) , oneOverS);
|
|
280
|
+
|
220
|
281
|
for ( FT26D6 xi = x0i + 2; xi < x1i - 1; xi++ ){
|
221
|
282
|
// Increase area for successive pixels by dy/dx
|
222
|
283
|
m_a[linestart + xi] += dTimesS;
|
223
|
284
|
}
|
224
|
285
|
|
225
|
|
- FT26D6 a2 = a1 + (( x1i - x0i - 3 )<<12)/oneOverS;
|
|
286
|
+
|
|
287
|
+ FT26D6 a2 = a1 + FT_UDIV((( x1i - x0i - 3 )<<12),oneOverS);
|
226
|
288
|
m_a[linestart + ( x1i - 1 )] += d * ( (1<<6) - a2 - am );
|
227
|
289
|
}
|
228
|
290
|
// Area in last pixel of scanline
|
229
|
291
|
m_a[linestart + x1i] += d * am;
|
230
|
292
|
}
|
|
293
|
+
|
231
|
294
|
x = xnext;
|
232
|
295
|
}
|
|
296
|
+ }
|
233
|
297
|
}
|
234
|
298
|
|
235
|
299
|
static int
|