v_video.c
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:14k
源码类别:

射击游戏

开发平台:

Visual C++

  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. // Gamma correction LUT stuff.
  21. // Functions to draw patches (by post) directly to screen.
  22. // Functions to blit a block to the screen.
  23. //
  24. //-----------------------------------------------------------------------------
  25. static const char
  26. rcsid[] = "$Id: v_video.c,v 1.5 1997/02/03 22:45:13 b1 Exp $";
  27. #include "i_system.h"
  28. #include "r_local.h"
  29. #include "doomdef.h"
  30. #include "doomdata.h"
  31. #include "m_bbox.h"
  32. #include "m_swap.h"
  33. #include "v_video.h"
  34. void WriteDebug(char *);
  35. char MsgText[256];
  36. // Each screen is [SCREENWIDTH*SCREENHEIGHT]; 
  37. byte* screens[5];
  38. int dirtybox[4]; 
  39. // Now where did these came from?
  40. byte gammatable[5][256] =
  41. {
  42.     {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
  43.      17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,
  44.      33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
  45.      49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
  46.      65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
  47.      81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,
  48.      97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,
  49.      113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
  50.      128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
  51.      144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
  52.      160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
  53.      176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
  54.      192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
  55.      208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
  56.      224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
  57.      240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255},
  58.     {2,4,5,7,8,10,11,12,14,15,16,18,19,20,21,23,24,25,26,27,29,30,31,
  59.      32,33,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,54,55,
  60.      56,57,58,59,60,61,62,63,64,65,66,67,69,70,71,72,73,74,75,76,77,
  61.      78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,
  62.      99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,
  63.      115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,129,
  64.      130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,
  65.      146,147,148,148,149,150,151,152,153,154,155,156,157,158,159,160,
  66.      161,162,163,163,164,165,166,167,168,169,170,171,172,173,174,175,
  67.      175,176,177,178,179,180,181,182,183,184,185,186,186,187,188,189,
  68.      190,191,192,193,194,195,196,196,197,198,199,200,201,202,203,204,
  69.      205,205,206,207,208,209,210,211,212,213,214,214,215,216,217,218,
  70.      219,220,221,222,222,223,224,225,226,227,228,229,230,230,231,232,
  71.      233,234,235,236,237,237,238,239,240,241,242,243,244,245,245,246,
  72.      247,248,249,250,251,252,252,253,254,255},
  73.     {4,7,9,11,13,15,17,19,21,22,24,26,27,29,30,32,33,35,36,38,39,40,42,
  74.      43,45,46,47,48,50,51,52,54,55,56,57,59,60,61,62,63,65,66,67,68,69,
  75.      70,72,73,74,75,76,77,78,79,80,82,83,84,85,86,87,88,89,90,91,92,93,
  76.      94,95,96,97,98,100,101,102,103,104,105,106,107,108,109,110,111,112,
  77.      113,114,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
  78.      129,130,131,132,133,133,134,135,136,137,138,139,140,141,142,143,144,
  79.      144,145,146,147,148,149,150,151,152,153,153,154,155,156,157,158,159,
  80.      160,160,161,162,163,164,165,166,166,167,168,169,170,171,172,172,173,
  81.      174,175,176,177,178,178,179,180,181,182,183,183,184,185,186,187,188,
  82.      188,189,190,191,192,193,193,194,195,196,197,197,198,199,200,201,201,
  83.      202,203,204,205,206,206,207,208,209,210,210,211,212,213,213,214,215,
  84.      216,217,217,218,219,220,221,221,222,223,224,224,225,226,227,228,228,
  85.      229,230,231,231,232,233,234,235,235,236,237,238,238,239,240,241,241,
  86.      242,243,244,244,245,246,247,247,248,249,250,251,251,252,253,254,254,
  87.      255},
  88.     {8,12,16,19,22,24,27,29,31,34,36,38,40,41,43,45,47,49,50,52,53,55,
  89.      57,58,60,61,63,64,65,67,68,70,71,72,74,75,76,77,79,80,81,82,84,85,
  90.      86,87,88,90,91,92,93,94,95,96,98,99,100,101,102,103,104,105,106,107,
  91.      108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,
  92.      125,126,127,128,129,130,131,132,133,134,135,135,136,137,138,139,140,
  93.      141,142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,
  94.      155,156,157,158,159,160,160,161,162,163,164,165,165,166,167,168,169,
  95.      169,170,171,172,173,173,174,175,176,176,177,178,179,180,180,181,182,
  96.      183,183,184,185,186,186,187,188,189,189,190,191,192,192,193,194,195,
  97.      195,196,197,197,198,199,200,200,201,202,202,203,204,205,205,206,207,
  98.      207,208,209,210,210,211,212,212,213,214,214,215,216,216,217,218,219,
  99.      219,220,221,221,222,223,223,224,225,225,226,227,227,228,229,229,230,
  100.      231,231,232,233,233,234,235,235,236,237,237,238,238,239,240,240,241,
  101.      242,242,243,244,244,245,246,246,247,247,248,249,249,250,251,251,252,
  102.      253,253,254,254,255},
  103.     {16,23,28,32,36,39,42,45,48,50,53,55,57,60,62,64,66,68,69,71,73,75,76,
  104.      78,80,81,83,84,86,87,89,90,92,93,94,96,97,98,100,101,102,103,105,106,
  105.      107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124,
  106.      125,126,128,128,129,130,131,132,133,134,135,136,137,138,139,140,141,
  107.      142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,155,
  108.      156,157,158,159,159,160,161,162,163,163,164,165,166,166,167,168,169,
  109.      169,170,171,172,172,173,174,175,175,176,177,177,178,179,180,180,181,
  110.      182,182,183,184,184,185,186,187,187,188,189,189,190,191,191,192,193,
  111.      193,194,195,195,196,196,197,198,198,199,200,200,201,202,202,203,203,
  112.      204,205,205,206,207,207,208,208,209,210,210,211,211,212,213,213,214,
  113.      214,215,216,216,217,217,218,219,219,220,220,221,221,222,223,223,224,
  114.      224,225,225,226,227,227,228,228,229,229,230,230,231,232,232,233,233,
  115.      234,234,235,235,236,236,237,237,238,239,239,240,240,241,241,242,242,
  116.      243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,
  117.      251,252,252,253,254,254,255,255}
  118. };
  119. int usegamma;
  120.  
  121. //
  122. // V_MarkRect 
  123. // 
  124. void V_MarkRect( int x, int y, int width, int height ) 
  125.    { 
  126.     M_AddToBox (dirtybox, x, y); 
  127.     M_AddToBox (dirtybox, x+width-1, y+height-1); 
  128.    } 
  129.  
  130. //
  131. // V_CopyRect 
  132. // 
  133. void V_CopyRect( int srcx, int srcy, int srcscrn, int width, int height, int destx, int desty, int destscrn ) 
  134.    { 
  135.     byte* src;
  136.     byte* dest; 
  137.  
  138. #ifdef RANGECHECK 
  139.     if (srcx < 0 || srcx+width > SCREENWIDTH || srcy < 0 || srcy+height > SCREENHEIGHT || destx < 0 ||
  140.         destx+width > SCREENWIDTH || desty < 0 || desty+height > SCREENHEIGHT || (unsigned)srcscrn > 4 || (unsigned)destscrn > 4)
  141.        {
  142.         I_Error ("Bad V_CopyRect");
  143.        }
  144. #endif 
  145.     V_MarkRect (destx, desty, width, height); 
  146.  
  147.     src = screens[srcscrn]+SCREENWIDTH*srcy+srcx; 
  148.     dest = screens[destscrn]+SCREENWIDTH*desty+destx; 
  149.     for ( ; height > 0 ; height--) 
  150.        { 
  151.         memcpy (dest, src, width); 
  152.         src += SCREENWIDTH; 
  153.         dest += SCREENWIDTH; 
  154.        } 
  155.    } 
  156.  
  157. //
  158. // V_DrawPatch
  159. // Masks a column based masked pic to the screen. 
  160. //
  161. void V_DrawPatch ( int x, int y, int scrn, patch_t* patch ) 
  162.    { 
  163.     int count;
  164.     int col; 
  165.     column_t* column; 
  166.     byte* desttop;
  167.     byte* dest;
  168.     byte* source; 
  169.     int w; 
  170.  
  171.     y -= SHORT(patch->topoffset); 
  172.     x -= SHORT(patch->leftoffset); 
  173. #ifdef RANGECHECK 
  174.     if (x<0 ||x+SHORT(patch->width) >SCREENWIDTH || y<0 || y+SHORT(patch->height)>SCREENHEIGHT || (unsigned)scrn>4)
  175.        {
  176.         fprintf( stderr, "Patch at %d,%d exceeds LFBn", x,y );
  177.         // No I_Error abort - what is up with TNT.WAD?
  178.         fprintf( stderr, "V_DrawPatch: bad patch (ignored)n");
  179.         return;
  180.        }
  181. #endif 
  182.  
  183.     if (!scrn)
  184.        {
  185.         //WriteDebug("V_MarkRect...n");
  186.         V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height)); 
  187.        }
  188.     col = 0; 
  189.     desttop = screens[scrn]+y*SCREENWIDTH+x; 
  190.     w = SHORT(patch->width);
  191.     //sprintf(MsgText, "width = %d, x/y = %d/%dn", w, x, y);
  192.     //WriteDebug(MsgText);
  193.     for ( ; col<w ; x++, col++, desttop++)
  194.        { 
  195.         //sprintf(MsgText, "col = %d length = %dn", col, column->length);
  196.         //WriteDebug(MsgText);
  197.         column = (column_t *)((byte *)patch + LONG(patch->columnofs[col])); 
  198.  
  199.         // step through the posts in a column 
  200.         while (column->topdelta != 0xff ) 
  201.            { 
  202.             source = (byte *)column + 3; 
  203.             dest = desttop + column->topdelta*SCREENWIDTH; 
  204.             count = column->length; 
  205.             //sprintf(MsgText, "count = %dn", count);
  206.             //WriteDebug(MsgText);
  207.  
  208.             while (count--) 
  209.                { 
  210.                 *dest = *source++; 
  211.                 dest += SCREENWIDTH; 
  212.                } 
  213.             column = (column_t *)((byte *)column + column->length + 4 );
  214.            } 
  215.        }
  216.     //WriteDebug("Finished V_DrawPatch...n");
  217.    } 
  218.  
  219. //
  220. // V_DrawPatchFlipped 
  221. // Masks a column based masked pic to the screen.
  222. // Flips horizontally, e.g. to mirror face.
  223. //
  224. void
  225. V_DrawPatchFlipped
  226. ( int x,
  227.   int y,
  228.   int scrn,
  229.   patch_t* patch ) 
  230.     int count;
  231.     int col; 
  232.     column_t* column; 
  233.     byte* desttop;
  234.     byte* dest;
  235.     byte* source; 
  236.     int w; 
  237.  
  238.     y -= SHORT(patch->topoffset); 
  239.     x -= SHORT(patch->leftoffset); 
  240. #ifdef RANGECHECK 
  241.     if (x<0
  242. ||x+SHORT(patch->width) >SCREENWIDTH
  243. || y<0
  244. || y+SHORT(patch->height)>SCREENHEIGHT 
  245. || (unsigned)scrn>4)
  246.     {
  247.       fprintf( stderr, "Patch origin %d,%d exceeds LFBn", x,y );
  248.       I_Error ("Bad V_DrawPatch in V_DrawPatchFlipped");
  249.     }
  250. #endif 
  251.  
  252.     if (!scrn)
  253. V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height)); 
  254.     col = 0; 
  255.     desttop = screens[scrn]+y*SCREENWIDTH+x; 
  256.  
  257.     w = SHORT(patch->width); 
  258.     for ( ; col<w ; x++, col++, desttop++) 
  259.     { 
  260. column = (column_t *)((byte *)patch + LONG(patch->columnofs[w-1-col])); 
  261.  
  262. // step through the posts in a column 
  263. while (column->topdelta != 0xff ) 
  264.     source = (byte *)column + 3; 
  265.     dest = desttop + column->topdelta*SCREENWIDTH; 
  266.     count = column->length; 
  267.  
  268.     while (count--) 
  269.     { 
  270. *dest = *source++; 
  271. dest += SCREENWIDTH; 
  272.     } 
  273.     column = (column_t *)(  (byte *)column + column->length 
  274.     + 4 ); 
  275.     }  
  276.  
  277. //
  278. // V_DrawPatchDirect
  279. // Draws directly to the screen on the pc. 
  280. //
  281. void
  282. V_DrawPatchDirect
  283. ( int x,
  284.   int y,
  285.   int scrn,
  286.   patch_t* patch ) 
  287. {
  288.     V_DrawPatch (x,y,scrn, patch); 
  289.     /*
  290.     int count;
  291.     int col; 
  292.     column_t* column; 
  293.     byte* desttop;
  294.     byte* dest;
  295.     byte* source; 
  296.     int w; 
  297.  
  298.     y -= SHORT(patch->topoffset); 
  299.     x -= SHORT(patch->leftoffset); 
  300. #ifdef RANGECHECK 
  301.     if (x<0
  302. ||x+SHORT(patch->width) >SCREENWIDTH
  303. || y<0
  304. || y+SHORT(patch->height)>SCREENHEIGHT 
  305. || (unsigned)scrn>4)
  306.     {
  307. I_Error ("Bad V_DrawPatchDirect");
  308.     }
  309. #endif 
  310.  
  311.     // V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height)); 
  312.     desttop = destscreen + y*SCREENWIDTH/4 + (x>>2); 
  313.  
  314.     w = SHORT(patch->width); 
  315.     for ( col = 0 ; col<w ; col++) 
  316.     { 
  317. outp (SC_INDEX+1,1<<(x&3)); 
  318. column = (column_t *)((byte *)patch + LONG(patch->columnofs[col])); 
  319.  
  320. // step through the posts in a column 
  321.  
  322. while (column->topdelta != 0xff ) 
  323.     source = (byte *)column + 3; 
  324.     dest = desttop + column->topdelta*SCREENWIDTH/4; 
  325.     count = column->length; 
  326.  
  327.     while (count--) 
  328.     { 
  329. *dest = *source++; 
  330. dest += SCREENWIDTH/4; 
  331.     } 
  332.     column = (column_t *)(  (byte *)column + column->length 
  333.     + 4 ); 
  334. if ( ((++x)&3) == 0 ) 
  335.     desttop++; // go to next byte, not next plane 
  336.     }*/ 
  337.  
  338. //
  339. // V_DrawBlock
  340. // Draw a linear block of pixels into the view buffer.
  341. //
  342. void
  343. V_DrawBlock
  344. ( int x,
  345.   int y,
  346.   int scrn,
  347.   int width,
  348.   int height,
  349.   byte* src ) 
  350.     byte* dest; 
  351.  
  352. #ifdef RANGECHECK 
  353.     if (x < 0 || x+width > SCREENWIDTH || y < 0 || y+height > SCREENHEIGHT || (unsigned)scrn > 4 )
  354.        {
  355.         I_Error ("Bad V_DrawBlock");
  356.        }
  357. #endif 
  358.  
  359.     V_MarkRect (x, y, width, height); 
  360.  
  361.     dest = screens[scrn] + y*SCREENWIDTH+x; 
  362.     while (height--) 
  363.     { 
  364. memcpy (dest, src, width); 
  365. src += width; 
  366. dest += SCREENWIDTH; 
  367.     } 
  368.  
  369. //
  370. // V_GetBlock
  371. // Gets a linear block of pixels from the view buffer.
  372. //
  373. void
  374. V_GetBlock
  375. ( int x,
  376.   int y,
  377.   int scrn,
  378.   int width,
  379.   int height,
  380.   byte* dest ) 
  381.     byte* src; 
  382.  
  383. #ifdef RANGECHECK 
  384.     if (x<0
  385. ||x+width >SCREENWIDTH
  386. || y<0
  387. || y+height>SCREENHEIGHT 
  388. || (unsigned)scrn>4 )
  389.     {
  390. I_Error ("Bad V_DrawBlock");
  391.     }
  392. #endif 
  393.  
  394.     src = screens[scrn] + y*SCREENWIDTH+x; 
  395.     while (height--) 
  396.     { 
  397. memcpy (dest, src, width); 
  398. src += SCREENWIDTH; 
  399. dest += width; 
  400.     } 
  401. //
  402. // V_Init
  403. // 
  404. void V_Init (void) 
  405.    { 
  406.     int i, j, x;
  407.     //byte* base;
  408.     DWORD  *buff;
  409.     // stick these in low dos memory on PCs
  410.     //base = I_AllocLow (SCREENWIDTH*SCREENHEIGHT*4);
  411.     for (i = 0; i < 5; i++)
  412.        {
  413.         x = SCREENWIDTH * SCREENHEIGHT;
  414.         screens[i] = (byte *)malloc(x);
  415.         buff = (DWORD *)screens[i];
  416.         x /= 4;
  417.         for (j = 0; j < x; j++)
  418.            buff[j] = 0x00000000;
  419.        }
  420. //  screens[i] = base + i*SCREENWIDTH*SCREENHEIGHT;
  421.    }