v_video.cpp 14 KB

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