R_DRAW.C 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. //**************************************************************************
  2. //**
  3. //** r_draw.c : Heretic 2 : Raven Software, Corp.
  4. //**
  5. //** $RCSfile: r_draw.c,v $
  6. //** $Revision: 1.11 $
  7. //** $Date: 96/01/06 18:37:37 $
  8. //** $Author: bgokey $
  9. //**
  10. //**************************************************************************
  11. #include "h2def.h"
  12. #include "r_local.h"
  13. /*
  14. All drawing to the view buffer is accomplished in this file. The other refresh
  15. files only know about ccordinates, not the architecture of the frame buffer.
  16. */
  17. byte *viewimage;
  18. int viewwidth, scaledviewwidth, viewheight, viewwindowx, viewwindowy;
  19. byte *ylookup[MAXHEIGHT];
  20. int columnofs[MAXWIDTH];
  21. //byte translations[3][256]; // color tables for different players
  22. byte *tinttable; // used for translucent sprites
  23. /*
  24. ==================
  25. =
  26. = R_DrawColumn
  27. =
  28. = Source is the top of the column to scale
  29. =
  30. ==================
  31. */
  32. lighttable_t *dc_colormap;
  33. int dc_x;
  34. int dc_yl;
  35. int dc_yh;
  36. fixed_t dc_iscale;
  37. fixed_t dc_texturemid;
  38. byte *dc_source; // first pixel in a column (possibly virtual)
  39. int dccount; // just for profiling
  40. #ifndef __WATCOMC__
  41. #ifndef __i386
  42. #ifndef __m68k
  43. void R_DrawColumn (void)
  44. {
  45. int count;
  46. byte *dest;
  47. fixed_t frac, fracstep;
  48. count = dc_yh - dc_yl;
  49. if (count < 0)
  50. return;
  51. #ifdef RANGECHECK
  52. if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  53. I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
  54. #endif
  55. dest = ylookup[dc_yl] + columnofs[dc_x];
  56. fracstep = dc_iscale;
  57. frac = dc_texturemid + (dc_yl-centery)*fracstep;
  58. do
  59. {
  60. *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
  61. dest += SCREENWIDTH;
  62. frac += fracstep;
  63. } while (count--);
  64. }
  65. #endif // __m68k
  66. #endif // __i386
  67. #endif
  68. void R_DrawColumnLow (void)
  69. {
  70. int count;
  71. byte *dest;
  72. fixed_t frac, fracstep;
  73. count = dc_yh - dc_yl;
  74. if (count < 0)
  75. return;
  76. #ifdef RANGECHECK
  77. if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  78. I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
  79. // dccount++;
  80. #endif
  81. dest = ylookup[dc_yl] + columnofs[dc_x];
  82. fracstep = dc_iscale;
  83. frac = dc_texturemid + (dc_yl-centery)*fracstep;
  84. do
  85. {
  86. *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
  87. dest += SCREENWIDTH;
  88. frac += fracstep;
  89. } while (count--);
  90. }
  91. /*
  92. #define FUZZTABLE 50
  93. #define FUZZOFF (SCREENWIDTH)
  94. int fuzzoffset[FUZZTABLE] = {
  95. FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF
  96. };
  97. int fuzzpos = 0;
  98. */
  99. #ifndef __WATCOMC__
  100. void R_DrawFuzzColumn (void)
  101. {
  102. int count;
  103. byte *dest;
  104. fixed_t frac, fracstep;
  105. if (!dc_yl)
  106. dc_yl = 1;
  107. if (dc_yh == viewheight-1)
  108. dc_yh = viewheight - 2;
  109. count = dc_yh - dc_yl;
  110. if (count < 0)
  111. return;
  112. #ifdef RANGECHECK
  113. if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  114. I_Error ("R_DrawFuzzColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
  115. #endif
  116. dest = ylookup[dc_yl] + columnofs[dc_x];
  117. fracstep = dc_iscale;
  118. frac = dc_texturemid + (dc_yl-centery)*fracstep;
  119. // OLD FUZZY INVISO SPRITE STUFF
  120. /* do
  121. {
  122. *dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]];
  123. if (++fuzzpos == FUZZTABLE)
  124. fuzzpos = 0;
  125. dest += SCREENWIDTH;
  126. frac += fracstep;
  127. } while (count--);
  128. */
  129. do
  130. {
  131. *dest = tinttable[*dest+
  132. (dc_colormap[dc_source[(frac>>FRACBITS)&127]]<<8)];
  133. dest += SCREENWIDTH;
  134. frac += fracstep;
  135. } while(count--);
  136. }
  137. #endif
  138. //============================================================================
  139. //
  140. // R_DrawAltFuzzColumn
  141. //
  142. //============================================================================
  143. void R_DrawAltFuzzColumn (void)
  144. {
  145. int count;
  146. byte *dest;
  147. fixed_t frac, fracstep;
  148. if (!dc_yl)
  149. dc_yl = 1;
  150. if (dc_yh == viewheight-1)
  151. dc_yh = viewheight - 2;
  152. count = dc_yh - dc_yl;
  153. if (count < 0)
  154. return;
  155. #ifdef RANGECHECK
  156. if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  157. I_Error ("R_DrawFuzzColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
  158. #endif
  159. dest = ylookup[dc_yl] + columnofs[dc_x];
  160. fracstep = dc_iscale;
  161. frac = dc_texturemid + (dc_yl-centery)*fracstep;
  162. do
  163. {
  164. *dest = tinttable[((*dest)<<8)
  165. +dc_colormap[dc_source[(frac>>FRACBITS)&127]]];
  166. dest += SCREENWIDTH;
  167. frac += fracstep;
  168. } while(count--);
  169. }
  170. /*
  171. ========================
  172. =
  173. = R_DrawTranslatedColumn
  174. =
  175. ========================
  176. */
  177. byte *dc_translation;
  178. byte *translationtables;
  179. void R_DrawTranslatedColumn (void)
  180. {
  181. int count;
  182. byte *dest;
  183. fixed_t frac, fracstep;
  184. count = dc_yh - dc_yl;
  185. if (count < 0)
  186. return;
  187. #ifdef RANGECHECK
  188. if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  189. I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
  190. #endif
  191. dest = ylookup[dc_yl] + columnofs[dc_x];
  192. fracstep = dc_iscale;
  193. frac = dc_texturemid + (dc_yl-centery)*fracstep;
  194. do
  195. {
  196. *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
  197. dest += SCREENWIDTH;
  198. frac += fracstep;
  199. } while (count--);
  200. }
  201. //============================================================================
  202. //
  203. // R_DrawTranslatedFuzzColumn
  204. //
  205. //============================================================================
  206. void R_DrawTranslatedFuzzColumn (void)
  207. {
  208. int count;
  209. byte *dest;
  210. fixed_t frac, fracstep;
  211. count = dc_yh - dc_yl;
  212. if (count < 0)
  213. return;
  214. #ifdef RANGECHECK
  215. if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  216. I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
  217. #endif
  218. dest = ylookup[dc_yl] + columnofs[dc_x];
  219. fracstep = dc_iscale;
  220. frac = dc_texturemid + (dc_yl-centery)*fracstep;
  221. do
  222. {
  223. *dest = tinttable[((*dest)<<8)
  224. +dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]];
  225. dest += SCREENWIDTH;
  226. frac += fracstep;
  227. } while (count--);
  228. }
  229. //============================================================================
  230. //
  231. // R_DrawTranslatedAltFuzzColumn
  232. //
  233. //============================================================================
  234. /*
  235. void R_DrawTranslatedAltFuzzColumn (void)
  236. {
  237. int count;
  238. byte *dest;
  239. fixed_t frac, fracstep;
  240. count = dc_yh - dc_yl;
  241. if (count < 0)
  242. return;
  243. #ifdef RANGECHECK
  244. if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  245. I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
  246. #endif
  247. dest = ylookup[dc_yl] + columnofs[dc_x];
  248. fracstep = dc_iscale;
  249. frac = dc_texturemid + (dc_yl-centery)*fracstep;
  250. do
  251. {
  252. *dest = tinttable[*dest
  253. +(dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8)];
  254. dest += SCREENWIDTH;
  255. frac += fracstep;
  256. } while (count--);
  257. }
  258. */
  259. //--------------------------------------------------------------------------
  260. //
  261. // PROC R_InitTranslationTables
  262. //
  263. //--------------------------------------------------------------------------
  264. void R_InitTranslationTables (void)
  265. {
  266. int i;
  267. byte *transLump;
  268. // Load tint table
  269. tinttable = W_CacheLumpName("TINTTAB", PU_STATIC);
  270. // Allocate translation tables
  271. translationtables = Z_Malloc(256*3*(MAXPLAYERS-1)+255,
  272. PU_STATIC, 0);
  273. translationtables = (byte *)(((int)translationtables+255)&~255);
  274. for(i = 0; i < 3*(MAXPLAYERS-1); i++)
  275. {
  276. transLump = W_CacheLumpNum(W_GetNumForName("trantbl0")+i, PU_STATIC);
  277. memcpy(translationtables+i*256, transLump, 256);
  278. Z_Free(transLump);
  279. }
  280. }
  281. /*
  282. ================
  283. =
  284. = R_DrawSpan
  285. =
  286. ================
  287. */
  288. int ds_y;
  289. int ds_x1;
  290. int ds_x2;
  291. lighttable_t *ds_colormap;
  292. fixed_t ds_xfrac;
  293. fixed_t ds_yfrac;
  294. fixed_t ds_xstep;
  295. fixed_t ds_ystep;
  296. byte *ds_source; // start of a 64*64 tile image
  297. int dscount; // just for profiling
  298. #ifndef __WATCOMC__
  299. #ifndef __i386
  300. #ifndef __m68k
  301. void R_DrawSpan (void)
  302. {
  303. fixed_t xfrac, yfrac;
  304. byte *dest;
  305. int count, spot;
  306. #ifdef RANGECHECK
  307. if (ds_x2 < ds_x1 || ds_x1<0 || ds_x2>=SCREENWIDTH
  308. || (unsigned)ds_y>SCREENHEIGHT)
  309. I_Error ("R_DrawSpan: %i to %i at %i",ds_x1,ds_x2,ds_y);
  310. // dscount++;
  311. #endif
  312. xfrac = ds_xfrac;
  313. yfrac = ds_yfrac;
  314. dest = ylookup[ds_y] + columnofs[ds_x1];
  315. count = ds_x2 - ds_x1;
  316. do
  317. {
  318. spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
  319. *dest++ = ds_colormap[ds_source[spot]];
  320. xfrac += ds_xstep;
  321. yfrac += ds_ystep;
  322. } while (count--);
  323. }
  324. #endif
  325. #endif
  326. #endif
  327. void R_DrawSpanLow (void)
  328. {
  329. fixed_t xfrac, yfrac;
  330. byte *dest;
  331. int count, spot;
  332. #ifdef RANGECHECK
  333. if (ds_x2 < ds_x1 || ds_x1<0 || ds_x2>=SCREENWIDTH
  334. || (unsigned)ds_y>SCREENHEIGHT)
  335. I_Error ("R_DrawSpan: %i to %i at %i",ds_x1,ds_x2,ds_y);
  336. // dscount++;
  337. #endif
  338. xfrac = ds_xfrac;
  339. yfrac = ds_yfrac;
  340. dest = ylookup[ds_y] + columnofs[ds_x1];
  341. count = ds_x2 - ds_x1;
  342. do
  343. {
  344. spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
  345. *dest++ = ds_colormap[ds_source[spot]];
  346. xfrac += ds_xstep;
  347. yfrac += ds_ystep;
  348. } while (count--);
  349. }
  350. /*
  351. ================
  352. =
  353. = R_InitBuffer
  354. =
  355. =================
  356. */
  357. void R_InitBuffer (int width, int height)
  358. {
  359. int i;
  360. viewwindowx = (SCREENWIDTH-width) >> 1;
  361. for (i=0 ; i<width ; i++)
  362. columnofs[i] = viewwindowx + i;
  363. if (width == SCREENWIDTH)
  364. viewwindowy = 0;
  365. else
  366. viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1;
  367. for (i=0 ; i<height ; i++)
  368. ylookup[i] = screen + (i+viewwindowy)*SCREENWIDTH;
  369. }
  370. /*
  371. ==================
  372. =
  373. = R_DrawViewBorder
  374. =
  375. = Draws the border around the view for different size windows
  376. ==================
  377. */
  378. boolean BorderNeedRefresh;
  379. void R_DrawViewBorder (void)
  380. {
  381. byte *src, *dest;
  382. int x,y;
  383. if (scaledviewwidth == SCREENWIDTH)
  384. return;
  385. src = W_CacheLumpName("F_022", PU_CACHE);
  386. dest = screen;
  387. for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++)
  388. {
  389. for (x=0 ; x<SCREENWIDTH/64 ; x++)
  390. {
  391. memcpy (dest, src+((y&63)<<6), 64);
  392. dest += 64;
  393. }
  394. if (SCREENWIDTH&63)
  395. {
  396. memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
  397. dest += (SCREENWIDTH&63);
  398. }
  399. }
  400. for(x=viewwindowx; x < viewwindowx+viewwidth; x += 16)
  401. {
  402. V_DrawPatch(x, viewwindowy-4, W_CacheLumpName("bordt", PU_CACHE));
  403. V_DrawPatch(x, viewwindowy+viewheight, W_CacheLumpName("bordb",
  404. PU_CACHE));
  405. }
  406. for(y=viewwindowy; y < viewwindowy+viewheight; y += 16)
  407. {
  408. V_DrawPatch(viewwindowx-4, y, W_CacheLumpName("bordl", PU_CACHE));
  409. V_DrawPatch(viewwindowx+viewwidth, y, W_CacheLumpName("bordr",
  410. PU_CACHE));
  411. }
  412. V_DrawPatch(viewwindowx-4, viewwindowy-4, W_CacheLumpName("bordtl",
  413. PU_CACHE));
  414. V_DrawPatch(viewwindowx+viewwidth, viewwindowy-4,
  415. W_CacheLumpName("bordtr", PU_CACHE));
  416. V_DrawPatch(viewwindowx+viewwidth, viewwindowy+viewheight,
  417. W_CacheLumpName("bordbr", PU_CACHE));
  418. V_DrawPatch(viewwindowx-4, viewwindowy+viewheight,
  419. W_CacheLumpName("bordbl", PU_CACHE));
  420. }
  421. /*
  422. ==================
  423. =
  424. = R_DrawTopBorder
  425. =
  426. = Draws the top border around the view for different size windows
  427. ==================
  428. */
  429. boolean BorderTopRefresh;
  430. void R_DrawTopBorder (void)
  431. {
  432. byte *src, *dest;
  433. int x,y;
  434. if (scaledviewwidth == SCREENWIDTH)
  435. return;
  436. /* if(shareware)
  437. {
  438. src = W_CacheLumpName ("FLOOR04", PU_CACHE);
  439. }
  440. else
  441. {
  442. src = W_CacheLumpName ("FLAT513", PU_CACHE);
  443. }
  444. */
  445. src = W_CacheLumpName("F_022", PU_CACHE);
  446. dest = screen;
  447. for (y=0 ; y<34 ; y++)
  448. {
  449. for (x=0 ; x<SCREENWIDTH/64 ; x++)
  450. {
  451. memcpy (dest, src+((y&63)<<6), 64);
  452. dest += 64;
  453. }
  454. if (SCREENWIDTH&63)
  455. {
  456. memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
  457. dest += (SCREENWIDTH&63);
  458. }
  459. }
  460. if(viewwindowy < 35)
  461. {
  462. for(x=viewwindowx; x < viewwindowx+viewwidth; x += 16)
  463. {
  464. V_DrawPatch(x, viewwindowy-4, W_CacheLumpName("bordt", PU_CACHE));
  465. }
  466. V_DrawPatch(viewwindowx-4, viewwindowy, W_CacheLumpName("bordl",
  467. PU_CACHE));
  468. V_DrawPatch(viewwindowx+viewwidth, viewwindowy,
  469. W_CacheLumpName("bordr", PU_CACHE));
  470. V_DrawPatch(viewwindowx-4, viewwindowy+16, W_CacheLumpName("bordl",
  471. PU_CACHE));
  472. V_DrawPatch(viewwindowx+viewwidth, viewwindowy+16,
  473. W_CacheLumpName("bordr", PU_CACHE));
  474. V_DrawPatch(viewwindowx-4, viewwindowy-4, W_CacheLumpName("bordtl",
  475. PU_CACHE));
  476. V_DrawPatch(viewwindowx+viewwidth, viewwindowy-4,
  477. W_CacheLumpName("bordtr", PU_CACHE));
  478. }
  479. }