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/FL8ltp.c $
21  * $Revision: 1.2 $
22  * $Author: kevin $
23  * $Date: 1994/08/16 12:57:21 $
24  *
25  * lit full perspective texture mapper.
26  * scanline processors.
27  *
28  */
29 
30 #include "cnvdat.h"
31 #include "fl8tmapdv.h"
32 #include "pertyp.h"
33 #include "plytyp.h"
34 #include "scrdat.h"
35 #include "tmapint.h"
36 
37 // prototypes
38 void gri_trans_lit_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm);
39 void gri_trans_lit_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm);
40 void gri_trans_lit_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
41 void gri_trans_lit_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
42 
gri_trans_lit_per_umap_hscan_scanline(grs_per_info * pi,grs_bitmap * bm)43 void gri_trans_lit_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
44     register int k, y_cint;
45     uchar *ltab = grd_screen->ltab;
46 
47     // locals used to speed PPC code
48     fix test;
49     fix l_u, l_v, l_du, l_dv, l_y_fix, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr, l_i, l_di;
50     int l_x, l_xl, l_xr, l_xr0, l_u_mask, l_v_mask, l_v_shift;
51     int gr_row, temp_y;
52     uchar *bm_bits, *p;
53 
54     gr_row = grd_bm.row;
55     bm_bits = bm->bits;
56     l_di = pi->di;
57     l_i = pi->i;
58     l_dyr = pi->dyr;
59     l_dtr = pi->dtr;
60     l_dyl = pi->dyl;
61     l_dxl = pi->dxl;
62     l_dtl = pi->dtl;
63     l_scan_slope = pi->scan_slope;
64     l_y_fix = pi->y_fix;
65     l_v_shift = pi->v_shift;
66     l_v_mask = pi->v_mask;
67     l_u_mask = pi->u_mask;
68     l_xr0 = pi->xr0;
69     l_x = pi->x;
70     l_xl = pi->xl;
71     l_xr = pi->xr;
72     l_u = pi->u;
73     l_v = pi->v;
74     l_du = pi->du;
75     l_dv = pi->dv;
76 
77     l_y_fix = l_x * l_scan_slope + fix_make(pi->yp, 0xffff);
78 
79 #if InvDiv
80     k = fix_div(fix_make(1, 0), pi->denom);
81     l_u = pi->u0 + fix_mul_asm_safe(pi->unum, k);
82     l_v = pi->v0 + fix_mul_asm_safe(pi->vnum, k);
83     l_du = fix_mul_asm_safe(pi->dunum, k);
84     l_dv = fix_mul_asm_safe(pi->dvnum, k);
85 #else
86     l_u = pi->u0 + fix_div(pi->unum, pi->denom);
87     l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
88     l_du = fix_div(pi->dunum, pi->denom);
89     l_dv = fix_div(pi->dvnum, pi->denom);
90 #endif
91 
92     l_u += l_x * l_du;
93     l_v += l_x * l_dv;
94 
95     y_cint = fix_int(l_y_fix);
96     if (l_scan_slope < 0)
97         gr_row = -gr_row;
98 
99     p = grd_bm.bits + l_x + y_cint * grd_bm.row;
100     if (l_x < l_xl) {
101         test = l_x * l_dyl - y_cint * l_dxl + pi->cl;
102         for (; l_x < l_xl; l_x++) {
103             if (test <= 0) {
104                 k = (l_u >> 16) & l_u_mask;
105                 k += (l_v >> l_v_shift) & l_v_mask;
106                 k = bm_bits[k];
107                 if (k)
108                     *p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],l_x,y_cint);
109             }
110 
111             temp_y = y_cint;
112             y_cint = fix_int(l_y_fix += l_scan_slope);
113             if (temp_y != y_cint) {
114                 p += gr_row;
115                 test += l_dtl;
116             } else
117                 test += l_dyl;
118 
119             p++;
120             l_u += l_du;
121             l_v += l_dv;
122             l_i += l_di;
123         }
124     }
125 
126     for (; l_x < l_xr0; l_x++) {
127         k = (l_u >> 16) & l_u_mask;
128         k += (l_v >> l_v_shift) & l_v_mask;
129         k = bm_bits[k];
130         if (k)
131             *p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],l_x,y_cint);
132 
133         temp_y = y_cint;
134         y_cint = fix_int(l_y_fix += l_scan_slope);
135         if (temp_y != y_cint)
136             p += gr_row;
137 
138         p++;
139         l_u += l_du;
140         l_v += l_dv;
141         l_i += l_di;
142     }
143 
144     if (l_x < l_xr) {
145         test = l_x * l_dyr - y_cint * pi->dxr + pi->cr;
146         p = grd_bm.bits + l_x + y_cint * grd_bm.row;
147         for (; l_x < l_xr; l_x++) {
148             if (test >= 0) {
149                 k = (l_u >> 16) & l_u_mask;
150                 k += (l_v >> l_v_shift) & l_v_mask;
151                 k = bm_bits[k];
152                 if (k)
153                     *p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],l_x,y_cint);
154             }
155 
156             temp_y = y_cint;
157             y_cint = fix_int(l_y_fix += l_scan_slope);
158             if (temp_y != y_cint) {
159                 p += gr_row;
160                 test += l_dtr;
161             } else
162                 test += l_dyr;
163 
164             p++;
165             l_u += l_du;
166             l_v += l_dv;
167             l_i += l_di;
168         }
169     }
170 
171     pi->y_fix = l_y_fix;
172     pi->x = l_x;
173     pi->u = l_u;
174     pi->v = l_v;
175     pi->du = l_du;
176     pi->dv = l_dv;
177     pi->di = l_di;
178     pi->i = l_i;
179 }
180 
gri_trans_lit_per_umap_vscan_scanline(grs_per_info * pi,grs_bitmap * bm)181 void gri_trans_lit_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
182     register int k, x_cint;
183     uchar *ltab = grd_screen->ltab;
184 
185     // locals used to speed PPC code
186     fix test;
187     fix l_dxr, l_x_fix, l_u, l_v, l_du, l_dv, l_scan_slope, l_dtl, l_dxl, l_dyl, l_dtr, l_dyr, l_i, l_di;
188     int l_yl, l_yr0, l_yr, l_y, l_u_mask, l_v_mask, l_v_shift;
189     int gr_row, temp_x;
190     uchar *bm_bits;
191     uchar *p;
192 
193     gr_row = grd_bm.row;
194     bm_bits = bm->bits;
195     l_di = pi->di;
196     l_i = pi->i;
197     l_dxr = pi->dxr;
198     l_x_fix = pi->x_fix;
199     l_y = pi->y;
200     l_yr = pi->yr;
201     l_yr0 = pi->yr0;
202     l_yl = pi->yl;
203     l_dyr = pi->dyr;
204     l_dtr = pi->dtr;
205     l_dyl = pi->dyl;
206     l_dxl = pi->dxl;
207     l_dtl = pi->dtl;
208     l_scan_slope = pi->scan_slope;
209     l_v_shift = pi->v_shift;
210     l_v_mask = pi->v_mask;
211     l_u_mask = pi->u_mask;
212     l_u = pi->u;
213     l_v = pi->v;
214     l_du = pi->du;
215     l_dv = pi->dv;
216 
217     l_x_fix = l_y * l_scan_slope + fix_make(pi->xp, 0xffff);
218 
219 #if InvDiv
220     k = fix_div(fix_make(1, 0), pi->denom);
221     l_u = pi->u0 + fix_mul_asm_safe(pi->unum, k);
222     l_v = pi->v0 + fix_mul_asm_safe(pi->vnum, k);
223     l_du = fix_mul_asm_safe(pi->dunum, k);
224     l_dv = fix_mul_asm_safe(pi->dvnum, k);
225 #else
226     l_u = pi->u0 + fix_div(pi->unum, pi->denom);
227     l_v = pi->v0 + fix_div(pi->vnum, pi->denom);
228     l_du = fix_div(pi->dunum, pi->denom);
229     l_dv = fix_div(pi->dvnum, pi->denom);
230 #endif
231 
232     l_u += l_y * l_du;
233     l_v += l_y * l_dv;
234 
235     x_cint = fix_int(l_x_fix);
236     p = grd_bm.bits + x_cint + l_y * gr_row;
237     if (l_y < l_yl) {
238         test = l_y * l_dxl - x_cint * l_dyl + pi->cl;
239         for (; l_y < l_yl; l_y++) {
240             if (test <= 0) {
241                 k = (l_u >> 16) & l_u_mask;
242                 k += (l_v >> l_v_shift) & l_v_mask;
243                 k = bm_bits[k];
244                 if (k)
245                     *p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],x_cint,l_y);
246             }
247 
248             temp_x = x_cint;
249             x_cint = fix_int(l_x_fix += l_scan_slope);
250             if (temp_x != x_cint) {
251                 test += l_dtl;
252                 p -= (temp_x - x_cint);
253             } else
254                 test += l_dxl;
255 
256             p += gr_row;
257             l_u += l_du;
258             l_v += l_dv;
259             l_i += l_di;
260         }
261     }
262 
263     for (; l_y < l_yr0; l_y++) {
264         k = (l_u >> 16) & l_u_mask;
265         k += (l_v >> l_v_shift) & l_v_mask;
266         k = bm_bits[k];
267         if (k)
268             *p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],x_cint,l_y);
269 
270         temp_x = x_cint;
271         x_cint = fix_int(l_x_fix += l_scan_slope);
272         if (temp_x != x_cint)
273             p -= (temp_x - x_cint);
274 
275         p += gr_row;
276         l_u += l_du;
277         l_v += l_dv;
278         l_i += l_di;
279     }
280 
281     if (l_y < l_yr) {
282         test = l_y * l_dxr - x_cint * l_dyr + pi->cr;
283         p = grd_bm.bits + x_cint + l_y * gr_row;
284         for (; l_y < l_yr; l_y++) {
285             if (test >= 0) {
286                 k = (l_u >> 16) & l_u_mask;
287                 k += (l_v >> l_v_shift) & l_v_mask;
288                 k = bm_bits[k];
289                 if (k)
290                     *p = ltab[(fix_light(l_i)) + k]; // gr_fill_upixel(ltab[(fix_int(l_i)<<8)+k],x_cint,l_y);
291             }
292 
293             temp_x = x_cint;
294             x_cint = fix_int(l_x_fix += l_scan_slope);
295             if (temp_x != x_cint) {
296                 test += l_dtr;
297                 p -= (temp_x - x_cint);
298             } else
299                 test += l_dxr;
300 
301             p += gr_row;
302             l_u += l_du;
303             l_v += l_dv;
304             l_i += l_di;
305         }
306     }
307 
308     pi->x_fix = l_x_fix;
309     pi->y = l_y;
310     pi->u = l_u;
311     pi->v = l_v;
312     pi->du = l_du;
313     pi->dv = l_dv;
314     pi->di = l_di;
315     pi->i = l_i;
316 }
317 
318 extern void gri_lit_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
319 extern void gri_lit_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
320 
gri_trans_lit_per_umap_hscan_init(grs_bitmap * bm,grs_per_setup * ps)321 void gri_trans_lit_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps) {
322     ps->shell_func = (void (*)())gri_lit_per_umap_hscan;
323     ps->scanline_func = (void (*)())gri_trans_lit_per_umap_hscan_scanline;
324 }
325 
gri_trans_lit_per_umap_vscan_init(grs_bitmap * bm,grs_per_setup * ps)326 void gri_trans_lit_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps) {
327     ps->shell_func = (void (*)())gri_lit_per_umap_vscan;
328     ps->scanline_func = (void (*)())gri_trans_lit_per_umap_vscan_scanline;
329 }
330