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