palette.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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. //Current palette w/o intensity adjustments (18 bit)
  29. char current_pal[16][3];
  30. //Current intensity level (percentage) per color
  31. char current_intensity[16];
  32. //Intensity modified palette (updated at all times)
  33. char intensity_pal[16][3];
  34. //Whether we are currently "faded out" from a quick fade function
  35. char faded_out=0;
  36. //Saved intensities while faded out
  37. char saved_intensity[16];
  38. //Default EGA hardware palette. Also used for VGA palette refrencing.
  39. char default_EGA_hardware_pal[16]={
  40. 0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63 };
  41. //Default palette rgbs
  42. char default_pal[16][3]={
  43. { 00,00,00 },
  44. { 00,00,42 },
  45. { 00,42,00 },
  46. { 00,42,42 },
  47. { 42,00,00 },
  48. { 42,00,42 },
  49. { 42,21,00 },
  50. { 42,42,42 },
  51. { 21,21,21 },
  52. { 21,21,63 },
  53. { 21,63,21 },
  54. { 21,63,63 },
  55. { 63,21,21 },
  56. { 63,21,63 },
  57. { 63,63,21 },
  58. { 63,63,63 } };
  59. //Set one EGA palette register. Blanks screen. Sets attr, 0-15, to
  60. //ccode, 0-63.
  61. void set_ega_register(char attr,char ccode) {
  62. asm {
  63. mov dx,03C0h
  64. mov al,attr
  65. out dx,al
  66. mov al,ccode
  67. out dx,al
  68. }
  69. }
  70. //Unblank the screen after setting EGA palette registers.
  71. void unblank_screen(void) {
  72. asm {
  73. mov dx,03C0h
  74. mov al,20h
  75. out dx,al
  76. out dx,al
  77. }
  78. }
  79. //Set one VGA DAC palette register.
  80. void set_vga_register(char color,char r,char g,char b) {
  81. //Change color number to DAC register
  82. if(color<0) color=-color;
  83. else color=default_EGA_hardware_pal[color];
  84. asm {
  85. mov dx,03C8h
  86. mov al,color
  87. out dx,al
  88. inc dx
  89. mov al,r
  90. out dx,al
  91. mov al,g
  92. out dx,al
  93. mov al,b
  94. out dx,al
  95. }
  96. }
  97. //Initialize palette- On both EGA and VGA, sets the proper palette
  98. //codes. (IE sets up the default EGA palette) Call before using any
  99. //other code. Also call on exit or anytime to fully reset the palette
  100. //to its defaults.
  101. void init_palette(void) {
  102. int t1;
  103. //On both EGA and VGA, we must set all 16 registers to the defaults.
  104. //Also copy it over to the current palette.
  105. wait_retrace();
  106. for(t1=0;t1<16;t1++) {
  107. set_ega_register(t1,default_EGA_hardware_pal[t1]);
  108. current_intensity[t1]=saved_intensity[t1]=100;
  109. if(vga_avail)
  110. set_vga_register(t1,default_pal[t1][0],default_pal[t1][1],
  111. default_pal[t1][2]);
  112. intensity_pal[t1][0]=current_pal[t1][0]=default_pal[t1][0];
  113. intensity_pal[t1][1]=current_pal[t1][1]=default_pal[t1][1];
  114. intensity_pal[t1][2]=current_pal[t1][2]=default_pal[t1][2];
  115. }
  116. unblank_screen();
  117. faded_out=0;
  118. //Palette is now fully at default, and all data is initialized.
  119. }
  120. //Set current palette intensity, internally only.
  121. void set_palette_intensity(char percent) {
  122. int t1,t2;
  123. if(percent<0) percent=0;
  124. if(percent>100) percent=100;
  125. if(faded_out) {
  126. //If faded out, save in saved_intensity and exit
  127. for(t1=0;t1<16;t1++)
  128. saved_intensity[t1]=percent;
  129. return;
  130. }
  131. //Copy palette to intensity palette, adjusting intensity
  132. for(t1=0;t1<16;t1++) {
  133. current_intensity[t1]=percent;
  134. for(t2=0;t2<3;t2++) {
  135. intensity_pal[t1][t2]=current_pal[t1][t2]*percent/100;
  136. }
  137. }
  138. //Done
  139. return;
  140. }
  141. //Set current palette intensity, internally only, but for only one color.
  142. void set_color_intensity(char color,char percent) {
  143. int t2;
  144. if(percent<0) percent=0;
  145. if(percent>100) percent=100;
  146. if(faded_out) {
  147. //Put in saved if faded out
  148. saved_intensity[color]=percent;
  149. return;
  150. }
  151. //Copy palette to intensity palette, adjusting intensity
  152. current_intensity[color]=percent;
  153. for(t2=0;t2<3;t2++)
  154. intensity_pal[color][t2]=current_pal[color][t2]*percent/100;
  155. //Done
  156. return;
  157. }
  158. //Set rgb for one color, internally only. Sets current_pal. Also sets
  159. //intensity_pal according to current intensity. R G B can range from
  160. //0 to 63.
  161. void set_rgb(char color,char r,char g,char b) {
  162. int t2;
  163. if(r<0) r=0; if(g<0) g=0; if(b<0) b=0;
  164. if(r>63) r=63; if(g>63) g=63; if(b>63) b=63;
  165. //Set current pal
  166. current_pal[color][0]=r;
  167. current_pal[color][1]=g;
  168. current_pal[color][2]=b;
  169. //Copy palette to intensity palette, adjusting intensity
  170. for(t2=0;t2<3;t2++)
  171. intensity_pal[color][t2]=current_pal[color][t2]*
  172. current_intensity[color]/100;
  173. //Done
  174. return;
  175. }
  176. //Update palette onscreen. Waits for retrace if specified. (default)
  177. void update_palette(char wait_for_retrace) {
  178. int t1,t2,r,g,b;
  179. if(faded_out) return;
  180. //Wait for retrace if applicable
  181. if(wait_for_retrace) wait_retrace();
  182. //VGA
  183. if(vga_avail) {
  184. for(t1=0;t1<16;t1++)
  185. set_vga_register(t1,intensity_pal[t1][0],intensity_pal[t1][1],
  186. intensity_pal[t1][2]);
  187. //Special code for #0
  188. set_vga_register(-6,intensity_pal[0][0],intensity_pal[0][1],
  189. intensity_pal[0][2]);
  190. for(t1=8;t1<20;t1++)
  191. set_vga_register(-t1,intensity_pal[0][0],intensity_pal[0][1],
  192. intensity_pal[0][2]);
  193. for(t1=21;t1<56;t1++)
  194. set_vga_register(-t1,intensity_pal[0][0],intensity_pal[0][1],
  195. intensity_pal[0][2]);
  196. //Done
  197. return;
  198. }
  199. //EGA- turn 18 bit to 6 bit
  200. for(t1=0;t1<16;t1++) {
  201. t2=0;
  202. r=intensity_pal[t1][0];
  203. g=intensity_pal[t1][1];
  204. b=intensity_pal[t1][2];
  205. if(r<16) ;
  206. else if(r<32) t2|=32;
  207. else if(r<48) t2|=4;
  208. else t2|=36;
  209. if(g<16) ;
  210. else if(g<32) t2|=16;
  211. else if(g<48) t2|=2;
  212. else t2|=18;
  213. if(b<16) ;
  214. else if(b<32) t2|=8;
  215. else if(b<48) t2|=1;
  216. else t2|=9;
  217. set_ega_register(t1,t2);
  218. }
  219. unblank_screen();
  220. //Done
  221. }
  222. //Very quick fade out. Saves intensity table for fade in. Be sure
  223. //to use in conjuction with the next function.
  224. void vquick_fadeout(void) {
  225. int t1,t2;
  226. if(faded_out) return;
  227. //Save intensity table
  228. for(t1=0;t1<16;t1++)
  229. saved_intensity[t1]=current_intensity[t1];
  230. //Quick fadeout
  231. for(t1=0;t1<10;t1++) {
  232. for(t2=0;t2<16;t2++)
  233. set_color_intensity(t2,current_intensity[t2]-10);
  234. update_palette();
  235. }
  236. //Done
  237. faded_out=1;
  238. }
  239. //Very quick fade in. Uses intensity table saved from fade out. For
  240. //use in conjuction with the previous function.
  241. void vquick_fadein(void) {
  242. int t1,t2;
  243. if(!faded_out) return;
  244. //Clear now so update function works
  245. faded_out=0;
  246. //Quick fadein
  247. for(t1=0;t1<10;t1++) {
  248. for(t2=0;t2<16;t2++) {
  249. current_intensity[t2]+=10;
  250. if(current_intensity[t2]>saved_intensity[t2])
  251. current_intensity[t2]=saved_intensity[t2];
  252. set_color_intensity(t2,current_intensity[t2]);
  253. }
  254. update_palette();
  255. }
  256. //Done
  257. }
  258. //Instant fade out
  259. void insta_fadeout(void) {
  260. int t1;
  261. if(faded_out) return;
  262. //Save intensity table
  263. for(t1=0;t1<16;t1++)
  264. saved_intensity[t1]=current_intensity[t1];
  265. for(t1=0;t1<16;t1++)
  266. set_color_intensity(t1,0);
  267. update_palette();
  268. //Done
  269. faded_out=1;
  270. }
  271. //Insta fade in
  272. void insta_fadein(void) {
  273. int t1;
  274. if(!faded_out) return;
  275. //Clear now so update function works
  276. faded_out=0;
  277. //Quick fadein
  278. for(t1=0;t1<16;t1++)
  279. set_color_intensity(t1,current_intensity[t1]=saved_intensity[t1]);
  280. update_palette();
  281. //Done
  282. }
  283. //Sets RGB's to default EGA palette
  284. void default_palette(void) {
  285. for(int t1=0;t1<16;t1++)
  286. set_rgb(t1,default_pal[t1][0],default_pal[t1][1],
  287. default_pal[t1][2]);
  288. update_palette();
  289. }
  290. //Get the current intensity of a color
  291. char get_color_intensity(char color) {
  292. if(faded_out)
  293. return saved_intensity[color];
  294. return current_intensity[color];
  295. }
  296. //Gets the current RGB of a color
  297. void get_rgb(char color,char &r,char &g,char &b) {
  298. r=current_pal[color][0];
  299. g=current_pal[color][1];
  300. b=current_pal[color][2];
  301. }
  302. //Returns non-zero if faded out
  303. char is_faded(void) {
  304. return faded_out;
  305. }