WINSTUB.CPP (32275B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 17 /*********************************************************************************************** 18 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** 19 *********************************************************************************************** 20 * * 21 * Project Name : Command & Conquer * 22 * * 23 * File Name : WINSTUB.CPP * 24 * * 25 * Programmer : Steve Tall * 26 * * 27 * Start Date : 10/04/95 * 28 * * 29 * Last Update : October 4th 1995 [ST] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Overview: * 33 * This file contains stubs for undefined externals when linked under Watcom for Win 95 * 34 * * 35 *---------------------------------------------------------------------------------------------* 36 * * 37 * Functions: * 38 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 39 40 #include "function.h" 41 #include "tcpip.h" 42 43 void output(short,short) 44 {} 45 46 bool InDebugger = false; 47 bool ReadyToQuit = false; 48 49 #if (0) 50 /*************************************************************************** 51 * Extract_Shape_Count -- returns # of shapes in the given shape block * 52 * * 53 * The # of shapes in a shape block is the first WORD in the block, so * 54 * this is the value returned. * 55 * * 56 * INPUT: * 57 * buffer pointer to shape block, created with MAKESHPS.EXE * 58 * * 59 * OUTPUT: * 60 * # shapes in the block * 61 * * 62 * WARNINGS: * 63 * none * 64 * * 65 * HISTORY: * 66 * 06/09/1992 JLB : Created. * 67 * 08/19/1993 SKB : Split drawshp.asm into several modules. * 68 * 05/25/1994 BR : Converted to 32-bit * 69 *=========================================================================*/ 70 int __cdecl Extract_Shape_Count(VOID const *buffer) 71 { 72 ShapeBlock_Type *block = (ShapeBlock_Type *)buffer; 73 74 return (block->NumShapes); 75 76 } /* end of Extract_Shape_Count */ 77 78 79 /*************************************************************************** 80 * Extract_Shape -- Gets pointer to shape in given shape block * 81 * * 82 * INPUT: * 83 * buffer pointer to shape block, created with MAKESHPS.EXE * 84 * shape index of shape to get * 85 * * 86 * OUTPUT: * 87 * pointer to shape in the shape block * 88 * * 89 * WARNINGS: * 90 * none * 91 * * 92 * HISTORY: * 93 * 06/09/1992 JLB : Created. * 94 * 08/19/1993 SKB : Split drawshp.asm into several modules. * 95 * 05/25/1994 BR : Converted to 32-bit * 96 *=========================================================================*/ 97 VOID * __cdecl Extract_Shape(VOID const *buffer, int shape) 98 { 99 ShapeBlock_Type *block = (ShapeBlock_Type*) buffer; 100 long offset; // Offset of shape data, from start of block 101 char *bytebuf = (char*) buffer; 102 103 /* 104 ----------------------- Return if invalid argument ----------------------- 105 */ 106 if (!buffer || shape < 0 || shape >= block->NumShapes) 107 return(NULL); 108 109 offset = block->Offsets[shape]; 110 111 return(bytebuf + 2 + offset); 112 113 } /* end of Extract_Shape */ 114 #endif //(0) 115 116 117 118 unsigned long CCFocusMessage = WM_USER+50; //Private message for receiving application focus 119 extern void VQA_PauseAudio(void); 120 extern void VQA_ResumeAudio(void); 121 122 123 ThemeType OldTheme = THEME_NONE; 124 125 126 /*********************************************************************************************** 127 * Focus_Loss -- this function is called when a library function detects focus loss * 128 * * 129 * * 130 * * 131 * INPUT: Nothing * 132 * * 133 * OUTPUT: Nothing * 134 * * 135 * WARNINGS: None * 136 * * 137 * HISTORY: * 138 * 2/1/96 2:10PM ST : Created * 139 *=============================================================================================*/ 140 141 void Focus_Loss(void) 142 { 143 if (SoundOn){ 144 if (OldTheme == THEME_NONE){ 145 OldTheme = Theme.What_Is_Playing(); 146 } 147 } 148 Theme.Stop(); 149 Stop_Primary_Sound_Buffer(); 150 if (WWMouse) WWMouse->Clear_Cursor_Clip(); 151 } 152 153 154 void Focus_Restore(void) 155 { 156 Restore_Cached_Icons(); 157 Map.Flag_To_Redraw(true); 158 Start_Primary_Sound_Buffer(TRUE); 159 if (WWMouse) WWMouse->Set_Cursor_Clip(); 160 VisiblePage.Clear(); 161 HiddenPage.Clear(); 162 } 163 164 165 166 /*********************************************************************************************** 167 * Check_For_Focus_Loss -- check for the end of the focus loss * 168 * * 169 * * 170 * * 171 * INPUT: Nothing * 172 * * 173 * OUTPUT: Nothing * 174 * * 175 * WARNINGS: None * 176 * * 177 * HISTORY: * 178 * 2/2/96 10:49AM ST : Created * 179 *=============================================================================================*/ 180 181 void Check_For_Focus_Loss(void) 182 { 183 184 // ST - 1/3/2019 10:40AM 185 #if (0) 186 static BOOL focus_last_time = 1; 187 MSG msg; 188 189 if ( !GameInFocus ){ 190 Focus_Loss(); 191 while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD ) ){ 192 if( !GetMessage( &msg, NULL, 0, 0 ) ){ 193 return; 194 } 195 TranslateMessage(&msg); 196 DispatchMessage(&msg); 197 } 198 } 199 200 if (!focus_last_time && GameInFocus){ 201 202 VQA_PauseAudio(); 203 CountDownTimerClass cd; 204 cd.Set(60*1); 205 206 do { 207 while (PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE )) { 208 if( !GetMessage( &msg, NULL, 0, 0 ) ){ 209 return; 210 } 211 TranslateMessage(&msg); 212 DispatchMessage(&msg); 213 } 214 215 } while(cd.Time()); 216 VQA_ResumeAudio(); 217 //AllSurfaces.Restore_Surfaces(); 218 //VisiblePage.Clear(); 219 //HiddenPage.Clear(); 220 //Map.Flag_To_Redraw(true); 221 PostMessage (MainWindow, CCFocusMessage,0,0); 222 } 223 224 focus_last_time = GameInFocus; 225 #endif 226 } 227 228 229 230 extern BOOL InMovie; 231 #if (0) //PG_TO_FIX 232 long FAR PASCAL _export Windows_Procedure (HWND hwnd, UINT message, UINT wParam, LONG lParam) 233 { 234 235 int low_param = LOWORD(wParam); 236 237 if (message == CCFocusMessage){ 238 Start_Primary_Sound_Buffer(TRUE); 239 if (!InMovie){ 240 Theme.Queue_Song(OldTheme); 241 OldTheme = THEME_NONE; 242 } 243 return(0); 244 } 245 246 247 switch ( message ){ 248 249 case WM_MOUSEMOVE: 250 case WM_SYSKEYDOWN: 251 case WM_SYSKEYUP: 252 case WM_KEYDOWN: 253 case WM_KEYUP: 254 case WM_LBUTTONDOWN: 255 case WM_LBUTTONUP: 256 case WM_LBUTTONDBLCLK: 257 case WM_MBUTTONDOWN: 258 case WM_MBUTTONUP: 259 case WM_MBUTTONDBLCLK: 260 case WM_RBUTTONDOWN: 261 case WM_RBUTTONUP: 262 case WM_RBUTTONDBLCLK: 263 Kbd.Message_Handler(hwnd, message, wParam, lParam); 264 return(0); 265 266 case WM_DESTROY: 267 CCDebugString ("C&C95 - WM_DESTROY message received.\n"); 268 CCDebugString ("C&C95 - About to call Prog_End.\n"); 269 Prog_End(); 270 CCDebugString ("C&C95 - About to Invalidate_Cached_Icons.\n"); 271 Invalidate_Cached_Icons(); 272 CCDebugString ("C&C95 - About to release the video surfaces.\n"); 273 VisiblePage.Un_Init(); 274 HiddenPage.Un_Init(); 275 AllSurfaces.Release(); 276 if (!InDebugger){ 277 CCDebugString ("C&C95 - About to reset the video mode.\n"); 278 Reset_Video_Mode(); 279 } 280 CCDebugString ("C&C95 - About to stop the profiler.\n"); 281 Stop_Profiler(); 282 CCDebugString ("C&C95 - Posting the quit message.\n"); 283 PostQuitMessage( 0 ); 284 /* 285 ** If we are shutting down gracefully than flag that the message loop has finished. 286 ** If this is a forced shutdown (ReadyToQuit == 0) then try and close down everything 287 ** before we exit. 288 */ 289 if (ReadyToQuit){ 290 CCDebugString ("C&C95 - We are now ready to quit.\n"); 291 ReadyToQuit = 2; 292 }else{ 293 CCDebugString ("C&C95 - Emergency shutdown.\n"); 294 CCDebugString ("C&C95 - Shut down the network stuff.\n"); 295 #ifndef DEMO 296 Shutdown_Network(); 297 #endif 298 CCDebugString ("C&C95 - Kill the Winsock stuff.\n"); 299 if (Winsock.Get_Connected()) Winsock.Close(); 300 CCDebugString ("C&C95 - Call ExitProcess.\n"); 301 ExitProcess(0); 302 } 303 CCDebugString ("C&C95 - Clean & ready to quit.\n"); 304 return(0); 305 306 case WM_ACTIVATEAPP: 307 GameInFocus=(BOOL)wParam; 308 if (!GameInFocus) { 309 Focus_Loss(); 310 } 311 AllSurfaces.Set_Surface_Focus (GameInFocus); 312 AllSurfaces.Restore_Surfaces(); 313 // if (GameInFocus){ 314 // Restore_Cached_Icons(); 315 // Map.Flag_To_Redraw(true); 316 // Start_Primary_Sound_Buffer(TRUE); 317 // if (WWMouse) WWMouse->Set_Cursor_Clip(); 318 // } 319 return(0); 320 #if (0) 321 case WM_ACTIVATE: 322 if (low_param == WA_INACTIVE){ 323 GameInFocus = FALSE; 324 Focus_Loss(); 325 } 326 return(0); 327 #endif //(0) 328 329 case WM_SYSCOMMAND: 330 switch ( wParam ) { 331 332 case SC_CLOSE: 333 /* 334 ** Windows sent us a close message. Probably in response to Alt-F4. Ignore it by 335 ** pretending to handle the message and returning 0; 336 */ 337 return (0); 338 339 case SC_SCREENSAVE: 340 /* 341 ** Windoze is about to start the screen saver. If we just return without passing 342 ** this message to DefWindowProc then the screen saver will not be allowed to start. 343 */ 344 return (0); 345 } 346 break; 347 348 #ifdef FORCE_WINSOCK 349 case WM_ACCEPT: 350 case WM_HOSTBYADDRESS: 351 case WM_HOSTBYNAME: 352 case WM_ASYNCEVENT: 353 case WM_UDPASYNCEVENT: 354 Winsock.Message_Handler(hwnd, message, wParam, lParam); 355 return (0); 356 #endif //FORCE_WINSOCK 357 } 358 359 return (DefWindowProc (hwnd, message, wParam, lParam)); 360 } 361 362 #endif 363 364 365 366 367 368 369 370 371 /*********************************************************************************************** 372 * Create_Main_Window -- opens the MainWindow for C&C * 373 * * 374 * * 375 * * 376 * INPUT: instance -- handle to program instance * 377 * * 378 * OUTPUT: Nothing * 379 * * 380 * WARNINGS: None * 381 * * 382 * HISTORY: * 383 * 10/10/95 4:08PM ST : Created * 384 *=============================================================================================*/ 385 386 #define CC_ICON 1 387 int ShowCommand; 388 389 void Create_Main_Window ( HANDLE instance ,int command_show , int width , int height ) 390 391 { 392 MainWindow = NULL; 393 return; 394 #if (0) 395 HWND hwnd ; 396 WNDCLASS wndclass ; 397 // 398 // Register the window class 399 // 400 401 wndclass.style = CS_HREDRAW | CS_VREDRAW ; 402 wndclass.lpfnWndProc = Windows_Procedure ; 403 wndclass.cbClsExtra = 0 ; 404 wndclass.cbWndExtra = 0 ; 405 wndclass.hInstance = instance ; 406 wndclass.hIcon = LoadIcon (instance, MAKEINTRESOURCE(CC_ICON)) ; 407 wndclass.hCursor = NULL; 408 wndclass.hbrBackground = NULL; 409 wndclass.lpszMenuName = "Command & Conquer"; //NULL 410 wndclass.lpszClassName = "Command & Conquer"; 411 412 RegisterClass (&wndclass) ; 413 414 415 // 416 // Create our main window 417 // 418 hwnd = CreateWindowEx ( 419 WS_EX_TOPMOST, 420 "Command & Conquer", 421 "Command & Conquer", 422 WS_POPUP | WS_MAXIMIZE, 423 0, 424 0, 425 width, 426 height, 427 NULL, 428 NULL, 429 instance, 430 NULL ); 431 432 ShowWindow (hwnd, command_show ); 433 ShowCommand = command_show; 434 UpdateWindow (hwnd); 435 SetFocus (hwnd); 436 MainWindow=hwnd; //Save the handle to our main window 437 hInstance = instance; 438 439 CCFocusMessage = RegisterWindowMessage ("CC_GOT_FOCUS"); 440 441 Audio_Focus_Loss_Function = &Focus_Loss; 442 Misc_Focus_Loss_Function = &Focus_Loss; 443 Misc_Focus_Restore_Function = &Focus_Restore; 444 Gbuffer_Focus_Loss_Function = &Focus_Loss; 445 #endif 446 } 447 448 void Window_Dialog_Box(HANDLE hinst, LPCTSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc) 449 { 450 #if (0) 451 MSG msg; 452 /* 453 ** Get rid of the Westwood mouse cursor because we are showing a 454 ** dialog box and we want to have the right windows cursor showing 455 ** for it. 456 */ 457 Hide_Mouse(); 458 ShowCursor(TRUE); 459 460 /* 461 ** Pop up the dialog box and then run a standard message handler 462 ** until the dialog box is closed. 463 */ 464 465 DialogBox(hinst, lpszTemplate, hwndOwner, dlgprc); 466 while (GetMessage(&msg, NULL, 0, 0) && !AllDone) { 467 TranslateMessage(&msg); 468 DispatchMessage(&msg); 469 } 470 471 /* 472 ** Restore the westwood mouse cursor and get rid of the windows one 473 ** because it is now time to restore back to the westwood way of 474 ** doing things. 475 */ 476 ShowCursor(FALSE); 477 Show_Mouse(); 478 #endif 479 } 480 481 482 483 typedef struct tColourList { 484 485 char Red; 486 char Green; 487 char Blue; 488 } ColourList; 489 490 ColourList ColourLookup[9]={ 491 0,0,0, 492 63,0,0, 493 0,63,0, 494 0,0,63, 495 63,0,63, 496 63,63,0, 497 0,63,63, 498 32,32,32, 499 63,63,63 500 }; 501 502 503 504 505 int DebugColour=1; 506 507 508 extern "C" void Set_Palette_Register(int number,int red ,int green ,int blue); 509 //#pragma off (unreferenced) 510 void Colour_Debug (int call_number) 511 { 512 //#if 0 513 //if (DebugColour==call_number || !call_number){ 514 515 //if (call_number){ 516 // Wait_Vert_Blank(); 517 //} 518 519 // ST - 1/3/2019 10:43AM 520 //Set_Palette_Register (0,ColourLookup[call_number].Red , 521 // ColourLookup[call_number].Green, 522 // ColourLookup[call_number].Blue); 523 //} 524 //#endif 525 } 526 527 //#pragma on (unreferenced) 528 529 530 531 532 533 BOOL Any_Locked (void) 534 { 535 if (SeenBuff.Get_LockCount() || 536 HidPage.Get_LockCount()){ 537 return (TRUE); 538 }else{ 539 return(FALSE); 540 } 541 } 542 543 544 545 546 547 548 549 HANDLE DebugFile = INVALID_HANDLE_VALUE; 550 551 /*********************************************************************************************** 552 * CCDebugString -- sends a string to the debugger and echos it to disk * 553 * * 554 * * 555 * * 556 * INPUT: string * 557 * * 558 * OUTPUT: Nothing * 559 * * 560 * WARNINGS: None * 561 * * 562 * HISTORY: * 563 * 10/28/96 12:48PM ST : Created * 564 *=============================================================================================*/ 565 void CCDebugString (char *string) 566 { 567 #if (0) 568 569 char outstr[256]; 570 571 sprintf (outstr, "%s", string); 572 573 DWORD actual; 574 if (DebugFile == INVALID_HANDLE_VALUE){ 575 DebugFile = CreateFile("debug.txt", GENERIC_WRITE, 0, 576 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 577 }else{ 578 DebugFile = CreateFile("debug.txt", GENERIC_WRITE, 0, 579 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 580 } 581 582 if (DebugFile != INVALID_HANDLE_VALUE){ 583 SetFilePointer (DebugFile, 0, NULL, FILE_END); 584 WriteFile(DebugFile, outstr, strlen(outstr)+1, &actual, NULL); 585 CloseHandle (DebugFile); 586 } 587 588 OutputDebugString (string); 589 590 #else 591 592 string = string; 593 594 #endif 595 596 } 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 // 612 // Miscellaneous stubs. Mainly for multi player stuff 613 // 614 // 615 // 616 617 //IPXAddressClass::IPXAddressClass(void) { 618 // int i; 619 // i++; 620 //} 621 //int IPXManagerClass::Num_Connections(void){ return (0); } 622 //int IPXManagerClass::Connection_ID( int ) { return (0); } 623 //IPXAddressClass * IPXManagerClass::Connection_Address( int ) { return ((IPXAddressClass*)0); } 624 //char * IPXManagerClass::Connection_Name( int ) { return ((char*)0); } 625 //int IPXAddressClass::Is_Broadcast() { return (0); } 626 //int IPXManagerClass::Send_Global_Message( void *, int, int, IPXAddressClass * ) { return (0); } 627 //int IPXManagerClass::Service() { return (0); } 628 //int IPXManagerClass::Get_Global_Message( void *, int *, IPXAddressClass *, short unsigned * ) { return (0); } 629 //int IPXAddressClass::operator ==( IPXAddressClass & ) { return (0); } 630 //IPXManagerClass::IPXManagerClass( int, int, int, int, short unsigned, short unsigned ) {} 631 //IPXManagerClass::~IPXManagerClass() { 632 // int i; 633 // i++; 634 // } 635 //int IPXManagerClass::Delete_Connection( int ) { return (0); } 636 //IPXAddressClass::IPXAddressClass( char unsigned *, char unsigned * ){} 637 //void IPXManagerClass::Set_Socket( short unsigned ){} 638 //int IPXManagerClass::Is_IPX() { return (0); } 639 //int IPXManagerClass::Init() { return (0); } 640 //void IPXAddressClass::Get_Address( char unsigned *, char unsigned * ){} 641 //void IPXManagerClass::Set_Bridge( char unsigned * ){} 642 //int IPXManagerClass::Global_Num_Send() { return (0); } 643 //void IPXManagerClass::Set_Timing( long unsigned, long unsigned, long unsigned ){} 644 //unsigned long IPXManagerClass::Global_Response_Time() { return (0); } 645 //int IPXManagerClass::Create_Connection( int, char *, IPXAddressClass * ) { return (0); } 646 //int IPXAddressClass::operator !=( IPXAddressClass & ) { return (0); } 647 //int IPXManagerClass::Send_Private_Message( void *, int, int, int ) { return (0); } 648 //int IPXManagerClass::Get_Private_Message( void *, int *, int * ) { return (0); } 649 //int IPXManagerClass::Connection_Index( int ) { return (0); } 650 //void IPXManagerClass::Reset_Response_Time(){} 651 //long unsigned IPXManagerClass::Response_Time() { return (0); } 652 //int IPXManagerClass::Private_Num_Send( int ) { return (0); } 653 654 //_VQAHandle * VQA_Alloc(void){ return ((_VQAHandle *)0); } 655 //void VQA_Init( _VQAHandle *, long ( *)()) {} 656 //long VQA_Open( _VQAHandle *, char const *, _VQAConfig * ) { return (0); } 657 //void VQA_Free( _VQAHandle * ) {} 658 //void VQA_Close( _VQAHandle * ) {} 659 //long VQA_Play( _VQAHandle *, long ) { return (0); } 660 661 //void VQA_Init(VQAHandle *, long(*)(VQAHandle *vqa, long action, void *buffer, long nbytes)){} 662 663 //long VQA_Open(VQAHandle *, char const *, VQAConfig *) 664 //{ 665 // return (0); 666 //} 667 668 //void VQA_Close(VQAHandle *){} 669 670 //long VQA_Play(VQAHandle *, long) 671 //{ 672 // return (0); 673 //} 674 675 676 unsigned char *VQPalette; 677 long VQNumBytes; 678 unsigned long VQSlowpal; 679 bool VQPaletteChange = false; 680 681 682 extern "C"{ 683 void __cdecl SetPalette(unsigned char *palette,long numbytes,unsigned long slowpal); 684 } 685 686 687 688 void Flag_To_Set_Palette(unsigned char *palette,long numbytes,unsigned long slowpal) 689 { 690 VQPalette = palette; 691 VQNumBytes = numbytes; 692 VQSlowpal = slowpal; 693 VQPaletteChange = true; 694 } 695 696 697 698 void Check_VQ_Palette_Set(void) 699 { 700 if (VQPaletteChange){ 701 SetPalette(VQPalette, VQNumBytes, VQSlowpal); 702 VQPaletteChange = false; 703 } 704 } 705 706 707 708 709 710 void __cdecl SetPalette(unsigned char *palette,long,unsigned long) 711 { 712 for (int i=0 ; i<256*3 ; i++){ 713 *(palette+i)&=63; 714 } 715 Increase_Palette_Luminance(palette , 15 , 15 , 15 ,63); 716 717 if (PalettesRead){ 718 memcpy (&PaletteInterpolationTable[0][0] , InterpolatedPalettes[PaletteCounter++] , 65536); 719 } 720 Set_Palette(palette); 721 } 722 723 724 725 /*********************************************************************************************** 726 * Memory_Error_Handler -- Handle a possibly fatal failure to allocate memory * 727 * * 728 * * 729 * * 730 * INPUT: Nothing * 731 * * 732 * OUTPUT: Nothing * 733 * * 734 * WARNINGS: None * 735 * * 736 * HISTORY: * 737 * 5/22/96 3:57PM ST : Created * 738 *=============================================================================================*/ 739 void Memory_Error_Handler(void) 740 { 741 GlyphX_Debug_Print("Error - out of memory."); 742 VisiblePage.Clear(); 743 Set_Palette(GamePalette); 744 while (Get_Mouse_State()){Show_Mouse();}; 745 CCMessageBox().Process("Error - out of memory.", "Abort", false); 746 Invalidate_Cached_Icons(); 747 748 // Nope. ST - 1/10/2019 10:38AM 749 //PostQuitMessage( 0 ); 750 //ExitProcess(0); 751 } 752 753 754 755 756 757 758 759 760 761 762 763 GraphicBufferClass* Read_PCX_File(char* name, char* Palette, void *Buff, long Size); 764 765 766 767 /*********************************************************************************************** 768 * Load_Title_Screen -- loads the title screen into the given video buffer * 769 * * 770 * * 771 * * 772 * INPUT: screen name * 773 * video buffer * 774 * ptr to buffer for palette * 775 * * 776 * OUTPUT: Nothing * 777 * * 778 * WARNINGS: None * 779 * * 780 * HISTORY: * 781 * 7/5/96 11:30AM ST : Created * 782 *=============================================================================================*/ 783 784 void Load_Title_Screen(char *name, GraphicViewPortClass *video_page, unsigned char *palette) 785 { 786 787 GraphicBufferClass *load_buffer; 788 789 790 load_buffer = Read_PCX_File (name, (char*)palette, NULL, 0); 791 792 if (load_buffer){ 793 load_buffer->Blit(*video_page); 794 delete load_buffer; 795 } 796 } 797 798 799 800 #include "filepcx.h" 801 802 /*************************************************************************** 803 * READ_PCX_FILE -- read a pcx file into a Graphic Buffer * 804 * * 805 * GraphicBufferClass* Read_PCX_File (char* name, char* palette ,void *Buff, long size ); * 806 * * 807 * * 808 * INPUT: name is a NULL terminated string of the fromat [xxxx.pcx] * 809 * palette is optional, if palette != NULL the the color palette of * 810 * the pcx file will be place in the memory block pointed * 811 * by palette. * 812 * Buff is optinal, if Buff == NULL a new memory Buffer * 813 * will be allocated, otherwise the file will be placed * 814 * at location pointd by Buffer; * 815 * Size is the size in bytes of the memory block pointed by Buff * 816 * is also optional; 817 * * 818 * OUTPUT: on succes a pointer to a GraphicBufferClass cointaining the * 819 * pcx file, NULL othewise. * 820 * * 821 * WARNINGS: * 822 * Appears to be a comment-free zone * 823 * * 824 * HISTORY: * 825 * 05/03/1995 JRJ : Created. * 826 * 04/30/1996 ST : Tidied up and modified to use CCFileClass * 827 *=========================================================================*/ 828 829 #define POOL_SIZE 2048 830 #define READ_CHAR() *file_ptr++ ; \ 831 if ( file_ptr >= & pool [ POOL_SIZE ] ) { \ 832 file_handle.Read (pool , POOL_SIZE ); \ 833 file_ptr = pool ; \ 834 } 835 836 /* 837 ** The old RGB was signed, so the shift right didn't work. ST - 1/4/2019 4:49PM 838 */ 839 typedef struct { 840 unsigned char red ; 841 unsigned char green ; 842 unsigned char blue ; 843 } PG_RGB ; 844 845 GraphicBufferClass* Read_PCX_File(char* name, char* palette, void *Buff, long Size) 846 { 847 int i, j; 848 unsigned rle; 849 unsigned color; 850 int scan_pos; 851 unsigned char *file_ptr; 852 int width; 853 int height; 854 unsigned char *buffer; 855 PCX_HEADER header; 856 PG_RGB *pal; 857 unsigned char pool [POOL_SIZE]; 858 GraphicBufferClass *pic; 859 860 CCFileClass file_handle(name); 861 862 if (!file_handle.Is_Available()) return (NULL); 863 864 file_handle.Open(READ); 865 866 file_handle.Read (&header, sizeof (PCX_HEADER)); 867 868 if (header.id != 10 && header.version != 5 && header.pixelsize != 8 ) return NULL ; 869 870 width = header.width - header.x + 1; 871 height = header.height - header.y + 1; 872 873 if (Buff) { 874 buffer = (unsigned char*) Buff; 875 i = Size / width; 876 height = MIN (i - 1, height); 877 pic = new GraphicBufferClass(width, height, buffer, Size); 878 if ( !(pic && pic->Get_Buffer()) ) return NULL ; 879 } else { 880 pic = new GraphicBufferClass(width, height, NULL, width*(height+4)); 881 if ( !(pic && pic->Get_Buffer()) ) return NULL ; 882 } 883 884 buffer = (unsigned char *) pic->Get_Buffer(); 885 file_ptr = pool ; 886 file_handle.Read (pool , POOL_SIZE); 887 888 if ( header.byte_per_line != width ){ 889 890 for ( scan_pos = j = 0 ; j < height ; j ++, scan_pos += width ) { 891 for ( i = 0 ; i < width ; ) { 892 rle = READ_CHAR (); 893 if ( rle > 192 ) { 894 rle -= 192 ; 895 color = READ_CHAR (); ; 896 memset ( buffer + scan_pos + i , color , rle ); 897 i += rle; 898 } else { 899 *(buffer+scan_pos + i++ ) = (char)rle; 900 } 901 } 902 } 903 904 if ( i == width ) rle = READ_CHAR (); 905 if ( rle > 192 ) rle = READ_CHAR (); 906 907 } else { 908 909 for ( i = 0 ; i < width * height ; ) { 910 rle = READ_CHAR (); 911 rle &= 0xff; 912 if ( rle > 192 ) { 913 rle -= 192 ; 914 color = READ_CHAR (); 915 memset ( buffer + i , color , rle ); 916 i += rle ; 917 }else{ 918 *(buffer + i++) = rle; 919 } 920 } 921 } 922 923 if ( palette ) { 924 file_handle.Seek (- (256 * (int)sizeof ( PG_RGB )) , SEEK_END ); 925 file_handle.Read (palette , 256L * sizeof ( PG_RGB )); 926 927 pal = ( PG_RGB * ) palette; 928 for (i = 0 ; i < 256 ; i ++) { 929 pal ->red >>= 2; 930 pal ->green >>= 2; 931 pal ->blue >>= 2; 932 pal ++ ; 933 } 934 } 935 936 file_handle.Close(); 937 return pic; 938 }