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