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