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 // $Source: r:/prj/lib/src/3d/RCS/tmap.asm $
20 // $Revision: 1.30 $
21 // $Author: jaemz $
22 // $Date: 1994/09/06 00:12:15 $
23 //
24 // Texture mappers
25 //
26 // $Log: tmap.asm $
27 // Revision 1.30 1994/09/06 00:12:15 jaemz
28 // Externed vbuf2 and nvert so we can peek at them later
29 //
30 // Revision 1.29 1994/08/18 03:47:36 jaemz
31 // added underscore for c to stereo globvs
32 //
33 // Revision 1.28 1994/08/16 18:37:43 kevin
34 // moved constants to 2d.inc. Modified code for compatability with new 2d.
35 //
36 // Revision 1.27 1994/08/04 16:36:36 jaemz
37 // *** empty log message ***
38 //
39 // Revision 1.26 1994/07/21 22:44:46 jaemz
40 // arrrgh
41 //
42 // Revision 1.25 1994/07/19 13:48:47 jaemz
43 // Added support for stereo
44 //
45 // Revision 1.24 1994/07/06 22:37:14 kevin
46 // use per_umap directly instead of going through canvas table.
47 //
48 // Revision 1.23 1994/05/19 09:41:20 kevin
49 // g3_light(draw)_t(l,floor_,wall_)map now use watcom register passing
50 // conventions. All perspective maps pass linearity tests. Non/power/of/2
51 // bitmaps are punted (for now). Point copy loop has been somewhat optimized.
52 //
53 // Revision 1.22 1994/05/04 18:46:44 kevin
54 // Do clut lighting check correctly. Check floors and full perspective
55 // tmaps for linearity.
56 //
57 // Revision 1.21 1994/05/02 23:00:52 kevin
58 // Added support for wall and floor specific texture maps.
59 //
60 // Revision 1.20 1993/12/27 21:29:32 kevin
61 // Hacked in rsd support.
62 //
63 // Revision 1.19 1993/12/04 12:44:22 kevin
64 // Changed 2d calls to conform to new icanvas.inc.
65 //
66 // Revision 1.18 1993/10/25 16:28:48 kaboom
67 // Same bug as last time for g3_draw_tmap.
68 //
69 // Revision 1.17 1993/10/22 12:58:02 kaboom
70 // Fixed bug in quad_tile routines---was losing pointer to vertices.
71 //
72 // Revision 1.16 1993/10/22 09:35:26 kaboom
73 // Added new linear map routines.
74 //
75 // Revision 1.15 1993/10/13 13:38:05 kevin
76 // Changed copy_loop to scale to full bitmap; hopefully without causing
77 // wrapping.
78 //
79 // Revision 1.14 1993/10/03 10:20:30 kaboom
80 // Fixed 2 register saving bugs. Also cleanup up code a little.
81 //
82 // Revision 1.13 1993/10/02 11:02:07 kaboom
83 // Changed names of clip_{line,polygon} to g3_clip_{line,polygon} to avoid
84 // name collisions.
85 //
86 // Revision 1.12 1993/10/02 09:29:54 kaboom
87 // Now calls uv versions of 2d primitives.
88 //
89 // Revision 1.11 1993/08/11 15:02:14 kaboom
90 // Added support for lighting texture mappers.
91 //
92 // Revision 1.10 1993/08/10 22:54:27 dc
93 // add _3d.inc to includes
94 //
95 // Revision 1.9 1993/07/08 23:37:54 kaboom
96 // Changed old use of align field in grs_bitmap to new wlog and hlog.
97 //
98 // Revision 1.8 1993/06/16 14:05:06 kaboom
99 // Replaced code for tiling in calc_warp_matrix accidentally deleted in
100 // last revision.
101 //
102 // Revision 1.7 1993/06/15 19:00:49 kaboom
103 // Fixed overflow and scaling problems with warp matrix calculation.
104 //
105 // Revision 1.6 1993/06/09 15:34:29 kaboom
106 // Fixed non-initialization of codes for g3_draw_tmap_tile, which
107 // sometimes caused massive destruction.
108 //
109 // Revision 1.5 1993/06/09 04:24:25 kaboom
110 // Changed g3_draw_tmap_tile to take basis vectors instead of texture map
111 // width and height.
112 //
113 // Revision 1.4 1993/05/11 15:24:21 matt
114 // Changed g3_draw_tmap_tile() to reuse warp matrix if anchor==0
115 //
116 // Revision 1.3 1993/05/11 15:02:00 matt
117 // Fixed an overflow problem in the warp matrix setup
118 //
119 // Revision 1.2 1993/05/10 15:07:51 matt
120 // Fixed g3_draw_tmap_quad_tile(), which didn't do divide for width and height
121 // count, so always acted like w,h=1,1.
122 //
123 // Revision 1.1 1993/05/04 17:39:54 matt
124 // Initial revision
125 //
126
127 #include "3d.h"
128 #include "GlobalV.h"
129 #include "lg.h"
130
131 extern void per_umap(grs_bitmap *bm, int n, grs_vertex **vpl, grs_tmap_info *ti);
132 extern void h_umap(grs_bitmap *bm, int n, grs_vertex **vpl, grs_tmap_info *ti);
133 extern void v_umap(grs_bitmap *bm, int n, grs_vertex **vpl, grs_tmap_info *ti);
134
135 // prototypes
136 int do_tmap_tile(g3s_phandle upperleft, g3s_vector *u_vec, g3s_vector *v_vec, int nverts, g3s_phandle *vp,
137 grs_bitmap *bm);
138 int do_check_tmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count);
139 int do_tmap(int n, g3s_phandle *vp, grs_bitmap *bm);
140 int do_tmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count);
141 void calc_warp_matrix2(g3s_phandle upperleft, fix x10, fix x20, fix y10, fix y20, fix z10, fix z20, grs_bitmap *bm);
142 int draw_tmap_common(int n, g3s_phandle *vp, grs_bitmap *bm);
143 int check_linear(int w);
144
145 #define _bm_w 8
146 #define _bm_h 10
147
148 void *tmap_func;
149 grs_bitmap unpack_bm;
150 grs_tmap_info ti;
151 grs_tmap_info *ti_ptr = &ti;
152
153 // matrix for 2d
154 fix warp[9];
155
156 long light_flag;
157
158 // arrays of point handles, used in clipping
159 extern g3s_phandle vbuf[];
160 extern g3s_phandle _vbuf2[];
161
162 // array of 2d points
163 extern grs_vertex p_vlist[];
164 extern grs_vertex *p_vpl[];
165 extern long _n_verts;
166
167 // tiles a texture map over an arbitarary polygon.
168 // takes eax=upperleft, ebx=width, ecx=height, edx=nverts, esi=ptr to points,
169 // edi=ptr to bitmap
g3_draw_lmap_tile(g3s_phandle upperleft,g3s_vector * u_vec,g3s_vector * v_vec,int nverts,g3s_phandle * vp,grs_bitmap * bm)170 int g3_draw_lmap_tile(g3s_phandle upperleft, g3s_vector *u_vec, g3s_vector *v_vec, int nverts, g3s_phandle *vp,
171 grs_bitmap *bm) {
172 tmap_func = (void *)&h_umap;
173 ti.tmap_type = GRC_BILIN;
174 ti.flags = 0;
175 light_flag = 0;
176 return (do_tmap_tile(upperleft, u_vec, v_vec, nverts, vp, bm));
177 }
178
g3_light_lmap_tile(g3s_phandle upperleft,g3s_vector * u_vec,g3s_vector * v_vec,int nverts,g3s_phandle * vp,grs_bitmap * bm)179 int g3_light_lmap_tile(g3s_phandle upperleft, g3s_vector *u_vec, g3s_vector *v_vec, int nverts, g3s_phandle *vp,
180 grs_bitmap *bm) {
181 tmap_func = (void *)&h_umap;
182 ti.tmap_type = GRC_LIT_BILIN;
183 ti.flags = 0;
184 light_flag = 1;
185 return (do_tmap_tile(upperleft, u_vec, v_vec, nverts, vp, bm));
186 }
187
g3_light_tmap_tile(g3s_phandle upperleft,g3s_vector * u_vec,g3s_vector * v_vec,int nverts,g3s_phandle * vp,grs_bitmap * bm)188 int g3_light_tmap_tile(g3s_phandle upperleft, g3s_vector *u_vec, g3s_vector *v_vec, int nverts, g3s_phandle *vp,
189 grs_bitmap *bm) {
190 tmap_func = (void *)&per_umap;
191 ti.tmap_type = GRC_LIT_PER;
192 ti.flags = 0;
193 light_flag = 1;
194 return (do_tmap_tile(upperleft, u_vec, v_vec, nverts, vp, bm));
195 }
196
g3_draw_tmap_tile(g3s_phandle upperleft,g3s_vector * u_vec,g3s_vector * v_vec,int nverts,g3s_phandle * vp,grs_bitmap * bm)197 int g3_draw_tmap_tile(g3s_phandle upperleft, g3s_vector *u_vec, g3s_vector *v_vec, int nverts, g3s_phandle *vp,
198 grs_bitmap *bm) {
199 tmap_func = (void *)&per_umap;
200 ti.tmap_type = GRC_PER;
201 ti.flags = 0;
202 light_flag = 0;
203 return (do_tmap_tile(upperleft, u_vec, v_vec, nverts, vp, bm));
204 }
205
do_tmap_tile(g3s_phandle upperleft,g3s_vector * u_vec,g3s_vector * v_vec,int nverts,g3s_phandle * vp,grs_bitmap * bm)206 int do_tmap_tile(g3s_phandle upperleft, g3s_vector *u_vec, g3s_vector *v_vec, int nverts, g3s_phandle *vp,
207 grs_bitmap *bm) {
208 byte andcode, orcode;
209 int i;
210 g3s_phandle *src;
211 g3s_phandle tempHand;
212 fix x10;
213 fix y10;
214 fix z10;
215 fix x20;
216 fix y20;
217 fix z20;
218
219 // get codes for this polygon
220 andcode = 0xff;
221 orcode = 0;
222 src = vp;
223 for (i = nverts; i > 0; i--) {
224 tempHand = *(src++);
225 andcode &= tempHand->codes;
226 orcode |= tempHand->codes;
227 }
228
229 // check codes for trivial reject.
230 if (andcode)
231 return CLIP_ALL;
232
233 // upper left handle of 0 means reuse old warp matrix.
234
235 // store elements of u difference vector as 10 warp differences.
236 x10 = u_vec->gX;
237 y10 = u_vec->gY;
238 z10 = u_vec->gZ;
239
240 // store elements of v difference vector as 20 warp differences.
241 x20 = v_vec->gX;
242 y20 = v_vec->gY;
243 z20 = v_vec->gZ;
244
245 // do warp matrix calculations
246 calc_warp_matrix2(upperleft, x10, x20, y10, y20, z10, z20, bm);
247
248 src = vp;
249 for (i = nverts; i > 0; i--) {
250 fix a, b;
251 fix blah1;
252 fix blah2;
253 fix blah3;
254
255 tempHand = *(src++);
256 a = fix_div(tempHand->gX, tempHand->gZ);
257 b = fix_div(tempHand->gY, tempHand->gZ);
258
259 blah1 = fix_mul(warp[0], a) + fix_mul(warp[1], b) + warp[2];
260 blah2 = fix_mul(warp[3], a) + fix_mul(warp[4], b) + warp[5];
261 blah3 = fix_mul(warp[6], a) + fix_mul(warp[7], b) + warp[8];
262
263 tempHand->uv.u = fix_div(blah1, blah3) >> 8;
264 tempHand->uv.v = fix_div(blah2, blah3) >> 8;
265 tempHand->p3_flags |= PF_U | PF_V;
266 }
267
268 return (draw_tmap_common(nverts, vp, bm));
269 }
270
g3_check_and_draw_lmap_quad_tile(g3s_phandle * vp,grs_bitmap * bm,int width_count,int height_count)271 int g3_check_and_draw_lmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count) {
272 tmap_func = (void *)&h_umap;
273 ti.tmap_type = GRC_BILIN;
274 ti.flags = 0;
275 light_flag = 0;
276 return (do_check_tmap_quad_tile(vp, bm, width_count, height_count));
277 }
278
g3_check_and_light_lmap_quad_tile(g3s_phandle * vp,grs_bitmap * bm,int width_count,int height_count)279 int g3_check_and_light_lmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count) {
280 tmap_func = (void *)&h_umap;
281 ti.tmap_type = GRC_LIT_BILIN;
282 ti.flags = 0;
283 light_flag = 1;
284 return (do_check_tmap_quad_tile(vp, bm, width_count, height_count));
285 }
286
g3_check_and_light_tmap_quad_tile(g3s_phandle * vp,grs_bitmap * bm,int width_count,int height_count)287 int g3_check_and_light_tmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count) {
288 tmap_func = (void *)&per_umap;
289 ti.tmap_type = GRC_LIT_PER;
290 ti.flags = 0;
291 light_flag = 1;
292 return (do_check_tmap_quad_tile(vp, bm, width_count, height_count));
293 }
294
g3_check_and_draw_tmap_quad_tile(g3s_phandle * vp,grs_bitmap * bm,int width_count,int height_count)295 int g3_check_and_draw_tmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count) {
296 tmap_func = (void *)&per_umap;
297 ti.tmap_type = GRC_PER;
298 ti.flags = 0;
299 light_flag = 0;
300 return (do_check_tmap_quad_tile(vp, bm, width_count, height_count));
301 }
302
do_check_tmap_quad_tile(g3s_phandle * vp,grs_bitmap * bm,int width_count,int height_count)303 int do_check_tmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count) {
304 if (g3_check_poly_facing(vp[0], vp[1], vp[2]))
305 return do_tmap_quad_tile(vp, bm, width_count, height_count);
306 else
307 return CLIP_ALL;
308 }
309
310 // takes eax=nverts edx=ptr to points, ebx=ptr to bitmap
g3_draw_floor_map(int n,g3s_phandle * vp,grs_bitmap * bm)311 int g3_draw_floor_map(int n, g3s_phandle *vp, grs_bitmap *bm) {
312 tmap_func = (void *)&h_umap;
313 ti.tmap_type = GRC_FLOOR;
314 ti.flags = TMF_FLOOR;
315 light_flag = 0;
316 return (do_tmap(n, vp, bm));
317 }
318
g3_light_floor_map(int n,g3s_phandle * vp,grs_bitmap * bm)319 int g3_light_floor_map(int n, g3s_phandle *vp, grs_bitmap *bm) {
320 tmap_func = (void *)&h_umap;
321 ti.tmap_type = GRC_LIT_FLOOR;
322 ti.flags = TMF_FLOOR;
323 light_flag = 1;
324 return (do_tmap(n, vp, bm));
325 }
326
g3_draw_wall_map(int n,g3s_phandle * vp,grs_bitmap * bm)327 int g3_draw_wall_map(int n, g3s_phandle *vp, grs_bitmap *bm) {
328 tmap_func = (void *)&v_umap;
329 ti.tmap_type = GRC_WALL1D;
330 ti.flags = TMF_WALL;
331 light_flag = 0;
332 return (do_tmap(n, vp, bm));
333 }
334
g3_light_wall_map(int n,g3s_phandle * vp,grs_bitmap * bm)335 int g3_light_wall_map(int n, g3s_phandle *vp, grs_bitmap *bm) {
336 tmap_func = (void *)&v_umap;
337 ti.tmap_type = GRC_LIT_WALL1D;
338 ti.flags = TMF_WALL;
339 light_flag = 1;
340 return (do_tmap(n, vp, bm));
341 }
342
g3_draw_lmap(int n,g3s_phandle * vp,grs_bitmap * bm)343 int g3_draw_lmap(int n, g3s_phandle *vp, grs_bitmap *bm) {
344 tmap_func = (void *)&h_umap;
345 ti.tmap_type = GRC_BILIN;
346 ti.flags = 0;
347 light_flag = 0;
348 return (do_tmap(n, vp, bm));
349 }
350
g3_light_lmap(int n,g3s_phandle * vp,grs_bitmap * bm)351 int g3_light_lmap(int n, g3s_phandle *vp, grs_bitmap *bm) {
352 tmap_func = (void *)&h_umap;
353 ti.tmap_type = GRC_LIT_BILIN;
354 ti.flags = 0;
355 light_flag = 1;
356 return (do_tmap(n, vp, bm));
357 }
358
g3_light_tmap(int n,g3s_phandle * vp,grs_bitmap * bm)359 int g3_light_tmap(int n, g3s_phandle *vp, grs_bitmap *bm) {
360 tmap_func = (void *)&per_umap;
361 ti.tmap_type = GRC_LIT_PER;
362 ti.flags = 0;
363 light_flag = 1;
364 return (do_tmap(n, vp, bm));
365 }
366
g3_draw_tmap(int n,g3s_phandle * vp,grs_bitmap * bm)367 int g3_draw_tmap(int n, g3s_phandle *vp, grs_bitmap *bm) {
368 tmap_func = (void *)&per_umap;
369 ti.tmap_type = GRC_PER;
370 ti.flags = 0;
371 light_flag = 0;
372 return (do_tmap(n, vp, bm));
373 }
374
do_tmap(int n,g3s_phandle * vp,grs_bitmap * bm)375 int do_tmap(int n, g3s_phandle *vp, grs_bitmap *bm) {
376 byte andcode, orcode;
377 int i;
378 g3s_phandle *src;
379 g3s_phandle tempHand;
380
381 // clang-format off
382 #ifdef stereo_on
383 test _g3d_stereo,1
384 jz no_stereo1
385 push eax // calling destroys eax
386 mov ecx,d [ti_ptr]
387 push ecx
388 mov ecx,d [ti_ptr+4]
389 push ecx
390 mov ecx,tmap_func
391 push ecx
392 mov ecx,light_flag
393 push ecx
394 call do_tmap_raw
395 pop eax
396 mov light_flag,eax
397 pop eax
398 mov tmap_func,eax
399 pop eax
400 mov d [ti_ptr+4],eax
401 pop eax
402 mov d [ti_ptr],eax
403 pop eax
404
405 pushm eax,ebx // copy list and codes and uv and rgb and i
406 // num points,pointer to bmap
407
408 move_to_stereo_and_uvi
409
410 set_rt_canv
411
412 popm eax,ebx
413 call do_tmap_raw
414
415 set_lt_canv
416 popad
417 ret
418
419 do_tmap_raw:
420 pushad
421 no_stereo1:
422 #endif
423
424 // clang-format on
425
426 // convert RSD bitmap to normal
427 if (bm->type == BMT_RSD8) {
428 if (gr_rsd8_convert(bm, &unpack_bm) != GR_UNPACK_RSD8_OK)
429 return CLIP_ALL;
430 else
431 bm = &unpack_bm;
432 }
433
434 // get codes for this polygon
435 andcode = 0xff;
436 orcode = 0;
437 src = vp;
438 for (i = n; i > 0; i--) {
439 tempHand = *(src++);
440 andcode &= tempHand->codes;
441 orcode |= tempHand->codes;
442 }
443
444 // check codes for trivial reject.
445 if (andcode)
446 return CLIP_ALL;
447
448 return (draw_tmap_common(n, vp, bm));
449 }
450
451 // draws a square texture map, where the corners of the 3d quad match the
452 // corners of the bitmap
453 // takes esi=ptr to points, edi=ptr to bitmap, eax=width count, ebx=height count
g3_draw_lmap_quad_tile(g3s_phandle * vp,grs_bitmap * bm,int width_count,int height_count)454 int g3_draw_lmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count) {
455 tmap_func = (void *)&h_umap;
456 ti.tmap_type = GRC_BILIN;
457 ti.flags = 0;
458 light_flag = 0;
459 return (do_tmap_quad_tile(vp, bm, width_count, height_count));
460 }
461
g3_light_lmap_quad_tile(g3s_phandle * vp,grs_bitmap * bm,int width_count,int height_count)462 int g3_light_lmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count) {
463 tmap_func = (void *)&h_umap;
464 ti.tmap_type = GRC_LIT_BILIN;
465 ti.flags = 0;
466 light_flag = 1;
467 return (do_tmap_quad_tile(vp, bm, width_count, height_count));
468 }
469
g3_light_tmap_quad_tile(g3s_phandle * vp,grs_bitmap * bm,int width_count,int height_count)470 int g3_light_tmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count) {
471 tmap_func = (void *)&per_umap;
472 ti.tmap_type = GRC_LIT_PER;
473 ti.flags = 0;
474 light_flag = 1;
475 return (do_tmap_quad_tile(vp, bm, width_count, height_count));
476 }
477
g3_draw_tmap_quad_tile(g3s_phandle * vp,grs_bitmap * bm,int width_count,int height_count)478 int g3_draw_tmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count) {
479 tmap_func = (void *)&per_umap;
480 ti.tmap_type = GRC_PER;
481 ti.flags = 0;
482 light_flag = 0;
483 return (do_tmap_quad_tile(vp, bm, width_count, height_count));
484 }
485
do_tmap_quad_tile(g3s_phandle * vp,grs_bitmap * bm,int width_count,int height_count)486 int do_tmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count) {
487 int temp_w, temp_h;
488 byte andcode, orcode;
489 int i;
490 g3s_phandle *src;
491 g3s_phandle tempHand;
492
493 temp_w = width_count << 8;
494 temp_h = height_count << 8;
495 _n_verts = 4;
496
497 vp[0]->uv.u = vp[0]->uv.v = 0;
498 vp[0]->p3_flags |= PF_U | PF_V;
499
500 vp[1]->uv.u = temp_w;
501 vp[1]->uv.v = 0;
502 vp[1]->p3_flags |= PF_U | PF_V;
503
504 vp[2]->uv.u = temp_w;
505 vp[2]->uv.v = temp_h;
506 vp[2]->p3_flags |= PF_U | PF_V;
507
508 vp[3]->uv.u = 0;
509 vp[3]->uv.v = temp_h;
510 vp[3]->p3_flags |= PF_U | PF_V;
511
512 // first, go though points and get codes
513 andcode = 0xff;
514 orcode = 0;
515 src = vp;
516 for (i = 4; i > 0; i--) {
517 tempHand = *(src++);
518 andcode &= tempHand->codes;
519 orcode |= tempHand->codes;
520 }
521
522 // check codes for trivial reject.
523 if (andcode)
524 return CLIP_ALL;
525
526 return (draw_tmap_common(4, vp, bm));
527 }
528
draw_tmap_common(int n,g3s_phandle * vp,grs_bitmap * bm)529 int draw_tmap_common(int n, g3s_phandle *vp, grs_bitmap *bm) {
530 int branch_to_copy = 0;
531 int hlog, wlog;
532 g3s_phandle temphand;
533 int i, temp;
534 grs_vertex *cur_vert;
535
536 // always clip for now
537 // copy to temp buffer for clipping
538 // BlockMove(vp,vbuf,n*4);
539 memmove(vbuf, vp, n * sizeof *vbuf);
540
541 _n_verts = n = g3_clip_polygon(n, vbuf, _vbuf2);
542 if (n == 0)
543 return CLIP_ALL;
544 if (ti.tmap_type >= GRC_CLUT_BILIN + 2)
545 branch_to_copy = check_linear(n);
546 else
547 branch_to_copy = 1;
548
549 // check if bitmap is power of 2
550 wlog = bm->wlog;
551 hlog = bm->hlog;
552
553 if (((1 << wlog) != bm->w) || ((1 << hlog) != bm->h))
554 return CLIP_ALL;
555
556 wlog += 8;
557 hlog += 8;
558
559 // now, copy 2d points to buffer for tmap call, projecting if neccesary
560 // for (i=n-1; i--; i>=0)
561 for (i = 0; i < n; i++) {
562 temphand = _vbuf2[i];
563 p_vpl[i] = cur_vert = &p_vlist[i];
564
565 // check if this point has been projected
566 if ((temphand->p3_flags & PF_PROJECTED) == 0)
567 g3_project_point(temphand);
568
569 cur_vert->x = temphand->sx;
570 cur_vert->y = temphand->sy;
571
572 temp = temphand->uv.u;
573 if (temp <= 0)
574 temp++;
575 else
576 temp--;
577 cur_vert->u = temp << wlog;
578
579 temp = temphand->uv.v;
580 if (temp <= 0)
581 temp++;
582 else
583 temp--;
584 cur_vert->v = temp << hlog;
585
586 cur_vert->i = temphand->i << 8;
587
588 if (!branch_to_copy) // fix Z
589 {
590 temp = temphand->gZ;
591 cur_vert->w = fix_div(0x010000, temp); // 1/Z
592 }
593 }
594
595 if (!light_flag) {
596 ((void (*)(grs_bitmap * bm, int n, grs_vertex **vpl, grs_tmap_info *ti)) tmap_func)(bm, _n_verts, p_vpl, &ti);
597 return CLIP_NONE;
598 } else {
599 extern fix gr_clut_lit_tol;
600 int temp_n;
601 fix imax, imin, temp_i;
602 grs_vertex *temp_p_vlist;
603
604 temp_p_vlist = p_vlist;
605 temp_n = n - 1;
606 imax = imin = temp_p_vlist[temp_n].i;
607 while (--n >= 0) {
608 temp_i = temp_p_vlist[n].i;
609 if (temp_i < imin)
610 imin = temp_i;
611 if (temp_i > imax)
612 imax = temp_i;
613 }
614
615 temp_i = imax - imin;
616 if (temp_i >= gr_clut_lit_tol) {
617 ((void (*)(grs_bitmap * bm, int n, grs_vertex **vpl, grs_tmap_info *ti)) tmap_func)(bm, _n_verts, p_vpl,
618 &ti);
619 return CLIP_NONE;
620 } else {
621 uchar *temp_ptr;
622
623 imin += imax;
624 imin >>= 9;
625 imin &= 0xff00;
626 temp_ptr = gr_get_light_tab() + imin;
627 ti.clut = temp_ptr;
628 ti.tmap_type += 2;
629 ti.flags |= TMF_CLUT;
630
631 ((void (*)(grs_bitmap * bm, int n, grs_vertex **vpl, grs_tmap_info *ti)) tmap_func)(bm, _n_verts, p_vpl,
632 &ti);
633 return CLIP_NONE;
634 }
635 }
636 }
637
638 // return 1 if punt (ignore Z), 0 if use it
check_linear(int n)639 int check_linear(int n) {
640 extern ubyte flat8_per_ltol;
641 g3s_phandle temphand;
642 fix zmin, zmax;
643 fix temp;
644 g3s_phandle *temp_vbuf2;
645
646 temp_vbuf2 = _vbuf2;
647 n--;
648 temphand = temp_vbuf2[n];
649 zmax = zmin = temphand->gZ;
650
651 while (--n >= 0) {
652 temphand = temp_vbuf2[n];
653 temp = temphand->gZ;
654
655 if (temp < zmin)
656 zmin = temp;
657 if (temp > zmax)
658 zmax = temp;
659 }
660
661 zmax -= zmin;
662 temp = zmin >> flat8_per_ltol;
663 if (temp >= zmax) {
664 ti.tmap_type = GRC_BILIN + (light_flag << 1);
665 tmap_func = (void *)&h_umap;
666 return 1; // punt
667 } else
668 return 0; // use Z
669 }
670
671 // compute warp matrix with deltas already set.
672 // arguments:
673 // deltas in x10,x20,y10,y20,z10,z20
674 // pointer to bitmap in bm_ptr
675 // esi=basis 0
calc_warp_matrix2(g3s_phandle upperleft,fix x10,fix x20,fix y10,fix y20,fix z10,fix z20,grs_bitmap * bm)676 void calc_warp_matrix2(g3s_phandle upperleft, fix x10, fix x20, fix y10, fix y20, fix z10, fix z20, grs_bitmap *bm) {
677 fix x0 = upperleft->gX;
678 fix y0 = upperleft->gY;
679 fix z0 = upperleft->gZ;
680
681 // compute the actual matrix.
682
683 warp[0] = fix_mul(y20, z0) - fix_mul(y0, z20);
684 warp[1] = fix_mul(x0, z20) - fix_mul(x20, z0);
685 warp[2] = fix_mul(x20, y0) - fix_mul(x0, y20);
686 warp[3] = fix_mul(y0, z10) - fix_mul(y10, z0);
687 warp[4] = fix_mul(x10, z0) - fix_mul(x0, z10);
688 warp[5] = fix_mul(x0, y10) - fix_mul(x10, y0);
689 warp[6] = fix_mul(y10, z20) - fix_mul(y20, z10);
690 warp[7] = fix_mul(x20, z10) - fix_mul(x10, z20);
691 warp[8] = fix_mul(x10, y20) - fix_mul(x20, y10);
692 }
693
694 // ------------------------------------------------------------------------------------------------
695 // MLA - calc_warp_matrix never called! none of this stuff used!?
696
697 /*
698 getdel macro dest,ofs,src1,src2
699 mov eax,[src1].ofs
700 sub eax,[src2].ofs
701 break_if o,'overflow in getdel'
702 mov dest,eax
703 endm
704
705 divm macro dest,reg
706 mov eax,dest
707 cdq
708 idiv reg
709 mov dest,eax
710 endm
711
712
713
714 // figure out the goofy warp matrix.
715 // takes three points: ebx,ecx,edx=basis 0,1,2 and bm_ptr must point to
716 // the address of the bitmap.
717 // only handles square bitmaps now.
718 void calc_warp_matrix(void)
719 {
720 // get deltas
721 // x10 = r1->x - r0->x x20 = r2->x - r0->x
722 // y10 = r1->y - r0->y y20 = r2->y - r0->y
723 // z10 = r1->z - r0->z z20 = r2->z - r0->z
724 // get 10 differences.
725 getdel x10,x,ecx,ebx
726 getdel y10,y,ecx,ebx
727 getdel z10,z,ecx,ebx
728 // get 20 differences.
729 getdel x20,x,edx,ebx
730 getdel y20,y,edx,ebx
731 getdel z20,z,edx,ebx
732 mov esi,ebx // esi -> basis0
733
734 mov ebx,width_count
735 cmp ebx,1
736 je skip_w_div
737 divm x10,ebx
738 divm y10,ebx
739 divm z10,ebx
740 skip_w_div:
741 mov ebx,height_count
742 cmp ebx,1
743 je skip_h_div
744 divm x20,ebx
745 divm y20,ebx
746 divm z20,ebx
747 skip_h_div:
748 jmp calc_warp_matrix2
749 }
750 */
751