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