123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990 |
- /*
- * $Source: f:/miner/source/texmap/rcs/ntmap.c $
- * $Revision: 1.61 $
- * $Author: jay $
- * $Date: 1996/03/12 20:15:58 $
- *
- * Start of conversion to new texture mapper.
- *
- * $Log: ntmap.c $
- * Revision 1.61 1996/03/12 20:15:58 jay
- * From JAY PATEL: changes for S3/Virge version
- *
- * Revision 1.60 1996/02/21 18:18:53 matt
- * From JOHN: changes to texture mapper, supposed to be slightly better & faster
- *
- * Revision 1.59 1996/02/12 11:11:37 jay
- * From JAY PATEL: code to add Diamond/S3 Virge support
- *
- * Revision 1.58 1996/01/24 16:37:28 champaign
- * From JOHN: texture mapper library cleaned up & optimized
- *
- * Revision 1.57 1995/11/28 10:40:24 matt
- * Allow screen heights up to 1024
- *
- * Revision 1.56 1995/08/21 18:06:20 matt
- * Allow screen height up to 768
- *
- * Revision 1.55 1995/07/17 11:04:00 matt
- * Added assert() for correct texture width
- *
- * Revision 1.54 1995/05/26 16:08:03 matt
- * Took out evil include of Descent main directory header file
- *
- * Revision 1.53 1995/04/18 14:36:14 matt
- * Moved window_clip vars to texmap library from Descent main source
- *
- * Revision 1.52 1995/03/14 15:13:06 john
- * Increased MAX_Y_Pointers to 480.
- *
- * Revision 1.51 1995/02/23 14:25:09 john
- * Added editor tmap.
- *
- * Revision 1.50 1995/02/20 18:22:58 john
- * Put all the externs in the assembly modules into tmap_inc.asm.
- * Also, moved all the C versions of the inner loops into a new module,
- * scanline.c.
- *
- * Revision 1.49 1995/02/20 17:09:11 john
- * Added code so that you can build the tmapper with no assembly!
- *
- * Revision 1.48 1995/01/06 11:11:30 mike
- * even when not in editor, have 400 lines in texture map scanline table.
- *
- * Revision 1.47 1994/12/15 16:43:25 matt
- * Took out code only needed by editor
- *
- * Revision 1.46 1994/12/09 22:35:37 mike
- * fix bug in before call to asm_tmap_scanline_per causing write of pixel onto past right border onto left.
- *
- * Revision 1.45 1994/12/06 16:31:06 mike
- * fix bug in asm_tmap_scanline_matt interface.
- *
- * Revision 1.44 1994/12/04 20:37:18 mike
- * *** empty log message ***
- *
- * Revision 1.43 1994/12/02 23:30:04 mike
- * optimizations.
- *
- * Revision 1.42 1994/11/30 00:57:43 mike
- * optimizations.
- *
- * Revision 1.41 1994/11/28 13:34:27 mike
- * optimizations.
- *
- * Revision 1.40 1994/11/28 01:30:01 mike
- * kill warning.
- *
- * Revision 1.39 1994/11/28 01:28:59 mike
- * optimizations.
- *
- * Revision 1.38 1994/11/21 14:08:07 john
- * Took out all multiple instead of divide code.
- *
- * Revision 1.37 1994/11/19 15:21:52 mike
- * rip out unused code.
- *
- * Revision 1.36 1994/11/14 11:42:51 mike
- * optimization.
- *
- * Revision 1.35 1994/11/12 16:41:36 mike
- * *** empty log message ***
- *
- * Revision 1.34 1994/11/10 21:28:41 mike
- * remove call to init_interface_vars_to_assembler.
- *
- * Revision 1.33 1994/11/10 11:08:59 mike
- * detail level stuff.
- *
- * Revision 1.32 1994/11/09 22:55:52 matt
- * Added variable Current_seg_depth for detail level optimization
- *
- * Revision 1.31 1994/11/09 19:57:31 john
- * Added texture rle caching.
- *
- * Revision 1.30 1994/11/09 19:54:48 mike
- * Call flat shader if Tmap_flat_flag set.
- *
- * Revision 1.29 1994/11/02 21:33:31 john
- * Added Burger Bill's optimization, ie.. 2 muls per 8 pixels.
- *
- * Revision 1.28 1994/11/02 11:32:16 john
- * Added code for c callable inner loop and code to
- * test dividing out z0.
- *
- * Revision 1.27 1994/10/28 20:54:32 matt
- * Added error checking
- *
- * Revision 1.26 1994/10/25 11:20:20 mike
- * fix bug in lighting overflow checking for one scanline tall linear texture maps.
- *
- * Revision 1.25 1994/08/03 15:40:33 mike
- * Prevent divide overflows, decrease occurrence of precision-caused glitches.
- *
- * Revision 1.24 1994/07/27 09:31:16 mike
- * Fix concave texture map problem, decrease occurrence of unimportant int 3.
- *
- * Revision 1.23 1994/06/17 12:23:31 mike
- * Support non-lighted texture maps.
- *
- * Revision 1.22 1994/06/11 08:10:24 mike
- * Fix mysterious hang bug, lighting value was out of range.
- *
- * Revision 1.21 1994/06/09 16:10:16 mike
- * Change SC2000 from constant to variable.
- *
- */
- #pragma off (unreferenced)
- static char rcsid[] = "$Id: ntmap.c 1.61 1996/03/12 20:15:58 jay Exp $";
- #pragma on (unreferenced)
- #define VESA 0
- #define NUM_TMAPS 16
- #define HEADLIGHT_LIGHTING 0
- #define WIREFRAME 0
- #define PERSPECTIVE 1
- #include <math.h>
- #include <limits.h>
- #include <stdio.h>
- #include <conio.h>
- #include <stdlib.h>
- #include "pa_enabl.h" //$$POLY_ACC
- #include "mono.h"
- #include "fix.h"
- #include "3d.h"
- #include "gr.h"
- #include "error.h"
- #include "key.h"
- #include "texmap.h"
- #include "texmapl.h"
- #include "rle.h"
- #include "scanline.h"
- #include "..\main\3dfx_des.h"
- #if defined(POLY_ACC)
- #include "poly_acc.h"
- #endif
- #define EDITOR_TMAP 1 //if in, include extra stuff
- #define F15_5 (F1_0*15 + F0_5)
- // 1 means enable special sc2000 code, else enable only for Descent
- #define SC2000K 0
- int SC2000 = SC2000K;
- // Temporary texture map, interface from Matt's 3d system to Mike's texture mapper.
- g3ds_tmap Tmap1;
- grs_bitmap Texmap_ptrs[NUM_TMAPS];
- grs_bitmap Texmap4_ptrs[NUM_TMAPS];
- fix Range_max=0; // debug, kill me
- int Interpolation_method=0; // 0 = choose best method
- int Lighting_on; // initialize to no lighting
- int Tmap_flat_flag = 0; // 1 = render texture maps as flat shaded polygons.
- int Current_seg_depth; // HACK INTERFACE: how far away the current segment (& thus texture) is
- int Max_perspective_depth;
- int Max_linear_depth;
- int Max_flat_depth;
- //variables for clipping the texture-mapper to screen region
- int Window_clip_left, Window_clip_bot, Window_clip_right, Window_clip_top;
- // These variables are the interface to assembler. They get set for each texture map, which is a real waste of time.
- // They should be set only when they change, which is generally when the window bounds change. And, even still, it's
- // a pretty bad interface.
- int bytes_per_row=-1;
- int write_buffer;
- int window_left;
- int window_right;
- int window_top;
- int window_bottom;
- int window_width;
- int window_height;
- uint dest_row_data;
- int loop_count;
- #define MAX_Y_POINTERS 1024
- int y_pointers[MAX_Y_POINTERS];
- #ifdef USE_SELECTORS
- short pixel_data_selector; // selector for current pixel data for texture mapper
- #endif
- fix fix_recip[FIX_RECIP_TABLE_SIZE];
- int Fix_recip_table_computed=0;
- fix fx_l, fx_u, fx_v, fx_z, fx_du_dx, fx_dv_dx, fx_dz_dx, fx_dl_dx;
- int fx_xleft, fx_xright, fx_y, fx_u_right, fx_v_right, fx_z_right;
- unsigned char * pixptr;
- int Transparency_on = 0;
- int dither_intensity_lighting = 0;
- ubyte * tmap_flat_cthru_table;
- ubyte tmap_flat_color;
- ubyte tmap_flat_shade_value;
- // F1_0/Z LOOKUP TABLE:
- // Sig bits... 10 looks fuzzy, but only uses 4K
- // 11 breaks up when close, but quite acceptable, Uses 8K
- // 12 looks good,except when very close. Can be used for game. Uses 16K. Recommended by John.
- #define DIVIDE_SIG_BITS 12
- #define Z_SHIFTER (30-DIVIDE_SIG_BITS)
- #define DIVIDE_TABLE_SIZE (1<<DIVIDE_SIG_BITS)
- ubyte divide_table_filled = 0;
- fix divide_table[1<<DIVIDE_SIG_BITS]; // Can use 16 bits if we divide by the greator of Z0 or Z1, instead of always Z0.
- void fill_divide_table()
- {
- int i;
- divide_table_filled = 1;
- divide_table[0]=f1_0;
- divide_table[1]=f1_0;
- for (i=2; i<DIVIDE_TABLE_SIZE; i++ ) {
- // entry[i] = 1.0 / i+0.5;
- divide_table[i] = fixdiv( F1_0*2, 2*i+1 );
- }
- }
- // -------------------------------------------------------------------------------------
- void init_fix_recip_table(void)
- {
- int i;
- fix_recip[0] = F1_0;
- for (i=1; i<FIX_RECIP_TABLE_SIZE; i++)
- fix_recip[i] = F1_0/i;
- Fix_recip_table_computed = 1;
- }
- // -------------------------------------------------------------------------------------
- // Initialize interface variables to assembler.
- // These things used to be constants. This routine is now (10/6/93) getting called for
- // every texture map. It should get called whenever the window changes, or, preferably,
- // not at all. I'm pretty sure these variables are only being used for range checking.
- void init_interface_vars_to_assembler(void)
- {
- grs_bitmap *bp;
- bp = &grd_curcanv->cv_bitmap;
- Assert(bp!=NULL);
- Assert(bp->bm_data!=NULL);
- Assert(bp->bm_h <= MAX_Y_POINTERS);
- // If bytes_per_row has changed, create new table of pointers.
- if (bytes_per_row != (int) bp->bm_rowsize) {
- int y_val, i;
- bytes_per_row = (int) bp->bm_rowsize;
- y_val = 0;
- for (i=0; i<MAX_Y_POINTERS; i++) {
- y_pointers[i] = y_val;
- y_val += bytes_per_row;
- }
- }
- write_buffer = (int) bp->bm_data;
- window_left = 0;
- window_right = (int) bp->bm_w-1;
- window_top = 0;
- window_bottom = (int) bp->bm_h-1;
- Window_clip_left = window_left;
- Window_clip_right = window_right;
- Window_clip_top = window_top;
- Window_clip_bot = window_bottom;
- window_width = bp->bm_w;
- window_height = bp->bm_h;
- if (!Fix_recip_table_computed)
- init_fix_recip_table();
- #if defined(POLY_ACC)
- pa_set_3d_offset(bp->bm_x, bp->bm_y);
- #endif
- if ( !divide_table_filled ) fill_divide_table();
- }
- // -------------------------------------------------------------------------------------
- // VARIABLES
- extern g3ds_tmap Tmap1;
- // -------------------------------------------------------------------------------------
- // Returns number preceding val modulo modulus.
- // prevmod(3,4) = 2
- // prevmod(0,4) = 3
- int prevmod(int val,int modulus)
- {
- if (val > 0)
- return val-1;
- else
- return modulus-1;
- // return (val + modulus - 1) % modulus;
- }
- // Returns number succeeding val modulo modulus.
- // succmod(3,4) = 0
- // succmod(0,4) = 1
- int succmod(int val,int modulus)
- {
- if (val < modulus-1)
- return val+1;
- else
- return 0;
- // return (val + 1) % modulus;
- }
- // -------------------------------------------------------------------------------------
- // Select topmost vertex (minimum y coordinate) and bottommost (maximum y coordinate) in
- // texture map. If either is part of a horizontal edge, then select leftmost vertex for
- // top, rightmost vertex for bottom.
- // Important: Vertex is selected with integer precision. So, if there are vertices at
- // (0.0,0.7) and (0.5,0.3), the first vertex is selected, because they y coordinates are
- // considered the same, so the smaller x is favored.
- // Parameters:
- // nv number of vertices
- // v3d pointer to 3d vertices containing u,v,x2d,y2d coordinates
- // Results in:
- // *min_y_ind
- // *max_y_ind
- // -------------------------------------------------------------------------------------
- void compute_y_bounds(g3ds_tmap *t, int *vlt, int *vlb, int *vrt, int *vrb,int *bottom_y_ind)
- {
- int i;
- int min_y,max_y;
- int min_y_ind;
- int original_vrt;
- fix min_x;
- // Scan all vertices, set min_y_ind to vertex with smallest y coordinate.
- min_y = f2i(t->verts[0].y2d);
- max_y = min_y;
- min_y_ind = 0;
- min_x = f2i(t->verts[0].x2d);
- *bottom_y_ind = 0;
- for (i=1; i<t->nv; i++) {
- if (f2i(t->verts[i].y2d) < min_y) {
- min_y = f2i(t->verts[i].y2d);
- min_y_ind = i;
- min_x = f2i(t->verts[i].x2d);
- } else if (f2i(t->verts[i].y2d) == min_y) {
- if (f2i(t->verts[i].x2d) < min_x) {
- min_y_ind = i;
- min_x = f2i(t->verts[i].x2d);
- }
- }
- if (f2i(t->verts[i].y2d) > max_y) {
- max_y = f2i(t->verts[i].y2d);
- *bottom_y_ind = i;
- }
- }
- //--removed mk, 11/27/94-- // Check for a non-upright-hourglass polygon and fix, if necessary, by bashing a y coordinate.
- //--removed mk, 11/27/94-- // min_y_ind = index of minimum y coordinate, *bottom_y_ind = index of maximum y coordinate
- //--removed mk, 11/27/94--{
- //--removed mk, 11/27/94-- int max_temp, min_temp;
- //--removed mk, 11/27/94--
- //--removed mk, 11/27/94-- max_temp = *bottom_y_ind;
- //--removed mk, 11/27/94-- if (*bottom_y_ind < min_y_ind)
- //--removed mk, 11/27/94-- max_temp += t->nv;
- //--removed mk, 11/27/94--
- //--removed mk, 11/27/94-- for (i=min_y_ind; i<max_temp; i++) {
- //--removed mk, 11/27/94-- if (f2i(t->verts[i%t->nv].y2d) > f2i(t->verts[(i+1)%t->nv].y2d)) {
- //--removed mk, 11/27/94-- Int3();
- //--removed mk, 11/27/94-- t->verts[(i+1)%t->nv].y2d = t->verts[i%t->nv].y2d;
- //--removed mk, 11/27/94-- }
- //--removed mk, 11/27/94-- }
- //--removed mk, 11/27/94--
- //--removed mk, 11/27/94-- min_temp = min_y_ind;
- //--removed mk, 11/27/94-- if (min_y_ind < *bottom_y_ind)
- //--removed mk, 11/27/94-- min_temp += t->nv;
- //--removed mk, 11/27/94--
- //--removed mk, 11/27/94-- for (i=*bottom_y_ind; i<min_temp; i++) {
- //--removed mk, 11/27/94-- if (f2i(t->verts[i%t->nv].y2d) < f2i(t->verts[(i+1)%t->nv].y2d)) {
- //--removed mk, 11/27/94-- Int3();
- //--removed mk, 11/27/94-- t->verts[(i+1)%t->nv].y2d = t->verts[i%t->nv].y2d;
- //--removed mk, 11/27/94-- }
- //--removed mk, 11/27/94-- }
- //--removed mk, 11/27/94--}
- // Set "vertex left top", etc. based on vertex with topmost y coordinate
- *vlt = min_y_ind;
- *vrt = *vlt;
- *vlb = prevmod(*vlt,t->nv);
- *vrb = succmod(*vrt,t->nv);
- // If right edge is horizontal, then advance along polygon bound until it no longer is or until all
- // vertices have been examined.
- // (Left edge cannot be horizontal, because *vlt is set to leftmost point with highest y coordinate.)
- original_vrt = *vrt;
- while (f2i(t->verts[*vrt].y2d) == f2i(t->verts[*vrb].y2d)) {
- if (succmod(*vrt,t->nv) == original_vrt) {
- break;
- }
- *vrt = succmod(*vrt,t->nv);
- *vrb = succmod(*vrt,t->nv);
- }
- }
- // -------------------------------------------------------------------------------------
- // Returns dx/dy given two vertices.
- // If dy == 0, returns 0.0
- // -------------------------------------------------------------------------------------
- //--fix compute_dx_dy_lin(g3ds_tmap *t, int top_vertex,int bottom_vertex)
- //--{
- //-- int dy;
- //--
- //-- // compute delta x with respect to y for any edge
- //-- dy = f2i(t->verts[bottom_vertex].y2d - t->verts[top_vertex].y2d) + 1;
- //-- if (dy)
- //-- return (t->verts[bottom_vertex].x2d - t->verts[top_vertex].x2d) / dy;
- //-- else
- //-- return 0;
- //--
- //--}
- fix compute_du_dy_lin(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
- {
- return fixmul(t->verts[bottom_vertex].u - t->verts[top_vertex].u, recip_dy);
- }
- fix compute_dv_dy_lin(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
- {
- return fixmul(t->verts[bottom_vertex].v - t->verts[top_vertex].v, recip_dy);
- }
- fix compute_dl_dy_lin(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
- {
- return fixmul(t->verts[bottom_vertex].l - t->verts[top_vertex].l, recip_dy);
- }
- fix compute_dx_dy(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
- {
- return fixmul(t->verts[bottom_vertex].x2d - t->verts[top_vertex].x2d, recip_dy);
- }
- fix compute_du_dy(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
- {
- return fixmul(fixmul(t->verts[bottom_vertex].u,t->verts[bottom_vertex].z) - fixmul(t->verts[top_vertex].u,t->verts[top_vertex].z), recip_dy);
- }
- fix compute_dv_dy(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
- {
- return fixmul(fixmul(t->verts[bottom_vertex].v,t->verts[bottom_vertex].z) - fixmul(t->verts[top_vertex].v,t->verts[top_vertex].z), recip_dy);
- }
- fix compute_dz_dy(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
- {
- return fixmul(t->verts[bottom_vertex].z - t->verts[top_vertex].z, recip_dy);
- }
- int Skip_short_flag=0;
- // -------------------------------------------------------------------------------------
- // Texture map current scanline in perspective.
- // -------------------------------------------------------------------------------------
- int Do_vertical_scan=0;
- int Break_on_flat=0;
- // -------------------------------------------------------------------------------------
- // Render a texture map with lighting using perspective interpolation in inner and outer loops.
- // -------------------------------------------------------------------------------------
- void ntmap_outerloop_correct_lighted( g3ds_tmap *t )
- {
- #define LINEAR 0 // 0=Perspective, 1=Linear
- #define LIGHTING 1 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_per // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_per // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 1 // Set to 1 to check window clip
- #define USE_UVS 1 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- void ntmap_outerloop_correct_nolight( g3ds_tmap *t )
- {
- #define LINEAR 0 // 0=Perspective, 1=Linear
- #define LIGHTING 0 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_per_nolight // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_per // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 1 // Set to 1 to check window clip
- #define USE_UVS 1 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- extern void asm_tmap_scanline_llt();
- void ntmap_outerloop_lin_lighted_trans( g3ds_tmap *t )
- {
- #define LINEAR 1 // 0=Perspective, 1=Linear
- #define LIGHTING 1 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_lin // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_llt // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 1 // Set to 1 to check window clip
- #define USE_UVS 1 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- extern void asm_tmap_scanline_lln();
- void ntmap_outerloop_lin_lighted_notrans( g3ds_tmap *t )
- {
- #define LINEAR 1 // 0=Perspective, 1=Linear
- #define LIGHTING 1 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_lin // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_lln // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 1 // Set to 1 to check window clip
- #define USE_UVS 1 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- extern void asm_tmap_scanline_plt();
- void ntmap_outerloop_per_lighted_trans( g3ds_tmap *t )
- {
- #define LINEAR 0 // 0=Perspective, 1=Linear
- #define LIGHTING 1 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_per // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_plt // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 1 // Set to 1 to check window clip
- #define USE_UVS 1 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- extern void asm_tmap_scanline_pln();
- void ntmap_outerloop_per_lighted_notrans( g3ds_tmap *t )
- {
- #define LINEAR 0 // 0=Perspective, 1=Linear
- #define LIGHTING 1 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_per // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_pln // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 1 // Set to 1 to check window clip
- #define USE_UVS 1 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- extern void asm_tmap_scanline_lnt();
- void ntmap_outerloop_lin_nolight_trans( g3ds_tmap *t )
- {
- #define LINEAR 1 // 0=Perspective, 1=Linear
- #define LIGHTING 0 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_lin_nolight // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_lnt // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 1 // Set to 1 to check window clip
- #define USE_UVS 1 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- extern void asm_tmap_scanline_lnn();
- void ntmap_outerloop_lin_nolight_notrans( g3ds_tmap *t )
- {
- #define LINEAR 1 // 0=Perspective, 1=Linear
- #define LIGHTING 0 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_lin_nolight // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_lnn // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 1 // Set to 1 to check window clip
- #define USE_UVS 1 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- extern void asm_tmap_scanline_pnt();
- void ntmap_outerloop_per_nolight_trans( g3ds_tmap *t )
- {
- #define LINEAR 0 // 0=Perspective, 1=Linear
- #define LIGHTING 0 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_per_nolight // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_pnt // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 1 // Set to 1 to check window clip
- #define USE_UVS 1 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- extern void asm_tmap_scanline_pnn();
- void ntmap_outerloop_per_nolight_notrans( g3ds_tmap *t )
- {
- #define LINEAR 0 // 0=Perspective, 1=Linear
- #define LIGHTING 0 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_per_nolight // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_pnn // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 1 // Set to 1 to check window clip
- #define USE_UVS 1 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- extern void asm_tmap_scanline_editor();
- extern void c_tmap_scanline_editor();
- void ntmap_outerloop_editor( g3ds_tmap *t )
- {
- #define LINEAR 0 // 0=Perspective, 1=Linear
- #define LIGHTING 0 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_editor // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_editor // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 0 // Set to 1 to check window clip
- #define USE_UVS 1 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- // -------------------------------------------------------------------------------------
- // Render a texture map.
- // Linear in outer loop, linear in inner loop.
- // -------------------------------------------------------------------------------------
- void texture_map_flat(g3ds_tmap *t)
- {
- #define LINEAR 1 // 0=Perspective, 1=Linear
- #define LIGHTING 0 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_flat // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_flat // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 1 // Set to 1 to check window clip
- #define USE_UVS 0 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- extern void asm_tmap_scanline_shaded(); // In tmapfade.asm
- void texture_map_flat_faded(g3ds_tmap *t)
- {
- #define LINEAR 1 // 0=Perspective, 1=Linear
- #define LIGHTING 0 // 0=No lighting, 1=Use lighting
- #ifdef NASM
- #define INNER_LOOP c_tmap_scanline_shaded // Function to be called when ready to draw.
- #else
- #define INNER_LOOP asm_tmap_scanline_shaded // Function to be called when ready to draw.
- #endif
- #define CHECK_WINDOW 1 // Set to 1 to check window clip
- #define USE_UVS 0 // Set to 1 to enable U,V interpolation
- #include "ntmapout.h"
- }
- // fix DivNum = F1_0*12;
- extern void draw_tmap_flat(grs_bitmap *bp,int nverts,g3s_point **vertbuf);
- // -------------------------------------------------------------------------------------
- // Interface from Matt's data structures to Mike's texture mapper.
- // -------------------------------------------------------------------------------------
- void draw_tmap(grs_bitmap *bp,int nverts,g3s_point **vertbuf)
- {
- int i;
- int lighting_mode = Lighting_on;
- int render_method;
- fix min_z;
- Assert(nverts <= MAX_TMAP_VERTS);
- Assert(bp->bm_w == 64);
- Assert(Lighting_on < 3);
- // If no transparency and seg depth is large, render as flat shaded.
- if ((Current_seg_depth > Max_linear_depth) && ((bp->bm_flags & 3) == 0)) {
- draw_tmap_flat(bp, nverts, vertbuf);
- return;
- }
- if ( bp->bm_flags & BM_FLAG_RLE )
- bp = rle_expand_texture( bp ); // Expand if rle'd
- Transparency_on = bp->bm_flags & BM_FLAG_TRANSPARENT;
- if (bp->bm_flags & BM_FLAG_NO_LIGHTING)
- lighting_mode = 0;
- pixptr = bp->bm_data;
- render_method = Interpolation_method;
- if (render_method==0) {
- if (Current_seg_depth > Max_perspective_depth)
- render_method = 1; // use linear
- else
- render_method = 2; // use perspective
- }
- // Setup texture map in Tmap1
- Tmap1.nv = nverts; // Initialize number of vertices
- for (i=0; i<nverts; i++) {
- g3ds_vertex *tvp = &Tmap1.verts[i];
- g3s_point *vp = vertbuf[i];
- tvp->x2d = vp->p3_sx;
- tvp->y2d = vp->p3_sy;
- tvp->u = vp->p3_u << 6; //* bp->bm_w;
- tvp->v = vp->p3_v << 6; //* bp->bm_h;
- // Perspective stuff:
- if ( render_method > 1 ) {
- //Check for overflow on fixdiv. Will overflow on vp->z <= something small. Allow only as low as 256.
- if (vp->p3_z < 256) {
- vp->p3_z = 256;
- // Int3(); // we would overflow if we divided!
- }
- tvp->z = vp->p3_z; //fixdiv(F1_0*12, vp->p3_z);
- if ( (i==0) || (tvp->z < min_z) )
- min_z = tvp->z;
- }
-
- // Lighting stuff:
- if (lighting_mode)
- tvp->l = vp->p3_l * NUM_LIGHTING_LEVELS;
- }
- // Calculate 1/Z for perspective
- if ( render_method > 1 ) {
- g3ds_vertex *tvp = Tmap1.verts;
- for (i=0; i<nverts; i++, tvp++) {
- tvp->z = fixdiv( min_z, tvp->z );
- // Z is now in the range 0-F1_0 (17 bits)
- // So, in the next line, we need to
- // scale Z down so that it fits in the available
- // number of significant bits (12 bits now). But, at the
- // same time, we're scaling it up by Z_SHIFTER amount so
- // that it use 30 bits for Z interpolation, which keeps the
- // dz_dx values from becoming so small that they go to zero.
- tvp->z <<= Z_SHIFTER-(17-DIVIDE_SIG_BITS);
- }
- }
- //old way:
- tvp->z = fixdiv(f1_0*12,tvp->z);
- // render_method:
- // 1 = linear, 2 = subdivided perspective, 3 = full perspective
- // lighting_mode:
- // 0 = no lighting, 1=lighting, 2=editor
- #ifndef __3DFX_NOT__
- if ( _3dfx_skip_ddraw )
- goto do_3dfx;
- #endif
- #if defined(POLY_ACC)
- switch (render_method)
- {
- /* obsolete 3/5/96.
- case 0: // choose best interpolation
- if (Current_seg_depth > Max_perspective_depth)
- pa_draw_tmap(bp, &Tmap1, Transparency_on, lighting_mode, 0); // linear
- else
- pa_draw_tmap(bp, &Tmap1, Transparency_on, lighting_mode, 1); // persp.
- break;
- */
- case 1: // linear interpolation
- pa_draw_tmap(bp, &Tmap1, Transparency_on, lighting_mode, 0, min_z); // linear
- break;
- case 2:
- case 3: // perspective every pixel interpolation
- pa_draw_tmap(bp, &Tmap1, Transparency_on, lighting_mode, 1, min_z); // persp.
- break;
- default:
- Assert(0); // Illegal value for Interpolation_method, must be 0,1,2,3
- }
- #else
- switch( lighting_mode ) {
- case 0:
- switch (render_method) {
- case 1: // linear interpolation
- if (Transparency_on)
- ntmap_outerloop_lin_nolight_trans(&Tmap1);
- else
- ntmap_outerloop_lin_nolight_notrans(&Tmap1);
- break;
- case 2: // subdivided perspective
- if (Transparency_on)
- ntmap_outerloop_per_nolight_trans( &Tmap1 );
- else
- ntmap_outerloop_per_nolight_notrans( &Tmap1 );
- break;
- case 3: // perspective every pixel interpolation
- ntmap_outerloop_correct_nolight( &Tmap1 );
- break;
- default:
- Assert(0); // Illegal value for Interpolation_method, must be 0,1,2,3
- }
- break;
- case 1:
- switch (render_method) {
- case 1: // linear interpolation
- if (Transparency_on)
- ntmap_outerloop_lin_lighted_trans(&Tmap1);
- else
- ntmap_outerloop_lin_lighted_notrans(&Tmap1);
- break;
- case 2: // subdivided perspective
- if (Transparency_on)
- ntmap_outerloop_per_lighted_trans( &Tmap1 );
- else
- ntmap_outerloop_per_lighted_notrans( &Tmap1 );
- break;
- case 3: // perspective every pixel interpolation
- ntmap_outerloop_correct_lighted( &Tmap1 );
- break;
- default:
- Assert(0); // Illegal value for Interpolation_method, must be 0,1,2,3
- }
- break;
- #ifdef EDITOR_TMAP
- case 2:
- ntmap_outerloop_editor( &Tmap1 );
- break;
- #endif
- }
- #endif //POLY_ACC
- #ifndef __3DFX_NOT__
- do_3dfx:
- if ( _3dfx_should_draw )
- {
- if ( Lighting_on )
- {
- guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB );
- _3dfxDrawTmap( bp, &Tmap1 );
- }
- else
- {
- guColorCombineFunction( GR_COLORCOMBINE_DECAL_TEXTURE );
- _3dfxDrawTmap( bp, &Tmap1 );
- }
- }
- _3dfx_triangles_rendered_post_clip += Tmap1.nv - 2;
- #endif
- }
- #ifndef __3DFX_NOT__
- #define SNAP( a ) ( ( fix ) ( (a) & ( 0xFFFFF000L ) ) )
- void _3dfxDrawTmap( grs_bitmap *bp, g3ds_tmap *Tmap1 )
- {
- GrVertex a, b, c;
- int i;
- if ( _3dfx_no_texture )
- guColorCombineFunction( GR_COLORCOMBINE_ITRGB );
- a.r = a.g = a.b = Tmap1->verts[0].l * fix_to_rgb;
- a.tmuvtx[0].oow = a.oow = Tmap1->verts[0].z * fix_to_ooz;
- a.tmuvtx[0].sow = Tmap1->verts[0].u * fix_to_st * a.oow;
- a.tmuvtx[0].tow = Tmap1->verts[0].v * fix_to_st * a.oow;
- a.x = SNAP( Tmap1->verts[0].x2d ) * fix_to_float;
- a.y = SNAP( Tmap1->verts[0].y2d ) * fix_to_float;
- for ( i = 1; i < Tmap1->nv - 1; i++ )
- {
- extern void sst1InitCheckForHang( void );
- b.r = b.g = b.b = Tmap1->verts[i].l * fix_to_rgb;
- b.tmuvtx[0].oow = b.oow = Tmap1->verts[i].z * fix_to_ooz;
- b.tmuvtx[0].sow = Tmap1->verts[i].u * fix_to_st * b.oow;
- b.tmuvtx[0].tow = Tmap1->verts[i].v * fix_to_st * b.oow;
- b.x = SNAP( Tmap1->verts[i].x2d ) * fix_to_float;
- b.y = SNAP( Tmap1->verts[i].y2d ) * fix_to_float;
- c.r = c.g = c.b = Tmap1->verts[i+1].l * fix_to_rgb;
- c.tmuvtx[0].oow = c.oow = Tmap1->verts[i+1].z * fix_to_ooz;
- c.tmuvtx[0].sow = Tmap1->verts[i+1].u * fix_to_st * c.oow;
- c.tmuvtx[0].tow = Tmap1->verts[i+1].v * fix_to_st * c.oow;
- c.x = SNAP( Tmap1->verts[i+1].x2d ) * fix_to_float;
- c.y = SNAP( Tmap1->verts[i+1].y2d ) * fix_to_float;
- sst1InitCheckForHang();
- grDrawTriangle( &a, &b, &c );
- sst1InitCheckForHang();
- }
- }
- #endif
|