r_draw.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // draw.c
  16. #include "r_local.h"
  17. image_t *draw_chars; // 8*8 graphic characters
  18. //=============================================================================
  19. /*
  20. ================
  21. Draw_FindPic
  22. ================
  23. */
  24. image_t *Draw_FindPic (char *name)
  25. {
  26. image_t *image;
  27. char fullname[MAX_QPATH];
  28. if (name[0] != '/' && name[0] != '\\')
  29. {
  30. Com_sprintf (fullname, sizeof(fullname), "pics/%s.pcx", name);
  31. image = R_FindImage (fullname, it_pic);
  32. }
  33. else
  34. image = R_FindImage (name+1, it_pic);
  35. return image;
  36. }
  37. /*
  38. ===============
  39. Draw_InitLocal
  40. ===============
  41. */
  42. void Draw_InitLocal (void)
  43. {
  44. draw_chars = Draw_FindPic ("conchars");
  45. }
  46. /*
  47. ================
  48. Draw_Char
  49. Draws one 8*8 graphics character
  50. It can be clipped to the top of the screen to allow the console to be
  51. smoothly scrolled off.
  52. ================
  53. */
  54. void Draw_Char (int x, int y, int num)
  55. {
  56. byte *dest;
  57. byte *source;
  58. int drawline;
  59. int row, col;
  60. num &= 255;
  61. if (num == 32 || num == 32+128)
  62. return;
  63. if (y <= -8)
  64. return; // totally off screen
  65. // if ( ( y + 8 ) >= vid.height )
  66. if ( ( y + 8 ) > vid.height ) // PGM - status text was missing in sw...
  67. return;
  68. #ifdef PARANOID
  69. if (y > vid.height - 8 || x < 0 || x > vid.width - 8)
  70. ri.Sys_Error (ERR_FATAL,"Con_DrawCharacter: (%i, %i)", x, y);
  71. if (num < 0 || num > 255)
  72. ri.Sys_Error (ERR_FATAL,"Con_DrawCharacter: char %i", num);
  73. #endif
  74. row = num>>4;
  75. col = num&15;
  76. source = draw_chars->pixels[0] + (row<<10) + (col<<3);
  77. if (y < 0)
  78. { // clipped
  79. drawline = 8 + y;
  80. source -= 128*y;
  81. y = 0;
  82. }
  83. else
  84. drawline = 8;
  85. dest = vid.buffer + y*vid.rowbytes + x;
  86. while (drawline--)
  87. {
  88. if (source[0] != TRANSPARENT_COLOR)
  89. dest[0] = source[0];
  90. if (source[1] != TRANSPARENT_COLOR)
  91. dest[1] = source[1];
  92. if (source[2] != TRANSPARENT_COLOR)
  93. dest[2] = source[2];
  94. if (source[3] != TRANSPARENT_COLOR)
  95. dest[3] = source[3];
  96. if (source[4] != TRANSPARENT_COLOR)
  97. dest[4] = source[4];
  98. if (source[5] != TRANSPARENT_COLOR)
  99. dest[5] = source[5];
  100. if (source[6] != TRANSPARENT_COLOR)
  101. dest[6] = source[6];
  102. if (source[7] != TRANSPARENT_COLOR)
  103. dest[7] = source[7];
  104. source += 128;
  105. dest += vid.rowbytes;
  106. }
  107. }
  108. /*
  109. =============
  110. Draw_GetPicSize
  111. =============
  112. */
  113. void Draw_GetPicSize (int *w, int *h, char *pic)
  114. {
  115. image_t *gl;
  116. gl = Draw_FindPic (pic);
  117. if (!gl)
  118. {
  119. *w = *h = -1;
  120. return;
  121. }
  122. *w = gl->width;
  123. *h = gl->height;
  124. }
  125. /*
  126. =============
  127. Draw_StretchPicImplementation
  128. =============
  129. */
  130. void Draw_StretchPicImplementation (int x, int y, int w, int h, image_t *pic)
  131. {
  132. byte *dest, *source;
  133. int v, u, sv;
  134. int height;
  135. int f, fstep;
  136. int skip;
  137. if ((x < 0) ||
  138. (x + w > vid.width) ||
  139. (y + h > vid.height))
  140. {
  141. ri.Sys_Error (ERR_FATAL,"Draw_Pic: bad coordinates");
  142. }
  143. height = h;
  144. if (y < 0)
  145. {
  146. skip = -y;
  147. height += y;
  148. y = 0;
  149. }
  150. else
  151. skip = 0;
  152. dest = vid.buffer + y * vid.rowbytes + x;
  153. for (v=0 ; v<height ; v++, dest += vid.rowbytes)
  154. {
  155. sv = (skip + v)*pic->height/h;
  156. source = pic->pixels[0] + sv*pic->width;
  157. if (w == pic->width)
  158. memcpy (dest, source, w);
  159. else
  160. {
  161. f = 0;
  162. fstep = pic->width*0x10000/w;
  163. for (u=0 ; u<w ; u+=4)
  164. {
  165. dest[u] = source[f>>16];
  166. f += fstep;
  167. dest[u+1] = source[f>>16];
  168. f += fstep;
  169. dest[u+2] = source[f>>16];
  170. f += fstep;
  171. dest[u+3] = source[f>>16];
  172. f += fstep;
  173. }
  174. }
  175. }
  176. }
  177. /*
  178. =============
  179. Draw_StretchPic
  180. =============
  181. */
  182. void Draw_StretchPic (int x, int y, int w, int h, char *name)
  183. {
  184. image_t *pic;
  185. pic = Draw_FindPic (name);
  186. if (!pic)
  187. {
  188. ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
  189. return;
  190. }
  191. Draw_StretchPicImplementation (x, y, w, h, pic);
  192. }
  193. /*
  194. =============
  195. Draw_StretchRaw
  196. =============
  197. */
  198. void Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data)
  199. {
  200. image_t pic;
  201. pic.pixels[0] = data;
  202. pic.width = cols;
  203. pic.height = rows;
  204. Draw_StretchPicImplementation (x, y, w, h, &pic);
  205. }
  206. /*
  207. =============
  208. Draw_Pic
  209. =============
  210. */
  211. void Draw_Pic (int x, int y, char *name)
  212. {
  213. image_t *pic;
  214. byte *dest, *source;
  215. int v, u;
  216. int tbyte;
  217. int height;
  218. pic = Draw_FindPic (name);
  219. if (!pic)
  220. {
  221. ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
  222. return;
  223. }
  224. if ((x < 0) ||
  225. (x + pic->width > vid.width) ||
  226. (y + pic->height > vid.height))
  227. return; // ri.Sys_Error (ERR_FATAL,"Draw_Pic: bad coordinates");
  228. height = pic->height;
  229. source = pic->pixels[0];
  230. if (y < 0)
  231. {
  232. height += y;
  233. source += pic->width*-y;
  234. y = 0;
  235. }
  236. dest = vid.buffer + y * vid.rowbytes + x;
  237. if (!pic->transparent)
  238. {
  239. for (v=0 ; v<height ; v++)
  240. {
  241. memcpy (dest, source, pic->width);
  242. dest += vid.rowbytes;
  243. source += pic->width;
  244. }
  245. }
  246. else
  247. {
  248. if (pic->width & 7)
  249. { // general
  250. for (v=0 ; v<height ; v++)
  251. {
  252. for (u=0 ; u<pic->width ; u++)
  253. if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
  254. dest[u] = tbyte;
  255. dest += vid.rowbytes;
  256. source += pic->width;
  257. }
  258. }
  259. else
  260. { // unwound
  261. for (v=0 ; v<height ; v++)
  262. {
  263. for (u=0 ; u<pic->width ; u+=8)
  264. {
  265. if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
  266. dest[u] = tbyte;
  267. if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
  268. dest[u+1] = tbyte;
  269. if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
  270. dest[u+2] = tbyte;
  271. if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
  272. dest[u+3] = tbyte;
  273. if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
  274. dest[u+4] = tbyte;
  275. if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
  276. dest[u+5] = tbyte;
  277. if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
  278. dest[u+6] = tbyte;
  279. if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
  280. dest[u+7] = tbyte;
  281. }
  282. dest += vid.rowbytes;
  283. source += pic->width;
  284. }
  285. }
  286. }
  287. }
  288. /*
  289. =============
  290. Draw_TileClear
  291. This repeats a 64*64 tile graphic to fill the screen around a sized down
  292. refresh window.
  293. =============
  294. */
  295. void Draw_TileClear (int x, int y, int w, int h, char *name)
  296. {
  297. int i, j;
  298. byte *psrc;
  299. byte *pdest;
  300. image_t *pic;
  301. int x2;
  302. if (x < 0)
  303. {
  304. w += x;
  305. x = 0;
  306. }
  307. if (y < 0)
  308. {
  309. h += y;
  310. y = 0;
  311. }
  312. if (x + w > vid.width)
  313. w = vid.width - x;
  314. if (y + h > vid.height)
  315. h = vid.height - y;
  316. if (w <= 0 || h <= 0)
  317. return;
  318. pic = Draw_FindPic (name);
  319. if (!pic)
  320. {
  321. ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
  322. return;
  323. }
  324. x2 = x + w;
  325. pdest = vid.buffer + y*vid.rowbytes;
  326. for (i=0 ; i<h ; i++, pdest += vid.rowbytes)
  327. {
  328. psrc = pic->pixels[0] + pic->width * ((i+y)&63);
  329. for (j=x ; j<x2 ; j++)
  330. pdest[j] = psrc[j&63];
  331. }
  332. }
  333. /*
  334. =============
  335. Draw_Fill
  336. Fills a box of pixels with a single color
  337. =============
  338. */
  339. void Draw_Fill (int x, int y, int w, int h, int c)
  340. {
  341. byte *dest;
  342. int u, v;
  343. if (x+w > vid.width)
  344. w = vid.width - x;
  345. if (y+h > vid.height)
  346. h = vid.height - y;
  347. if (x < 0)
  348. {
  349. w += x;
  350. x = 0;
  351. }
  352. if (y < 0)
  353. {
  354. h += y;
  355. y = 0;
  356. }
  357. if (w < 0 || h < 0)
  358. return;
  359. dest = vid.buffer + y*vid.rowbytes + x;
  360. for (v=0 ; v<h ; v++, dest += vid.rowbytes)
  361. for (u=0 ; u<w ; u++)
  362. dest[u] = c;
  363. }
  364. //=============================================================================
  365. /*
  366. ================
  367. Draw_FadeScreen
  368. ================
  369. */
  370. void Draw_FadeScreen (void)
  371. {
  372. int x,y;
  373. byte *pbuf;
  374. int t;
  375. for (y=0 ; y<vid.height ; y++)
  376. {
  377. pbuf = (byte *)(vid.buffer + vid.rowbytes*y);
  378. t = (y & 1) << 1;
  379. for (x=0 ; x<vid.width ; x++)
  380. {
  381. if ((x & 3) != t)
  382. pbuf[x] = 0;
  383. }
  384. }
  385. }