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/fl8p.c $
21  * $Revision: 1.15 $
22  * $Author: kevin $
23  * $Date: 1994/11/02 19:38:32 $
24  *
25  * 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 // prototypes
44 void gri_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
45 void gri_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
46 
47 /**************************************************************
48 Routines to scan polygon.  hscan=standard horizontal scanlines.
49 vscan=vertical scanlines.
50 **************************************************************/
51 
gri_per_umap_hscan(grs_bitmap * bm,int n,grs_vertex ** vpl,grs_per_setup * ps)52 void gri_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     int yp_min, yp_max, yp_next;
60     int x_min, x_max, xr_min, xr_max, xl_min, xl_max;
61     int n_min, n_left, n_right;
62     int j;
63 
64     pi.scale = grd_bm.w;
65     pi.scan_slope = ps->scan_slope;
66     pi.dp = ps->dp;
67     pi.clut = ps->clut;
68     if (fix_abs(pi.scan_slope) > FIX_UNIT)
69         return;
70 
71     if (bm->row != 1 << (bm->wlog))
72         return;
73     if (bm->h != 1 << (bm->hlog))
74         return;
75     pi.u_mask = bm->row - 1;
76     pi.v_mask = (bm->h - 1) << bm->wlog;
77     pi.v_shift = 16 - bm->wlog;
78 
79     n_min = 0;
80     y_prime[n_min] = vpl[n_min]->y - fix_mul(vpl[n_min]->x, ps->scan_slope);
81     yp_min = yp_max = fix_cint(y_prime[n_min]);
82 
83     for (j = 1; j < n; j++) {
84         y_prime[j] = vpl[j]->y - fix_mul(vpl[j]->x, ps->scan_slope);
85         pi.yp = fix_cint(y_prime[j]);
86         if (pi.yp < yp_min) {
87             yp_min = pi.yp;
88             n_min = j;
89         }
90         if (pi.yp > yp_max)
91             yp_max = pi.yp;
92     }
93 
94     if (yp_max == yp_min)
95         return;
96 
97     pi.denom = fix_16_20(ps->c + fix_mul(ps->b, y_prime[0]));
98     pi.u0 =
99         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);
100     pi.v0 =
101         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);
102 
103     n_left = n_right = n_min;
104     pi.yp = yp_min;
105     while (fix_cint(y_prime[(n_left + n - 1) % n]) == pi.yp)
106         n_left = (n_left + n - 1) % n;
107     while (fix_cint(y_prime[(n_right + 1) % n]) == pi.yp)
108         n_right = (n_right + 1) % n;
109 
110     pi.yp--;
111     pi.denom = fix_16_20(ps->c + pi.yp * ps->b);
112     pi.unum = ps->gamma_u + ps->beta_u * pi.yp;
113     pi.dunum = ps->alpha_u + fix_mul(ps->scan_slope, ps->beta_u);
114     pi.vnum = ps->gamma_v + ps->beta_v * pi.yp;
115     pi.dvnum = ps->alpha_v + fix_mul(ps->scan_slope, ps->beta_v);
116 
117     if (n_right != n_left) {
118 
119         pi.dxl = (vpl[n_right]->x - vpl[n_left]->x) / pi.scale;
120         pi.dyl = (vpl[n_right]->y - vpl[n_left]->y) / pi.scale;
121         pi.x = fix_cint(vpl[n_left]->x);
122         pi.xl = fix_cint(vpl[n_right]->x);
123         if (pi.scan_slope > 0) {
124             x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope));
125             x_min = fix_int(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope)) + 1;
126         } else {
127             x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope));
128             x_min = fix_int(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope)) + 1;
129         }
130         if (pi.x < x_min)
131             pi.x = x_min;
132         if (pi.xl > x_max)
133             pi.xl = x_max;
134         pi.xr0 = pi.xr = pi.xl;
135         pi.cl = fix_mul(pi.dxl, vpl[n_left]->y) - fix_mul(pi.dyl, vpl[n_left]->x);
136         if (pi.x * pi.dyl - fix_mul(fix_make(pi.yp - 1, 0) + pi.x * pi.scan_slope, pi.dxl) + pi.cl < 0) {
137             pi.dyl = -pi.dyl;
138             pi.dxl = -pi.dxl;
139             pi.cl = -pi.cl;
140         }
141         if (pi.scan_slope > 0)
142             pi.dtl = pi.dyl - pi.dxl;
143         else
144             pi.dtl = pi.dyl + pi.dxl;
145 
146         ((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
147 
148         pi.denom += fix_16_20(ps->b), pi.unum += ps->beta_u, pi.vnum += ps->beta_v;
149         yp_min--; /* first line already done */
150     }
151     pi.yp++;
152     while (pi.yp < yp_max) {
153         /* check left edge */
154         if (fix_cint(y_prime[n_left]) <= pi.yp) {
155             int n_prev;
156             fix d;
157             do {
158                 if (fix_cint(y_prime[n_left]) == pi.yp)
159                     n_prev = n_left;
160                 if (--n_left < 0)
161                     n_left = n - 1;
162             } while (fix_cint(y_prime[n_left]) <= pi.yp);
163             yp_left = y_prime[n_prev];
164             x_left = vpl[n_prev]->x;
165             y_left = vpl[n_prev]->y;
166             xl_min = fix_cint(x_left);
167             xl_max = fix_cint(vpl[n_left]->x);
168             pi.dxl = (vpl[n_left]->x - x_left) / pi.scale;
169             pi.dyl = (vpl[n_left]->y - y_left) / pi.scale;
170             pi.cl = fix_mul(pi.dxl, y_left) - fix_mul(pi.dyl, x_left);
171             d = pi.dyl - fix_mul(pi.dxl, pi.scan_slope);
172             dx_left = fix_div(pi.dxl, d);
173             x_left = fix_div(fix_mul(pi.dyl, x_left) + fix_mul(pi.dxl, fix_ceil(yp_left) - y_left), d);
174             if (xl_max < xl_min) {
175                 fix foo = xl_min;
176                 xl_min = xl_max;
177                 xl_max = foo;
178             }
179             if (fix_mul(vpl[n_left]->x - FIX_UNIT, pi.dyl) - fix_mul(vpl[n_left]->y - pi.scan_slope, pi.dxl) + pi.cl <
180                 0) {
181                 pi.dyl = -pi.dyl;
182                 pi.dxl = -pi.dxl;
183                 pi.cl = -pi.cl;
184             }
185             if (pi.scan_slope > 0)
186                 pi.dtl = pi.dyl - pi.dxl;
187             else
188                 pi.dtl = pi.dyl + pi.dxl;
189             yp_left = y_prime[n_left];
190         }
191 
192         /* check right edge */
193         if (fix_cint(y_prime[n_right]) <= pi.yp) {
194             int n_prev;
195             fix d;
196             do {
197                 if (fix_cint(y_prime[n_right]) == pi.yp)
198                     n_prev = n_right;
199                 if (++n_right == n)
200                     n_right = 0;
201             } while (fix_cint(y_prime[n_right]) <= pi.yp);
202             yp_right = y_prime[n_prev];
203             x_right = vpl[n_prev]->x;
204             y_right = vpl[n_prev]->y;
205             xr_min = fix_cint(x_right);
206             xr_max = fix_cint(vpl[n_right]->x);
207             pi.dxr = (vpl[n_right]->x - x_right) / pi.scale;
208             pi.dyr = (vpl[n_right]->y - y_right) / pi.scale;
209             pi.cr = fix_mul(pi.dxr, y_right) - fix_mul(pi.dyr, x_right);
210             d = pi.dyr - fix_mul(pi.dxr, pi.scan_slope);
211             dx_right = fix_div(pi.dxr, d);
212             x_right = fix_div(fix_mul(pi.dyr, x_right) + fix_mul(pi.dxr, fix_ceil(yp_right) - y_right), d);
213             if (xr_max < xr_min) {
214                 fix foo = xr_min;
215                 xr_min = xr_max;
216                 xr_max = foo;
217             }
218             if (fix_mul(vpl[n_right]->x - FIX_UNIT, pi.dyr) - fix_mul(vpl[n_right]->y - pi.scan_slope, pi.dxr) + pi.cr <
219                 0) {
220                 pi.dyr = -pi.dyr;
221                 pi.dxr = -pi.dxr;
222                 pi.cr = -pi.cr;
223             }
224             if (pi.scan_slope > 0)
225                 pi.dtr = pi.dyr - pi.dxr;
226             else
227                 pi.dtr = pi.dyr + pi.dxr;
228             yp_right = y_prime[n_right];
229         }
230         yp_next = (yp_right < yp_left) ? fix_cint(yp_right) : fix_cint(yp_left);
231 
232         /* do 0th scanline if at yp_min */
233         if (pi.yp == yp_min) {
234             x_left -= dx_left;
235             x_right -= dx_right;
236             pi.yp--;
237         }
238         for (; pi.yp < yp_next; pi.yp++) {
239             if ((pi.yp + 1 == yp_max) && (n_left != n_right)) {
240                 pi.dxl = (vpl[n_right]->x - vpl[n_left]->x) / pi.scale;
241                 pi.dyl = (vpl[n_right]->y - vpl[n_left]->y) / pi.scale;
242                 pi.x = fix_cint(vpl[n_left]->x);
243                 pi.xl = fix_cint(vpl[n_right]->x);
244                 if (pi.scan_slope > 0) {
245                     x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope));
246                     x_min = fix_int(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope)) + 1;
247                 } else {
248                     x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope));
249                     x_min = fix_int(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope)) + 1;
250                 }
251                 if (pi.x < x_min)
252                     pi.x = x_min;
253                 if (pi.xl > x_max)
254                     pi.xl = x_max;
255                 pi.xr0 = pi.xr = pi.xl;
256                 pi.cl = fix_mul(pi.dxl, vpl[n_left]->y) - fix_mul(pi.dyl, vpl[n_left]->x);
257                 if (pi.x * pi.dyl - fix_mul(fix_make(pi.yp + 1, 0) + pi.x * pi.scan_slope, pi.dxl) + pi.cl < 0) {
258                     pi.dyl = -pi.dyl;
259                     pi.dxl = -pi.dxl;
260                     pi.cl = -pi.cl;
261                 }
262                 if (pi.scan_slope > 0)
263                     pi.dtl = pi.dyl - pi.dxl;
264                 else
265                     pi.dtl = pi.dyl + pi.dxl;
266 
267                 ((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
268 
269                 pi.yp = yp_max;
270                 break;
271             }
272 
273             if (dx_left > 0) {
274                 pi.x = fix_fint(x_left);
275                 pi.xl = fix_cint(x_left + dx_left);
276             } else {
277                 pi.x = fix_fint(x_left + dx_left);
278                 pi.xl = fix_cint(x_left);
279             }
280             if (dx_right > 0) {
281                 pi.xr0 = fix_fint(x_right);
282                 pi.xr = fix_cint(x_right + dx_right);
283             } else {
284                 pi.xr0 = fix_fint(x_right + dx_right);
285                 pi.xr = fix_cint(x_right);
286             }
287             if (pi.scan_slope > 0) {
288                 x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope));
289                 x_min = fix_int(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope)) + 1;
290             } else {
291                 x_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.top - 1) - pi.yp, 1), pi.scan_slope));
292                 x_min = fix_int(fix_div(fix_make((grd_int_clip.bot - 1) - pi.yp, 1), pi.scan_slope)) + 1;
293             }
294             if (xl_min > x_min)
295                 x_min = xl_min;
296             if (xr_max < x_max)
297                 x_max = xr_max;
298             if (pi.xr > x_max)
299                 pi.xr = x_max;
300             if (pi.xr0 > x_max)
301                 pi.xr0 = x_max;
302             if (pi.xl > pi.xr0)
303                 pi.xl = pi.xr0;
304             if (pi.x < x_min)
305                 pi.x = x_min;
306 
307             ((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
308 
309             x_left += dx_left, x_right += dx_right;
310             pi.denom += fix_16_20(ps->b), pi.unum += ps->beta_u, pi.vnum += ps->beta_v;
311         }
312     }
313 }
314 
gri_per_umap_vscan(grs_bitmap * bm,int n,grs_vertex ** vpl,grs_per_setup * ps)315 void gri_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps) {
316     grs_per_info pi;
317     fix x_prime[10];
318     fix xp_top, xp_bot;
319     fix x_top, x_bot;
320     fix y_top, y_bot;
321     fix dy_top, dy_bot;
322     int xp_min, xp_max, xp_next;
323     int y_min, y_max, yr_min, yr_max, yl_min, yl_max;
324     int n_min, n_top, n_bot;
325     int j;
326 
327     pi.scale = grd_bm.w;
328     pi.scan_slope = ps->scan_slope;
329     pi.dp = ps->dp;
330     pi.clut = ps->clut;
331     if (fix_abs(pi.scan_slope) >= FIX_UNIT)
332         return;
333 
334     if (bm->row != 1 << (bm->wlog))
335         return;
336     if (bm->h != 1 << (bm->hlog))
337         return;
338     pi.u_mask = bm->row - 1;
339     pi.v_mask = (bm->h - 1) << bm->wlog;
340     pi.v_shift = 16 - bm->wlog;
341 
342     xp_min = xp_max = fix_cint(x_prime[n_min = 0] = vpl[0]->x - fix_mul(vpl[0]->y, ps->scan_slope));
343     for (j = 1; j < n; j++) {
344         pi.xp = fix_cint(x_prime[j] = vpl[j]->x - fix_mul(vpl[j]->y, ps->scan_slope));
345         if (pi.xp < xp_min) {
346             xp_min = pi.xp;
347             n_min = j;
348         }
349         if (pi.xp > xp_max)
350             xp_max = pi.xp;
351     }
352     if (xp_max == xp_min)
353         return;
354     pi.denom = fix_16_20(ps->c + fix_mul(ps->a, x_prime[0]));
355     pi.u0 =
356         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);
357     pi.v0 =
358         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);
359 
360     n_top = n_bot = n_min;
361     pi.xp = xp_min;
362     while (fix_cint(x_prime[(n_top + 1) % n]) == pi.xp)
363         n_top = (n_top + 1) % n;
364     while (fix_cint(x_prime[(n_bot + n - 1) % n]) == pi.xp)
365         n_bot = (n_bot + n - 1) % n;
366 
367     pi.xp--;
368     pi.denom = fix_16_20(ps->c + pi.xp * ps->a);
369     pi.unum = ps->gamma_u + ps->alpha_u * pi.xp;
370     pi.dunum = ps->beta_u + fix_mul(ps->scan_slope, ps->alpha_u);
371     pi.vnum = ps->gamma_v + ps->alpha_v * pi.xp;
372     pi.dvnum = ps->beta_v + fix_mul(ps->scan_slope, ps->alpha_v);
373 
374     if (n_bot != n_top) {
375 
376         pi.dxl = (vpl[n_bot]->x - vpl[n_top]->x) / pi.scale;
377         pi.dyl = (vpl[n_bot]->y - vpl[n_top]->y) / pi.scale;
378         pi.y = fix_cint(vpl[n_top]->y);
379         pi.yl = fix_cint(vpl[n_bot]->y);
380         if (pi.scan_slope > 0) {
381             y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope));
382             y_min = fix_int(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope)) + 1;
383         } else {
384             y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope));
385             y_min = fix_int(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope)) + 1;
386         }
387         if (pi.y < y_min)
388             pi.y = y_min;
389         if (pi.yl > y_max)
390             pi.yl = y_max;
391         pi.yr0 = pi.yr = pi.yl;
392 
393         pi.cl = -fix_mul(pi.dxl, vpl[n_top]->y) + fix_mul(pi.dyl, vpl[n_top]->x);
394         if (pi.y * pi.dxl - fix_mul(fix_make(pi.xp - 1, 0) + pi.y * pi.scan_slope, pi.dyl) + pi.cl < 0) {
395             pi.dyl = -pi.dyl;
396             pi.dxl = -pi.dxl;
397             pi.cl = -pi.cl;
398         }
399         if (pi.scan_slope > 0)
400             pi.dtl = pi.dxl - pi.dyl;
401         else
402             pi.dtl = pi.dyl + pi.dxl;
403 
404         ((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
405 
406         pi.denom += fix_16_20(ps->a), pi.unum += ps->alpha_u, pi.vnum += ps->alpha_v;
407         xp_min--; /* first line already done */
408     }
409     pi.xp++;
410     while (pi.xp < xp_max) {
411         /* check top edge */
412         if (fix_cint(x_prime[n_top]) <= pi.xp) {
413             int n_prev;
414             fix d;
415             do {
416                 if (fix_cint(x_prime[n_top]) == pi.xp)
417                     n_prev = n_top;
418                 if (++n_top == n)
419                     n_top = 0;
420             } while (fix_cint(x_prime[n_top]) <= pi.xp);
421             xp_top = x_prime[n_prev];
422             x_top = vpl[n_prev]->x;
423             y_top = vpl[n_prev]->y;
424             yl_min = fix_cint(y_top);
425             yl_max = fix_cint(vpl[n_top]->y);
426             pi.dxl = (vpl[n_top]->x - x_top) / pi.scale;
427             pi.dyl = (vpl[n_top]->y - y_top) / pi.scale;
428             pi.cl = -fix_mul(pi.dxl, y_top) + fix_mul(pi.dyl, x_top);
429             d = pi.dxl - fix_mul(pi.dyl, pi.scan_slope);
430             dy_top = fix_div(pi.dyl, d);
431             y_top = fix_div(fix_mul(pi.dxl, y_top) + fix_mul(pi.dyl, fix_ceil(xp_top) - x_top), d);
432             if (yl_max < yl_min) {
433                 fix foo = yl_min;
434                 yl_min = yl_max;
435                 yl_max = foo;
436             }
437             if (fix_mul(vpl[n_top]->y - FIX_UNIT, pi.dxl) - fix_mul(vpl[n_top]->x - pi.scan_slope, pi.dyl) + pi.cl <
438                 0) {
439                 pi.dyl = -pi.dyl;
440                 pi.dxl = -pi.dxl;
441                 pi.cl = -pi.cl;
442             }
443             if (pi.scan_slope > 0)
444                 pi.dtl = pi.dxl - pi.dyl;
445             else
446                 pi.dtl = pi.dyl + pi.dxl;
447             xp_top = x_prime[n_top];
448         }
449 
450         /* check bot edge */
451         if (fix_cint(x_prime[n_bot]) <= pi.xp) {
452             int n_prev;
453             fix d;
454             do {
455                 if (fix_cint(x_prime[n_bot]) == pi.xp)
456                     n_prev = n_bot;
457                 if (--n_bot < 0)
458                     n_bot = n - 1;
459             } while (fix_cint(x_prime[n_bot]) <= pi.xp);
460             xp_bot = x_prime[n_prev];
461             x_bot = vpl[n_prev]->x;
462             y_bot = vpl[n_prev]->y;
463             yr_min = fix_cint(y_bot);
464             yr_max = fix_cint(vpl[n_bot]->y);
465             pi.dxr = (vpl[n_bot]->x - x_bot) / pi.scale;
466             pi.dyr = (vpl[n_bot]->y - y_bot) / pi.scale;
467             pi.cr = -fix_mul(pi.dxr, y_bot) + fix_mul(pi.dyr, x_bot);
468             d = pi.dxr - fix_mul(pi.dyr, pi.scan_slope);
469             dy_bot = fix_div(pi.dyr, d);
470             y_bot = fix_div(fix_mul(pi.dxr, y_bot) + fix_mul(pi.dyr, fix_ceil(xp_bot) - x_bot), d);
471             if (yr_max < yr_min) {
472                 fix foo = yr_min;
473                 yr_min = yr_max;
474                 yr_max = foo;
475             }
476             if (fix_mul(vpl[n_bot]->y - FIX_UNIT, pi.dxr) - fix_mul(vpl[n_bot]->x - pi.scan_slope, pi.dyr) + pi.cr <
477                 0) {
478                 pi.dyr = -pi.dyr;
479                 pi.dxr = -pi.dxr;
480                 pi.cr = -pi.cr;
481             }
482             if (pi.scan_slope > 0)
483                 pi.dtr = pi.dxr - pi.dyr;
484             else
485                 pi.dtr = pi.dyr + pi.dxr;
486             xp_bot = x_prime[n_bot];
487         }
488         xp_next = (xp_bot < xp_top) ? fix_cint(xp_bot) : fix_cint(xp_top);
489 
490         /* do 0th scanline if at xp_min */
491         if (pi.xp == xp_min) {
492             y_top -= dy_top;
493             y_bot -= dy_bot;
494             pi.xp--;
495         }
496         for (; pi.xp < xp_next; pi.xp++) {
497             if ((pi.xp + 1 == xp_max) && (n_top != n_bot)) {
498                 pi.dxl = (vpl[n_bot]->x - vpl[n_top]->x) / pi.scale;
499                 pi.dyl = (vpl[n_bot]->y - vpl[n_top]->y) / pi.scale;
500                 pi.y = fix_cint(vpl[n_top]->y);
501                 pi.yl = fix_cint(vpl[n_bot]->y);
502                 if (pi.scan_slope > 0) {
503                     y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope));
504                     y_min = fix_int(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope)) + 1;
505                 } else {
506                     y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope));
507                     y_min = fix_int(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope)) + 1;
508                 }
509                 if (pi.y < y_min)
510                     pi.y = y_min;
511                 if (pi.yl > y_max)
512                     pi.yl = y_max;
513                 pi.yr0 = pi.yr = pi.yl;
514                 pi.cl = -fix_mul(pi.dxl, vpl[n_top]->y) + fix_mul(pi.dyl, vpl[n_top]->x);
515                 if (pi.y * pi.dxl - fix_mul(fix_make(pi.xp + 1, 0) + pi.y * pi.scan_slope, pi.dyl) + pi.cl < 0) {
516                     pi.dyl = -pi.dyl;
517                     pi.dxl = -pi.dxl;
518                     pi.cl = -pi.cl;
519                 }
520                 if (pi.scan_slope > 0)
521                     pi.dtl = pi.dxl - pi.dyl;
522                 else
523                     pi.dtl = pi.dyl + pi.dxl;
524 
525                 ((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
526 
527                 pi.xp = xp_max;
528                 break;
529             }
530 
531             if (dy_top > 0) {
532                 pi.y = fix_fint(y_top);
533                 pi.yl = fix_cint(y_top + dy_top);
534             } else {
535                 pi.y = fix_fint(y_top + dy_top);
536                 pi.yl = fix_cint(y_top);
537             }
538             if (dy_bot > 0) {
539                 pi.yr0 = fix_fint(y_bot);
540                 pi.yr = fix_cint(y_bot + dy_bot);
541             } else {
542                 pi.yr0 = fix_fint(y_bot + dy_bot);
543                 pi.yr = fix_cint(y_bot);
544             }
545             if (pi.scan_slope > 0) {
546                 y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope));
547                 y_min = fix_int(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope)) + 1;
548             } else {
549                 y_max = safe_fix_cint(fix_div(fix_make((grd_int_clip.left - 1) - pi.xp, 1), pi.scan_slope));
550                 y_min = fix_int(fix_div(fix_make((grd_int_clip.right - 1) - pi.xp, 1), pi.scan_slope)) + 1;
551             }
552             if (yl_min > y_min)
553                 y_min = yl_min;
554             if (yr_max < y_max)
555                 y_max = yr_max;
556             if (pi.yr > y_max)
557                 pi.yr = y_max;
558             if (pi.yr0 > y_max)
559                 pi.yr0 = y_max;
560             if (pi.yl > pi.yr0)
561                 pi.yl = pi.yr0;
562             if (pi.y < y_min)
563                 pi.y = y_min;
564 
565             ((void (*)(grs_per_info *, grs_bitmap *))(ps->scanline_func))(&pi, bm);
566 
567             y_top += dy_top, y_bot += dy_bot;
568             pi.denom += fix_16_20(ps->a), pi.unum += ps->alpha_u, pi.vnum += ps->alpha_v;
569         }
570     }
571 }
572