home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser-CD 2000 January / LCD_01_2000.iso / games / doom / pmdoom / src / r_draw8.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-17  |  12.2 KB  |  510 lines

  1. /*  Emacs style mode select   -*- C++ -*-  */
  2. /* ----------------------------------------------------------------------------- */
  3. /*  */
  4. /*  $Id:$ */
  5. /*  */
  6. /*  Copyright (C) 1993-1996 by id Software, Inc. */
  7. /*  */
  8. /*  This source is available for distribution and/or modification */
  9. /*  only under the terms of the DOOM Source Code License as */
  10. /*  published by id Software. All rights reserved. */
  11. /*  */
  12. /*  The source is distributed in the hope that it will be useful, */
  13. /*  but WITHOUT ANY WARRANTY; without even the implied warranty of */
  14. /*  FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License */
  15. /*  for more details. */
  16. /*  */
  17. /*  $Log:$ */
  18. /*  */
  19. /*  DESCRIPTION: */
  20. /*     The actual span/column drawing functions. */
  21. /*     Here find the main potential for optimization, */
  22. /*      e.g. inline assembly, different algorithms. */
  23. /*  */
  24. /* ----------------------------------------------------------------------------- */
  25.  
  26.  
  27. static const char
  28. rcsid[] = "$Id: r_draw.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
  29.  
  30.  
  31. #include "doomdef.h"
  32.  
  33. #include "i_system.h"
  34. #include "z_zone.h"
  35. #include "w_wad.h"
  36.  
  37. #include "r_local.h"
  38.  
  39. /*  Needs access to LFB (guess what). */
  40. #include "v_video.h"
  41. #include "i_video.h"
  42.  
  43. /*  State. */
  44. #include "doomstat.h"
  45.  
  46. /*  */
  47. /*  R_DrawColumn */
  48. /*  Source is the top of the column to scale. */
  49. /*  */
  50.  
  51. /*  A column is a vertical slice/span from a wall texture that, */
  52. /*   given the DOOM style restrictions on the view orientation, */
  53. /*   will always have constant z depth. */
  54. /*  Thus a special case loop for very fast rendering can */
  55. /*   be used. It has also been used with Wolfenstein 3D. */
  56. /*   */
  57. #ifndef ATARI
  58. void R_DrawColumn8 (void) 
  59.     int            count; 
  60.     byte*        dest; 
  61.     fixed_t        frac;
  62.     fixed_t        fracstep;     
  63.  
  64.     count = dc_yh - dc_yl; 
  65.  
  66.     /*  Zero length, column does not exceed a pixel. */
  67.     if (count < 0) 
  68.     return; 
  69.                  
  70. #ifdef RANGECHECK 
  71.     if ((unsigned)dc_x >= SCREENWIDTH
  72.     || dc_yl < 0
  73.     || dc_yh >= SCREENHEIGHT) 
  74.     I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); 
  75. #endif 
  76.  
  77.     /*  Framebuffer destination address. */
  78.     /*  Use ylookup LUT to avoid multiply with ScreenWidth. */
  79.     /*  Use columnofs LUT for subwindows?  */
  80.     dest = ylookup[dc_yl] + columnofs[dc_x];  
  81.  
  82.     /*  Determine scaling, */
  83.     /*   which is the only mapping to be done. */
  84.     fracstep = dc_iscale; 
  85.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  86.  
  87.     /*  Inner loop that does the actual texture mapping, */
  88.     /*   e.g. a DDA-lile scaling. */
  89.     /*  This is as fast as it gets. */
  90.     do 
  91.     {
  92.     /*  Re-map color indices from wall texture column */
  93.     /*   using a lighting/special effects LUT. */
  94.     *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
  95.     
  96.     dest += SCREENWIDTH;
  97.     frac += fracstep;
  98.     
  99.     } while (count--); 
  100.  
  101.  
  102. void R_DrawColumnLow8 (void) 
  103.     int            count; 
  104.     byte*        dest; 
  105.     byte*        dest2;
  106.     fixed_t        frac;
  107.     fixed_t        fracstep;     
  108.  
  109.     count = dc_yh - dc_yl; 
  110.  
  111.     /*  Zero length. */
  112.     if (count < 0) 
  113.     return; 
  114.                  
  115. #ifdef RANGECHECK 
  116.     if ((unsigned)dc_x >= SCREENWIDTH
  117.     || dc_yl < 0
  118.     || dc_yh >= SCREENHEIGHT)
  119.     {
  120.     
  121.     I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
  122.     }
  123.     /*     dccount++;  */
  124. #endif 
  125.     /*  Blocky mode, need to multiply by 2. */
  126. /*     dc_x <<= 1; */
  127.     
  128.     dest = ylookup[dc_yl] + columnofs[dc_x << 1];
  129.     dest2 = ylookup[dc_yl] + columnofs[(dc_x <<1)+1];
  130.     
  131.     fracstep = dc_iscale; 
  132.     frac = dc_texturemid + (dc_yl-centery)*fracstep;
  133.     
  134.     do 
  135.     {
  136.     /*  Hack. Does not work corretly. */
  137.     *dest2 = *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
  138.     dest += SCREENWIDTH;
  139.     dest2 += SCREENWIDTH;
  140.     frac += fracstep; 
  141.  
  142.     } while (count--);
  143. }
  144. #endif
  145.  
  146. /*  */
  147. /*  Spectre/Invisibility. */
  148. /*  */
  149. #define FUZZTABLE        50 
  150. #define FUZZOFF    (SCREENWIDTH)
  151.  
  152.  
  153. int    fuzzoffset[FUZZTABLE] =
  154. {
  155.     FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  156.     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  157.     FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,
  158.     FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  159.     FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
  160.     FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
  161.     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF 
  162. }; 
  163.  
  164. int    fuzzpos = 0; 
  165.  
  166.  
  167. /*  */
  168. /*  Framebuffer postprocessing. */
  169. /*  Creates a fuzzy image by copying pixels */
  170. /*   from adjacent ones to left and right. */
  171. /*  Used with an all black colormap, this */
  172. /*   could create the SHADOW effect, */
  173. /*   i.e. spectres and invisible players. */
  174. /*  */
  175. #ifndef ATARI
  176. void R_DrawFuzzColumn8 (void) 
  177.     int            count; 
  178.     byte*        dest; 
  179.     fixed_t        frac;
  180.     fixed_t        fracstep;     
  181.  
  182.     /*  Adjust borders. Low...  */
  183.     if (!dc_yl) 
  184.     dc_yl = 1;
  185.  
  186.     /*  .. and high. */
  187.     if (dc_yh == viewheight-1) 
  188.     dc_yh = viewheight - 2; 
  189.          
  190.     count = dc_yh - dc_yl; 
  191.  
  192.     /*  Zero length. */
  193.     if (count < 0) 
  194.     return; 
  195.  
  196.     
  197. #ifdef RANGECHECK 
  198.     if ((unsigned)dc_x >= SCREENWIDTH
  199.     || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  200.     {
  201.     I_Error ("R_DrawFuzzColumn: %i to %i at %i",
  202.          dc_yl, dc_yh, dc_x);
  203.     }
  204. #endif
  205.     
  206.     /*  Does not work with blocky mode. */
  207.     dest = ylookup[dc_yl] + columnofs[dc_x];
  208.  
  209.     /*  Looks familiar. */
  210.     fracstep = dc_iscale; 
  211.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  212.  
  213.     /*  Looks like an attempt at dithering, */
  214.     /*   using the colormap #6 (of 0-31, a bit */
  215.     /*   brighter than average). */
  216.     do 
  217.     {
  218.     /*  Lookup framebuffer, and retrieve */
  219.     /*   a pixel that is either one column */
  220.     /*   left or right of the current one. */
  221.     /*  Add index from colormap to index. */
  222.     *dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]]; 
  223.  
  224.     /*  Clamp table lookup index. */
  225.     if (++fuzzpos == FUZZTABLE) 
  226.         fuzzpos = 0;
  227.     
  228.     dest += SCREENWIDTH;
  229.  
  230.     frac += fracstep; 
  231.     } while (count--); 
  232.  
  233. void R_DrawFuzzColumnLow8 (void) 
  234.     int            count; 
  235.     byte        *dest,*dest2; 
  236.     fixed_t        frac;
  237.     fixed_t        fracstep;     
  238.  
  239.     /*  Adjust borders. Low...  */
  240.     if (!dc_yl) 
  241.     dc_yl = 1;
  242.  
  243.     /*  .. and high. */
  244.     if (dc_yh == viewheight-1) 
  245.     dc_yh = viewheight - 2; 
  246.          
  247.     count = dc_yh - dc_yl; 
  248.  
  249.     /*  Zero length. */
  250.     if (count < 0) 
  251.     return; 
  252.  
  253.     
  254. #ifdef RANGECHECK 
  255.     if ((unsigned)dc_x >= SCREENWIDTH
  256.     || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  257.     {
  258.     I_Error ("R_DrawFuzzColumn: %i to %i at %i",
  259.          dc_yl, dc_yh, dc_x);
  260.     }
  261. #endif
  262.     
  263.     /*  Does not work with blocky mode. */
  264.     dest = ylookup[dc_yl] + columnofs[dc_x << 1];
  265.     dest2 = ylookup[dc_yl] + columnofs[(dc_x << 1)+1];
  266.  
  267.     /*  Looks familiar. */
  268.     fracstep = dc_iscale; 
  269.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  270.  
  271.     /*  Looks like an attempt at dithering, */
  272.     /*   using the colormap #6 (of 0-31, a bit */
  273.     /*   brighter than average). */
  274.     do 
  275.     {
  276.     /*  Lookup framebuffer, and retrieve */
  277.     /*   a pixel that is either one column */
  278.     /*   left or right of the current one. */
  279.     /*  Add index from colormap to index. */
  280.     *dest = *dest2 = colormaps[6*256+dest[fuzzoffset[fuzzpos]]]; 
  281.  
  282.     /*  Clamp table lookup index. */
  283.     if (++fuzzpos == FUZZTABLE) 
  284.         fuzzpos = 0;
  285.     
  286.     dest += SCREENWIDTH;
  287.     dest2 += SCREENWIDTH;
  288.  
  289.     frac += fracstep; 
  290.     } while (count--); 
  291. }  
  292.  
  293. /*  */
  294. /*  R_DrawTranslatedColumn */
  295. /*  Used to draw player sprites */
  296. /*   with the green colorramp mapped to others. */
  297. /*  Could be used with different translation */
  298. /*   tables, e.g. the lighter colored version */
  299. /*   of the BaronOfHell, the HellKnight, uses */
  300. /*   identical sprites, kinda brightened up. */
  301. /*  */
  302. void R_DrawTranslatedColumn8 (void) 
  303.     int            count; 
  304.     byte*        dest; 
  305.     fixed_t        frac;
  306.     fixed_t        fracstep;     
  307.  
  308.     count = dc_yh - dc_yl; 
  309.     if (count < 0) 
  310.     return; 
  311.                  
  312. #ifdef RANGECHECK 
  313.     if ((unsigned)dc_x >= SCREENWIDTH
  314.     || dc_yl < 0
  315.     || dc_yh >= SCREENHEIGHT)
  316.     {
  317.     I_Error ( "R_DrawColumn: %i to %i at %i",
  318.           dc_yl, dc_yh, dc_x);
  319.     }
  320.     
  321. #endif 
  322.     
  323.     /*  FIXME. As above. */
  324.     dest = ylookup[dc_yl] + columnofs[dc_x]; 
  325.  
  326.     /*  Looks familiar. */
  327.     fracstep = dc_iscale; 
  328.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  329.  
  330.     /*  Here we do an additional index re-mapping. */
  331.     do 
  332.     {
  333.     /*  Translation tables are used */
  334.     /*   to map certain colorramps to other ones, */
  335.     /*   used with PLAY sprites. */
  336.     /*  Thus the "green" ramp of the player 0 sprite */
  337.     /*   is mapped to gray, red, black/indigo.  */
  338.     *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
  339.     dest += SCREENWIDTH;
  340.     
  341.     frac += fracstep; 
  342.     } while (count--); 
  343.  
  344. void R_DrawTranslatedColumnLow8 (void) 
  345.     int            count; 
  346.     byte        *dest,*dest2; 
  347.     fixed_t        frac;
  348.     fixed_t        fracstep;     
  349.  
  350.     count = dc_yh - dc_yl; 
  351.     if (count < 0) 
  352.     return; 
  353.                  
  354. #ifdef RANGECHECK 
  355.     if ((unsigned)dc_x >= SCREENWIDTH
  356.     || dc_yl < 0
  357.     || dc_yh >= SCREENHEIGHT)
  358.     {
  359.     I_Error ( "R_DrawColumn: %i to %i at %i",
  360.           dc_yl, dc_yh, dc_x);
  361.     }
  362.     
  363. #endif 
  364.     
  365.     /*  FIXME. As above. */
  366.     dest = ylookup[dc_yl] + columnofs[dc_x << 1]; 
  367.     dest2 = ylookup[dc_yl] + columnofs[(dc_x << 1)+1]; 
  368.  
  369.     /*  Looks familiar. */
  370.     fracstep = dc_iscale; 
  371.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  372.  
  373.     /*  Here we do an additional index re-mapping. */
  374.     do 
  375.     {
  376.     /*  Translation tables are used */
  377.     /*   to map certain colorramps to other ones, */
  378.     /*   used with PLAY sprites. */
  379.     /*  Thus the "green" ramp of the player 0 sprite */
  380.     /*   is mapped to gray, red, black/indigo.  */
  381.     *dest = *dest2 = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
  382.     dest += SCREENWIDTH;
  383.     dest2 += SCREENWIDTH;
  384.     
  385.     frac += fracstep; 
  386.     } while (count--); 
  387.  
  388.  
  389. /*  */
  390. /*  R_DrawSpan  */
  391. /*  With DOOM style restrictions on view orientation, */
  392. /*   the floors and ceilings consist of horizontal slices */
  393. /*   or spans with constant z depth. */
  394. /*  However, rotation around the world z axis is possible, */
  395. /*   thus this mapping, while simpler and faster than */
  396. /*   perspective correct texture mapping, has to traverse */
  397. /*   the texture at an angle in all but a few cases. */
  398. /*  In consequence, flats are not stored by column (like walls), */
  399. /*   and the inner loop has to step in texture space u and v. */
  400. /*  */
  401.  
  402. /*  */
  403. /*  Draws the actual span. */
  404. void R_DrawSpan8 (void) 
  405.     fixed_t        xfrac;
  406.     fixed_t        yfrac; 
  407.     byte*        dest; 
  408.     int            count;
  409.     int            spot; 
  410.      
  411. #ifdef RANGECHECK 
  412.     if (ds_x2 < ds_x1
  413.     || ds_x1<0
  414.     || ds_x2>=SCREENWIDTH  
  415.     || (unsigned)ds_y>SCREENHEIGHT)
  416.     {
  417.     I_Error( "R_DrawSpan: %i to %i at %i",
  418.          ds_x1,ds_x2,ds_y);
  419.     }
  420. /*     dscount++;  */
  421. #endif 
  422.  
  423.     
  424.     xfrac = ds_xfrac; 
  425.     yfrac = ds_yfrac; 
  426.      
  427.     dest = ylookup[ds_y] + columnofs[ds_x1];
  428.  
  429.     /*  We do not check for zero spans here? */
  430.     count = ds_x2 - ds_x1; 
  431.  
  432.     do 
  433.     {
  434.     /*  Current texture index in u,v. */
  435.     spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
  436.  
  437.     /*  Lookup pixel from flat texture tile, */
  438.     /*   re-index using light/colormap. */
  439.     *dest++ = ds_colormap[ds_source[spot]];
  440.  
  441.     /*  Next step in u,v. */
  442.     xfrac += ds_xstep; 
  443.     yfrac += ds_ystep;
  444.     
  445.     } while (count--); 
  446.  
  447.  
  448.  
  449.  
  450. /*  */
  451. /*  Again.. */
  452. /*  */
  453. void R_DrawSpanLow8 (void) 
  454.     fixed_t        xfrac;
  455.     fixed_t        yfrac; 
  456.     byte*        dest; 
  457.     int            count;
  458.     int            spot; 
  459.      
  460. #ifdef RANGECHECK 
  461.     if (ds_x2 < ds_x1
  462.     || ds_x1<0
  463.     || ds_x2>=SCREENWIDTH  
  464.     || (unsigned)ds_y>SCREENHEIGHT)
  465.     {
  466.     I_Error( "R_DrawSpan: %i to %i at %i",
  467.          ds_x1,ds_x2,ds_y);
  468.     }
  469. /*     dscount++;  */
  470. #endif 
  471.      
  472.     xfrac = ds_xfrac; 
  473.     yfrac = ds_yfrac; 
  474.  
  475.     /*  Blocky mode, need to multiply by 2. */
  476. /*     ds_x1 <<= 1; */
  477. /*     ds_x2 <<= 1; */
  478.     
  479.     dest = ylookup[ds_y] + columnofs[ds_x1 << 1];
  480.   
  481.     
  482.     count = ds_x2 - ds_x1; 
  483.     do 
  484.     { 
  485.     spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
  486.     /*  Lowres/blocky mode does it twice, */
  487.     /*   while scale is adjusted appropriately. */
  488.     *dest++ = ds_colormap[ds_source[spot]]; 
  489.     *dest++ = ds_colormap[ds_source[spot]];
  490.     
  491.     xfrac += ds_xstep; 
  492.     yfrac += ds_ystep; 
  493.  
  494.     } while (count--); 
  495. }
  496. #endif
  497.