1 /*
2
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 */
19 /*
20 * $Source: r:/prj/lib/src/2d/RCS/fl8lp.c $
21 * $Revision: 1.23 $
22 * $Author: kevin $
23 * $Date: 1994/11/02 19:39:45 $
24 *
25 * lit full perspective texture mapper.
26 *
27 */
28
29 // ************************************************************************************
30 // ************************************************************************************
31 //
32 // MLA - don't think we need to optimize this, its in C on the PC too
33 //
34 // ************************************************************************************
35 // ************************************************************************************
36
37 #include "cnvdat.h"
38 #include "pertyp.h"
39 #include "plytyp.h"
40 #define safe_fix_cint(x) ((fix_frac(x) == 0) ? (fix_int(x)) : (fix_int(x) + 1))
41 #define fix_16_20(a) ((a) >> 4)
42
43 /**************************************************************
44 Routines to scan polygon. hscan=standard horizontal scanlines.
45 vscan=vertical scanlines.
46 **************************************************************/
47
48 // prototypes
49 void gri_lit_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
50 void gri_lit_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
51
gri_lit_per_umap_hscan(grs_bitmap * bm,int n,grs_vertex ** vpl,grs_per_setup * ps)52 void gri_lit_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps) {
53 grs_per_info pi;
54 fix y_prime[10];
55 fix yp_left, yp_right;
56 fix x_left, x_right;
57 fix y_left, y_right;
58 fix dx_left, dx_right;
59 fix i_left, i_right;
60 fix di_left, di_right;
61 int yp_min, yp_max, yp_next;
62 int x_min, x_max, xr_min, xr_max, xl_min, xl_max;
63 int n_min, n_left, n_right;
64 int j;
65
66 pi.scale = grd_bm.w;
67 pi.scan_slope = ps->scan_slope;
68 pi.dp = ps->dp;
69 pi.clut = ps->clut;
70 if (fix_abs(pi.scan_slope) > FIX_UNIT)
71 return;
72
73 if (bm->row != 1 << (bm->wlog))
74 return;
75 if (bm->h != 1 << (bm->hlog))
76 return;
77 pi.u_mask = bm->row - 1;
78 pi.v_mask = (bm->h - 1) << bm->wlog;
79 pi.v_shift = 16 - bm->wlog;
80
81 yp_min = yp_max = fix_cint(y_prime[n_min = 0] = vpl[0]->y - fix_mul(vpl[0]->x, ps->scan_slope));
82 for (j = 1; j < n; j++) {
83 pi.yp = fix_cint(y_prime[j] = vpl[j]->y - fix_mul(vpl[j]->x, ps->scan_slope));
84 if (pi.yp < yp_min) {
85 yp_min = pi.yp;
86 n_min = j;
87 }
88 if (pi.yp > yp_max)
89 yp_max = pi.yp;
90 }
91 if (yp_max == yp_min)
92 return;
93 pi.denom = fix_16_20(ps->c + fix_mul(ps->b, y_prime[0]));
94 pi.u0 =
95 vpl[0]->u - fix_div(fix_mul(vpl[0]->x, ps->alpha_u) + fix_mul(vpl[0]->y, ps->beta_u) + ps->gamma_u, pi.denom);
96 pi.v0 =
97 vpl[0]->v - fix_div(fix_mul(vpl[0]->x, ps->alpha_v) + fix_mul(vpl[0]->y, ps->beta_v) + ps->gamma_v, pi.denom);
98
99 n_left = n_right = n_min;
100 pi.yp = yp_min;
101 while (fix_cint(y_prime[(n_left + n - 1) % n]) == pi.yp)
102 n_left = (n_left + n - 1) % n;
103 while (fix_cint(y_prime[(n_right + 1) % n]) == pi.yp)
104 n_right = (n_right + 1) % n;
105
106 pi.yp--;
107 pi.denom = fix_16_20(ps->c + pi.yp * ps->b);
108 pi.unum = ps->gamma_u + pi.yp * ps->beta_u;
109 pi.dunum = ps->alpha_u + fix_mul(ps->scan_slope, ps->beta_u);
110 pi.vnum = ps->gamma_v + pi.yp * ps->beta_v;
111 pi.dvnum = ps->alpha_v + fix_mul(ps->scan_slope, ps->beta_v);
112
113 if (n_right != n_left) {
114
115 pi.dxl = (vpl[n_right]->x - vpl[n_left]->x) / pi.scale;
116 pi.dyl = (vpl[n_right]->y - vpl[n_left]->y) / pi.scale;
117 pi.x = fix_cint(vpl[n_left]->x);
118 pi.xl = fix_cint(vpl[n_right]->x);
119 if (pi.scan_slope > 0) {
120 x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope));
121 x_min = fix_int(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope)) + 1;
122 } else {
123 x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope));
124 x_min = fix_int(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope)) + 1;
125 }
126 if (pi.x < x_min)
127 pi.x = x_min;
128 if (pi.xl > x_max)
129 pi.xl = x_max;
130 pi.xr0 = pi.xr = pi.xl;
131 pi.i = vpl[n_left]->i;
132 if (pi.xr - pi.x)
133 pi.di = (vpl[n_right]->i - pi.i) / (pi.xr - pi.x);
134 else {
135 pi.di = 0x7fffffff;
136 if (vpl[n_right]->i - pi.i < 0)
137 pi.di = -pi.di;
138 }
139
140 pi.cl = fix_mul(pi.dxl, vpl[n_left]->y) - fix_mul(pi.dyl, vpl[n_left]->x);
141 if (pi.x * pi.dyl - fix_mul(fix_make(pi.yp - 1, 0) + pi.x * pi.scan_slope, pi.dxl) + pi.cl < 0) {
142 pi.dyl = -pi.dyl;
143 pi.dxl = -pi.dxl;
144 pi.cl = -pi.cl;
145 }
146 if (pi.scan_slope > 0)
147 pi.dtl = pi.dyl - pi.dxl;
148 else
149 pi.dtl = pi.dyl + pi.dxl;
150
151 ((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
152
153 pi.denom += fix_16_20(ps->b), pi.unum += ps->beta_u, pi.vnum += ps->beta_v;
154 yp_min--; /* first line already done */
155 }
156 pi.yp++;
157 while (pi.yp < yp_max) {
158 /* check left edge */
159 if (fix_cint(y_prime[n_left]) <= pi.yp) {
160 int n_prev, dyp;
161 fix d;
162 do {
163 if (fix_cint(y_prime[n_left]) == pi.yp)
164 n_prev = n_left;
165 if (--n_left < 0)
166 n_left = n - 1;
167 } while (fix_cint(y_prime[n_left]) <= pi.yp);
168 yp_left = y_prime[n_prev];
169 x_left = vpl[n_prev]->x;
170 y_left = vpl[n_prev]->y;
171 i_left = vpl[n_prev]->i;
172 dyp = fix_cint(y_prime[n_left]) - fix_cint(yp_left);
173 di_left = (vpl[n_left]->i - i_left) / dyp;
174 xl_min = fix_cint(x_left);
175 xl_max = fix_cint(vpl[n_left]->x);
176 pi.dxl = (vpl[n_left]->x - x_left) / pi.scale;
177 pi.dyl = (vpl[n_left]->y - y_left) / pi.scale;
178 pi.cl = fix_mul(pi.dxl, y_left) - fix_mul(pi.dyl, x_left);
179 d = pi.dyl - fix_mul(pi.dxl, pi.scan_slope);
180 dx_left = fix_div(pi.dxl, d);
181 x_left = fix_div(fix_mul(pi.dyl, x_left) + fix_mul(pi.dxl, fix_ceil(yp_left) - y_left), d);
182 if (xl_max < xl_min) {
183 fix foo = xl_min;
184 xl_min = xl_max;
185 xl_max = foo;
186 }
187 if (fix_mul(vpl[n_left]->x - FIX_UNIT, pi.dyl) - fix_mul(vpl[n_left]->y - pi.scan_slope, pi.dxl) + pi.cl <
188 0) {
189 pi.dyl = -pi.dyl;
190 pi.dxl = -pi.dxl;
191 pi.cl = -pi.cl;
192 }
193 if (pi.scan_slope > 0)
194 pi.dtl = pi.dyl - pi.dxl;
195 else
196 pi.dtl = pi.dyl + pi.dxl;
197 yp_left = y_prime[n_left];
198 }
199
200 /* check right edge */
201 if (fix_cint(y_prime[n_right]) <= pi.yp) {
202 int n_prev, dyp;
203 fix d;
204 do {
205 if (fix_cint(y_prime[n_right]) == pi.yp)
206 n_prev = n_right;
207 if (++n_right == n)
208 n_right = 0;
209 } while (fix_cint(y_prime[n_right]) <= pi.yp);
210 yp_right = y_prime[n_prev];
211 x_right = vpl[n_prev]->x;
212 y_right = vpl[n_prev]->y;
213 i_right = vpl[n_prev]->i;
214 dyp = fix_cint(y_prime[n_right]) - fix_cint(yp_right);
215 di_right = (vpl[n_right]->i - i_right) / dyp;
216 xr_min = fix_cint(x_right);
217 xr_max = fix_cint(vpl[n_right]->x);
218 pi.dxr = (vpl[n_right]->x - x_right) / pi.scale;
219 pi.dyr = (vpl[n_right]->y - y_right) / pi.scale;
220 pi.cr = fix_mul(pi.dxr, y_right) - fix_mul(pi.dyr, x_right);
221 d = pi.dyr - fix_mul(pi.dxr, pi.scan_slope);
222 dx_right = fix_div(pi.dxr, d);
223 x_right = fix_div(fix_mul(pi.dyr, x_right) + fix_mul(pi.dxr, fix_ceil(yp_right) - y_right), d);
224 if (xr_max < xr_min) {
225 fix foo = xr_min;
226 xr_min = xr_max;
227 xr_max = foo;
228 }
229 if (fix_mul(vpl[n_right]->x - FIX_UNIT, pi.dyr) - fix_mul(vpl[n_right]->y - pi.scan_slope, pi.dxr) + pi.cr <
230 0) {
231 pi.dyr = -pi.dyr;
232 pi.dxr = -pi.dxr;
233 pi.cr = -pi.cr;
234 }
235 if (pi.scan_slope > 0)
236 pi.dtr = pi.dyr - pi.dxr;
237 else
238 pi.dtr = pi.dyr + pi.dxr;
239 yp_right = y_prime[n_right];
240 }
241 yp_next = (yp_right < yp_left) ? fix_cint(yp_right) : fix_cint(yp_left);
242
243 /* do 0th scanline if at yp_min */
244 if (pi.yp == yp_min) {
245 x_left -= dx_left;
246 x_right -= dx_right;
247 pi.yp--;
248 }
249 for (; pi.yp < yp_next; pi.yp++) {
250 if ((pi.yp + 1 == yp_max) && (n_left != n_right)) {
251 pi.dxl = (vpl[n_right]->x - vpl[n_left]->x) / pi.scale;
252 pi.dyl = (vpl[n_right]->y - vpl[n_left]->y) / pi.scale;
253 pi.x = fix_cint(vpl[n_left]->x);
254 pi.xl = fix_cint(vpl[n_right]->x);
255 if (pi.scan_slope > 0) {
256 x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope));
257 x_min = fix_int(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope)) + 1;
258 } else {
259 x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope));
260 x_min = fix_int(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope)) + 1;
261 }
262 if (pi.x < x_min)
263 pi.x = x_min;
264 if (pi.xl > x_max)
265 pi.xl = x_max;
266 pi.xr0 = pi.xr = pi.xl;
267 pi.i = i_left;
268 if (pi.xr - pi.x)
269 pi.di = (i_right - pi.i) / (pi.xr - pi.x);
270 else {
271 pi.di = 0x7fffffff;
272 if (i_right - pi.i < 0)
273 pi.di = -pi.di;
274 }
275
276 pi.cl = fix_mul(pi.dxl, vpl[n_left]->y) - fix_mul(pi.dyl, vpl[n_left]->x);
277 if (pi.x * pi.dyl - fix_mul(fix_make(pi.yp + 1, 0) + pi.x * pi.scan_slope, pi.dxl) + pi.cl < 0) {
278 pi.dyl = -pi.dyl;
279 pi.dxl = -pi.dxl;
280 pi.cl = -pi.cl;
281 }
282 if (pi.scan_slope > 0)
283 pi.dtl = pi.dyl - pi.dxl;
284 else
285 pi.dtl = pi.dyl + pi.dxl;
286
287 ((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
288
289 pi.yp = yp_max;
290 break;
291 }
292
293 if (dx_left > 0) {
294 pi.x = fix_fint(x_left);
295 pi.xl = fix_cint(x_left + dx_left);
296 } else {
297 pi.x = fix_fint(x_left + dx_left);
298 pi.xl = fix_cint(x_left);
299 }
300 if (dx_right > 0) {
301 pi.xr0 = fix_fint(x_right);
302 pi.xr = fix_cint(x_right + dx_right);
303 } else {
304 pi.xr0 = fix_fint(x_right + dx_right);
305 pi.xr = fix_cint(x_right);
306 }
307 if (pi.scan_slope > 0) {
308 x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope));
309 x_min = fix_int(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope)) + 1;
310 } else {
311 x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope));
312 x_min = fix_int(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope)) + 1;
313 }
314 if (xl_min > x_min)
315 x_min = xl_min;
316 if (xr_max < x_max)
317 x_max = xr_max;
318 if (pi.xr > x_max)
319 pi.xr = x_max;
320 if (pi.xr0 > x_max)
321 pi.xr0 = x_max;
322 if (pi.xl > pi.xr0)
323 pi.xl = pi.xr0;
324 if (pi.x < x_min)
325 pi.x = x_min;
326 pi.i = i_left;
327 if (pi.xr - pi.x)
328 pi.di = (i_right - pi.i) / (pi.xr - pi.x);
329 else {
330 pi.di = 0x7fffffff;
331 if (i_right - pi.i < 0)
332 pi.di = -pi.di;
333 }
334
335 ((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
336
337 if (pi.yp >= yp_min) {
338 i_left += di_left, i_right += di_right;
339 }
340 x_left += dx_left, x_right += dx_right;
341 pi.denom += fix_16_20(ps->b), pi.unum += ps->beta_u, pi.vnum += ps->beta_v;
342 }
343 }
344 }
345
gri_lit_per_umap_vscan(grs_bitmap * bm,int n,grs_vertex ** vpl,grs_per_setup * ps)346 void gri_lit_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps) {
347 grs_per_info pi;
348 fix x_prime[10];
349 fix xp_top, xp_bot;
350 fix x_top, x_bot;
351 fix y_top, y_bot;
352 fix dy_top, dy_bot;
353 fix i_top, i_bot;
354 fix di_top, di_bot;
355 int xp_min, xp_max, xp_next;
356 int y_min, y_max, yr_min, yr_max, yl_min, yl_max;
357 int n_min, n_top, n_bot;
358 int j;
359
360 pi.scale = grd_bm.w;
361 pi.scan_slope = ps->scan_slope;
362 pi.dp = ps->dp;
363 pi.clut = ps->clut;
364 if (fix_abs(pi.scan_slope) >= FIX_UNIT)
365 return;
366
367 if (bm->row != 1 << (bm->wlog))
368 return;
369 if (bm->h != 1 << (bm->hlog))
370 return;
371 pi.u_mask = bm->row - 1;
372 pi.v_mask = (bm->h - 1) << bm->wlog;
373 pi.v_shift = 16 - bm->wlog;
374
375 xp_min = xp_max = fix_cint(x_prime[n_min = 0] = vpl[0]->x - fix_mul(vpl[0]->y, ps->scan_slope));
376 for (j = 1; j < n; j++) {
377 pi.xp = fix_cint(x_prime[j] = vpl[j]->x - fix_mul(vpl[j]->y, ps->scan_slope));
378 if (pi.xp < xp_min) {
379 xp_min = pi.xp;
380 n_min = j;
381 }
382 if (pi.xp > xp_max)
383 xp_max = pi.xp;
384 }
385 if (xp_max == xp_min)
386 return;
387 pi.denom = fix_16_20(ps->c + fix_mul(ps->a, x_prime[0]));
388 pi.u0 =
389 vpl[0]->u - fix_div(fix_mul(vpl[0]->x, ps->alpha_u) + fix_mul(vpl[0]->y, ps->beta_u) + ps->gamma_u, pi.denom);
390 pi.v0 =
391 vpl[0]->v - fix_div(fix_mul(vpl[0]->x, ps->alpha_v) + fix_mul(vpl[0]->y, ps->beta_v) + ps->gamma_v, pi.denom);
392
393 n_top = n_bot = n_min;
394 pi.xp = xp_min;
395 while (fix_cint(x_prime[(n_top + 1) % n]) == pi.xp)
396 n_top = (n_top + 1) % n;
397 while (fix_cint(x_prime[(n_bot + n - 1) % n]) == pi.xp)
398 n_bot = (n_bot + n - 1) % n;
399
400 pi.xp--;
401 pi.denom = fix_16_20(ps->c + pi.xp * ps->a);
402 pi.unum = ps->gamma_u + pi.xp * ps->alpha_u;
403 pi.dunum = ps->beta_u + fix_mul(ps->scan_slope, ps->alpha_u);
404 pi.vnum = ps->gamma_v + pi.xp * ps->alpha_v;
405 pi.dvnum = ps->beta_v + fix_mul(ps->scan_slope, ps->alpha_v);
406
407 if (n_bot != n_top) {
408
409 pi.dxl = (vpl[n_bot]->x - vpl[n_top]->x) / pi.scale;
410 pi.dyl = (vpl[n_bot]->y - vpl[n_top]->y) / pi.scale;
411 pi.y = fix_cint(vpl[n_top]->y);
412 pi.yl = fix_cint(vpl[n_bot]->y);
413 if (pi.scan_slope > 0) {
414 y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope));
415 y_min = fix_int(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope)) + 1;
416 } else {
417 y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope));
418 y_min = fix_int(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope)) + 1;
419 }
420 if (pi.y < y_min)
421 pi.y = y_min;
422 if (pi.yl > y_max)
423 pi.yl = y_max;
424 pi.yr0 = pi.yr = pi.yl;
425 pi.i = vpl[n_top]->i;
426 if (pi.yr - pi.y)
427 pi.di = (vpl[n_bot]->i - pi.i) / (pi.yr - pi.y);
428 else {
429 pi.di = 0x7fffffff;
430 if (vpl[n_bot]->i - pi.i < 0)
431 pi.di = -pi.di;
432 }
433
434 pi.cl = -fix_mul(pi.dxl, vpl[n_top]->y) + fix_mul(pi.dyl, vpl[n_top]->x);
435 if (pi.y * pi.dxl - fix_mul(fix_make(pi.xp - 1, 0) + pi.y * pi.scan_slope, pi.dyl) + pi.cl < 0) {
436 pi.dyl = -pi.dyl;
437 pi.dxl = -pi.dxl;
438 pi.cl = -pi.cl;
439 }
440 if (pi.scan_slope > 0)
441 pi.dtl = pi.dxl - pi.dyl;
442 else
443 pi.dtl = pi.dyl + pi.dxl;
444
445 ((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
446
447 pi.denom += fix_16_20(ps->a), pi.unum += ps->alpha_u, pi.vnum += ps->alpha_v;
448 xp_min--; /* first line already done */
449 }
450 pi.xp++;
451 while (pi.xp < xp_max) {
452 /* check top edge */
453 if (fix_cint(x_prime[n_top]) <= pi.xp) {
454 int n_prev, dxp;
455 fix d;
456 do {
457 if (fix_cint(x_prime[n_top]) == pi.xp)
458 n_prev = n_top;
459 if (++n_top == n)
460 n_top = 0;
461 } while (fix_cint(x_prime[n_top]) <= pi.xp);
462 xp_top = x_prime[n_prev];
463 x_top = vpl[n_prev]->x;
464 y_top = vpl[n_prev]->y;
465 i_top = vpl[n_prev]->i;
466 dxp = fix_cint(x_prime[n_top]) - fix_cint(xp_top);
467 di_top = (vpl[n_top]->i - i_top) / dxp;
468 yl_min = fix_cint(y_top);
469 yl_max = fix_cint(vpl[n_top]->y);
470 pi.dxl = (vpl[n_top]->x - x_top) / pi.scale;
471 pi.dyl = (vpl[n_top]->y - y_top) / pi.scale;
472 pi.cl = -fix_mul(pi.dxl, y_top) + fix_mul(pi.dyl, x_top);
473 d = pi.dxl - fix_mul(pi.dyl, pi.scan_slope);
474 dy_top = fix_div(pi.dyl, d);
475 y_top = fix_div(fix_mul(pi.dxl, y_top) + fix_mul(pi.dyl, fix_ceil(xp_top) - x_top), d);
476 if (yl_max < yl_min) {
477 fix foo = yl_min;
478 yl_min = yl_max;
479 yl_max = foo;
480 }
481 if (fix_mul(vpl[n_top]->y - FIX_UNIT, pi.dxl) - fix_mul(vpl[n_top]->x - pi.scan_slope, pi.dyl) + pi.cl <
482 0) {
483 pi.dyl = -pi.dyl;
484 pi.dxl = -pi.dxl;
485 pi.cl = -pi.cl;
486 }
487 if (pi.scan_slope > 0)
488 pi.dtl = pi.dxl - pi.dyl;
489 else
490 pi.dtl = pi.dyl + pi.dxl;
491 xp_top = x_prime[n_top];
492 }
493
494 /* check bot edge */
495 if (fix_cint(x_prime[n_bot]) <= pi.xp) {
496 int n_prev, dxp;
497 fix d;
498 do {
499 if (fix_cint(x_prime[n_bot]) == pi.xp)
500 n_prev = n_bot;
501 if (--n_bot < 0)
502 n_bot = n - 1;
503 } while (fix_cint(x_prime[n_bot]) <= pi.xp);
504 xp_bot = x_prime[n_prev];
505 x_bot = vpl[n_prev]->x;
506 y_bot = vpl[n_prev]->y;
507 i_bot = vpl[n_prev]->i;
508 dxp = fix_cint(x_prime[n_bot]) - fix_cint(xp_bot);
509 di_bot = (vpl[n_bot]->i - i_bot) / dxp;
510 yr_min = fix_cint(y_bot);
511 yr_max = fix_cint(vpl[n_bot]->y);
512 pi.dxr = (vpl[n_bot]->x - x_bot) / pi.scale;
513 pi.dyr = (vpl[n_bot]->y - y_bot) / pi.scale;
514 pi.cr = -fix_mul(pi.dxr, y_bot) + fix_mul(pi.dyr, x_bot);
515 d = pi.dxr - fix_mul(pi.dyr, pi.scan_slope);
516 dy_bot = fix_div(pi.dyr, d);
517 y_bot = fix_div(fix_mul(pi.dxr, y_bot) + fix_mul(pi.dyr, fix_ceil(xp_bot) - x_bot), d);
518 if (yr_max < yr_min) {
519 fix foo = yr_min;
520 yr_min = yr_max;
521 yr_max = foo;
522 }
523 if (fix_mul(vpl[n_bot]->y - FIX_UNIT, pi.dxr) - fix_mul(vpl[n_bot]->x - pi.scan_slope, pi.dyr) + pi.cr <
524 0) {
525 pi.dyr = -pi.dyr;
526 pi.dxr = -pi.dxr;
527 pi.cr = -pi.cr;
528 }
529 if (pi.scan_slope > 0)
530 pi.dtr = pi.dxr - pi.dyr;
531 else
532 pi.dtr = pi.dyr + pi.dxr;
533 xp_bot = x_prime[n_bot];
534 }
535 xp_next = (xp_bot < xp_top) ? fix_cint(xp_bot) : fix_cint(xp_top);
536
537 /* do 0th scanline if at xp_min */
538 if (pi.xp == xp_min) {
539 y_top -= dy_top;
540 y_bot -= dy_bot;
541 pi.xp--;
542 }
543 for (; pi.xp < xp_next; pi.xp++) {
544 if ((pi.xp + 1 == xp_max) && (n_top != n_bot)) {
545 pi.dxl = (vpl[n_bot]->x - vpl[n_top]->x) / pi.scale;
546 pi.dyl = (vpl[n_bot]->y - vpl[n_top]->y) / pi.scale;
547 pi.y = fix_cint(vpl[n_top]->y);
548 pi.yl = fix_cint(vpl[n_bot]->y);
549 if (pi.scan_slope > 0) {
550 y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope));
551 y_min = fix_int(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope)) + 1;
552 } else {
553 y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope));
554 y_min = fix_int(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope)) + 1;
555 }
556 if (pi.y < y_min)
557 pi.y = y_min;
558 if (pi.yl > y_max)
559 pi.yl = y_max;
560 pi.yr0 = pi.yr = pi.yl;
561 pi.i = i_top;
562 if (pi.yr - pi.y)
563 pi.di = (i_bot - pi.i) / (pi.yr - pi.y);
564 else {
565 pi.di = 0x7fffffff;
566 if (i_bot - pi.i < 0)
567 pi.di = -pi.di;
568 }
569
570 pi.cl = -fix_mul(pi.dxl, vpl[n_top]->y) + fix_mul(pi.dyl, vpl[n_top]->x);
571 if (pi.y * pi.dxl - fix_mul(fix_make(pi.xp + 1, 0) + pi.y * pi.scan_slope, pi.dyl) + pi.cl < 0) {
572 pi.dyl = -pi.dyl;
573 pi.dxl = -pi.dxl;
574 pi.cl = -pi.cl;
575 }
576 if (pi.scan_slope > 0)
577 pi.dtl = pi.dxl - pi.dyl;
578 else
579 pi.dtl = pi.dyl + pi.dxl;
580
581 ((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
582
583 pi.xp = xp_max;
584 break;
585 }
586
587 if (dy_top > 0) {
588 pi.y = fix_fint(y_top);
589 pi.yl = fix_cint(y_top + dy_top);
590 } else {
591 pi.y = fix_fint(y_top + dy_top);
592 pi.yl = fix_cint(y_top);
593 }
594 if (dy_bot > 0) {
595 pi.yr0 = fix_fint(y_bot);
596 pi.yr = fix_cint(y_bot + dy_bot);
597 } else {
598 pi.yr0 = fix_fint(y_bot + dy_bot);
599 pi.yr = fix_cint(y_bot);
600 }
601 if (pi.scan_slope > 0) {
602 y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope));
603 y_min = fix_int(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope)) + 1;
604 } else {
605 y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope));
606 y_min = fix_int(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope)) + 1;
607 }
608 if (yl_min > y_min)
609 y_min = yl_min;
610 if (yr_max < y_max)
611 y_max = yr_max;
612 if (pi.yr > y_max)
613 pi.yr = y_max;
614 if (pi.yr0 > y_max)
615 pi.yr0 = y_max;
616 if (pi.yl > pi.yr0)
617 pi.yl = pi.yr0;
618 if (pi.y < y_min)
619 pi.y = y_min;
620 pi.i = i_top;
621 if (pi.yr - pi.y)
622 pi.di = (i_bot - pi.i) / (pi.yr - pi.y);
623 else {
624 pi.di = 0x7fffffff;
625 if (i_bot - pi.i < 0)
626 pi.di = -pi.di;
627 }
628
629 ((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
630
631 if (pi.xp >= xp_min) {
632 i_top += di_top, i_bot += di_bot;
633 }
634
635 y_top += dy_top, y_bot += dy_bot;
636 pi.denom += fix_16_20(ps->a), pi.unum += ps->alpha_u, pi.vnum += ps->alpha_v;
637 }
638 }
639 }
640