home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser-CD 2000 January / LCD_01_2000.iso / games / doom / pmdoom / src / r_draw32.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-17  |  11.4 KB  |  484 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. unsigned long    fuzzmask;
  52.  
  53. /*  */
  54. /*  A column is a vertical slice/span from a wall texture that, */
  55. /*   given the DOOM style restrictions on the view orientation, */
  56. /*   will always have constant z depth. */
  57. /*  Thus a special case loop for very fast rendering can */
  58. /*   be used. It has also been used with Wolfenstein 3D. */
  59. /*   */
  60.  
  61. void R_DrawColumn32 (void) 
  62.     int            count; 
  63.     unsigned long    *dest; 
  64.     fixed_t        frac;
  65.     fixed_t        fracstep;     
  66.  
  67.     count = dc_yh - dc_yl; 
  68.  
  69.     /*  Zero length, column does not exceed a pixel. */
  70.     if (count < 0) 
  71.     return; 
  72.                  
  73. #ifdef RANGECHECK 
  74.     if ((unsigned)dc_x >= SCREENWIDTH
  75.     || dc_yl < 0
  76.     || dc_yh >= SCREENHEIGHT) 
  77.     I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); 
  78. #endif 
  79.  
  80.     /*  Framebuffer destination address. */
  81.     /*  Use ylookup LUT to avoid multiply with ScreenWidth. */
  82.     /*  Use columnofs LUT for subwindows?  */
  83.     dest = (unsigned long *) (ylookup[dc_yl] + columnofs[dc_x] );  
  84.  
  85.     /*  Determine scaling, */
  86.     /*   which is the only mapping to be done. */
  87.     fracstep = dc_iscale; 
  88.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  89.  
  90.     /*  Inner loop that does the actual texture mapping, */
  91.     /*   e.g. a DDA-lile scaling. */
  92.     /*  This is as fast as it gets. */
  93.     do 
  94.     {
  95.         /*  Re-map color indices from wall texture column */
  96.         /*   using a lighting/special effects LUT. */
  97.         *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
  98.     
  99.         dest += SCREENWIDTH;
  100.         frac += fracstep;
  101.     } while (count--); 
  102.  
  103.  
  104. void R_DrawColumnLow32 (void) 
  105.     int            count; 
  106.     unsigned long    *dest; 
  107.     fixed_t        frac;
  108.     fixed_t        fracstep;     
  109.  
  110.     count = dc_yh - dc_yl; 
  111.  
  112.     /*  Zero length. */
  113.     if (count < 0) 
  114.     return; 
  115.                  
  116. #ifdef RANGECHECK 
  117.     if ((unsigned)dc_x >= SCREENWIDTH
  118.     || dc_yl < 0
  119.     || dc_yh >= SCREENHEIGHT)
  120.     {
  121.     
  122.     I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
  123.     }
  124.     /*     dccount++;  */
  125. #endif 
  126.     /*  Blocky mode, need to multiply by 2. */
  127. /*     dc_x <<= 1; */
  128.     
  129.     dest = (unsigned long *) (ylookup[dc_yl] + columnofs[dc_x << 1] );
  130.     
  131.     fracstep = dc_iscale; 
  132.     frac = dc_texturemid + (dc_yl-centery)*fracstep;
  133.     
  134.     do 
  135.     {
  136.         unsigned long couleur;
  137.  
  138.         couleur=dc_colormap[dc_source[(frac>>FRACBITS)&127]];
  139.  
  140.         *dest++ = couleur;
  141.         *dest-- = couleur;
  142.  
  143.         dest += SCREENWIDTH>>1;
  144.         frac += fracstep; 
  145.     } while (count--);
  146. }
  147.  
  148. /*  */
  149. /*  Spectre/Invisibility. */
  150. /*  */
  151.  
  152. /*  */
  153. /*  Framebuffer postprocessing. */
  154. /*  Creates a fuzzy image by copying pixels */
  155. /*   from adjacent ones to left and right. */
  156. /*  Used with an all black colormap, this */
  157. /*   could create the SHADOW effect, */
  158. /*   i.e. spectres and invisible players. */
  159. /*  */
  160.  
  161. void R_DrawFuzzColumn32 (void) 
  162.     int            count; 
  163.     unsigned long    *dest; 
  164.     fixed_t        frac;
  165.     fixed_t        fracstep;     
  166.  
  167.     count = dc_yh - dc_yl; 
  168.  
  169.     /*  Zero length. */
  170.     if (count < 0) 
  171.     return; 
  172.  
  173.     
  174. #ifdef RANGECHECK 
  175.     if ((unsigned)dc_x >= SCREENWIDTH
  176.     || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  177.     {
  178.     I_Error ("R_DrawFuzzColumn: %i to %i at %i",
  179.          dc_yl, dc_yh, dc_x);
  180.     }
  181. #endif
  182.     
  183.     /*  Does not work with blocky mode. */
  184.     dest = (unsigned long *) (ylookup[dc_yl] + columnofs[dc_x] );
  185.  
  186.     /*  Looks familiar. */
  187.     fracstep = dc_iscale; 
  188.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  189.  
  190.     /*  Looks like an attempt at dithering, */
  191.     /*   using the colormap #6 (of 0-31, a bit */
  192.     /*   brighter than average). */
  193.     do 
  194.     {
  195.         /*  Lookup framebuffer, and retrieve */
  196.         /*   a pixel that is either one column */
  197.         /*   left or right of the current one. */
  198.         /*  Add index from colormap to index. */
  199.         *dest = (*dest >> 1) & fuzzmask; 
  200.  
  201.         dest += SCREENWIDTH;
  202.  
  203.         frac += fracstep; 
  204.     } while (count--); 
  205.  
  206. void R_DrawFuzzColumnLow32 (void) 
  207.     int            count; 
  208.     unsigned long     *dest; 
  209.     fixed_t        frac;
  210.     fixed_t        fracstep;     
  211.  
  212.     count = dc_yh - dc_yl; 
  213.  
  214.     /*  Zero length. */
  215.     if (count < 0) 
  216.     return; 
  217.  
  218.     
  219. #ifdef RANGECHECK 
  220.     if ((unsigned)dc_x >= SCREENWIDTH
  221.     || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  222.     {
  223.     I_Error ("R_DrawFuzzColumn: %i to %i at %i",
  224.          dc_yl, dc_yh, dc_x);
  225.     }
  226. #endif
  227. /*     dc_x <<= 1; */
  228.     
  229.     /*  Does not work with blocky mode. */
  230.     dest = (unsigned long *) (ylookup[dc_yl] + columnofs[dc_x << 1]);
  231.  
  232.     /*  Looks familiar. */
  233.     fracstep = dc_iscale; 
  234.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  235.  
  236.     /*  Looks like an attempt at dithering, */
  237.     /*   using the colormap #6 (of 0-31, a bit */
  238.     /*   brighter than average). */
  239.     do 
  240.     {
  241.         unsigned long couleur;
  242.  
  243.         /*  Lookup framebuffer, and retrieve */
  244.         /*   a pixel that is either one column */
  245.         /*   left or right of the current one. */
  246.         /*  Add index from colormap to index. */
  247.         couleur = (*dest >> 1) & fuzzmask; 
  248.  
  249.         *dest++ = couleur;
  250.         *dest-- = couleur;
  251.  
  252.         dest += SCREENWIDTH>>1;
  253.  
  254.         frac += fracstep; 
  255.     } while (count--); 
  256.   
  257.  
  258.  
  259. /*  */
  260. /*  R_DrawTranslatedColumn */
  261. /*  Used to draw player sprites */
  262. /*   with the green colorramp mapped to others. */
  263. /*  Could be used with different translation */
  264. /*   tables, e.g. the lighter colored version */
  265. /*   of the BaronOfHell, the HellKnight, uses */
  266. /*   identical sprites, kinda brightened up. */
  267. /*  */
  268.  
  269. void R_DrawTranslatedColumn32 (void) 
  270.     int            count; 
  271.     unsigned long     *dest; 
  272.     fixed_t        frac;
  273.     fixed_t        fracstep;     
  274.  
  275.     count = dc_yh - dc_yl; 
  276.     if (count < 0) 
  277.     return; 
  278.                  
  279. #ifdef RANGECHECK 
  280.     if ((unsigned)dc_x >= SCREENWIDTH
  281.     || dc_yl < 0
  282.     || dc_yh >= SCREENHEIGHT)
  283.     {
  284.     I_Error ( "R_DrawColumn: %i to %i at %i",
  285.           dc_yl, dc_yh, dc_x);
  286.     }
  287.     
  288. #endif 
  289.     
  290.     /*  FIXME. As above. */
  291.     dest = (unsigned long *) (ylookup[dc_yl] + columnofs[dc_x]); 
  292.  
  293.     /*  Looks familiar. */
  294.     fracstep = dc_iscale; 
  295.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  296.  
  297.     /*  Here we do an additional index re-mapping. */
  298.     do 
  299.     {
  300.         /*  Translation tables are used */
  301.         /*   to map certain colorramps to other ones, */
  302.         /*   used with PLAY sprites. */
  303.         /*  Thus the "green" ramp of the player 0 sprite */
  304.         /*   is mapped to gray, red, black/indigo.  */
  305.         *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
  306.         dest += SCREENWIDTH;
  307.     
  308.         frac += fracstep; 
  309.     } while (count--); 
  310.  
  311. void R_DrawTranslatedColumnLow32 (void) 
  312.     int            count; 
  313.     unsigned long    *dest; 
  314.     fixed_t        frac;
  315.     fixed_t        fracstep;     
  316.  
  317.     count = dc_yh - dc_yl; 
  318.     if (count < 0) 
  319.     return; 
  320.                  
  321. #ifdef RANGECHECK 
  322.     if ((unsigned)dc_x >= SCREENWIDTH
  323.     || dc_yl < 0
  324.     || dc_yh >= SCREENHEIGHT)
  325.     {
  326.     I_Error ( "R_DrawColumn: %i to %i at %i",
  327.           dc_yl, dc_yh, dc_x);
  328.     }
  329.     
  330. #endif 
  331. /*     dc_x <<= 1; */
  332.     
  333.     /*  FIXME. As above. */
  334.     dest = (unsigned long *) (ylookup[dc_yl] + columnofs[dc_x << 1]); 
  335.  
  336.     /*  Looks familiar. */
  337.     fracstep = dc_iscale; 
  338.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  339.  
  340.     /*  Here we do an additional index re-mapping. */
  341.     do 
  342.     {
  343.         unsigned long couleur;
  344.         /*  Translation tables are used */
  345.         /*   to map certain colorramps to other ones, */
  346.         /*   used with PLAY sprites. */
  347.         /*  Thus the "green" ramp of the player 0 sprite */
  348.         /*   is mapped to gray, red, black/indigo.  */
  349.         couleur = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
  350.     
  351.         *dest++ = couleur;
  352.         *dest-- = couleur;
  353.  
  354.         dest += SCREENWIDTH>>1;
  355.     
  356.         frac += fracstep; 
  357.     } while (count--); 
  358.  
  359. /*  */
  360. /*  R_DrawSpan  */
  361. /*  With DOOM style restrictions on view orientation, */
  362. /*   the floors and ceilings consist of horizontal slices */
  363. /*   or spans with constant z depth. */
  364. /*  However, rotation around the world z axis is possible, */
  365. /*   thus this mapping, while simpler and faster than */
  366. /*   perspective correct texture mapping, has to traverse */
  367. /*   the texture at an angle in all but a few cases. */
  368. /*  In consequence, flats are not stored by column (like walls), */
  369. /*   and the inner loop has to step in texture space u and v. */
  370. /*  */
  371.  
  372. /*  */
  373. /*  Draws the actual span. */
  374. void R_DrawSpan32 (void) 
  375.     fixed_t        xfrac;
  376.     fixed_t        yfrac; 
  377.     unsigned long    *dest; 
  378.     int            count;
  379.     int            spot; 
  380.      
  381. #ifdef RANGECHECK 
  382.     if (ds_x2 < ds_x1
  383.     || ds_x1<0
  384.     || ds_x2>=SCREENWIDTH  
  385.     || (unsigned)ds_y>SCREENHEIGHT)
  386.     {
  387.     I_Error( "R_DrawSpan: %i to %i at %i",
  388.          ds_x1,ds_x2,ds_y);
  389.     }
  390. /*     dscount++;  */
  391. #endif 
  392.  
  393.     
  394.     xfrac = ds_xfrac; 
  395.     yfrac = ds_yfrac; 
  396.      
  397.     dest = (unsigned long *) (ylookup[ds_y] + columnofs[ds_x1]);
  398.  
  399.     /*  We do not check for zero spans here? */
  400.     count = ds_x2 - ds_x1; 
  401.  
  402.     do 
  403.     {
  404.         /*  Current texture index in u,v. */
  405.         spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
  406.  
  407.         /*  Lookup pixel from flat texture tile, */
  408.         /*   re-index using light/colormap. */
  409.         *dest++ = ds_colormap[ds_source[spot]];
  410.  
  411.         /*  Next step in u,v. */
  412.         xfrac += ds_xstep; 
  413.         yfrac += ds_ystep;
  414.     } while (count--); 
  415.  
  416.  
  417.  
  418.  
  419. /*  */
  420. /*  Again.. */
  421. /*  */
  422. void R_DrawSpanLow32 (void) 
  423.     fixed_t        xfrac;
  424.     fixed_t        yfrac; 
  425.     unsigned long    *dest; 
  426.     int            count;
  427.     int            spot; 
  428.      
  429. #ifdef RANGECHECK 
  430.     if (ds_x2 < ds_x1
  431.     || ds_x1<0
  432.     || ds_x2>=SCREENWIDTH  
  433.     || (unsigned)ds_y>SCREENHEIGHT)
  434.     {
  435.     I_Error( "R_DrawSpan: %i to %i at %i",
  436.          ds_x1,ds_x2,ds_y);
  437.     }
  438. /*     dscount++;  */
  439. #endif 
  440.      
  441.     xfrac = ds_xfrac; 
  442.     yfrac = ds_yfrac; 
  443.  
  444.     /*  Blocky mode, need to multiply by 2. */
  445. /*     ds_x1 <<= 1; */
  446. /*     ds_x2 <<= 1; */
  447.     
  448.     dest = (unsigned long *) (ylookup[ds_y] + columnofs[ds_x1 << 1]);
  449.   
  450.     
  451. /*     count = (ds_x2 - ds_x1) >> 1;  */
  452.     count = ds_x2 - ds_x1;
  453.     do 
  454.     { 
  455.         unsigned long couleur;
  456.  
  457.         spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
  458.         /*  Lowres/blocky mode does it twice, */
  459.         /*   while scale is adjusted appropriately. */
  460.  
  461.         couleur = ds_colormap[ds_source[spot]]; 
  462.  
  463.         *dest++ = couleur;
  464.         *dest++ = couleur;
  465.     
  466.         xfrac += ds_xstep; 
  467.         yfrac += ds_ystep; 
  468.     } while (count--); 
  469. }
  470.