v_video.c 13 KB

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