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.
16 * Flat shader derived from texture mapper (a little slow)
30 //#include "tmapext.h"
35 void (*scanline_func)(int,fix,fix);
37 // -------------------------------------------------------------------------------------
38 // Texture map current scanline.
39 // Uses globals Du_dx and Dv_dx to incrementally compute u,v coordinates
40 // -------------------------------------------------------------------------------------
41 void tmap_scanline_flat(int y, fix xleft, fix xright)
46 // setup to call assembler scanline renderer
49 fx_xleft = xleft/F1_0; // (xleft >> 16) != xleft/F1_0 for negative numbers, f2i caused random crashes
50 fx_xright = xright/F1_0;
52 if ( Gr_scanline_darkening_level >= GR_FADE_LEVELS )
53 cur_tmap_scanline_flat();
55 tmap_flat_shade_value = Gr_scanline_darkening_level;
56 cur_tmap_scanline_shaded();
61 //--unused-- void tmap_scanline_shaded(int y, fix xleft, fix xright)
65 //--unused-- dx = xright - xleft;
67 //--unused-- // setup to call assembler scanline renderer
69 //--unused-- fx_y = y << 16;
70 //--unused-- fx_xleft = xleft;
71 //--unused-- fx_xright = xright;
73 //--unused-- asm_tmap_scanline_shaded();
77 // -------------------------------------------------------------------------------------
78 // Render a texture map.
79 // Linear in outer loop, linear in inner loop.
80 // -------------------------------------------------------------------------------------
81 void texture_map_flat(g3ds_tmap *t, int color)
83 int vlt,vrt,vlb,vrb; // vertex left top, vertex right top, vertex left bottom, vertex right bottom
85 fix dx_dy_left,dx_dy_right;
93 tmap_flat_color = color;
95 // Determine top and bottom y coords.
96 compute_y_bounds(t,&vlt,&vlb,&vrt,&vrb,&max_y_vertex);
98 // Set top and bottom (of entire texture map) y coordinates.
99 topy = f2i(v3d[vlt].y2d);
100 boty = f2i(v3d[max_y_vertex].y2d);
102 // Set amount to change x coordinate for each advance to next scanline.
103 dy = f2i(t->verts[vlb].y2d) - f2i(t->verts[vlt].y2d);
104 if (dy < FIX_RECIP_TABLE_SIZE)
105 recip_dy = fix_recip[dy];
109 dx_dy_left = compute_dx_dy(t,vlt,vlb, recip_dy);
111 dy = f2i(t->verts[vrb].y2d) - f2i(t->verts[vrt].y2d);
112 if (dy < FIX_RECIP_TABLE_SIZE)
113 recip_dy = fix_recip[dy];
117 dx_dy_right = compute_dx_dy(t,vrt,vrb, recip_dy);
119 // Set initial values for x, u, v
120 xleft = v3d[vlt].x2d;
121 xright = v3d[vrt].x2d;
123 // scan all rows in texture map from top through first break.
124 // @mk: Should we render the scanline for y==boty? This violates Matt's spec.
126 for (y = topy; y < boty; y++) {
128 // See if we have reached the end of the current left edge, and if so, set
129 // new values for dx_dy and x,u,v
130 if (y == f2i(v3d[vlb].y2d)) {
131 // Handle problem of double points. Search until y coord is different. Cannot get
132 // hung in an infinite loop because we know there is a vertex with a lower y coordinate
133 // because in the for loop, we don't scan all spanlines.
134 while (y == f2i(v3d[vlb].y2d)) {
136 vlb = prevmod(vlb,t->nv);
138 dy = f2i(t->verts[vlb].y2d) - f2i(t->verts[vlt].y2d);
139 if (dy < FIX_RECIP_TABLE_SIZE)
140 recip_dy = fix_recip[dy];
144 dx_dy_left = compute_dx_dy(t,vlt,vlb, recip_dy);
146 xleft = v3d[vlt].x2d;
149 // See if we have reached the end of the current left edge, and if so, set
150 // new values for dx_dy and x. Not necessary to set new values for u,v.
151 if (y == f2i(v3d[vrb].y2d)) {
152 while (y == f2i(v3d[vrb].y2d)) {
154 vrb = succmod(vrb,t->nv);
157 dy = f2i(t->verts[vrb].y2d) - f2i(t->verts[vrt].y2d);
158 if (dy < FIX_RECIP_TABLE_SIZE)
159 recip_dy = fix_recip[dy];
163 dx_dy_right = compute_dx_dy(t,vrt,vrb, recip_dy);
165 xright = v3d[vrt].x2d;
169 //tmap_scanline_flat(y, xleft, xright);
170 (*scanline_func)(y, xleft, xright);
173 xright += dx_dy_right;
176 //tmap_scanline_flat(y, xleft, xright);
177 (*scanline_func)(y, xleft, xright);
181 // -----------------------------------------------------------------------------------------
182 // This is the gr_upoly-like interface to the texture mapper which uses texture-mapper compatible
183 // (ie, avoids cracking) edge/delta computation.
184 void gr_upoly_tmap(int nverts, int *vert )
186 gr_upoly_tmap_ylr(nverts, vert, tmap_scanline_flat);
190 #include "dxxerror.h"
192 typedef struct pnt2d {
197 #pragma off (unreferenced) //bp not referenced
200 //this takes the same partms as draw_tmap, but draws a flat-shaded polygon
201 void draw_tmap_flat(grs_bitmap *bp,int nverts,g3s_point **vertbuf)
203 pnt2d points[MAX_TMAP_VERTS];
208 Assert(nverts < MAX_TMAP_VERTS);
210 average_light = vertbuf[0]->p3_l;
211 for (i=1; i<nverts; i++)
212 average_light += vertbuf[i]->p3_l;
215 average_light = f2i(average_light * NUM_LIGHTING_LEVELS/4);
217 average_light = f2i(average_light * NUM_LIGHTING_LEVELS/nverts);
219 if (average_light < 0)
221 else if (average_light > NUM_LIGHTING_LEVELS-1)
222 average_light = NUM_LIGHTING_LEVELS-1;
224 color = gr_fade_table[average_light*256 + bp->avg_color];
227 for (i=0;i<nverts;i++) {
228 points[i].x = vertbuf[i]->p3_sx;
229 points[i].y = vertbuf[i]->p3_sy;
232 gr_upoly_tmap(nverts,(int *) points);
236 #pragma on (unreferenced)
239 // -----------------------------------------------------------------------------------------
240 //This is like gr_upoly_tmap() but instead of drawing, it calls the specified
241 //function with ylr values
242 void gr_upoly_tmap_ylr(int nverts, int *vert, void (*ylr_func)(int,fix,fix) )
247 //--now called from g3_start_frame-- init_interface_vars_to_assembler();
251 for (i=0; i<nverts; i++) {
252 my_tmap.verts[i].x2d = *vert++;
253 my_tmap.verts[i].y2d = *vert++;
256 scanline_func = ylr_func;
258 texture_map_flat(&my_tmap, COLOR);