palette.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /* $Id$
  2. * MegaZeux
  3. *
  4. * Copyright (C) 1996 Greg Janson
  5. * Copyright (C) 1998 Matthew D. Williams - dbwilli@scsn.net
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. //Palette code. Works on both the EGA and the VGA, although fading and
  22. //intensity percentage resolution is much less on the EGA, and rgb values
  23. //are rounded to 6 bit when output to the graphics card. (VGA rgb values
  24. //are 18 bit)
  25. #include "palette.h"
  26. #include "retrace.h"
  27. #include "comp_chk.h"
  28. char smzx_mode =0;
  29. //Current palette w/o intensity adjustments (18 bit)
  30. char current_pal[16][3];
  31. //Current intensity level (percentage) per color
  32. char current_intensity[16];
  33. //Intensity modified palette (updated at all times)
  34. char intensity_pal[16][3];
  35. //Whether we are currently "faded out" from a quick fade function
  36. char faded_out=0;
  37. //Saved intensities while faded out
  38. char saved_intensity[16];
  39. //Default EGA hardware palette. Also used for VGA palette refrencing.
  40. char default_EGA_hardware_pal[16]={
  41. 0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63 };
  42. //Default palette rgbs
  43. char default_pal[16][3]={
  44. { 00,00,00 },
  45. { 00,00,42 },
  46. { 00,42,00 },
  47. { 00,42,42 },
  48. { 42,00,00 },
  49. { 42,00,42 },
  50. { 42,21,00 },
  51. { 42,42,42 },
  52. { 21,21,21 },
  53. { 21,21,63 },
  54. { 21,63,21 },
  55. { 21,63,63 },
  56. { 63,21,21 },
  57. { 63,21,63 },
  58. { 63,63,21 },
  59. { 63,63,63 } };
  60. //Set one EGA palette register. Blanks screen. Sets attr, 0-15, to
  61. //ccode, 0-63.
  62. void set_ega_register(char attr,char ccode) {
  63. asm {
  64. mov dx,03C0h
  65. mov al,attr
  66. out dx,al
  67. mov al,ccode
  68. out dx,al
  69. }
  70. }
  71. //Unblank the screen after setting EGA palette registers.
  72. void unblank_screen(void) {
  73. asm {
  74. mov dx,03C0h
  75. mov al,20h
  76. out dx,al
  77. out dx,al
  78. }
  79. }
  80. //Set one VGA DAC palette register.
  81. void set_vga_register(char color,char r,char g,char b) {
  82. //Change color number to DAC register
  83. if(smzx_mode==0)
  84. {
  85. if(color<0) color=-color;
  86. else color=default_EGA_hardware_pal[color];
  87. }
  88. asm {
  89. mov dx,03C8h
  90. mov al,color
  91. out dx,al
  92. inc dx
  93. mov al,r
  94. out dx,al
  95. mov al,g
  96. out dx,al
  97. mov al,b
  98. out dx,al
  99. }
  100. }
  101. //Initialize palette- On both EGA and VGA, sets the proper palette
  102. //codes. (IE sets up the default EGA palette) Call before using any
  103. //other code. Also call on exit or anytime to fully reset the palette
  104. //to its defaults.
  105. void init_palette(void) {
  106. int t1;
  107. //On both EGA and VGA, we must set all 16 registers to the defaults.
  108. //Also copy it over to the current palette.
  109. wait_retrace();
  110. for(t1=0;t1<16;t1++) {
  111. set_ega_register(t1,default_EGA_hardware_pal[t1]);
  112. current_intensity[t1]=saved_intensity[t1]=100;
  113. if(vga_avail)
  114. set_vga_register(t1,default_pal[t1][0],default_pal[t1][1],
  115. default_pal[t1][2]);
  116. intensity_pal[t1][0]=current_pal[t1][0]=default_pal[t1][0];
  117. intensity_pal[t1][1]=current_pal[t1][1]=default_pal[t1][1];
  118. intensity_pal[t1][2]=current_pal[t1][2]=default_pal[t1][2];
  119. }
  120. unblank_screen();
  121. faded_out=0;
  122. //Palette is now fully at default, and all data is initialized.
  123. }
  124. //Set current palette intensity, internally only.
  125. void set_palette_intensity(char percent) {
  126. int t1,t2;
  127. if(percent<0) percent=0;
  128. if(percent>100) percent=100;
  129. if(faded_out) {
  130. //If faded out, save in saved_intensity and exit
  131. for(t1=0;t1<16;t1++)
  132. saved_intensity[t1]=percent;
  133. return;
  134. }
  135. //Copy palette to intensity palette, adjusting intensity
  136. for(t1=0;t1<16;t1++) {
  137. current_intensity[t1]=percent;
  138. for(t2=0;t2<3;t2++) {
  139. intensity_pal[t1][t2]=current_pal[t1][t2]*percent/100;
  140. }
  141. }
  142. //Done
  143. return;
  144. }
  145. //Set current palette intensity, internally only, but for only one color.
  146. void set_color_intensity(char color,char percent) {
  147. int t2;
  148. if(percent<0) percent=0;
  149. if(percent>100) percent=100;
  150. if(faded_out) {
  151. //Put in saved if faded out
  152. saved_intensity[color]=percent;
  153. return;
  154. }
  155. //Copy palette to intensity palette, adjusting intensity
  156. current_intensity[color]=percent;
  157. for(t2=0;t2<3;t2++)
  158. intensity_pal[color][t2]=current_pal[color][t2]*percent/100;
  159. //Done
  160. return;
  161. }
  162. //Set rgb for one color, internally only. Sets current_pal. Also sets
  163. //intensity_pal according to current intensity. R G B can range from
  164. //0 to 63.
  165. void set_rgb(char color,char r,char g,char b) {
  166. int t2;
  167. if(r<0) r=0; if(g<0) g=0; if(b<0) b=0;
  168. if(r>63) r=63; if(g>63) g=63; if(b>63) b=63;
  169. //Set current pal
  170. current_pal[color][0]=r;
  171. current_pal[color][1]=g;
  172. current_pal[color][2]=b;
  173. //Copy palette to intensity palette, adjusting intensity
  174. for(t2=0;t2<3;t2++)
  175. intensity_pal[color][t2]=current_pal[color][t2]*
  176. current_intensity[color]/100;
  177. //Done
  178. return;
  179. }
  180. //Update palette onscreen. Waits for retrace if specified. (default)
  181. void update_palette(char wait_for_retrace) {
  182. if(smzx_mode)
  183. {
  184. smzx_update_palette(wait_for_retrace);
  185. }
  186. else
  187. {
  188. normal_update_palette(wait_for_retrace);
  189. }
  190. }
  191. void normal_update_palette(char wait_for_retrace) {
  192. smzx_mode = 0;
  193. int t1,t2,r,g,b;
  194. if(faded_out) return;
  195. //Wait for retrace if applicable
  196. if(wait_for_retrace) wait_retrace();
  197. //VGA
  198. if(vga_avail) {
  199. for(t1=0;t1<16;t1++)
  200. set_vga_register(t1,intensity_pal[t1][0],intensity_pal[t1][1],
  201. intensity_pal[t1][2]);
  202. //Special code for #0
  203. set_vga_register(-6,intensity_pal[0][0],intensity_pal[0][1],
  204. intensity_pal[0][2]);
  205. for(t1=8;t1<20;t1++)
  206. set_vga_register(-t1,intensity_pal[0][0],intensity_pal[0][1],
  207. intensity_pal[0][2]);
  208. for(t1=21;t1<56;t1++)
  209. set_vga_register(-t1,intensity_pal[0][0],intensity_pal[0][1],
  210. intensity_pal[0][2]);
  211. //Done
  212. return;
  213. }
  214. //EGA- turn 18 bit to 6 bit
  215. for(t1=0;t1<16;t1++) {
  216. t2=0;
  217. r=intensity_pal[t1][0];
  218. g=intensity_pal[t1][1];
  219. b=intensity_pal[t1][2];
  220. if(r<16) ;
  221. else if(r<32) t2|=32;
  222. else if(r<48) t2|=4;
  223. else t2|=36;
  224. if(g<16) ;
  225. else if(g<32) t2|=16;
  226. else if(g<48) t2|=2;
  227. else t2|=18;
  228. if(b<16) ;
  229. else if(b<32) t2|=8;
  230. else if(b<48) t2|=1;
  231. else t2|=9;
  232. set_ega_register(t1,t2);
  233. }
  234. unblank_screen();
  235. //Done
  236. }
  237. void smzx_update_palette(char wait_for_retrace) {
  238. smzx_mode = 1;
  239. int t1,t2,r,g,b;
  240. if(faded_out)return;
  241. //Wait for retrace if applicable
  242. if(wait_for_retrace)wait_retrace();
  243. //VGA
  244. if(vga_avail)
  245. {
  246. for(t1=0;t1<256;t1++)
  247. set_vga_register(t1,
  248. ((intensity_pal[t1&15][0] << 1) + intensity_pal[t1>>4][0])/3 ,
  249. ((intensity_pal[t1&15][1] << 1) + intensity_pal[t1>>4][1])/3 ,
  250. ((intensity_pal[t1&15][2] << 1) + intensity_pal[t1>>4][2])/3 );
  251. return;
  252. }
  253. //EGA- turn 18 bit to 6 bit
  254. for(t1=0;t1<16;t1++) {
  255. t2=0;
  256. r=intensity_pal[t1][0];
  257. g=intensity_pal[t1][1];
  258. b=intensity_pal[t1][2];
  259. if(r<16) ;
  260. else if(r<32) t2|=32;
  261. else if(r<48) t2|=4;
  262. else t2|=36;
  263. if(g<16) ;
  264. else if(g<32) t2|=16;
  265. else if(g<48) t2|=2;
  266. else t2|=18;
  267. if(b<16) ;
  268. else if(b<32) t2|=8;
  269. else if(b<48) t2|=1;
  270. else t2|=9;
  271. set_ega_register(t1,t2);
  272. }
  273. unblank_screen();
  274. }
  275. //Very quick fade out. Saves intensity table for fade in. Be sure
  276. //to use in conjuction with the next function.
  277. void vquick_fadeout(void) {
  278. int t1,t2;
  279. if(faded_out) return;
  280. //Save intensity table
  281. for(t1=0;t1<16;t1++)
  282. saved_intensity[t1]=current_intensity[t1];
  283. //Quick fadeout
  284. for(t1=0;t1<10;t1++) {
  285. for(t2=0;t2<16;t2++)
  286. set_color_intensity(t2,current_intensity[t2]-10);
  287. update_palette();
  288. }
  289. //Done
  290. faded_out=1;
  291. }
  292. //Very quick fade in. Uses intensity table saved from fade out. For
  293. //use in conjuction with the previous function.
  294. void vquick_fadein(void) {
  295. int t1,t2;
  296. if(!faded_out) return;
  297. //Clear now so update function works
  298. faded_out=0;
  299. //Quick fadein
  300. for(t1=0;t1<10;t1++) {
  301. for(t2=0;t2<16;t2++) {
  302. current_intensity[t2]+=10;
  303. if(current_intensity[t2]>saved_intensity[t2])
  304. current_intensity[t2]=saved_intensity[t2];
  305. set_color_intensity(t2,current_intensity[t2]);
  306. }
  307. update_palette();
  308. }
  309. //Done
  310. }
  311. //Instant fade out
  312. void insta_fadeout(void) {
  313. int t1;
  314. if(faded_out) return;
  315. //Save intensity table
  316. for(t1=0;t1<16;t1++)
  317. saved_intensity[t1]=current_intensity[t1];
  318. for(t1=0;t1<16;t1++)
  319. set_color_intensity(t1,0);
  320. update_palette();
  321. //Done
  322. faded_out=1;
  323. }
  324. //Insta fade in
  325. void insta_fadein(void) {
  326. int t1;
  327. if(!faded_out) return;
  328. //Clear now so update function works
  329. faded_out=0;
  330. //Quick fadein
  331. for(t1=0;t1<16;t1++)
  332. set_color_intensity(t1,current_intensity[t1]=saved_intensity[t1]);
  333. update_palette();
  334. //Done
  335. }
  336. //Sets RGB's to default EGA palette
  337. void default_palette(void) {
  338. for(int t1=0;t1<16;t1++)
  339. set_rgb(t1,default_pal[t1][0],default_pal[t1][1],
  340. default_pal[t1][2]);
  341. update_palette();
  342. }
  343. //Get the current intensity of a color
  344. char get_color_intensity(char color) {
  345. if(faded_out)
  346. return saved_intensity[color];
  347. return current_intensity[color];
  348. }
  349. //Gets the current RGB of a color
  350. void get_rgb(char color,char &r,char &g,char &b) {
  351. r=current_pal[color][0];
  352. g=current_pal[color][1];
  353. b=current_pal[color][2];
  354. }
  355. //Returns non-zero if faded out
  356. char is_faded(void) {
  357. return faded_out;
  358. }
  359. void set_Color_Aspect(char color,char aspect,int value)
  360. {
  361. switch((int) aspect)
  362. {
  363. case 0:
  364. set_rgb(color,(char) value,current_pal[color][1],current_pal[color][2]);
  365. break;
  366. case 1:
  367. set_rgb(color,current_pal[color][0],(char) value,current_pal[color][2]);
  368. break;
  369. case 2:
  370. set_rgb(color,current_pal[color][0],current_pal[color][1],(char)value);
  371. break;
  372. }
  373. update_palette();
  374. }
  375. int get_Color_Aspect(char color,char aspect)
  376. {
  377. return (int) current_pal[color][aspect];
  378. }