home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / texmap / tmapflat.c < prev    next >
Text File  |  1998-06-08  |  9KB  |  325 lines

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