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