Fix compiler warnings
[btb/d2x.git] / texmap / tmapflat.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13 /*
14  * $Source: /cvs/cvsroot/d2x/texmap/tmapflat.c,v $
15  * $Revision: 1.2 $
16  * $Author: bradleyb $
17  * $Date: 2001-01-31 14:04:46 $
18  *
19  * Flat shader derived from texture mapper (a little slow)
20  *
21  * $Log: not supported by cvs2svn $
22  * Revision 1.1.1.1  2001/01/19 03:30:16  bradleyb
23  * Import of d2x-0.0.8
24  *
25  * Revision 1.2  1999/10/07 21:03:29  donut
26  * OGL rendering of cloaked stuff
27  *
28  * Revision 1.1.1.1  1999/06/14 22:14:10  donut
29  * Import of d1x 1.37 source.
30  *
31  * Revision 1.13  1995/02/20  18:23:24  john
32  * Added new module for C versions of inner loops.
33  * 
34  * Revision 1.12  1995/02/20  17:09:17  john
35  * Added code so that you can build the tmapper with no assembly!
36  * 
37  * Revision 1.11  1994/11/30  00:58:01  mike
38  * optimizations.
39  * 
40  * Revision 1.10  1994/11/28  13:34:32  mike
41  * optimizations.
42  * 
43  * Revision 1.9  1994/11/19  15:21:46  mike
44  * rip out unused code.
45  * 
46  * Revision 1.8  1994/11/12  16:41:41  mike
47  * *** empty log message ***
48  * 
49  * Revision 1.7  1994/11/09  23:05:12  mike
50  * do lighting on texture maps which get flat shaded instead.
51  * 
52  * Revision 1.6  1994/10/06  19:53:07  matt
53  * Added function that takes same parms as draw_tmap(), but renders flat
54  * 
55  * Revision 1.5  1994/10/06  18:38:12  john
56  * Added the ability to fade a scanline by calling gr_upoly_tmap
57  * with Gr_scanline_darkening_level with a value < MAX_FADE_LEVELS.
58  * 
59  * Revision 1.4  1994/05/25  18:46:32  matt
60  * Added gr_upoly_tmap_ylr(), which generates ylr's for a polygon
61  * 
62  * Revision 1.3  1994/04/08  16:25:58  mike
63  * Comment out some includes (of header files)
64  * call init_interface_vars_to_assembler.
65  * 
66  * Revision 1.2  1994/03/31  08:33:44  mike
67  * Fixup flat shading version of texture mapper (get it?)
68  * (Or maybe not, I admit to not testing my code...hahahah!)
69  * 
70  * Revision 1.1  1993/09/08  17:29:10  mike
71  * Initial revision
72  * 
73  *
74  */
75
76 #include <conf.h>
77
78 #include "fix.h"
79 #include "vecmat.h"
80 #include "gr.h"
81 #include "grdef.h"
82 #include "texmap.h"
83 #include "texmapl.h"
84 #ifdef NO_ASM
85 #include "scanline.h"
86 #endif
87
88 //#include "tmapext.h"
89
90 #ifndef OGL
91
92 void (*scanline_func)(int,fix,fix);
93
94 // -------------------------------------------------------------------------------------
95 //      Texture map current scanline.
96 //      Uses globals Du_dx and Dv_dx to incrementally compute u,v coordinates
97 // -------------------------------------------------------------------------------------
98 void tmap_scanline_flat(int y, fix xleft, fix xright)
99 {
100         if (xright < xleft)
101                 return;
102
103         // setup to call assembler scanline renderer
104
105         fx_y = y;
106         fx_xleft = f2i(xleft);
107         fx_xright = f2i(xright);
108
109         if ( Gr_scanline_darkening_level >= GR_FADE_LEVELS )
110                 #ifdef NO_ASM
111                         c_tmap_scanline_flat();
112                 #else
113                         asm_tmap_scanline_flat();
114                 #endif
115         else    {
116                 tmap_flat_shade_value = Gr_scanline_darkening_level;
117                 #ifdef NO_ASM
118                         c_tmap_scanline_shaded();
119                 #else
120                         asm_tmap_scanline_shaded();
121                 #endif
122         }       
123 }
124
125
126 //--unused-- void tmap_scanline_shaded(int y, fix xleft, fix xright)
127 //--unused-- {
128 //--unused--    fix     dx;
129 //--unused-- 
130 //--unused--    dx = xright - xleft;
131 //--unused-- 
132 //--unused--    // setup to call assembler scanline renderer
133 //--unused-- 
134 //--unused--    fx_y = y << 16;
135 //--unused--    fx_xleft = xleft;
136 //--unused--    fx_xright = xright;
137 //--unused-- 
138 //--unused--    asm_tmap_scanline_shaded();
139 //--unused-- }
140
141
142 // -------------------------------------------------------------------------------------
143 //      Render a texture map.
144 // Linear in outer loop, linear in inner loop.
145 // -------------------------------------------------------------------------------------
146 void texture_map_flat(g3ds_tmap *t, int color)
147 {
148         int     vlt,vrt,vlb,vrb;        // vertex left top, vertex right top, vertex left bottom, vertex right bottom
149         int     topy,boty,y, dy;
150         fix     dx_dy_left,dx_dy_right;
151         int     max_y_vertex;
152         fix     xleft,xright;
153         fix     recip_dy;
154         g3ds_vertex *v3d;
155
156         v3d = t->verts;
157
158         tmap_flat_color = color;
159
160         // Determine top and bottom y coords.
161         compute_y_bounds(t,&vlt,&vlb,&vrt,&vrb,&max_y_vertex);
162
163         // Set top and bottom (of entire texture map) y coordinates.
164         topy = f2i(v3d[vlt].y2d);
165         boty = f2i(v3d[max_y_vertex].y2d);
166
167         // Set amount to change x coordinate for each advance to next scanline.
168         dy = f2i(t->verts[vlb].y2d) - f2i(t->verts[vlt].y2d);
169         if (dy < FIX_RECIP_TABLE_SIZE)
170                 recip_dy = fix_recip[dy];
171         else
172                 recip_dy = F1_0/dy;
173
174         dx_dy_left = compute_dx_dy(t,vlt,vlb, recip_dy);
175
176         dy = f2i(t->verts[vrb].y2d) - f2i(t->verts[vrt].y2d);
177         if (dy < FIX_RECIP_TABLE_SIZE)
178                 recip_dy = fix_recip[dy];
179         else
180                 recip_dy = F1_0/dy;
181
182         dx_dy_right = compute_dx_dy(t,vrt,vrb, recip_dy);
183
184         // Set initial values for x, u, v
185         xleft = v3d[vlt].x2d;
186         xright = v3d[vrt].x2d;
187
188         // scan all rows in texture map from top through first break.
189         // @mk: Should we render the scanline for y==boty?  This violates Matt's spec.
190
191         for (y = topy; y < boty; y++) {
192
193                 // See if we have reached the end of the current left edge, and if so, set
194                 // new values for dx_dy and x,u,v
195                 if (y == f2i(v3d[vlb].y2d)) {
196                         // Handle problem of double points.  Search until y coord is different.  Cannot get
197                         // hung in an infinite loop because we know there is a vertex with a lower y coordinate
198                         // because in the for loop, we don't scan all spanlines.
199                         while (y == f2i(v3d[vlb].y2d)) {
200                                 vlt = vlb;
201                                 vlb = prevmod(vlb,t->nv);
202                         }
203                         dy = f2i(t->verts[vlb].y2d) - f2i(t->verts[vlt].y2d);
204                         if (dy < FIX_RECIP_TABLE_SIZE)
205                                 recip_dy = fix_recip[dy];
206                         else
207                                 recip_dy = F1_0/dy;
208
209                         dx_dy_left = compute_dx_dy(t,vlt,vlb, recip_dy);
210
211                         xleft = v3d[vlt].x2d;
212                 }
213
214                 // See if we have reached the end of the current left edge, and if so, set
215                 // new values for dx_dy and x.  Not necessary to set new values for u,v.
216                 if (y == f2i(v3d[vrb].y2d)) {
217                         while (y == f2i(v3d[vrb].y2d)) {
218                                 vrt = vrb;
219                                 vrb = succmod(vrb,t->nv);
220                         }
221
222                         dy = f2i(t->verts[vrb].y2d) - f2i(t->verts[vrt].y2d);
223                         if (dy < FIX_RECIP_TABLE_SIZE)
224                                 recip_dy = fix_recip[dy];
225                         else
226                                 recip_dy = F1_0/dy;
227
228                         dx_dy_right = compute_dx_dy(t,vrt,vrb, recip_dy);
229
230                         xright = v3d[vrt].x2d;
231
232                 }
233
234                 //tmap_scanline_flat(y, xleft, xright);
235                 (*scanline_func)(y, xleft, xright);
236
237                 xleft += dx_dy_left;
238                 xright += dx_dy_right;
239
240         }
241         //tmap_scanline_flat(y, xleft, xright);
242         (*scanline_func)(y, xleft, xright);
243 }
244
245
246 //      -----------------------------------------------------------------------------------------
247 //      This is the gr_upoly-like interface to the texture mapper which uses texture-mapper compatible
248 //      (ie, avoids cracking) edge/delta computation.
249 void gr_upoly_tmap(int nverts, int *vert )
250 {
251         gr_upoly_tmap_ylr(nverts, vert, tmap_scanline_flat);
252 }
253
254 #include "3d.h"
255 #include "error.h"
256
257 typedef struct pnt2d {
258         fix x,y;
259 } pnt2d;
260
261 #ifdef __WATCOMC__
262 #pragma off (unreferenced)              //bp not referenced
263 #endif
264
265 //this takes the same partms as draw_tmap, but draws a flat-shaded polygon
266 void draw_tmap_flat(grs_bitmap *bp,int nverts,g3s_point **vertbuf)
267 {
268         pnt2d   points[MAX_TMAP_VERTS];
269         int     i;
270         fix     average_light;
271         int     color;
272
273         Assert(nverts < MAX_TMAP_VERTS);
274
275         average_light = vertbuf[0]->p3_l;
276         for (i=1; i<nverts; i++)
277                 average_light += vertbuf[i]->p3_l;
278
279         if (nverts == 4)
280                 average_light = f2i(average_light * NUM_LIGHTING_LEVELS/4);
281         else
282                 average_light = f2i(average_light * NUM_LIGHTING_LEVELS/nverts);
283
284         if (average_light < 0)
285                 average_light = 0;
286         else if (average_light > NUM_LIGHTING_LEVELS-1)
287                 average_light = NUM_LIGHTING_LEVELS-1;
288
289         color = gr_fade_table[average_light*256 + bp->avg_color];
290         gr_setcolor(color);
291
292         for (i=0;i<nverts;i++) {
293                 points[i].x = vertbuf[i]->p3_sx;
294                 points[i].y = vertbuf[i]->p3_sy;
295         }
296
297         gr_upoly_tmap(nverts,(int *) points);
298
299 }
300 #ifdef __WATCOMC__
301 #pragma on (unreferenced)
302 #endif
303
304 //      -----------------------------------------------------------------------------------------
305 //This is like gr_upoly_tmap() but instead of drawing, it calls the specified
306 //function with ylr values
307 void gr_upoly_tmap_ylr(int nverts, int *vert, void (*ylr_func)(int,fix,fix) )
308 {
309         g3ds_tmap       my_tmap;
310         int                     i;
311
312         //--now called from g3_start_frame-- init_interface_vars_to_assembler();
313
314         my_tmap.nv = nverts;
315
316         for (i=0; i<nverts; i++) {
317                 my_tmap.verts[i].x2d = *vert++;
318                 my_tmap.verts[i].y2d = *vert++;
319         }
320
321         scanline_func = ylr_func;
322
323         texture_map_flat(&my_tmap, COLOR);
324 }
325
326 #endif //!OGL