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/gencop.c $
21 * $Revision: 1.2 $
22 * $Author: kevin $
23 * $Date: 1994/08/16 12:56:46 $
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_opaque_clut_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm);
37 void gri_opaque_clut_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm);
38 void gri_opaque_clut_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps);
39 void gri_opaque_clut_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps);
40
gri_opaque_clut_per_umap_hscan_scanline(grs_per_info * pi,grs_bitmap * bm)41 void gri_opaque_clut_per_umap_hscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
42 register int k, y_cint;
43 uchar *p;
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 uchar *t_clut;
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
94 if (l_scan_slope < 0)
95 gr_row = -gr_row;
96
97 p = grd_bm.bits + l_x + y_cint * grd_bm.row;
98 if (l_x < l_xl) {
99 fix test = l_x * l_dyl - y_cint * l_dxl + pi->cl;
100 for (; l_x < l_xl; l_x++) {
101 if (test <= 0) {
102 k = (l_u >> 16) & l_u_mask;
103 k += (l_v >> l_v_shift) & l_v_mask;
104 *p = t_clut[bm_bits[k]]; // gr_fill_upixel(t_clut[bm_bits[k]],l_x,y_cint);
105 }
106 temp_y = y_cint;
107 y_cint = fix_int(l_y_fix += l_scan_slope);
108
109 if (temp_y != y_cint) {
110 p += gr_row;
111 test += l_dtl;
112 } else
113 test += l_dyl;
114
115 p++;
116 l_u += l_du;
117 l_v += l_dv;
118 }
119 }
120
121 for (; l_x < l_xr0; l_x++) {
122 k = (l_u >> 16) & l_u_mask;
123 k += (l_v >> l_v_shift) & l_v_mask;
124 *(p++) = t_clut[bm_bits[k]]; // gr_fill_upixel(t_clut[bm_bits[k]],l_x,y_cint);
125 temp_y = y_cint;
126 y_cint = fix_int(l_y_fix += l_scan_slope);
127 if (temp_y != y_cint)
128 p += gr_row;
129
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 k = (l_u >> 16) & l_u_mask;
140 k += (l_v >> l_v_shift) & l_v_mask;
141 *p = t_clut[bm_bits[k]]; // gr_fill_upixel(t_clut[bm_bits[k]],l_x,y_cint);
142 }
143 temp_y = y_cint;
144 y_cint = fix_int(l_y_fix += l_scan_slope);
145 if (temp_y != y_cint) {
146 p += gr_row;
147 test += l_dtr;
148 } else
149 test += l_dyr;
150
151 p++;
152 l_u += l_du;
153 l_v += l_dv;
154 }
155 }
156
157 pi->y_fix = l_y_fix;
158 pi->x = l_x;
159 pi->u = l_u;
160 pi->v = l_v;
161 pi->du = l_du;
162 pi->dv = l_dv;
163 }
164
gri_opaque_clut_per_umap_vscan_scanline(grs_per_info * pi,grs_bitmap * bm)165 void gri_opaque_clut_per_umap_vscan_scanline(grs_per_info *pi, grs_bitmap *bm) {
166 register int k, x_cint;
167
168 // locals used to speed PPC code
169 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;
170 int l_yl, l_yr0, l_yr, l_y, l_u_mask, l_v_mask, l_v_shift;
171 int gr_row, temp_x;
172 uchar *bm_bits;
173 uchar *p;
174 uchar *t_clut;
175
176 t_clut = pi->clut;
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 l_u += l_y * l_du;
214 l_v += l_y * l_dv;
215
216 x_cint = fix_int(l_x_fix);
217 p = grd_bm.bits + x_cint + l_y * gr_row;
218 if (l_y < l_yl) {
219 fix test = l_y * l_dxl - x_cint * l_dyl + pi->cl;
220 for (; l_y < l_yl; l_y++) {
221 if (test <= 0) {
222 k = (l_u >> 16) & l_u_mask;
223 k += (l_v >> l_v_shift) & l_v_mask;
224 *p = t_clut[bm_bits[k]]; // gr_fill_upixel(t_clut[bm_bits[k]],x_cint,l_y);
225 }
226 temp_x = x_cint;
227 x_cint = fix_int(l_x_fix += l_scan_slope);
228 if (temp_x != x_cint) {
229 test += l_dtl;
230 p -= (temp_x - x_cint);
231 } else
232 test += l_dxl;
233
234 p += gr_row;
235 l_u += l_du;
236 l_v += l_dv;
237 }
238 }
239
240 for (; l_y < l_yr0; l_y++) {
241 k = (l_u >> 16) & l_u_mask;
242 k += (l_v >> l_v_shift) & l_v_mask;
243 *p = t_clut[bm_bits[k]]; // gr_fill_upixel(t_clut[bm_bits[k]],x_cint,l_y);
244
245 temp_x = x_cint;
246 x_cint = fix_int(l_x_fix += l_scan_slope);
247 if (temp_x != x_cint)
248 p -= (temp_x - x_cint);
249
250 p += gr_row;
251 l_u += l_du;
252 l_v += l_dv;
253 }
254
255 if (l_y < l_yr) {
256 fix test = l_y * l_dxr - x_cint * l_dyr + pi->cr;
257 p = grd_bm.bits + x_cint + l_y * gr_row;
258 for (; l_y < l_yr; l_y++) {
259 if (test >= 0) {
260 k = (l_u >> 16) & l_u_mask;
261 k += (l_v >> l_v_shift) & l_v_mask;
262 *p = t_clut[bm_bits[k]]; // gr_fill_upixel(t_clut[bm_bits[k]],x_cint,l_y);
263 }
264
265 temp_x = x_cint;
266 x_cint = fix_int(l_x_fix += l_scan_slope);
267 if (temp_x != x_cint) {
268 test += l_dtr;
269 p -= (temp_x - x_cint);
270 } else
271 test += l_dxr;
272
273 p += gr_row;
274 l_u += l_du;
275 l_v += l_dv;
276 }
277 }
278
279 pi->x_fix = l_x_fix;
280 pi->y = l_y;
281 pi->u = l_u;
282 pi->v = l_v;
283 pi->du = l_du;
284 pi->dv = l_dv;
285 }
286
287 extern void gri_per_umap_hscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
288 extern void gri_per_umap_vscan(grs_bitmap *bm, int n, grs_vertex **vpl, grs_per_setup *ps);
289
gri_opaque_clut_per_umap_hscan_init(grs_bitmap * bm,grs_per_setup * ps)290 void gri_opaque_clut_per_umap_hscan_init(grs_bitmap *bm, grs_per_setup *ps) {
291 ps->shell_func = (void (*)())gri_per_umap_hscan;
292 ps->scanline_func = (void (*)())gri_opaque_clut_per_umap_hscan_scanline;
293 }
294
gri_opaque_clut_per_umap_vscan_init(grs_bitmap * bm,grs_per_setup * ps)295 void gri_opaque_clut_per_umap_vscan_init(grs_bitmap *bm, grs_per_setup *ps) {
296 ps->shell_func = (void (*)())gri_per_umap_vscan;
297 ps->scanline_func = (void (*)())gri_opaque_clut_per_umap_vscan_scanline;
298 }
299