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