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