Subversion Repositories Kolibri OS

Rev

Rev 300 | Blame | Last modification | View Log | Download | RSS feed

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