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