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