DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

v_video.cpp (14291B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #include "Precompiled.h"
     30 #include "globaldata.h"
     31 
     32 
     33 #include "i_system.h"
     34 #include "r_local.h"
     35 
     36 #include "doomdef.h"
     37 #include "doomdata.h"
     38 
     39 #include "m_bbox.h"
     40 #include "m_swap.h"
     41 
     42 #include "v_video.h"
     43 
     44 
     45 // Each screen is [ORIGINAL_WIDTH*ORIGINALHEIGHT]; 
     46  
     47 
     48 
     49 
     50 // Now where did these came from?
     51 const 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 			 
    138 //
    139 // V_MarkRect 
    140 // 
    141 void
    142 V_MarkRect
    143 ( int		x,
    144   int		y,
    145   int		width,
    146   int		height ) 
    147 { 
    148     M_AddToBox (::g->dirtybox, x, y); 
    149     M_AddToBox (::g->dirtybox, x+width-1, y+height-1); 
    150 } 
    151  
    152 
    153 //
    154 // V_CopyRect 
    155 // 
    156 void
    157 V_CopyRect
    158 ( int		srcx,
    159   int		srcy,
    160   int		srcscrn,
    161   int		width,
    162   int		height,
    163   int		destx,
    164   int		desty,
    165   int		destscrn ) 
    166 { 
    167     byte*	src;
    168     byte*	dest; 
    169 	 
    170 #ifdef RANGECHECK 
    171     if (srcx<0
    172 	||srcx+width >ORIGINAL_WIDTH
    173 	|| srcy<0
    174 	|| srcy+height>ORIGINAL_HEIGHT 
    175 	||destx<0||destx+width >ORIGINAL_WIDTH
    176 	|| desty<0
    177 	|| desty+height>ORIGINAL_HEIGHT
    178 	|| (unsigned)srcscrn>4
    179 	|| (unsigned)destscrn>4)
    180     {
    181 	I_Error ("Bad V_CopyRect");
    182     }
    183 #endif 
    184     V_MarkRect (destx, desty, width, height); 
    185 
    186 	// SMF - rewritten for scaling
    187 	srcx *= GLOBAL_IMAGE_SCALER;
    188 	srcy *= GLOBAL_IMAGE_SCALER;
    189 	destx *= GLOBAL_IMAGE_SCALER;
    190 	desty *= GLOBAL_IMAGE_SCALER;
    191 	width *= GLOBAL_IMAGE_SCALER;
    192 	height *= GLOBAL_IMAGE_SCALER;
    193 
    194 	src = ::g->screens[srcscrn] + srcy * SCREENWIDTH + srcx; 
    195 	dest = ::g->screens[destscrn] + desty * SCREENWIDTH + destx; 
    196 
    197 	for ( ; height>0 ; height--) { 
    198 		memcpy(dest, src, width); 
    199 		src += SCREENWIDTH; 
    200 		dest += SCREENWIDTH; 
    201 	} 
    202 } 
    203  
    204 
    205 //
    206 // V_DrawPatch
    207 // Masks a column based masked pic to the screen. 
    208 //
    209 void
    210 V_DrawPatch
    211 ( int		x,
    212   int		y,
    213   int		scrn,
    214   patch_t*	patch ) 
    215 { 
    216 
    217     int				count;
    218     int				col; 
    219     postColumn_t*	column; 
    220     byte*			source; 
    221     int				w; 
    222 	 
    223     y -= SHORT(patch->topoffset); 
    224     x -= SHORT(patch->leftoffset); 
    225 #ifdef RANGECHECK 
    226     if (x<0
    227 	||x+SHORT(patch->width) >ORIGINAL_WIDTH
    228 	|| y<0
    229 	|| y+SHORT(patch->height)>ORIGINAL_HEIGHT
    230 	|| (unsigned)scrn>4)
    231     {
    232       I_PrintfE("Patch at %d,%d exceeds LFB\n", x,y );
    233       // No I_Error abort - what is up with TNT.WAD?
    234       I_PrintfE("V_DrawPatch: bad patch (ignored)\n");
    235       return;
    236     }
    237 #endif 
    238 
    239     if (!scrn)
    240 		V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height)); 
    241 
    242     col = 0; 
    243 	int destx = x;
    244 	int desty = y;
    245 	 
    246     w = SHORT(patch->width);
    247 
    248 	// SMF - rewritten for scaling
    249 	for ( ; col < w ; x++, col++ ) {
    250 		column = (postColumn_t *)((byte *)patch + LONG(patch->columnofs[col]));
    251 
    252 		destx = x;
    253 
    254 		// step through the posts in a column
    255 		while (column->topdelta != 0xff ) {
    256 			source = (byte *)column + 3;
    257 			desty = y + column->topdelta;
    258 			count = column->length;
    259 
    260 			while (count--) {
    261 				int scaledx, scaledy;
    262 				scaledx = destx * GLOBAL_IMAGE_SCALER;
    263 				scaledy = desty * GLOBAL_IMAGE_SCALER;
    264 				byte src = *source++;
    265 
    266 				for ( int i = 0; i < GLOBAL_IMAGE_SCALER; i++ ) {
    267 					for ( int j = 0; j < GLOBAL_IMAGE_SCALER; j++ ) {
    268 						::g->screens[scrn][( scaledx + j ) + ( scaledy + i ) * SCREENWIDTH] = src;
    269 					}
    270 				}
    271 
    272 				desty++;
    273 			}
    274 
    275 			column = (postColumn_t *)( (byte *)column + column->length + 4 );
    276 		}
    277 	}
    278 } 
    279  
    280 //
    281 // V_DrawPatchFlipped 
    282 // Masks a column based masked pic to the screen.
    283 // Flips horizontally, e.g. to mirror face.
    284 //
    285 void
    286 V_DrawPatchFlipped
    287 ( int		x,
    288   int		y,
    289   int		scrn,
    290   patch_t*	patch ) 
    291 { 
    292 
    293     int				count;
    294     int				col; 
    295     postColumn_t*	column; 
    296     byte*			source; 
    297     int				w; 
    298 	 
    299     y -= SHORT(patch->topoffset); 
    300     x -= SHORT(patch->leftoffset); 
    301 #ifdef RANGECHECK 
    302     if (x<0
    303 	||x+SHORT(patch->width) >ORIGINAL_WIDTH
    304 	|| y<0
    305 	|| y+SHORT(patch->height)>ORIGINAL_HEIGHT
    306 	|| (unsigned)scrn>4)
    307     {
    308       I_PrintfE("Patch origin %d,%d exceeds LFB\n", x,y );
    309       I_Error ("Bad V_DrawPatch in V_DrawPatchFlipped");
    310     }
    311 #endif 
    312  
    313     if (!scrn)
    314 	V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height)); 
    315 
    316     col = 0; 
    317 	int destx = x;
    318 	int desty = y;
    319 
    320     w = SHORT(patch->width); 
    321 
    322     for ( ; col<w ; x++, col++ ) 
    323     { 
    324 		column = (postColumn_t *)((byte *)patch + LONG(patch->columnofs[w-1-col])); 
    325 
    326 		destx = x;
    327 	 
    328 		// step through the posts in a column 
    329 		while (column->topdelta != 0xff ) 
    330 		{ 
    331 			source = (byte *)column + 3; 
    332 			desty = y + column->topdelta;
    333 			count = column->length; 
    334 				 
    335 			while (count--) 
    336 			{
    337 				int scaledx, scaledy;
    338 				scaledx = destx * GLOBAL_IMAGE_SCALER;
    339 				scaledy = desty * GLOBAL_IMAGE_SCALER;
    340 				byte src = *source++;
    341 
    342 				for ( int i = 0; i < GLOBAL_IMAGE_SCALER; i++ ) {
    343 					for ( int j = 0; j < GLOBAL_IMAGE_SCALER; j++ ) {
    344 						::g->screens[scrn][( scaledx + j ) + ( scaledy + i ) * SCREENWIDTH] = src;
    345 					}
    346 				}
    347 
    348 				desty++;
    349 			} 
    350 			column = (postColumn_t *)(  (byte *)column + column->length + 4 );
    351 		} 
    352     }			 
    353 } 
    354  
    355 
    356 
    357 //
    358 // V_DrawPatchDirect
    359 // Draws directly to the screen on the pc. 
    360 //
    361 void
    362 V_DrawPatchDirect
    363 ( int		x,
    364   int		y,
    365   int		scrn,
    366   patch_t*	patch ) 
    367 {
    368     V_DrawPatch (x,y,scrn, patch); 
    369 
    370     /*
    371     int		count;
    372     int		col; 
    373     postColumn_t*	column; 
    374     byte*	desttop;
    375     byte*	dest;
    376     byte*	source; 
    377     int		w; 
    378 	 
    379     y -= SHORT(patch->topoffset); 
    380     x -= SHORT(patch->leftoffset); 
    381 
    382 #ifdef RANGECHECK 
    383     if (x<0
    384 	||x+SHORT(patch->width) >ORIGINAL_WIDTH
    385 	|| y<0
    386 	|| y+SHORT(patch->height)>ORIGINAL_HEIGHT
    387 	|| (unsigned)scrn>4)
    388     {
    389 	I_Error ("Bad V_DrawPatchDirect");
    390     }
    391 #endif 
    392  
    393     //	V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height)); 
    394     desttop = destscreen + y*ORIGINAL_WIDTH/4 + (x>>2); 
    395 	 
    396     w = SHORT(patch->width); 
    397     for ( col = 0 ; col<w ; col++) 
    398     { 
    399 	outp (SC_INDEX+1,1<<(x&3)); 
    400 	column = (postColumn_t *)((byte *)patch + LONG(patch->columnofs[col])); 
    401  
    402 	// step through the posts in a column 
    403 	 
    404 	while (column->topdelta != 0xff ) 
    405 	{ 
    406 	    source = (byte *)column + 3; 
    407 	    dest = desttop + column->topdelta*ORIGINAL_WIDTH/4; 
    408 	    count = column->length; 
    409  
    410 	    while (count--) 
    411 	    { 
    412 		*dest = *source++; 
    413 		dest += ORIGINAL_WIDTH/4; 
    414 	    } 
    415 	    column = (postColumn_t *)(  (byte *)column + column->length 
    416 				    + 4 ); 
    417 	} 
    418 	if ( ((++x)&3) == 0 ) 
    419 	    desttop++;	// go to next byte, not next plane 
    420     }*/ 
    421 } 
    422  
    423 
    424 
    425 //
    426 // V_DrawBlock
    427 // Draw a linear block of pixels into the view buffer.
    428 //
    429 void
    430 V_DrawBlock
    431 ( int		x,
    432   int		y,
    433   int		scrn,
    434   int		width,
    435   int		height,
    436   byte*		src ) 
    437 { 
    438     byte*	dest; 
    439 	 
    440 #ifdef RANGECHECK 
    441     if (x<0
    442 	||x+width >SCREENWIDTH
    443 	|| y<0
    444 	|| y+height>SCREENHEIGHT
    445 	|| (unsigned)scrn>4 )
    446     {
    447 	I_Error ("Bad V_DrawBlock");
    448     }
    449 #endif 
    450  
    451     V_MarkRect (x, y, width, height); 
    452  
    453     dest = ::g->screens[scrn] + y*SCREENWIDTH+x; 
    454 
    455     while (height--) 
    456     { 
    457 	memcpy(dest, src, width); 
    458 	src += width; 
    459 	dest += SCREENWIDTH; 
    460     } 
    461 } 
    462  
    463 
    464 
    465 //
    466 // V_GetBlock
    467 // Gets a linear block of pixels from the view buffer.
    468 //
    469 void
    470 V_GetBlock
    471 ( int		x,
    472   int		y,
    473   int		scrn,
    474   int		width,
    475   int		height,
    476   byte*		dest ) 
    477 { 
    478     byte*	src; 
    479 	 
    480 #ifdef RANGECHECK 
    481     if (x<0
    482 	||x+width >SCREENWIDTH
    483 	|| y<0
    484 	|| y+height>SCREENHEIGHT
    485 	|| (unsigned)scrn>4 )
    486     {
    487 	I_Error ("Bad V_DrawBlock");
    488     }
    489 #endif 
    490  
    491     src = ::g->screens[scrn] + y*SCREENWIDTH+x; 
    492 
    493     while (height--) 
    494     { 
    495 	memcpy(dest, src, width); 
    496 	src += SCREENWIDTH; 
    497 	dest += width; 
    498     } 
    499 } 
    500 
    501 
    502 
    503 
    504 //
    505 // V_Init
    506 // 
    507 void V_Init (void) 
    508 { 
    509     int		i;
    510     byte*	base;
    511 
    512     // stick these in low dos memory on PCs
    513 
    514     base = (byte*)DoomLib::Z_Malloc(SCREENWIDTH*SCREENHEIGHT*4, PU_STATIC, 0);
    515 
    516     for (i=0 ; i<4 ; i++)
    517 		::g->screens[i] = base + i*SCREENWIDTH*SCREENHEIGHT;
    518 }
    519