R_DRAW.C 11 KB

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