PALETTE.C 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  12. */
  13. /*
  14. * $Source: f:/miner/source/2d/rcs/palette.c $
  15. * $Revision: 1.41 $
  16. * $Author: john $
  17. * $Date: 1995/02/02 14:26:31 $
  18. *
  19. * Graphical routines for setting the palette
  20. *
  21. * $Log: palette.c $
  22. * Revision 1.41 1995/02/02 14:26:31 john
  23. * Made palette fades work better with gamma thingy..
  24. *
  25. * Revision 1.40 1994/12/08 19:03:46 john
  26. * Made functions use cfile.
  27. *
  28. * Revision 1.39 1994/12/01 11:23:27 john
  29. * Limited Gamma from 0-8.
  30. *
  31. * Revision 1.38 1994/11/28 01:31:08 mike
  32. * optimize color lookup function, caching recently used colors.
  33. *
  34. * Revision 1.37 1994/11/18 22:50:18 john
  35. * Changed shorts to ints in parameters.
  36. *
  37. * Revision 1.36 1994/11/15 17:54:59 john
  38. * Made text palette fade in when game over.
  39. *
  40. * Revision 1.35 1994/11/10 19:53:14 matt
  41. * Fixed error handling is gr_use_palette_table()
  42. *
  43. * Revision 1.34 1994/11/07 13:53:48 john
  44. * Added better gamma stufff.
  45. *
  46. * Revision 1.33 1994/11/07 13:37:56 john
  47. * Added gamma correction stuff.
  48. *
  49. * Revision 1.32 1994/11/05 13:20:14 john
  50. * Fixed bug with find_closest_color_current not working.
  51. *
  52. * Revision 1.31 1994/11/05 13:08:09 john
  53. * MAde it return 0 when palette already faded out.
  54. *
  55. * Revision 1.30 1994/11/05 13:05:34 john
  56. * Added back in code to allow keys during fade.
  57. *
  58. * Revision 1.29 1994/11/05 12:49:50 john
  59. * Fixed bug with previous comment..
  60. *
  61. * Revision 1.28 1994/11/05 12:48:46 john
  62. * Made palette only fade in / out when its supposed to.
  63. *
  64. * Revision 1.27 1994/11/05 12:46:43 john
  65. * Changed palette stuff a bit.
  66. *
  67. * Revision 1.26 1994/11/01 12:59:35 john
  68. * Reduced palette.256 size.
  69. *
  70. * Revision 1.25 1994/10/26 23:55:35 john
  71. * Took out roller; Took out inverse table.
  72. *
  73. * Revision 1.24 1994/10/04 22:03:05 matt
  74. * Fixed bug: palette wasn't fading all the way out or in
  75. *
  76. * Revision 1.23 1994/09/22 16:08:40 john
  77. * Fixed some palette stuff.
  78. *
  79. * Revision 1.22 1994/09/19 11:44:31 john
  80. * Changed call to allocate selector to the dpmi module.
  81. *
  82. * Revision 1.21 1994/09/12 19:28:09 john
  83. * Fixed bug with unclipped fonts clipping.
  84. *
  85. * Revision 1.20 1994/09/12 18:18:39 john
  86. * Set 254 and 255 to fade to themselves in fadetable
  87. *
  88. * Revision 1.19 1994/09/12 14:40:10 john
  89. * Neatend.
  90. *
  91. * Revision 1.18 1994/09/09 09:31:55 john
  92. * Made find_closest_color not look at superx spot of 254
  93. *
  94. * Revision 1.17 1994/08/09 11:27:08 john
  95. * Add cthru stuff.
  96. *
  97. * Revision 1.16 1994/08/01 11:03:51 john
  98. * MAde it read in old/new palette.256
  99. *
  100. * Revision 1.15 1994/07/27 18:30:27 john
  101. * Took away the blending table.
  102. *
  103. * Revision 1.14 1994/06/09 10:39:52 john
  104. * In fade out.in functions, returned 1 if key was pressed...
  105. *
  106. * Revision 1.13 1994/05/31 19:04:16 john
  107. * Added key to stop fade if desired.
  108. *
  109. * Revision 1.12 1994/05/06 12:50:20 john
  110. * Added supertransparency; neatend things up; took out warnings.
  111. *
  112. * Revision 1.11 1994/05/03 19:39:02 john
  113. * *** empty log message ***
  114. *
  115. * Revision 1.10 1994/04/22 11:16:07 john
  116. * *** empty log message ***
  117. *
  118. * Revision 1.9 1994/04/08 16:59:40 john
  119. * Add fading poly's; Made palette fade 32 instead of 16.
  120. *
  121. * Revision 1.8 1994/03/16 17:21:17 john
  122. * Added slow palette searching options.
  123. *
  124. * Revision 1.7 1994/01/07 11:47:33 john
  125. * made use cflib
  126. *
  127. * Revision 1.6 1993/12/21 11:41:04 john
  128. * *** empty log message ***
  129. *
  130. * Revision 1.5 1993/12/09 15:02:47 john
  131. * Changed palette stuff majorly
  132. *
  133. * Revision 1.4 1993/12/07 12:31:41 john
  134. * moved bmd_palette to gr_palette
  135. *
  136. * Revision 1.3 1993/10/15 16:22:23 john
  137. * *** empty log message ***
  138. *
  139. * Revision 1.2 1993/09/26 18:59:46 john
  140. * fade stuff
  141. *
  142. * Revision 1.1 1993/09/08 11:44:03 john
  143. * Initial revision
  144. *
  145. *
  146. */
  147. #include <conio.h>
  148. #include <stdlib.h>
  149. #include <stdio.h>
  150. #include <io.h>
  151. #include "types.h"
  152. #include "mem.h"
  153. #include "gr.h"
  154. #include "grdef.h"
  155. #include "cfile.h"
  156. #include "error.h"
  157. #include "mono.h"
  158. #include "fix.h"
  159. #include "key.h"
  160. extern int gr_installed;
  161. ubyte gr_palette[256*3];
  162. ubyte gr_current_pal[256*3];
  163. ubyte gr_fade_table[256*34];
  164. ushort gr_palette_selector;
  165. ushort gr_fade_table_selector;
  166. ubyte gr_palette_gamma = 0;
  167. int gr_palette_gamma_param = 0;
  168. ubyte gr_palette_faded_out = 1;
  169. void gr_palette_set_gamma( int gamma )
  170. {
  171. if ( gamma < 0 ) gamma = 0;
  172. if ( gamma > 8 ) gamma = 8;
  173. if (gr_palette_gamma_param != gamma ) {
  174. gr_palette_gamma_param = gamma;
  175. gr_palette_gamma = gamma;
  176. if (!gr_palette_faded_out)
  177. gr_palette_load( gr_palette );
  178. }
  179. }
  180. int gr_palette_get_gamma()
  181. {
  182. return gr_palette_gamma_param;
  183. }
  184. void gr_use_palette_table( char * filename )
  185. {
  186. CFILE *fp;
  187. int i,fsize;
  188. fp = cfopen( filename, "rb" );
  189. if ( fp==NULL)
  190. Error("Can't open palette file <%s>",filename);
  191. fsize = cfilelength( fp );
  192. Assert( fsize == 9472 );
  193. cfread( gr_palette, 256*3, 1, fp );
  194. cfread( gr_fade_table, 256*34, 1, fp );
  195. cfclose(fp);
  196. // This is the TRANSPARENCY COLOR
  197. for (i=0; i<GR_FADE_LEVELS; i++ ) {
  198. gr_fade_table[i*256+255] = 255;
  199. }
  200. }
  201. #define SQUARE(x) ((x)*(x))
  202. #define MAX_COMPUTED_COLORS 32
  203. int Num_computed_colors=0;
  204. typedef struct {
  205. ubyte r,g,b,color_num;
  206. } color_record;
  207. color_record Computed_colors[MAX_COMPUTED_COLORS];
  208. // Add a computed color (by gr_find_closest_color) to list of computed colors in Computed_colors.
  209. // If list wasn't full already, increment Num_computed_colors.
  210. // If was full, replace a random one.
  211. void add_computed_color(int r, int g, int b, int color_num)
  212. {
  213. int add_index;
  214. if (Num_computed_colors < MAX_COMPUTED_COLORS) {
  215. add_index = Num_computed_colors;
  216. Num_computed_colors++;
  217. } else
  218. add_index = (rand() * MAX_COMPUTED_COLORS) >> 15;
  219. Computed_colors[add_index].r = r;
  220. Computed_colors[add_index].g = g;
  221. Computed_colors[add_index].b = b;
  222. Computed_colors[add_index].color_num = color_num;
  223. }
  224. void init_computed_colors(void)
  225. {
  226. int i;
  227. for (i=0; i<MAX_COMPUTED_COLORS; i++)
  228. Computed_colors[i].r = 255; // Make impossible to match.
  229. }
  230. int gr_find_closest_color( int r, int g, int b )
  231. {
  232. int i, j;
  233. int best_value, best_index, value;
  234. if (Num_computed_colors == 0)
  235. init_computed_colors();
  236. // If we've already computed this color, return it!
  237. for (i=0; i<Num_computed_colors; i++)
  238. if (r == Computed_colors[i].r)
  239. if (g == Computed_colors[i].g)
  240. if (b == Computed_colors[i].b) {
  241. if (i > 4) {
  242. color_record trec;
  243. trec = Computed_colors[i-1];
  244. Computed_colors[i-1] = Computed_colors[i];
  245. Computed_colors[i] = trec;
  246. return Computed_colors[i-1].color_num;
  247. }
  248. return Computed_colors[i].color_num;
  249. }
  250. // r &= 63;
  251. // g &= 63;
  252. // b &= 63;
  253. best_value = SQUARE(r-gr_palette[0])+SQUARE(g-gr_palette[1])+SQUARE(b-gr_palette[2]);
  254. best_index = 0;
  255. if (best_value==0) {
  256. add_computed_color(r, g, b, best_index);
  257. return best_index;
  258. }
  259. j=0;
  260. // only go to 255, 'cause we dont want to check the transparent color.
  261. for (i=1; i<254; i++ ) {
  262. j += 3;
  263. value = SQUARE(r-gr_palette[j])+SQUARE(g-gr_palette[j+1])+SQUARE(b-gr_palette[j+2]);
  264. if ( value < best_value ) {
  265. if (value==0) {
  266. add_computed_color(r, g, b, i);
  267. return i;
  268. }
  269. best_value = value;
  270. best_index = i;
  271. }
  272. }
  273. add_computed_color(r, g, b, best_index);
  274. return best_index;
  275. }
  276. int gr_find_closest_color_15bpp( int rgb )
  277. {
  278. return gr_find_closest_color( ((rgb>>10)&31)*2, ((rgb>>5)&31)*2, (rgb&31)*2 );
  279. }
  280. int gr_find_closest_color_current( int r, int g, int b )
  281. {
  282. int i, j;
  283. int best_value, best_index, value;
  284. // r &= 63;
  285. // g &= 63;
  286. // b &= 63;
  287. best_value = SQUARE(r-gr_current_pal[0])+SQUARE(g-gr_current_pal[1])+SQUARE(b-gr_current_pal[2]);
  288. best_index = 0;
  289. if (best_value==0)
  290. return best_index;
  291. j=0;
  292. // only go to 255, 'cause we dont want to check the transparent color.
  293. for (i=1; i<254; i++ ) {
  294. j += 3;
  295. value = SQUARE(r-gr_current_pal[j])+SQUARE(g-gr_current_pal[j+1])+SQUARE(b-gr_current_pal[j+2]);
  296. if ( value < best_value ) {
  297. if (value==0)
  298. return i;
  299. best_value = value;
  300. best_index = i;
  301. }
  302. }
  303. return best_index;
  304. }
  305. static int last_r=0, last_g=0, last_b=0;
  306. void gr_palette_step_up( int r, int g, int b )
  307. {
  308. int i;
  309. ubyte *p;
  310. int temp;
  311. if (gr_palette_faded_out) return;
  312. if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
  313. last_r = r;
  314. last_g = g;
  315. last_b = b;
  316. outp( 0x3c6, 0xff );
  317. outp( 0x3c8, 0 );
  318. p=gr_palette;
  319. for (i=0; i<256; i++ ) {
  320. temp = (int)(*p++) + r + gr_palette_gamma;
  321. if (temp<0) temp=0;
  322. else if (temp>63) temp=63;
  323. outp( 0x3c9, temp );
  324. temp = (int)(*p++) + g + gr_palette_gamma;
  325. if (temp<0) temp=0;
  326. else if (temp>63) temp=63;
  327. outp( 0x3c9, temp );
  328. temp = (int)(*p++) + b + gr_palette_gamma;
  329. if (temp<0) temp=0;
  330. else if (temp>63) temp=63;
  331. outp( 0x3c9, temp );
  332. }
  333. }
  334. void gr_palette_clear()
  335. {
  336. int i;
  337. outp( 0x3c6, 0xff );
  338. outp( 0x3c8, 0 );
  339. for (i=0; i<768; i++ ) {
  340. outp( 0x3c9, 0 );
  341. }
  342. gr_palette_faded_out = 1;
  343. }
  344. void gr_palette_load( ubyte * pal )
  345. {
  346. int i;
  347. ubyte c;
  348. outp( 0x3c6, 0xff );
  349. outp( 0x3c8, 0 );
  350. for (i=0; i<768; i++ ) {
  351. c = pal[i] + gr_palette_gamma;
  352. if ( c > 63 ) c = 63;
  353. outp( 0x3c9,c);
  354. gr_current_pal[i] = pal[i];
  355. }
  356. gr_palette_faded_out = 0;
  357. init_computed_colors();
  358. }
  359. int gr_palette_fade_out(ubyte *pal, int nsteps, int allow_keys )
  360. {
  361. ubyte c;
  362. int i,j;
  363. fix fade_palette[768];
  364. fix fade_palette_delta[768];
  365. allow_keys = allow_keys;
  366. if (gr_palette_faded_out) return 0;
  367. for (i=0; i<768; i++ ) {
  368. fade_palette[i] = i2f(pal[i]+gr_palette_gamma);
  369. fade_palette_delta[i] = fade_palette[i] / nsteps;
  370. }
  371. for (j=0; j<nsteps; j++ ) {
  372. gr_sync_display();
  373. outp( 0x3c6, 0xff );
  374. outp( 0x3c8, 0 );
  375. for (i=0; i<768; i++ ) {
  376. fade_palette[i] -= fade_palette_delta[i];
  377. if (fade_palette[i] < 0 )
  378. fade_palette[i] = 0;
  379. c = f2i(fade_palette[i]);
  380. if ( c > 63 ) c = 63;
  381. outp( 0x3c9, c );
  382. }
  383. }
  384. gr_palette_faded_out = 1;
  385. return 0;
  386. }
  387. int gr_palette_fade_in(ubyte *pal, int nsteps, int allow_keys)
  388. {
  389. int i,j;
  390. ubyte c;
  391. fix fade_palette[768];
  392. fix fade_palette_delta[768];
  393. allow_keys = allow_keys;
  394. if (!gr_palette_faded_out) return 0;
  395. for (i=0; i<768; i++ ) {
  396. gr_current_pal[i] = pal[i];
  397. fade_palette[i] = 0;
  398. fade_palette_delta[i] = i2f(pal[i]+gr_palette_gamma) / nsteps;
  399. }
  400. for (j=0; j<nsteps; j++ ) {
  401. gr_sync_display();
  402. outp( 0x3c6, 0xff );
  403. outp( 0x3c8, 0 );
  404. for (i=0; i<768; i++ ) {
  405. fade_palette[i] += fade_palette_delta[i];
  406. if (fade_palette[i] > i2f(pal[i]+gr_palette_gamma) )
  407. fade_palette[i] = i2f(pal[i]+gr_palette_gamma);
  408. c = f2i(fade_palette[i]);
  409. if ( c > 63 ) c = 63;
  410. outp( 0x3c9, c );
  411. }
  412. }
  413. gr_palette_faded_out = 0;
  414. return 0;
  415. }
  416. void gr_make_cthru_table(ubyte * table, ubyte r, ubyte g, ubyte b )
  417. {
  418. int i;
  419. ubyte r1, g1, b1;
  420. for (i=0; i<256; i++ ) {
  421. r1 = gr_palette[i*3+0] + r;
  422. if ( r1 > 63 ) r1 = 63;
  423. g1 = gr_palette[i*3+1] + g;
  424. if ( g1 > 63 ) g1 = 63;
  425. b1 = gr_palette[i*3+2] + b;
  426. if ( b1 > 63 ) b1 = 63;
  427. table[i] = gr_find_closest_color( r1, g1, b1 );
  428. }
  429. }
  430. void gr_palette_read(ubyte * palette)
  431. {
  432. int i;
  433. outp( 0x3c6, 0xff );
  434. outp( 0x3c7, 0 );
  435. for (i=0; i<768; i++ ) {
  436. *palette++ = inp( 0x3c9 );
  437. }
  438. }
  439.