home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser-CD 2000 January / LCD_01_2000.iso / games / doom / pmdoom / src / r_draw.c < prev    next >
C/C++ Source or Header  |  1999-12-17  |  10KB  |  406 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. /*  All drawing to the view buffer is accomplished in this file. */
  48. /*  The other refresh files only know about ccordinates, */
  49. /*   not the architecture of the frame buffer. */
  50. /*  Conveniently, the frame buffer is a linear one, */
  51. /*   and we need only the base address, */
  52. /*   and the total size == width*height*depth/8., */
  53. /*  */
  54.  
  55.  
  56. byte*        viewimage; 
  57. int        viewwidth;
  58. int        scaledviewwidth;
  59. int        viewheight;
  60. int        viewwindowx;
  61. int        viewwindowy; 
  62. int        columnofs[MAXWIDTH]; 
  63.  
  64. byte    *ylookup[MAXHEIGHT]; 
  65.  
  66. /*  Color tables for different players, */
  67. /*   translate a limited part to another */
  68. /*   (color ramps used for  suit colors). */
  69. /*  */
  70. byte        translations[3][256];    
  71.  
  72.  
  73.  
  74.  
  75. /*  */
  76. /*  R_DrawColumn */
  77. /*  Source is the top of the column to scale. */
  78. /*  */
  79. lighttable_t*        dc_colormap; 
  80. int            dc_x; 
  81. int            dc_yl; 
  82. int            dc_yh; 
  83. fixed_t            dc_iscale; 
  84. fixed_t            dc_texturemid;
  85.  
  86. /*  first pixel in a column (possibly virtual)  */
  87. byte*            dc_source;        
  88.  
  89. /*  just for profiling  */
  90. int            dccount;
  91.  
  92. byte*    dc_translation;
  93. byte*    translationtables;
  94.  
  95. /*  */
  96. /*  R_InitTranslationTables */
  97. /*  Creates the translation tables to map */
  98. /*   the green color ramp to gray, brown, red. */
  99. /*  Assumes a given structure of the PLAYPAL. */
  100. /*  Could be read from a lump instead. */
  101. /*  */
  102. void R_InitTranslationTables (void)
  103. {
  104.     int        i;
  105.     
  106. #if 0
  107.     translationtables = Z_Malloc (256*3+255, PU_STATIC, 0);
  108.     translationtables = (byte *)(( (int)translationtables + 255 )& ~255);
  109. #else
  110.     translationtables = Z_Malloc (256*3, PU_STATIC, 0);
  111. #endif
  112.     
  113.     /*  translate just the 16 green colors */
  114.     for (i=0 ; i<256 ; i++)
  115.     {
  116.     if (i >= 0x70 && i<= 0x7f)
  117.     {
  118.         /*  map green ramp to gray, brown, red */
  119.         translationtables[i] = 0x60 + (i&0xf);
  120.         translationtables [i+256] = 0x40 + (i&0xf);
  121.         translationtables [i+512] = 0x20 + (i&0xf);
  122.     }
  123.     else
  124.     {
  125.         /*  Keep all other colors as is. */
  126.         translationtables[i] = translationtables[i+256] 
  127.         = translationtables[i+512] = i;
  128.     }
  129.     }
  130. }
  131.  
  132. /*  */
  133. /*  R_DrawSpan  */
  134. /*  With DOOM style restrictions on view orientation, */
  135. /*   the floors and ceilings consist of horizontal slices */
  136. /*   or spans with constant z depth. */
  137. /*  However, rotation around the world z axis is possible, */
  138. /*   thus this mapping, while simpler and faster than */
  139. /*   perspective correct texture mapping, has to traverse */
  140. /*   the texture at an angle in all but a few cases. */
  141. /*  In consequence, flats are not stored by column (like walls), */
  142. /*   and the inner loop has to step in texture space u and v. */
  143. /*  */
  144. int            ds_y; 
  145. int            ds_x1; 
  146. int            ds_x2;
  147.  
  148. lighttable_t*        ds_colormap; 
  149.  
  150. fixed_t            ds_xfrac; 
  151. fixed_t            ds_yfrac; 
  152. fixed_t            ds_xstep; 
  153. fixed_t            ds_ystep;
  154.  
  155. /*  start of a 64*64 tile image  */
  156. byte*            ds_source;    
  157.  
  158. /*  just for profiling */
  159. int            dscount;
  160.  
  161.  
  162. /*  */
  163. /*  R_InitBuffer  */
  164. /*  Creats lookup tables that avoid */
  165. /*   multiplies and other hazzles */
  166. /*   for getting the framebuffer address */
  167. /*   of a pixel to draw. */
  168. /*  */
  169. void
  170. R_InitBuffer
  171. ( int        width,
  172.   int        height ) 
  173.     int        i; 
  174.  
  175.     /*  Handle resize, */
  176.     /*   e.g. smaller view windows */
  177.     /*   with border and/or status bar. */
  178.     viewwindowx = (SCREENWIDTH-width) >> 1; 
  179.  
  180.     /*  Column offset. For windows. */
  181.     for (i=0 ; i<width ; i++) 
  182.     columnofs[i] = (viewwindowx + i)*pixel_size;
  183.  
  184.     /*  Samw with base row offset. */
  185.     if (width == SCREENWIDTH) 
  186.     viewwindowy = 0; 
  187.     else 
  188.     viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1; 
  189.  
  190.     /*  Preclaculate all row offsets. */
  191.     for (i=0 ; i<height ; i++) 
  192.     ylookup[i] = screens[0] + (i+viewwindowy)*SCREENWIDTH*pixel_size; 
  193.  
  194. /*  */
  195. /*  R_FillBackScreen */
  196. /*  Fills the back screen with a pattern */
  197. /*   for variable screen sizes */
  198. /*  Also draws a beveled edge. */
  199. /*  */
  200. void R_FillBackScreen (void) 
  201.     byte    *src,*src1;
  202.     byte    *dest; 
  203.     unsigned short *destsrc;
  204.     unsigned long *destsrc32;
  205.     int        x;
  206.     int        y; 
  207.     patch_t*    patch;
  208.  
  209.     /*  DOOM border patch. */
  210.     char    name1[] = "FLOOR7_2";
  211.  
  212.     /*  DOOM II border patch. */
  213.     char    name2[] = "GRNROCK";    
  214.  
  215.     char*    name;
  216.     
  217.     if (scaledviewwidth == 320)
  218.     return;
  219.     
  220.     if ( gamemode == commercial)
  221.     name = name2;
  222.     else
  223.     name = name1;
  224.     
  225.     src = W_CacheLumpName (name, PU_CACHE); 
  226.      
  227.     switch (pixel_size)
  228.     {
  229.         case 1:
  230.             dest = screens[1]; 
  231.             for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++) 
  232.             { 
  233.                 for (x=0 ; x<SCREENWIDTH/64 ; x++) 
  234.                 { 
  235.                     memcpy (dest, src+((y&63)<<6), 64); 
  236.                     dest += 64; 
  237.                 } 
  238.  
  239.                 if (SCREENWIDTH&63)
  240.                 { 
  241.                     memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63); 
  242.                     dest += (SCREENWIDTH&63); 
  243.                 } 
  244.             } 
  245.             break;
  246.         case 2:
  247.             destsrc = (unsigned short *) screens[1]; 
  248.      
  249.             for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++) 
  250.             { 
  251.                 unsigned short *dest1;
  252.  
  253.                 src1 = src + ((y & 63) << 6);
  254.                 dest1 = destsrc;
  255.  
  256.                 for (x=0; x<SCREENWIDTH ; x++)
  257.                     *dest1++ = truecolor_palette[ src1[x & 63] ];            
  258.                 destsrc += SCREENWIDTH;
  259.             } 
  260.             break;
  261.         case 3:
  262.             dest=screens[1];
  263.             for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++) 
  264.             { 
  265.                 byte    *dest1;
  266.  
  267.                 src1 = src + ((y & 63) << 6);
  268.                 dest1 = dest;
  269.  
  270.                 for (x=0; x<SCREENWIDTH ; x++)
  271.                 {
  272.                     unsigned long couleur;
  273.  
  274.                     couleur = truecolor_palette[ src1[x & 63] ];
  275.  
  276.                     *dest1++ = couleur;
  277.                     *dest1++ = couleur >> 8;
  278.                     *dest1++ = couleur >> 16;            
  279.                 }
  280.                 dest += SCREENWIDTH*3;
  281.             } 
  282.             break;
  283.         case 4:
  284.             destsrc32 = (unsigned long *) screens[1]; 
  285.      
  286.             for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++) 
  287.             { 
  288.                 unsigned long *dest1;
  289.  
  290.                 src1 = src + ((y & 63) << 6);
  291.                 dest1 = destsrc32;
  292.  
  293.                 for (x=0; x<SCREENWIDTH ; x++)
  294.                     *dest1++ = truecolor_palette[ src1[x & 63] ];            
  295.                 destsrc32 += SCREENWIDTH;
  296.             } 
  297.             break;
  298.     }
  299.     
  300.     patch = W_CacheLumpName ("brdr_t",PU_CACHE);
  301.  
  302.     for (x=0 ; x<scaledviewwidth ; x+=8)
  303.     V_DrawPatch (viewwindowx+x,viewwindowy-8,1,patch);
  304.     patch = W_CacheLumpName ("brdr_b",PU_CACHE);
  305.  
  306.     for (x=0 ; x<scaledviewwidth ; x+=8)
  307.     V_DrawPatch (viewwindowx+x,viewwindowy+viewheight,1,patch);
  308.     patch = W_CacheLumpName ("brdr_l",PU_CACHE);
  309.  
  310.     for (y=0 ; y<viewheight ; y+=8)
  311.     V_DrawPatch (viewwindowx-8,viewwindowy+y,1,patch);
  312.     patch = W_CacheLumpName ("brdr_r",PU_CACHE);
  313.  
  314.     for (y=0 ; y<viewheight ; y+=8)
  315.     V_DrawPatch (viewwindowx+scaledviewwidth,viewwindowy+y,1,patch);
  316.  
  317.  
  318.     /*  Draw beveled edge.  */
  319.     V_DrawPatch (viewwindowx-8,
  320.          viewwindowy-8,
  321.          1,
  322.          W_CacheLumpName ("brdr_tl",PU_CACHE));
  323.     
  324.     V_DrawPatch (viewwindowx+scaledviewwidth,
  325.          viewwindowy-8,
  326.          1,
  327.          W_CacheLumpName ("brdr_tr",PU_CACHE));
  328.     
  329.     V_DrawPatch (viewwindowx-8,
  330.          viewwindowy+viewheight,
  331.          1,
  332.          W_CacheLumpName ("brdr_bl",PU_CACHE));
  333.     
  334.     V_DrawPatch (viewwindowx+scaledviewwidth,
  335.          viewwindowy+viewheight,
  336.          1,
  337.          W_CacheLumpName ("brdr_br",PU_CACHE));
  338.  
  339.  
  340. /*  */
  341. /*  Copy a screen buffer. */
  342. /*  */
  343. void
  344. R_VideoErase
  345. ( unsigned    ofs,
  346.   int        count ) 
  347.   /*  LFB copy. */
  348.   /*  This might not be a good idea if memcpy */
  349.   /*   is not optiomal, e.g. byte by byte on */
  350.   /*   a 32bit CPU, as GNU GCC/Linux libc did */
  351.   /*   at one point. */
  352.     memcpy (screens[0]+ofs*pixel_size, screens[1]+ofs*pixel_size, count*pixel_size); 
  353.  
  354.  
  355. /*  */
  356. /*  R_DrawViewBorder */
  357. /*  Draws the border around the view */
  358. /*   for different size windows? */
  359. /*  */
  360. void
  361. V_MarkRect
  362. ( int        x,
  363.   int        y,
  364.   int        width,
  365.   int        height ); 
  366.  
  367. void R_DrawViewBorder (void) 
  368.     int        top;
  369.     int        side;
  370.     int        ofs;
  371.     int        i; 
  372.  
  373.     if (scaledviewwidth == SCREENWIDTH) 
  374.     return; 
  375.   
  376.     top = ((SCREENHEIGHT-SBARHEIGHT)-viewheight)/2; 
  377.     side = (SCREENWIDTH-scaledviewwidth)/2; 
  378.  
  379.     /*  copy top and one line of left side  */
  380.     R_VideoErase (0, top*SCREENWIDTH+side); 
  381.  
  382.     /*  copy one line of right side and bottom  */
  383.     ofs = (viewheight+top)*SCREENWIDTH-side; 
  384.     R_VideoErase (ofs, top*SCREENWIDTH+side); 
  385.  
  386.     /*  copy sides using wraparound  */
  387.     ofs = top*SCREENWIDTH + SCREENWIDTH-side; 
  388.     side <<= 1;
  389.     
  390.     for (i=1 ; i<viewheight ; i++) 
  391.     { 
  392.     R_VideoErase (ofs, side); 
  393.     ofs += SCREENWIDTH; 
  394.     } 
  395.  
  396.     /*  ?  */
  397.     V_MarkRect (0,0,SCREENWIDTH, SCREENHEIGHT-SBARHEIGHT); 
  398.