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