QUAKEGRB.C 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. #include "qlumpy.h"
  2. typedef struct
  3. {
  4. short ofs, length;
  5. } row_t;
  6. typedef struct
  7. {
  8. int width, height;
  9. int widthbits, heightbits;
  10. unsigned char data[4];
  11. } qtex_t;
  12. typedef struct
  13. {
  14. int width, height;
  15. byte data[4]; // variably sized
  16. } qpic_t;
  17. #define SCRN(x,y) (*(byteimage+(y)*byteimagewidth+x))
  18. /*
  19. ==============
  20. GrabRaw
  21. filename RAW x y width height
  22. ==============
  23. */
  24. void GrabRaw (void)
  25. {
  26. int x,y,xl,yl,xh,yh,w,h;
  27. byte *screen_p;
  28. int linedelta;
  29. GetToken (false);
  30. xl = atoi (token);
  31. GetToken (false);
  32. yl = atoi (token);
  33. GetToken (false);
  34. w = atoi (token);
  35. GetToken (false);
  36. h = atoi (token);
  37. xh = xl+w;
  38. yh = yl+h;
  39. screen_p = byteimage + yl*byteimagewidth + xl;
  40. linedelta = byteimagewidth - w;
  41. for (y=yl ; y<yh ; y++)
  42. {
  43. for (x=xl ; x<xh ; x++)
  44. {
  45. *lump_p++ = *screen_p;
  46. *screen_p++ = 0;
  47. }
  48. screen_p += linedelta;
  49. }
  50. }
  51. /*
  52. ==============
  53. GrabPalette
  54. filename PALETTE [startcolor endcolor]
  55. ==============
  56. */
  57. void GrabPalette (void)
  58. {
  59. int start,end,length;
  60. if (TokenAvailable())
  61. {
  62. GetToken (false);
  63. start = atoi (token);
  64. GetToken (false);
  65. end = atoi (token);
  66. }
  67. else
  68. {
  69. start = 0;
  70. end = 255;
  71. }
  72. length = 3*(end-start+1);
  73. memcpy (lump_p, lbmpalette+start*3, length);
  74. lump_p += length;
  75. }
  76. /*
  77. ==============
  78. GrabPic
  79. filename qpic x y width height
  80. ==============
  81. */
  82. void GrabPic (void)
  83. {
  84. int x,y,xl,yl,xh,yh;
  85. int width;
  86. byte transcolor;
  87. qpic_t *header;
  88. GetToken (false);
  89. xl = atoi (token);
  90. GetToken (false);
  91. yl = atoi (token);
  92. GetToken (false);
  93. xh = xl-1+atoi (token);
  94. GetToken (false);
  95. yh = yl-1+atoi (token);
  96. if (xh<xl || yh<yl || xl < 0 || yl<0 || xh>319 || yh>199)
  97. Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,xh,yh);
  98. transcolor = 255;
  99. //
  100. // fill in header
  101. //
  102. header = (qpic_t *)lump_p;
  103. width = xh-xl+1;
  104. header->width = LittleLong(width);
  105. header->height = LittleLong(yh-yl+1);
  106. //
  107. // start grabbing posts
  108. //
  109. lump_p = (byte *)header->data;
  110. for (y=yl ; y<= yh ; y++)
  111. for (x=xl ; x<=xh ; x++)
  112. *lump_p++ = SCRN(x,y);
  113. }
  114. /*
  115. =============================================================================
  116. COLORMAP GRABBING
  117. =============================================================================
  118. */
  119. /*
  120. ===============
  121. BestColor
  122. ===============
  123. */
  124. byte BestColor (int r, int g, int b, int start, int stop)
  125. {
  126. int i;
  127. int dr, dg, db;
  128. int bestdistortion, distortion;
  129. int bestcolor;
  130. byte *pal;
  131. //
  132. // let any color go to 0 as a last resort
  133. //
  134. bestdistortion = ( (int)r*r + (int)g*g + (int)b*b )*2;
  135. bestcolor = 0;
  136. pal = lbmpalette + start*3;
  137. for (i=start ; i<= stop ; i++)
  138. {
  139. dr = r - (int)pal[0];
  140. dg = g - (int)pal[1];
  141. db = b - (int)pal[2];
  142. pal += 3;
  143. distortion = dr*dr + dg*dg + db*db;
  144. if (distortion < bestdistortion)
  145. {
  146. if (!distortion)
  147. return i; // perfect match
  148. bestdistortion = distortion;
  149. bestcolor = i;
  150. }
  151. }
  152. return bestcolor;
  153. }
  154. /*
  155. ==============
  156. GrabColormap
  157. filename COLORMAP levels fullbrights
  158. the first map is an identiy 0-255
  159. the final map is all black except for the fullbrights
  160. the remaining maps are evenly spread
  161. fullbright colors start at the top of the palette.
  162. ==============
  163. */
  164. void GrabColormap (void)
  165. {
  166. int levels, brights;
  167. int l, c;
  168. float frac, red, green, blue;
  169. GetToken (false);
  170. levels = atoi (token);
  171. GetToken (false);
  172. brights = atoi (token);
  173. // identity lump
  174. for (l=0 ; l<256 ; l++)
  175. *lump_p++ = l;
  176. // shaded levels
  177. for (l=1;l<levels;l++)
  178. {
  179. frac = 1.0 - (float)l/(levels-1);
  180. for (c=0 ; c<256-brights ; c++)
  181. {
  182. red = lbmpalette[c*3];
  183. green = lbmpalette[c*3+1];
  184. blue = lbmpalette[c*3+2];
  185. red = (int)(red*frac+0.5);
  186. green = (int)(green*frac+0.5);
  187. blue = (int)(blue*frac+0.5);
  188. //
  189. // note: 254 instead of 255 because 255 is the transparent color, and we
  190. // don't want anything remapping to that
  191. //
  192. *lump_p++ = BestColor(red,green,blue, 0, 254);
  193. }
  194. for ( ; c<256 ; c++)
  195. *lump_p++ = c;
  196. }
  197. *lump_p++ = brights;
  198. }
  199. /*
  200. ==============
  201. GrabColormap2
  202. experimental -- not used by quake
  203. filename COLORMAP2 range levels fullbrights
  204. fullbright colors start at the top of the palette.
  205. Range can be greater than 1 to allow overbright color tables.
  206. the first map is all 0
  207. the last (levels-1) map is at range
  208. ==============
  209. */
  210. void GrabColormap2 (void)
  211. {
  212. int levels, brights;
  213. int l, c;
  214. float frac, red, green, blue;
  215. float range;
  216. GetToken (false);
  217. range = atof (token);
  218. GetToken (false);
  219. levels = atoi (token);
  220. GetToken (false);
  221. brights = atoi (token);
  222. // shaded levels
  223. for (l=0;l<levels;l++)
  224. {
  225. frac = range - range*(float)l/(levels-1);
  226. for (c=0 ; c<256-brights ; c++)
  227. {
  228. red = lbmpalette[c*3];
  229. green = lbmpalette[c*3+1];
  230. blue = lbmpalette[c*3+2];
  231. red = (int)(red*frac+0.5);
  232. green = (int)(green*frac+0.5);
  233. blue = (int)(blue*frac+0.5);
  234. //
  235. // note: 254 instead of 255 because 255 is the transparent color, and we
  236. // don't want anything remapping to that
  237. //
  238. *lump_p++ = BestColor(red,green,blue, 0, 254);
  239. }
  240. // fullbrights allways stay the same
  241. for ( ; c<256 ; c++)
  242. *lump_p++ = c;
  243. }
  244. *lump_p++ = brights;
  245. }
  246. /*
  247. =============================================================================
  248. MIPTEX GRABBING
  249. =============================================================================
  250. */
  251. typedef struct
  252. {
  253. char name[16];
  254. unsigned width, height;
  255. unsigned offsets[4]; // four mip maps stored
  256. } miptex_t;
  257. byte pixdata[256];
  258. int d_red, d_green, d_blue;
  259. /*
  260. =============
  261. AveragePixels
  262. =============
  263. */
  264. byte AveragePixels (int count)
  265. {
  266. int r,g,b;
  267. int i;
  268. int vis;
  269. int pix;
  270. int dr, dg, db;
  271. int bestdistortion, distortion;
  272. int bestcolor;
  273. byte *pal;
  274. int fullbright;
  275. int e;
  276. vis = 0;
  277. r = g = b = 0;
  278. fullbright = 0;
  279. for (i=0 ; i<count ; i++)
  280. {
  281. pix = pixdata[i];
  282. if (pix == 255)
  283. fullbright = 2;
  284. else if (pix >= 240)
  285. {
  286. return pix;
  287. if (!fullbright)
  288. {
  289. fullbright = true;
  290. r = 0;
  291. g = 0;
  292. b = 0;
  293. }
  294. }
  295. else
  296. {
  297. if (fullbright)
  298. continue;
  299. }
  300. r += lbmpalette[pix*3];
  301. g += lbmpalette[pix*3+1];
  302. b += lbmpalette[pix*3+2];
  303. vis++;
  304. }
  305. if (fullbright == 2)
  306. return 255;
  307. r /= vis;
  308. g /= vis;
  309. b /= vis;
  310. if (!fullbright)
  311. {
  312. r += d_red;
  313. g += d_green;
  314. b += d_blue;
  315. }
  316. //
  317. // find the best color
  318. //
  319. bestdistortion = r*r + g*g + b*b;
  320. bestcolor = 0;
  321. if (fullbright)
  322. {
  323. i = 240;
  324. e = 255;
  325. }
  326. else
  327. {
  328. i = 0;
  329. e = 240;
  330. }
  331. for ( ; i< e ; i++)
  332. {
  333. pix = i; //pixdata[i];
  334. pal = lbmpalette + pix*3;
  335. dr = r - (int)pal[0];
  336. dg = g - (int)pal[1];
  337. db = b - (int)pal[2];
  338. distortion = dr*dr + dg*dg + db*db;
  339. if (distortion < bestdistortion)
  340. {
  341. if (!distortion)
  342. {
  343. d_red = d_green = d_blue = 0; // no distortion yet
  344. return pix; // perfect match
  345. }
  346. bestdistortion = distortion;
  347. bestcolor = pix;
  348. }
  349. }
  350. if (!fullbright)
  351. { // error diffusion
  352. pal = lbmpalette + bestcolor*3;
  353. d_red = r - (int)pal[0];
  354. d_green = g - (int)pal[1];
  355. d_blue = b - (int)pal[2];
  356. }
  357. return bestcolor;
  358. }
  359. /*
  360. ==============
  361. GrabMip
  362. filename MIP x y width height
  363. must be multiples of sixteen
  364. ==============
  365. */
  366. void GrabMip (void)
  367. {
  368. int x,y,xl,yl,xh,yh,w,h;
  369. byte *screen_p, *source;
  370. int linedelta;
  371. miptex_t *qtex;
  372. int miplevel, mipstep;
  373. int xx, yy, pix;
  374. int count;
  375. GetToken (false);
  376. xl = atoi (token);
  377. GetToken (false);
  378. yl = atoi (token);
  379. GetToken (false);
  380. w = atoi (token);
  381. GetToken (false);
  382. h = atoi (token);
  383. if ( (w & 15) || (h & 15) )
  384. Error ("line %i: miptex sizes must be multiples of 16", scriptline);
  385. xh = xl+w;
  386. yh = yl+h;
  387. qtex = (miptex_t *)lump_p;
  388. qtex->width = LittleLong(w);
  389. qtex->height = LittleLong(h);
  390. strcpy (qtex->name, lumpname);
  391. lump_p = (byte *)&qtex->offsets[4];
  392. screen_p = byteimage + yl*byteimagewidth + xl;
  393. linedelta = byteimagewidth - w;
  394. source = lump_p;
  395. qtex->offsets[0] = LittleLong(lump_p - (byte *)qtex);
  396. for (y=yl ; y<yh ; y++)
  397. {
  398. for (x=xl ; x<xh ; x++)
  399. {
  400. pix = *screen_p;
  401. *screen_p++ = 0;
  402. if (pix == 255)
  403. pix = 0;
  404. *lump_p++ = pix;
  405. }
  406. screen_p += linedelta;
  407. }
  408. //
  409. // subsample for greater mip levels
  410. //
  411. d_red = d_green = d_blue = 0; // no distortion yet
  412. for (miplevel = 1 ; miplevel<4 ; miplevel++)
  413. {
  414. qtex->offsets[miplevel] = LittleLong(lump_p - (byte *)qtex);
  415. mipstep = 1<<miplevel;
  416. for (y=0 ; y<h ; y+=mipstep)
  417. {
  418. for (x = 0 ; x<w ; x+= mipstep)
  419. {
  420. count = 0;
  421. for (yy=0 ; yy<mipstep ; yy++)
  422. for (xx=0 ; xx<mipstep ; xx++)
  423. {
  424. pixdata[count] = source[ (y+yy)*w + x + xx ];
  425. count++;
  426. }
  427. *lump_p++ = AveragePixels (count);
  428. }
  429. }
  430. }
  431. }