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 
15 #pragma off (unreferenced)
16 static char rcsid[] = "$Id: winferno.c,v 1.1.1.1 2001/01/19 03:30:14 bradleyb Exp $";
17 #pragma on (unreferenced)
18 
19 #include "desw.h"
20 #include <mmsystem.h>
21 
22 #include <stdlib.h>
23 #include <stdio.h>
24 
25 #include "gr.h"
26 #include "gamepal.h"
27 #include "palette.h"
28 #include "key.h"
29 #include "mono.h"
30 #include "timer.h"
31 #include "3d.h"
32 #include "bm.h"
33 #include "inferno.h"
34 #include "error.h"
35 #include "game.h"
36 #include "mem.h"
37 #include "screens.h"
38 #include "texmap.h"
39 #include "texmerge.h"
40 #include "menu.h"
41 #include "polyobj.h"
42 #include "pcx.h"
43 #include "args.h"
44 #include "player.h"
45 #include "text.h"
46 #include "gamefont.h"
47 #include "kconfig.h"
48 #include "newmenu.h"
49 #include "desc_id.h"
50 #include "config.h"
51 #include "cfile.h"
52 #include "mission.h"
53 #include "network.h"
54 #include "newdemo.h"
55 #include "digi.h"
56 #include "songs.h"
57 #include "ipx.h"
58 #include "modem.h"
59 #include "joy.h"
60 #include "movie.h"
61 
62 #ifdef _3DFX
63 #include "3dfx_des.h"
64 #endif
65 
66 
67 
68 //	Globals --------------------------------------------------------------------
69 extern int Network_allow_socket_changes;
70 extern char gr_palette[3*256];
71 extern int grd_fades_disabled;
72 extern int MenuHiresAvailable;
73 extern int piggy_low_memory;
74 
75 int Function_mode=FMODE_MENU;		//game or editor?
76 int Screen_mode=-1;					//game screen or editor screen?
77 int descent_critical_error = 0;
78 unsigned descent_critical_deverror = 0;
79 unsigned descent_critical_errcode = 0;
80 
81 /// CHANGE THIS.  PUT THIS WHERE IT SHOULD ME.
82 
83 int WVIDEO_running=1;		//debugger can set to 1 if running
84 
85 
86 //	Version ID Info. -----------------------------------------------------------
87 
88 #include "vers_id.h"
89 
90 //Current version number
91 
92 ubyte Version_major = 1;		//FULL VERSION
93 ubyte Version_minor = 2;
94 
95 int registered_copy=0;
96 char name_copy[DESC_ID_LEN];
97 
98 static const char desc_id_checksum_str[] = DESC_ID_CHKSUM_TAG "0000";	//4-byte checksum
99 char desc_id_exit_num = 0;
100 time_t t_current_time, t_saved_time;
101 
102 byte CybermouseActive = 0;
103 
104 static 	char 	title_pal[768];
105 
106 
107 //	THIS IS A HACK UNTIL WE HAVE MOVIES
108 int MovieHires = 1;
109 char CDROM_dir[30] = "";
110 int Hogfile_on_CD = 0;
111 
112 
113 // Function Prototypes --------------------------------------------------------
114 int init_cdrom();
115 int InitGraphics(void);
116 void DisplayDescentTitle(void);
117 void TestSounds();
118 void check_joystick_calibration();
119 
120 void check_id_checksum_and_date();
121 
122 HANDLE clipboard_renderformat(int cf);
123 HPALETTE SetPalette(HDC hdc, HPALETTE hPal);
124 void DestroyPalette(HPALETTE hPal);
125 
126 #define HOGNAME "descent2.hog"
127 
128 extern int CD_audio_desktop_dev;
129 extern DWORD CD_audio_desktop_vol;
130 
131 
132 //	Functions ------------------------------------------------------------------
133 
InitCD(char * arg)134 void InitCD(char *arg)
135 {
136 	int i;
137 
138 	logentry("Initializing CD-ROM...\n");
139 
140 	if (!init_cdrom()) {		//look for Cd, etc.
141 		#ifdef RELEASE
142 			Error("Sorry, the Descent II CD must be present to run.");
143 		#endif
144 	}
145 	else {		//check to make sure not running off CD
146 //		if (toupper(arg[0]) == toupper(CDROM_dir[0]))
147 //			Error("You cannot run Descent II directly from your CD-ROM drive.\n"
148 //					"       To run Descent II, CD to the directory you installed to, then type D2.\n"
149 //					"       To install Descent II, type %c:\\INSTALL.",toupper(CDROM_dir[0]));
150 	}
151 
152 //	Let's save the current volume of CD-audio-out
153 //	Find CD-AUDIO device if there is one.
154 	for (i = 0; i < auxGetNumDevs(); i++)
155 	{
156 		AUXCAPS caps;
157 		auxGetDevCaps(i, &caps, sizeof(caps));
158 		if (caps.wTechnology == AUXCAPS_CDAUDIO) {
159 			CD_audio_desktop_dev = i;
160 			mprintf((0, "CD audio operating on AUX %d.\n", CD_audio_desktop_dev));
161 			break;
162 		}
163 	}
164 
165 	if (CD_audio_desktop_dev != -1) {
166 	//	 get the volume!
167 		auxGetVolume(CD_audio_desktop_dev, &CD_audio_desktop_vol);
168 		mprintf((1, "CD vol: 0x%x\n", CD_audio_desktop_vol));
169 	}
170 }
171 
172 
InitVideo()173 void InitVideo()
174 {
175 	int flag;
176 
177 	logentry("Initializing Video System...\n");
178 
179 	if (FindArg("-hw_3dacc")) flag = 1;
180 	else flag = 0;
181 
182 	if (!gfxInit(flag))
183 		Error("Unable to initialize GFX system.");
184 
185 //@@   #ifdef _3DFX
186 //@@   _3dfx_available = _3dfx_Init();
187 //@@   #endif
188 }
189 
InitIO()190 void InitIO()
191 {
192 	logentry("Initializing IO System...\n");
193 
194 	key_init();
195 
196 	if (!win95_controls_init())
197 		logentry("\tUnable to detect an auxillary control.\n");
198 	mouse_set_window (_hAppWnd);
199 	mouse_set_mode(0);  				// Non-centering mode
200 }
201 
202 
InitData()203 void InitData()
204 {
205 	logentry("Initializing Data...\n");
206 
207 	ReadConfigFile();
208 
209 	if (! cfile_init(HOGNAME)) {		//didn't find HOG.  Check on CD
210 		#ifdef RELEASE
211 			Error("Could not find required file <%s>",HOGNAME);
212 		#endif
213 	}
214 
215 	load_text();
216 
217 //print out the banner title
218 #ifndef RELEASE
219 	cprintf("\nDESCENT II %s v%d.%d",VERSION_TYPE,Version_major,Version_minor);
220 	#ifdef VERSION_NAME
221 	cprintf("  %s", VERSION_NAME);
222 	#endif
223 	cprintf("  %s %s\n", __DATE__,__TIME__);
224 	cprintf("%s\n%s\n",TXT_COPYRIGHT,TXT_TRADEMARK);
225 	cprintf("\n\n");
226 #endif
227 
228 	check_id_checksum_and_date();
229 }
230 
231 
InitSound()232 void InitSound()
233 {
234 	logentry("Initializing Sound System...\n");
235 
236 	if (digi_init()) {
237 		logentry("Unable to initialize sound system.\n");
238 	}
239 }
240 
241 
InitNetwork()242 void InitNetwork()
243 {
244 	int socket=0, showaddress=0;
245 	int ipx_error;
246 	int t;
247 
248 	logentry("Initializing Networking system...\n");
249 
250 	if ((t=FindArg("-socket")))
251 		socket = atoi( Args[t+1] );
252 
253 	if ( FindArg("-showaddress") ) showaddress=1;
254 
255 	if ((ipx_error=ipx_init(IPX_DEFAULT_SOCKET+socket,showaddress))==0)	{
256   		mprintf((0, "IPX protocol on channel %x.\n", IPX_DEFAULT_SOCKET+socket ));
257 		Network_active = 1;
258 	}
259 	else {
260 		switch( ipx_error )	{
261 			case 3: 	mprintf((1, "%s\n", TXT_NO_NETWORK)); break;
262 			case -2: mprintf((1, "%s 0x%x.\n", TXT_SOCKET_ERROR, IPX_DEFAULT_SOCKET+socket)); break;
263 			case -4: mprintf((1, "%s\n", TXT_MEMORY_IPX )); break;
264 			default:
265 				mprintf((1, "\t%s %d\n", TXT_ERROR_IPX, ipx_error ));
266 		}
267 
268 		logentry("%s\n",TXT_NETWORK_DISABLED);
269 		Network_active = 0;		// Assume no network
270 	}
271 
272 	mprintf((0, "Here?"));
273 
274 	ipx_read_user_file( "descent.usr" );
275 	ipx_read_network_file( "descent.net" );
276 }
277 
278 
InitDescent()279 void InitDescent()
280 {
281 	Lighting_on = 1;							//	Turn on lighting for now.
282 
283 //	Set Display Mode
284 
285 	if (!dd_VR_offscreen_buffer)
286 		set_display_mode(0);
287 
288 //	Create and Set Initial Palette.
289 	logentry("Initializing palette system...\n" );
290 	gr_use_palette_table(DEFAULT_PALETTE);
291 	gr_palette_load(gr_palette);
292 
293 	logentry( "Initializing font system...\n" );
294 	gamefont_init();
295 
296 	if (FindArg("-lowresmovies"))
297 		MovieHires = 0;
298 
299 	MenuHires = MenuHiresAvailable = 1;
300 
301 //	Set up movies and title
302 	logentry("Initializing movie libraries...\n" );
303 	init_movies();		//init movie libraries
304 
305 	if (!init_subtitles("intro.tex"))
306 		mprintf((1, "Unable to open subtitles.\n"));
307 	PlayMovie("intro.mve",MOVIE_ABORT_ON);
308 	HideCursorW();
309 
310 	close_subtitles();
311 	songs_play_song( SONG_TITLE, 1);
312 
313 	FontHires = MenuHires;
314 
315 	//LoadCursorWin(MOUSE_WAIT_CURSOR);
316 
317 	DEFINE_SCREEN("DESCENTB.PCX");
318 	DisplayDescentTitle();
319 
320 //	SendMessage(_hAppWnd, WM_SETREDRAW, FALSE, 0);
321 
322 //	Doing some 3d initialization
323 	logentry( "Doing bm_init...\n" );
324 	bm_init();
325 
326 	DDGRRESTORE
327 
328 	logentry( "Initializing 3d system...\n" );
329 	g3_init();
330 
331 	logentry( "Initializing texture caching system...\n" );
332 	texmerge_init( 10 );		// 10 cache bitmaps
333 
334 	logentry("Final initialization...\n" );
335 
336 	memcpy(gr_palette,title_pal,sizeof(gr_palette));
337 
338 	set_screen_mode(SCREEN_MENU);
339 
340 	init_game();
341 
342 	set_detail_level_parameters(Detail_level);
343 
344 //	SendMessage(_hAppWnd, WM_SETREDRAW, TRUE, 0);
345 	//LoadCursorWin(MOUSE_DEFAULT_CURSOR);
346 }
347 
348 
InitPilot()349 void InitPilot()
350 {
351 //	Title Page gone, now start main program
352 //	Players[Player_num].callsign[0] = '\0';
353 
354 	do_register_player(title_pal);
355 
356 	gr_palette_fade_out( title_pal, 32, 0 );
357 
358 	//check for special stamped version
359 	if (registered_copy) {
360 		char time_str[32];
361 		char time_str2[32];
362 
363 		_ctime(&t_saved_time, time_str);
364 		_ctime(&t_current_time, time_str2);
365 
366 		nm_messagebox("EVALUATION COPY",1,"Continue",
367 			"This special evaluation copy\n"
368 			"of DESCENT II has been issued to:\n\n"
369 			"%s\n"
370 			"\nEXPIRES %s\nYOUR TIME: %s\nNOT FOR DISTRIBUTION",
371 			name_copy, time_str,time_str2);
372 
373 		gr_palette_fade_out( gr_palette, 32, 0 );
374 	}
375 
376 	Game_mode = GM_GAME_OVER;
377 }
378 
379 
380 //	Winferno Internal Routines
381 
DisplayDescentTitle(void)382 void DisplayDescentTitle(void)
383 {
384 //	Create Descent Title Window and Load Title bitmap, and display it.
385 	int			pcx_error;
386 	int			width, height;
387 
388 	logentry("Displaying title...\n");
389 
390 //	Display Title Bitmap, using title palette.
391 	pcx_error = pcx_get_dimensions("DESCENTB.PCX", &width, &height);
392 	if (pcx_error != PCX_ERROR_NONE)	{
393 		gr_close();
394 		Error( "Couldn't load pcx file 'DESCENTB.PCX', PCX load error: %s\n", pcx_errormsg(pcx_error));
395 	}
396 
397 //	pcx_canvas = dd_gr_create_canvas(width, height );
398 
399 	gr_palette_clear();
400 
401 	dd_gr_set_current_canvas(NULL);
402 	DDGRLOCK(dd_grd_curcanv)
403 	{
404 		pcx_error=pcx_read_bitmap( "DESCENTB.PCX", &grd_curcanv->cv_bitmap,
405 				grd_curcanv->cv_bitmap.bm_type,
406 				title_pal );
407 	}
408 	DDGRUNLOCK(dd_grd_curcanv)
409 
410 	if (pcx_error == PCX_ERROR_NONE)	{
411 	//	Blt to screen, then restore display
412 		DDGRRESTORE;
413 		gr_palette_fade_in( title_pal, 32, 0 );
414 	} else {
415 		gr_close();
416 		Error( "Couldn't load pcx file 'DESCENT.PCX', PCX load error: %s\n", pcx_errormsg(pcx_error));
417 	}
418 }
419 
420 
do_register_player(ubyte * title_pal)421 do_register_player(ubyte *title_pal)
422 {
423 	Players[Player_num].callsign[0] = '\0';
424 
425 	if (!Auto_demo) 	{
426 
427 		key_flush();
428 
429 		memcpy(gr_palette,title_pal,sizeof(gr_palette));
430 		remap_fonts_and_menus(1);
431 		RegisterPlayer();		//get player's name
432 	}
433 }
434 
435 
436 //@@void check_joystick_calibration()
437 //@@{
438 //@@	int x1, y1, x2, y2, c;
439 //@@	fix t1;
440 //@@
441 //@@	if ( (Config_control_type!=CONTROL_JOYSTICK) &&
442 //@@		  (Config_control_type!=CONTROL_FLIGHTSTICK_PRO) &&
443 //@@		  (Config_control_type!=CONTROL_THRUSTMASTER_FCS) &&
444 //@@		  (Config_control_type!=CONTROL_GRAVIS_GAMEPAD)
445 //@@		) return;
446 //@@
447 //@@	joy_get_pos( &x1, &y1 );
448 //@@
449 //@@	t1 = timer_get_fixed_seconds();
450 //@@	while( timer_get_fixed_seconds() < t1 + F1_0/100 )
451 //@@		;
452 //@@
453 //@@	joy_get_pos( &x2, &y2 );
454 //@@
455 //@@	// If joystick hasn't moved...
456 //@@	if ( (abs(x2-x1)<30) &&  (abs(y2-y1)<30) )	{
457 //@@		if ( (abs(x1)>30) || (abs(x2)>30) ||  (abs(y1)>30) || (abs(y2)>30) )	{
458 //@@			c = nm_messagebox( NULL, 2, TXT_CALIBRATE, TXT_SKIP, TXT_JOYSTICK_NOT_CEN );
459 //@@			if ( c==0 )	{
460 //@@				joydefs_calibrate();
461 //@@			}
462 //@@		}
463 //@@	}
464 //@@
465 //@@}
466 
467 
find_descent_cd()468 int find_descent_cd()
469 {
470 	char path[4];
471 	char oldpath[MAX_PATH];
472 	char volume[256];
473 	int i;
474 	int cdrom_drive=-1;
475 
476 	path[1] = ':';
477 	path[2] = '\\';
478 	path[3] = 0;
479 
480 	GetCurrentDirectory(MAX_PATH, oldpath);
481 
482 	for (i = 0; i < 26; i++)
483 	{
484 		path[0] = 'A'+i;
485 		if (GetDriveType(path) == DRIVE_CDROM) {
486 			cdrom_drive = -3;
487 			GetVolumeInformation(path, volume, 256, NULL, NULL, NULL, NULL, 0);
488 			mprintf((0, "CD volume: %s\n", volume));
489 			if (!strcmpi(volume, "DESCENT_II") || !strcmpi(volume, "DESCENT.II")) {
490 				if (!chdir(path))
491 					if (!chdir("\\d2data")) {
492 						cdrom_drive = i;
493 						break;
494 					}
495 			}
496 		}
497 	}
498 
499 	SetCurrentDirectory(oldpath);
500 	return cdrom_drive;
501 }
502 
503 
init_cdrom()504 int init_cdrom()
505 {
506 	int i;
507 
508 	//scan for CD, etc.
509 
510 	i = find_descent_cd();
511 
512 	if (i < 0) {			//no CD
513 
514 		#ifndef RELEASE
515 		if ((i=FindArg("-cdproxy")) != 0) {
516 			strcpy(CDROM_dir,"d:\\d2data\\");	//set directory
517 			CDROM_dir[0] = Args[i+1][0];
518 			return 1;
519 		}
520 		#endif
521 
522 		return 0;
523 	}
524 	else {
525 		strcpy(CDROM_dir,"d:\\d2data\\");	//set directory
526 		CDROM_dir[0] = 'A'+i;					//set correct drive leter
527 		mprintf((0, "Descent 2 CD-ROM: %s\n", CDROM_dir));
528 		return 1;
529 	}
530 }
531 
532 
533 //	----------------------------------------------------------------------------
534 
535 void
check_id_checksum_and_date()536 check_id_checksum_and_date()
537 {
538 	const char name[sizeof(DESC_ID_TAG)-1+DESC_ID_LEN] = DESC_ID_TAG;
539 	char time_str[] = DESC_DEAD_TIME_TAG "00000000";	//second part gets overwritten
540 	int i, found;
541 	unsigned long *checksum, test_checksum;
542 	time_t current_time, saved_time;
543 
544 	saved_time = (time_t)strtol(time_str + strlen(DESC_DEAD_TIME_TAG), NULL, 16);
545 
546 	t_saved_time = saved_time;
547 
548 	if (saved_time == (time_t)0)
549 		return;
550 
551 	mprintf((1, "TIME STAMPED: %d\n", saved_time));
552 
553 	strcpy(name_copy,name+strlen(DESC_ID_TAG));
554 	registered_copy = 1;
555 
556 	t_current_time = current_time = time(NULL);
557 
558 	mprintf((1, "CURTIME: %d\n", current_time));
559 
560 	if (current_time >= saved_time)
561 		desc_id_exit_num = 1;
562 
563 	test_checksum = 0;
564 	for (i = 0; i < strlen(name_copy); i++) {
565 		found = 0;
566 		test_checksum += name_copy[i];
567 		if (((test_checksum / 2) * 2) != test_checksum)
568 			found = 1;
569 		test_checksum = test_checksum >> 1;
570 		if (found)
571 			test_checksum |= 0x80000000;
572 	}
573 	checksum = (unsigned long *)(desc_id_checksum_str + strlen(DESC_ID_CHKSUM_TAG));
574 	if (test_checksum != *checksum)
575 		desc_id_exit_num = 2;
576 
577 	cprintf ("%s %s\n", TXT_REGISTRATION, name_copy);
578 }
579 
580 
581 //	----------------------------------------------------------------------------
582 //	Nifty clipboard functions for placing a screen shot
583 //	----------------------------------------------------------------------------
584 
585 extern HANDLE win95_dib_from_bitmap(HBITMAP hbm);
586 
win95_save_pcx_shot()587 void win95_save_pcx_shot()
588 {
589 	char message[100];
590 	static int savenum = 0;
591 	fix t1;
592 
593 	dd_grs_canvas *screen_canv = dd_grd_screencanv;
594 	dd_grs_canvas *temp_canv_1, *save_canv; 	//*temp_canv_2,
595 	grs_font *save_font;
596 	ubyte pal[768];
597 
598 	char savename[FILENAME_LEN];	//NO STEREO savename2[FILENAME_LEN];
599 
600 	int w,h,aw,x,y;
601 
602 	stop_time();
603 
604 	mprintf((0, "Screen shot!\n"));
605 
606 /* Start */
607 	save_canv = dd_grd_curcanv;
608 	temp_canv_1 = dd_gr_create_canvas(screen_canv->canvas.cv_bitmap.bm_w,
609 													 screen_canv->canvas.cv_bitmap.bm_h);
610 
611 	dd_gr_blt_notrans(screen_canv, 0, 0, 0, 0, temp_canv_1, 0, 0, 0, 0);
612 
613 /* Saved screen shot */
614 	dd_gr_set_current_canvas(save_canv);
615 
616 	if ( savenum > 99 ) savenum = 0;
617 	sprintf(savename,"screen%02d.pcx",savenum++);
618 	sprintf( message, "%s '%s'", TXT_DUMPING_SCREEN, savename );
619 
620 	dd_gr_set_current_canvas(NULL);
621 
622 	DDGRLOCK(dd_grd_curcanv);
623 	{
624 		save_font = grd_curcanv->cv_font;
625 		gr_set_curfont(GAME_FONT);
626 		gr_set_fontcolor(gr_find_closest_color_current(0,31,0),-1);
627 		gr_get_string_size(message,&w,&h,&aw);
628 
629 		x = (grd_curcanv->cv_w-w)/2;
630 		y = (grd_curcanv->cv_h-h)/2;
631 
632 		gr_setcolor(gr_find_closest_color_current(0,0,0));
633 		gr_rect(x-2,y-2,x+w+2,y+h+2);
634 		gr_printf(x,y,message);
635 		gr_set_curfont(save_font);
636 	}
637 	DDGRUNLOCK(dd_grd_curcanv);
638 
639 	if (GRMODEINFO(modex)) dd_gr_flip();
640 
641 	t1 = timer_get_fixed_seconds() + F1_0;
642 
643 	gr_palette_read(pal);		//get actual palette from the hardware
644 
645 	DDGRLOCK(temp_canv_1);
646 		pcx_write_bitmap(savename,&temp_canv_1->canvas.cv_bitmap,pal);
647 	DDGRUNLOCK(temp_canv_1);
648 
649 	while ( timer_get_fixed_seconds() < t1 );		// Wait so that messag stays up at least 1 second.
650 
651 	dd_gr_set_current_canvas(screen_canv);
652 
653 	dd_gr_blt_notrans(temp_canv_1, 0,0,0,0, dd_grd_curcanv, 0,0,0,0);
654 
655 	if (GRMODEINFO(modex)) dd_gr_flip();
656 
657 	dd_gr_free_canvas(temp_canv_1);
658 
659 	dd_gr_set_current_canvas(save_canv);
660 
661 	key_flush();
662 	start_time();
663 }
664 
665 
666 HANDLE hClipData = NULL;
667 
clipboard_screenshot()668 BOOL clipboard_screenshot()
669 {
670 	if (OpenClipboard(_hAppWnd)) {
671 		EmptyClipboard();
672 		SetClipboardData (CF_DIB     ,clipboard_renderformat(CF_DIB));
673 		SetClipboardData (CF_BITMAP  ,clipboard_renderformat(CF_BITMAP));
674 		SetClipboardData (CF_PALETTE ,clipboard_renderformat(CF_PALETTE));
675 		CloseClipboard ();
676 		return TRUE;
677 	}
678 	else return FALSE;
679 }
680 
681 
clipboard_renderformat(int cf)682 HANDLE clipboard_renderformat(int cf)
683 {
684 	HANDLE hMem = NULL;
685 	HBITMAP hbm;
686 
687 	switch(cf)
688 	{
689 		case CF_BITMAP:
690 		{
691 		// Create screen shot BBM
692 			mprintf((1, "Creating DDB for clipboard.\n"));
693 			hMem = win95_screen_shot();
694 			if (!hMem) mprintf((1, "Unable to create clipboard object: CF_BITMAP\n"));
695 			break;
696 		}
697 
698 		case CF_DIB:
699 		{
700 		// Create DIB and all memory associated with it.
701 			mprintf((1, "Creating DIB for clipboard.\n"));
702 			hbm = win95_screen_shot();
703 			hMem = win95_dib_from_bitmap(hbm);
704 			if (!hMem) mprintf((1, "Unable to create clipboard object: CF_DIB\n"));
705 			DeleteObject(hbm);
706 			break;
707 		}
708 
709 		case CF_PALETTE:
710 		{
711 		//	 Get current palette! (create a GDI palette from grpal)
712 			PALETTE lpal;
713 			char grpal[768];
714 			int i;
715 
716 			mprintf((1, "Creating Palette for clipboard.\n"));
717 			gr_palette_read(grpal);
718 			lpal.version = 0x300;
719 			lpal.num_entries = 256;
720 			for (i = 0; i < 256; i++)
721 			{
722 				lpal.entries[i].peRed = grpal[i*3] << 2;
723 				lpal.entries[i].peGreen = grpal[i*3+1] << 2;
724 				lpal.entries[i].peBlue = grpal[i*3+2] << 2;
725 				lpal.entries[i].peFlags = 0;
726 			}
727 
728 			hMem = CreatePalette((LOGPALETTE*)&lpal);
729 			if (!hMem) mprintf((1, "Unable to create clipboard object: CF_PALETTE\n"));
730 			break;
731 		}
732 	}
733 
734 	return hMem;
735 }
736 
737