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