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