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-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13 
14 #define WIN95
15 #define WIN32_LEAN_AND_MEAN
16 #include <windows.h>
17 
18 #include <conio.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <io.h>
22 
23 #include "ddraw.h"
24 
25 #include "types.h"
26 #include "mem.h"
27 #include "gr.h"
28 #include "cfile.h"
29 #include "error.h"
30 #include "mono.h"
31 #include "fix.h"
32 #include "key.h"
33 #include "winapp.h"
34 #include "dd.h"
35 
36 typedef struct LOGPAL256 {
37 	WORD ver;
38 	WORD num;
39 	PALETTEENTRY ScratchPal[256];
40 } LOGPAL256;
41 
42 
43 //	Special --------------------------------------------------------------------
44 extern int gr_installed;
45 
46 
47 //	Globals --------------------------------------------------------------------
48 
49 ubyte gr_palette[256*3];					// Main Palette in RGB
50 ubyte gr_current_pal[256*3];				// Current Valid Palette in RGB
51 ubyte gr_fade_table[256*34];			 	// Fade Palette Table in RGB
52 
53 ubyte	gr_palette_gamma = 0;
54 int 	gr_palette_gamma_param = 0;
55 ubyte	gr_palette_faded_out = 1;
56 
57 int grd_fades_disabled=0;					// Used to skip fading for development
58 
59 static LPDIRECTDRAWPALETTE	_lpDDPalActive = 0;
60 static LPDIRECTDRAW	lpDD = NULL;
61 
62 static BOOL PalGDI = FALSE;
63 static HPALETTE hPalGDI = 0;
64 static LOGPAL256 PalGDIData;
65 
66 
67 void ClearSystemPalette();
68 
69 
70 //	Functions ------------------------------------------------------------------
71 
grwin_set_winpalette(LPDIRECTDRAW lpdd,LPDIRECTDRAWPALETTE lpDDPal)72 void grwin_set_winpalette(LPDIRECTDRAW lpdd, LPDIRECTDRAWPALETTE lpDDPal)
73 {
74 	_lpDDPalActive = lpDDPal;
75 	lpDD = lpdd;
76 
77 }
78 
79 
grwin_get_winpalette(void)80 LPDIRECTDRAWPALETTE grwin_get_winpalette(void)
81 {
82 	return _lpDDPalActive;
83 
84 }
85 
86 
grwin_cleanup_palette()87 void grwin_cleanup_palette()
88 {
89 	if (hPalGDI) DeleteObject(hPalGDI);
90 }
91 
92 
grwin_set_palette_exclusive(int yes)93 void grwin_set_palette_exclusive(int yes)
94 {
95 	if (yes) {
96 		PalGDI = FALSE;
97 		if (hPalGDI) DeleteObject(hPalGDI);
98 		hPalGDI = 0;
99 	}
100 	else {
101 		HDC hdc;
102 
103 		ClearSystemPalette();
104 
105 		PalGDI = TRUE;
106 		PalGDIData.ver = 0x300;
107 		PalGDIData.num = 256;
108 		hPalGDI = CreatePalette((PLOGPALETTE)&PalGDIData);
109 
110 		hdc = GetDC(GetLibraryWindow());
111 		SelectPalette(hdc, hPalGDI, FALSE);
112 		ReleaseDC(GetLibraryWindow(), hdc);
113 	}
114 }
115 
116 
grwin_gdi_realizepal(HDC hdc)117 void grwin_gdi_realizepal(HDC hdc)
118 {
119 	if (PalGDI) {
120 		SelectPalette(hdc, hPalGDI, FALSE);
121 		RealizePalette(hdc);
122 	}
123 }
124 
125 
126 //	----------------------------------------------------------------------------
127 
gr_palette_set_gamma(int gamma)128 void gr_palette_set_gamma( int gamma )
129 {
130 	if ( gamma < 0 ) gamma = 0;
131 	if ( gamma > 8 ) gamma = 8;
132 
133 	if (gr_palette_gamma_param != gamma )	{
134 		gr_palette_gamma_param = gamma;
135 		gr_palette_gamma = gamma;
136 		if (!gr_palette_faded_out)	{
137 			gr_palette_load( gr_palette );
138 		}
139 	}
140 }
141 
gr_palette_get_gamma()142 int gr_palette_get_gamma()
143 {
144 	return gr_palette_gamma_param;
145 }
146 
147 
gr_use_palette_table(char * filename)148 void gr_use_palette_table( char * filename )
149 {
150 	CFILE *fp;
151 	int i,fsize;
152 
153 	fp = cfopen( filename, "rb" );
154 	if ( fp==NULL)
155 		Error("Can't open palette file <%s>",filename);
156 
157 	fsize	= cfilelength( fp );
158 	Assert( fsize == 9472 );
159 	cfread( gr_palette, 256*3, 1, fp );
160 	cfread( gr_fade_table, 256*34, 1, fp );
161 	cfclose(fp);
162 
163 	// This is the TRANSPARENCY COLOR
164 	for (i=0; i<GR_FADE_LEVELS; i++ )	{
165 		gr_fade_table[i*256+255] = 255;
166 	}
167 
168 }
169 
170 #define SQUARE(x) ((x)*(x))
171 
172 #define	MAX_COMPUTED_COLORS	32
173 
174 int	Num_computed_colors=0;
175 
176 typedef struct {
177 	ubyte	r,g,b,color_num;
178 } color_record;
179 
180 color_record Computed_colors[MAX_COMPUTED_COLORS];
181 
182 //	Add a computed color (by gr_find_closest_color) to list of computed colors in Computed_colors.
183 //	If list wasn't full already, increment Num_computed_colors.
184 //	If was full, replace a random one.
add_computed_color(int r,int g,int b,int color_num)185 void add_computed_color(int r, int g, int b, int color_num)
186 {
187 	int	add_index;
188 
189 	if (Num_computed_colors < MAX_COMPUTED_COLORS) {
190 		add_index = Num_computed_colors;
191 		Num_computed_colors++;
192 	} else
193 		add_index = (rand() * MAX_COMPUTED_COLORS) >> 15;
194 
195 	Computed_colors[add_index].r = r;
196 	Computed_colors[add_index].g = g;
197 	Computed_colors[add_index].b = b;
198 	Computed_colors[add_index].color_num = color_num;
199 }
200 
init_computed_colors(void)201 void init_computed_colors(void)
202 {
203 	int	i;
204 
205 	for (i=0; i<MAX_COMPUTED_COLORS; i++)
206 		Computed_colors[i].r = 255;		//	Make impossible to match.
207 }
208 
gr_find_closest_color(int r,int g,int b)209 int gr_find_closest_color( int r, int g, int b )
210 {
211 	int i, j;
212 	int best_value, best_index, value;
213 
214 	if (Num_computed_colors == 0)
215 		init_computed_colors();
216 
217 	//	If we've already computed this color, return it!
218 	for (i=0; i<Num_computed_colors; i++)
219 		if (r == Computed_colors[i].r)
220 			if (g == Computed_colors[i].g)
221 				if (b == Computed_colors[i].b) {
222 					if (i > 4) {
223 						color_record	trec;
224 						trec = Computed_colors[i-1];
225 						Computed_colors[i-1] = Computed_colors[i];
226 						Computed_colors[i] = trec;
227 						return Computed_colors[i-1].color_num;
228 					}
229 					return Computed_colors[i].color_num;
230 				}
231 
232 //	r &= 63;
233 //	g &= 63;
234 //	b &= 63;
235 
236 	best_value = SQUARE(r-gr_palette[0])+SQUARE(g-gr_palette[1])+SQUARE(b-gr_palette[2]);
237 	best_index = 0;
238 	if (best_value==0) {
239 		add_computed_color(r, g, b, best_index);
240  		return best_index;
241 	}
242 	j=0;
243 	// only go to 255, 'cause we dont want to check the transparent color.
244 	for (i=1; i<254; i++ )	{
245 		j += 3;
246 		value = SQUARE(r-gr_palette[j])+SQUARE(g-gr_palette[j+1])+SQUARE(b-gr_palette[j+2]);
247 		if ( value < best_value )	{
248 			if (value==0) {
249 				add_computed_color(r, g, b, i);
250 				return i;
251 			}
252 			best_value = value;
253 			best_index = i;
254 		}
255 	}
256 	add_computed_color(r, g, b, best_index);
257 	return best_index;
258 }
259 
gr_find_closest_color_15bpp(int rgb)260 int gr_find_closest_color_15bpp( int rgb )
261 {
262 	return gr_find_closest_color( ((rgb>>10)&31)*2, ((rgb>>5)&31)*2, (rgb&31)*2 );
263 }
264 
265 
gr_find_closest_color_current(int r,int g,int b)266 int gr_find_closest_color_current( int r, int g, int b )
267 {
268 	int i, j;
269 	int best_value, best_index, value;
270 
271 //	r &= 63;
272 //	g &= 63;
273 //	b &= 63;
274 
275 	best_value = SQUARE(r-gr_current_pal[0])+SQUARE(g-gr_current_pal[1])+SQUARE(b-gr_current_pal[2]);
276 	best_index = 0;
277 	if (best_value==0)
278  		return best_index;
279 
280 	j=0;
281 	// only go to 255, 'cause we dont want to check the transparent color.
282 	for (i=1; i<254; i++ )	{
283 		j += 3;
284 		value = SQUARE(r-gr_current_pal[j])+SQUARE(g-gr_current_pal[j+1])+SQUARE(b-gr_current_pal[j+2]);
285 		if ( value < best_value )	{
286 			if (value==0)
287 				return i;
288 			best_value = value;
289 			best_index = i;
290 		}
291 	}
292 	return best_index;
293 }
294 
295 
296 static int last_r=0, last_g=0, last_b=0;
297 
gr_palette_step_up(int r,int g,int b)298 void gr_palette_step_up( int r, int g, int b )
299 {
300 	HRESULT ddresult;
301 	int i;
302 	ubyte *p;
303 	int temp;
304 
305 	Assert(_lpDDPalActive!=0);
306 
307 	if (gr_palette_faded_out) return;
308 
309 	if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
310 
311 	last_r = r;
312 	last_g = g;
313 	last_b = b;
314 
315 	p=gr_palette;
316 	for (i=0; i<256; i++ )	{
317 		temp = (int)(*p++) + r + gr_palette_gamma;
318 		if (temp<0) temp=0;
319 		else if (temp>63) temp=63;
320 		PalGDIData.ScratchPal[i].peRed = temp << 2;
321 		temp = (int)(*p++) + g + gr_palette_gamma;
322 		if (temp<0) temp=0;
323 		else if (temp>63) temp=63;
324 		PalGDIData.ScratchPal[i].peGreen = temp << 2;
325 		temp = (int)(*p++) + b + gr_palette_gamma;
326 		if (temp<0) temp=0;
327 		else if (temp>63) temp=63;
328 		PalGDIData.ScratchPal[i].peBlue = temp << 2;
329 		PalGDIData.ScratchPal[i].peFlags = PC_NOCOLLAPSE;
330 	}
331 
332 	if (!PalGDI) {
333 		ddresult = IDirectDrawPalette_SetEntries(_lpDDPalActive, 0, 0, 256, PalGDIData.ScratchPal);
334 		Assert(ddresult == DD_OK);
335 	}
336 	else {
337 		HDC hdc;
338 
339 		hdc = GetDC(GetLibraryWindow());
340 		SetPaletteEntries(hPalGDI, 0, PalGDIData.num, PalGDIData.ScratchPal);
341 		RealizePalette(hdc);
342 		ReleaseDC(GetLibraryWindow(), hdc);
343 	}
344 
345 }
346 
gr_palette_clear()347 void gr_palette_clear()
348 {
349 	int i;
350 	HRESULT ddresult;
351 
352 	Assert(_lpDDPalActive!=0);
353 
354 //	Zero out Palette
355 	for (i = 0; i < 256; i++)
356 	{
357 		PalGDIData.ScratchPal[i].peRed =
358 		PalGDIData.ScratchPal[i].peBlue =
359 		PalGDIData.ScratchPal[i].peGreen = 0;
360 		PalGDIData.ScratchPal[i].peFlags = 0;
361 	}
362 
363 	if (!hPalGDI) {
364 		ddresult = IDirectDrawPalette_SetEntries(_lpDDPalActive, 0,
365 									0, 256,
366 									PalGDIData.ScratchPal);
367 		Assert(ddresult == DD_OK);
368 	}
369 	else {
370 		HDC hdc;
371 
372 		hdc = GetDC(GetLibraryWindow());
373 		SetPaletteEntries(hPalGDI, 0, PalGDIData.num, PalGDIData.ScratchPal);
374 		RealizePalette(hdc);
375 		ReleaseDC(GetLibraryWindow(), hdc);
376 	}
377 
378 	gr_palette_faded_out = 1;
379 	if (GRMODEINFO(emul)) DDClearDisplay();
380 
381 }
382 
gr_palette_load(ubyte * pal)383 void gr_palette_load( ubyte * pal )
384 {
385 	int i;
386 	ubyte c;
387 	HRESULT ddresult;
388 
389 	Assert(_lpDDPalActive!=0);
390 
391 	for (i=0; i<256; i++ )	{
392 		c = pal[i*3] + gr_palette_gamma;
393 		if ( c > 63 ) c = 63;
394 		PalGDIData.ScratchPal[i].peRed = c << 2;
395  		gr_current_pal[i*3] = pal[i*3];
396 		c = pal[i*3+1] + gr_palette_gamma;
397 		if ( c > 63 ) c = 63;
398 		PalGDIData.ScratchPal[i].peGreen = c << 2;
399  		gr_current_pal[i*3+1] = pal[i*3+1];
400 		c = pal[i*3+2] + gr_palette_gamma;
401 		if ( c > 63 ) c = 63;
402 		PalGDIData.ScratchPal[i].peBlue = c << 2;
403  		gr_current_pal[i*3+2] = pal[i*3+2];
404 		PalGDIData.ScratchPal[i].peFlags = 0;
405 	}
406 
407 	if (!hPalGDI) {
408 		ddresult = IDirectDrawPalette_SetEntries(_lpDDPalActive, 0,
409 											0, 256,
410 											PalGDIData.ScratchPal);
411 		Assert(ddresult == DD_OK);
412 	}
413 	else {
414 		HDC hdc;
415 
416 		hdc = GetDC(GetLibraryWindow());
417 		SetPaletteEntries(hPalGDI, 0, PalGDIData.num, PalGDIData.ScratchPal);
418 		RealizePalette(hdc);
419 		ReleaseDC(GetLibraryWindow(), hdc);
420 	}
421 
422 	gr_palette_faded_out = 0;
423 
424 	init_computed_colors();
425 }
426 
427 extern void gr_sync_display(void);
428 
gr_palette_fade_out(ubyte * pal,int nsteps,int allow_keys)429 int gr_palette_fade_out(ubyte *pal, int nsteps, int allow_keys )
430 {
431 	ubyte c;
432 	int i,j;
433 	HRESULT ddresult;
434 	fix fade_palette[768];
435 	fix fade_palette_delta[768];
436 
437 	allow_keys  = allow_keys;
438 
439 	Assert(_lpDDPalActive!=0);
440 
441 	if (gr_palette_faded_out) return 0;
442 
443 	#ifndef NDEBUG
444 	if (grd_fades_disabled) {
445 		gr_palette_clear();
446 		return 0;
447 	}
448 	#endif
449 
450 	for (i=0; i<768; i++ )	{
451 		fade_palette[i] = i2f(pal[i]+gr_palette_gamma);
452 		fade_palette_delta[i] = fade_palette[i] / nsteps;
453 	}
454 
455 
456 	for (j=0; j<nsteps; j++ )	{
457 		for (i=0; i<256; i++ )	{
458 			fade_palette[i*3] -= fade_palette_delta[i*3];
459 			if (fade_palette[i*3] < 0) fade_palette[i*3] = 0;
460 			fade_palette[i*3+1] -= fade_palette_delta[i*3+1];
461 			if (fade_palette[i*3+1] < 0) fade_palette[i*3+1] = 0;
462 			fade_palette[i*3+2] -= fade_palette_delta[i*3+2];
463 			if (fade_palette[i*3+2] < 0) fade_palette[i*3+2] = 0;
464 			c = f2i(fade_palette[i*3]);
465 			if ( c > 63 ) c = 63;
466 			PalGDIData.ScratchPal[i].peRed = c << 2;
467 			c = f2i(fade_palette[i*3+1]);
468 			if ( c > 63 ) c = 63;
469 			PalGDIData.ScratchPal[i].peGreen = c << 2;
470 			c = f2i(fade_palette[i*3+2]);
471 			if ( c > 63 ) c = 63;
472 			PalGDIData.ScratchPal[i].peBlue = c << 2;
473 			PalGDIData.ScratchPal[i].peFlags = 0;
474 		}
475 
476 		if (!hPalGDI) {
477 			IDirectDraw_WaitForVerticalBlank(lpDD, DDWAITVB_BLOCKBEGIN, NULL);
478 			ddresult = IDirectDrawPalette_SetEntries(_lpDDPalActive, 0,
479 											0, 256,
480 											PalGDIData.ScratchPal);
481 			Assert(ddresult == DD_OK);
482 		}
483 		else {
484 			HDC hdc;
485 
486 			hdc = GetDC(GetLibraryWindow());
487 			SetPaletteEntries(hPalGDI, 0, PalGDIData.num, PalGDIData.ScratchPal);
488 			RealizePalette(hdc);
489 			ReleaseDC(GetLibraryWindow(), hdc);
490 		}
491 	}
492 	gr_palette_faded_out = 1;
493 
494 	if (GRMODEINFO(emul)) DDClearDisplay();
495 
496 	return 0;
497 }
498 
gr_palette_fade_in(ubyte * pal,int nsteps,int allow_keys)499 int gr_palette_fade_in(ubyte *pal, int nsteps, int allow_keys)
500 {
501 	HRESULT ddresult;
502 	int i,j;
503 	ubyte c;
504 	fix fade_palette[768];
505 	fix fade_palette_delta[768];
506 
507 	allow_keys  = allow_keys;
508 
509 	Assert(_lpDDPalActive!=0);
510 
511 	if (!gr_palette_faded_out) return 0;
512 
513 	#ifndef NDEBUG
514 	if (grd_fades_disabled) {
515 		gr_palette_load(pal);
516 		return 0;
517 	}
518 	#endif
519 
520 	for (i=0; i<768; i++ )	{
521 		gr_current_pal[i] = pal[i];
522 		fade_palette[i] = 0;
523 		fade_palette_delta[i] = i2f(pal[i]+gr_palette_gamma) / nsteps;
524 	}
525 
526 	for (j=0; j<nsteps; j++ )	{
527 		for (i=0; i<256; i++ )	{
528 			fade_palette[i*3] += fade_palette_delta[i*3];
529 			fade_palette[i*3+1] += fade_palette_delta[i*3+1];
530 			fade_palette[i*3+2] += fade_palette_delta[i*3+2];
531 			if (fade_palette[i*3] > i2f(pal[i*3]+gr_palette_gamma) )
532 				fade_palette[i*3] = i2f(pal[i*3]+gr_palette_gamma);
533 			if (fade_palette[i*3+1] > i2f(pal[i*3+1]+gr_palette_gamma) )
534 				fade_palette[i*3+1] = i2f(pal[i*3+1]+gr_palette_gamma);
535 			if (fade_palette[i*3+2] > i2f(pal[i*3+2]+gr_palette_gamma) )
536 				fade_palette[i*3+2] = i2f(pal[i*3+2]+gr_palette_gamma);
537 
538 			c = f2i(fade_palette[i*3]);
539 			if ( c > 63 ) c = 63;
540 			PalGDIData.ScratchPal[i].peRed = c << 2;
541 			c = f2i(fade_palette[i*3+1]);
542 			if ( c > 63 ) c = 63;
543 			PalGDIData.ScratchPal[i].peGreen = c << 2;
544 			c = f2i(fade_palette[i*3+2]);
545 			if ( c > 63 ) c = 63;
546 			PalGDIData.ScratchPal[i].peBlue = c << 2;
547 			PalGDIData.ScratchPal[i].peFlags = 0;
548 		}
549 
550 		if (!hPalGDI) {
551 			IDirectDraw_WaitForVerticalBlank(lpDD, DDWAITVB_BLOCKBEGIN, NULL);
552 			ddresult = IDirectDrawPalette_SetEntries(_lpDDPalActive, 0,
553 											0, 256,
554 											PalGDIData.ScratchPal);
555 			Assert (ddresult == DD_OK);
556 		}
557 		else {
558 			HDC hdc;
559 
560 			hdc = GetDC(GetLibraryWindow());
561 			SetPaletteEntries(hPalGDI, 0, PalGDIData.num, PalGDIData.ScratchPal);
562 			RealizePalette(hdc);
563 			ReleaseDC(GetLibraryWindow(), hdc);
564 		}
565 	}
566 
567 	gr_palette_faded_out = 0;
568 	return 0;
569 }
570 
gr_make_cthru_table(ubyte * table,ubyte r,ubyte g,ubyte b)571 void gr_make_cthru_table(ubyte * table, ubyte r, ubyte g, ubyte b )
572 {
573 	int i;
574 	ubyte r1, g1, b1;
575 
576 	for (i=0; i<256; i++ )	{
577 		r1 = gr_palette[i*3+0] + r;
578 		if ( r1 > 63 ) r1 = 63;
579 		g1 = gr_palette[i*3+1] + g;
580 		if ( g1 > 63 ) g1 = 63;
581 		b1 = gr_palette[i*3+2] + b;
582 		if ( b1 > 63 ) b1 = 63;
583 		table[i] = gr_find_closest_color( r1, g1, b1 );
584 	}
585 }
586 
gr_palette_read(ubyte * palette)587 void gr_palette_read(ubyte * palette)
588 {
589 	int i;
590 	HRESULT ddresult;
591 
592 	Assert(_lpDDPalActive!=0);
593 
594 	if (!hPalGDI) {
595 		ddresult = IDirectDrawPalette_GetEntries(_lpDDPalActive, 0, 0, 256, PalGDIData.ScratchPal);
596 		Assert(ddresult == DD_OK);
597 	}
598 	else {
599 		SetPaletteEntries(hPalGDI, 0, 256, PalGDIData.ScratchPal);
600 	}
601 
602 	for (i=0; i<256; i++ )	{
603 		*palette++ = PalGDIData.ScratchPal[i].peRed >> 2;
604 		*palette++ = PalGDIData.ScratchPal[i].peGreen >> 2;
605 		*palette++ = PalGDIData.ScratchPal[i].peBlue >> 2;
606 	}
607 }
608 
609 
610 
gr_copy_palette(ubyte * gr_palette,ubyte * pal,int size)611 void gr_copy_palette(ubyte *gr_palette, ubyte *pal, int size)
612 {
613 	memcpy(gr_palette, pal, size);
614 
615 	Num_computed_colors = 0;
616 }
617 
618 
619 //	GDI Palette Functions taken from ancient WinG version
620 
ClearSystemPalette()621 void ClearSystemPalette()
622 {
623 	LOGPAL256 palette = {
624 		0x300,
625 		256,
626 	};
627 	HPALETTE screenpal = 0;
628 	HDC		screenDC;
629 	int 		counter;
630 
631 //	Reset system palette to black to quicken WinG.
632 	for (counter = 0; counter < 256; counter++)
633 	{
634 		palette.ScratchPal[counter].peRed = 0;
635 		palette.ScratchPal[counter].peGreen = 0;
636 		palette.ScratchPal[counter].peBlue = 0;
637 		palette.ScratchPal[counter].peFlags = PC_NOCOLLAPSE;
638 	}
639 
640 //	Create, select, realize, and deselect/delete palette.
641 	screenDC = GetDC(NULL);
642 	screenpal = CreatePalette((LOGPALETTE*)&palette);
643 	screenpal = SelectPalette(screenDC, screenpal, FALSE);
644 	RealizePalette(screenDC);
645 	screenpal = SelectPalette(screenDC, screenpal, FALSE);
646 	DeleteObject(screenpal);
647 	ReleaseDC(NULL, screenDC);
648 }
649 
650 
651 
652 
653 
654 
655 
656 
657 
658 
659 
660 
661 
662 
663 
664 
665 
666