SENDFILE.CPP (26760B)
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 - Red Alert * 22 * * 23 * File Name : SENDFILE.CPP * 24 * * 25 * Programmer : Steve Tall * 26 * * 27 * Start Date : Audust 20th, 1996 * 28 * * 29 * Last Update : August 20th, 1996 [ST] * 30 * * 31 *-----------------------------------------------------------------------------------* 32 * Overview: * 33 * * 34 * Functions for scenario file transfer between machines * 35 * * 36 *-----------------------------------------------------------------------------------* 37 * Functions: * 38 * * 39 * * 40 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 41 42 #if (0)//PG 43 #include "function.h" 44 45 //#include "WolDebug.h" 46 47 #ifdef WINSOCK_IPX 48 #include "WSProto.h" 49 #else 50 51 #ifdef WIN32 52 #include "tcpip.h" 53 #else 54 #include "fakesock.h" 55 #endif //WIN32 56 57 #endif //WINSOCK_IPX 58 59 bool Receive_Remote_File ( char *file_name, unsigned int file_length, int gametype); 60 bool Send_Remote_File ( char *file_name, int gametype ); 61 62 #ifdef FIXIT_CSII // checked - ajw 9/28/98 63 extern bool Is_Mission_Counterstrike (char *file_name); 64 extern bool Is_Mission_Aftermath (char *file_name); 65 #endif 66 67 #define RESPONSE_TIMEOUT 60*60 68 69 #ifdef WOLAPI_INTEGRATION 70 #include "WolapiOb.h" 71 extern WolapiObject* pWolapi; 72 #endif 73 74 /*********************************************************************************************** 75 * Get_Scenario_File_From_Host -- Initiates download of scenario file from game host * 76 * * 77 * * 78 * * 79 * INPUT: ptr to buffer to copy file name into * 80 * game type - 0 for modem/null modem, 1 otherwise * 81 * * 82 * OUTPUT: true if file sucessfully downloaded * 83 * * 84 * WARNINGS: None * 85 * * 86 * HISTORY: * 87 * 8/22/96 3:06PM ST : Created * 88 *=============================================================================================*/ 89 bool Get_Scenario_File_From_Host(char *return_name, int gametype) 90 { 91 //WWDebugString ("RA95 - In Get_Scenario_From_Host\n"); 92 93 unsigned int file_length; 94 95 SerialPacketType send_packet; 96 SerialPacketType receive_packet; 97 GlobalPacketType net_send_packet; 98 GlobalPacketType net_receive_packet; 99 unsigned int packet_len; 100 unsigned short product_id; 101 102 IPXAddressClass sender_address; 103 104 CDTimerClass<SystemTimerClass> response_timer; // timeout timer for waiting for responses 105 106 /* 107 ** Send the scenario request using guaranteed delivery. 108 */ 109 if (!gametype) { 110 memset ((void*)&send_packet, 0, sizeof (send_packet)); 111 send_packet.Command = SERIAL_REQ_SCENARIO; 112 NullModem.Send_Message (&send_packet, sizeof(send_packet), 1); 113 } else { 114 memset ((void*)&net_send_packet, 0, sizeof (net_send_packet)); 115 net_send_packet.Command = NET_REQ_SCENARIO; 116 Ipx.Send_Global_Message (&net_send_packet, sizeof (net_send_packet), 117 1, &(Session.HostAddress) ); 118 } 119 120 121 122 //WWDebugString ("RA95 - Waiting for response from host\n"); 123 124 /* 125 ** Wait for host to respond with a file info packet 126 */ 127 response_timer = RESPONSE_TIMEOUT; 128 if (!gametype){ 129 do { 130 NullModem.Service(); 131 132 if (NullModem.Get_Message ((void*)&receive_packet, (int*)&packet_len) > 0) { 133 134 if (receive_packet.Command == SERIAL_FILE_INFO){ 135 strcpy (return_name, receive_packet.ScenarioInfo.ShortFileName); 136 file_length = receive_packet.ScenarioInfo.FileLength; 137 break; 138 } 139 } 140 } while ( response_timer ); 141 }else{ 142 do { 143 Ipx.Service(); 144 int receive_packet_length = sizeof (net_receive_packet); 145 if (Ipx.Get_Global_Message (&net_receive_packet, &receive_packet_length, 146 &sender_address, &product_id)){ 147 148 //WWDebugString ("RA95 - Got packet from host\n"); 149 #ifdef WINSOCK_IPX 150 if (net_receive_packet.Command == NET_FILE_INFO && sender_address == Session.HostAddress) { 151 #else //WINSOCK_IPX 152 if (net_receive_packet.Command == NET_FILE_INFO && 153 (Winsock.Get_Connected() || sender_address == Session.HostAddress)){ 154 #endif //WINSOCK_IPX 155 strcpy (return_name, net_receive_packet.ScenarioInfo.ShortFileName); 156 file_length = net_receive_packet.ScenarioInfo.FileLength; 157 //WWDebugString ("RA95 - Got file info packet from host\n"); 158 break; 159 } 160 } 161 162 #ifdef WOLAPI_INTEGRATION 163 if( Session.Type == GAME_INTERNET && pWolapi && ( ::timeGetTime() > pWolapi->dwTimeNextWolapiPump ) ) 164 { 165 pWolapi->pChat->PumpMessages(); 166 pWolapi->dwTimeNextWolapiPump = ::timeGetTime() + WOLAPIPUMPWAIT; 167 } 168 #endif 169 } while ( response_timer ); 170 } 171 172 //char rt[80]; 173 //sprintf (rt, "RA95 - response_timer = %d\n", response_timer ); 174 //WWDebugString (rt); 175 176 /* 177 ** If we timed out then something horrible has happened to the other player so just 178 ** return failure. 179 */ 180 if (!response_timer) return (false); 181 182 // debugprint( "about to download '%s'\n", return_name ); 183 184 /* 185 ** Receive the file from the host 186 */ 187 return (Receive_Remote_File ( return_name, file_length, gametype)); 188 } 189 190 191 192 193 194 195 196 /*********************************************************************************************** 197 * Receive_Remote_File -- Handles incoming file download packets from the game host * 198 * * 199 * * 200 * * 201 * INPUT: file name to save as * 202 * length of file to expect * 203 * game type - 0 for modem/null modem, 1 otherwise * 204 * * 205 * OUTPUT: true if file downloaded was completed * 206 * * 207 * WARNINGS: This fuction can modify the file name passed in * 208 * * 209 * HISTORY: * 210 * 8/22/96 3:07PM ST : Created * 211 *=============================================================================================*/ 212 bool Receive_Remote_File ( char *file_name, unsigned int file_length, int gametype) 213 { 214 215 //WWDebugString ("RA95 - In Receive_Remote_File\n"); 216 unsigned short product_id; 217 IPXAddressClass sender_address; 218 219 /* 220 ** Dialog & button dimensions 221 */ 222 int d_dialog_w = 200 *RESFACTOR; // dialog width 223 int d_dialog_h = 90*RESFACTOR; // dialog height 224 int d_dialog_x = ((320*RESFACTOR - d_dialog_w) / 2); // dialog x-coord 225 int d_dialog_y = ((200*RESFACTOR - d_dialog_h) / 2); // centered y-coord 226 int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord 227 228 int d_margin1=10; 229 int d_txt6_h=15; 230 231 #if (GERMAN | FRENCH) 232 int d_cancel_w = 50*RESFACTOR; 233 #else 234 int d_cancel_w = 40*RESFACTOR; 235 #endif 236 int d_cancel_h = 9*RESFACTOR; 237 int d_cancel_x = d_dialog_cx - d_cancel_w / 2; 238 int d_cancel_y = d_dialog_y + d_dialog_h - 20*RESFACTOR; 239 240 int d_progress_w = 100*RESFACTOR; 241 int d_progress_h = 10*RESFACTOR; 242 int d_progress_x = (SeenBuff.Get_Width()/2) - d_progress_w/2; 243 int d_progress_y = d_dialog_y + 45*RESFACTOR; 244 245 int width; 246 int height; 247 248 char *info_string = (char*)Text_String (TXT_RECEIVING_SCENARIO); 249 250 Fancy_Text_Print(TXT_NONE, 0, 0, GadgetClass::Get_Color_Scheme(), 251 TBLACK, TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); 252 253 Format_Window_String(info_string, SeenBuff.Get_Height(), width, height); 254 255 256 /* 257 ** Button Enumerations 258 */ 259 enum { 260 BUTTON_CANCEL = 100, 261 BUTTON_PROGRESS 262 }; 263 264 /* 265 ** Buttons 266 */ 267 //TextButtonClass *buttons; // button list 268 269 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, 270 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 271 #if (GERMAN | FRENCH) 272 d_cancel_x, d_cancel_y); 273 #else 274 d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); 275 #endif 276 277 GaugeClass progress_meter (BUTTON_PROGRESS, 278 d_progress_x, d_progress_y, d_progress_w, d_progress_h); 279 280 Fancy_Text_Print(TXT_NONE, 0, 0, GadgetClass::Get_Color_Scheme(), 281 TBLACK, TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); 282 283 284 typedef enum { 285 REDRAW_NONE = 0, 286 REDRAW_PROGRESS, 287 REDRAW_BUTTONS, 288 REDRAW_BACKGROUND, 289 REDRAW_ALL = REDRAW_BACKGROUND 290 } RedrawType; 291 292 293 bool process = true; 294 RedrawType display = REDRAW_ALL; // redraw level 295 KeyNumType input; 296 GadgetClass *commands; // button list 297 bool return_code; 298 int update_time = 0; 299 300 301 302 RemoteFileTransferType receive_packet; 303 304 int last_received_block = -1; //No blocks received yet 305 unsigned int total_length = 0; 306 unsigned int packet_len; 307 308 /* 309 ** If the file name is already in use, use the temp file name 310 */ 311 CCFileClass test_file (file_name); 312 if (test_file.Is_Available()){ 313 strcpy (file_name, "DOWNLOAD.TMP"); 314 } 315 316 RawFileClass save_file (file_name); 317 318 /* 319 ** If the file already exists then delete it and re-create it. 320 */ 321 if (save_file.Is_Available()) save_file.Delete(); 322 323 /* 324 ** Open the file for write 325 */ 326 save_file.Open ( WRITE ); 327 328 commands = &cancelbtn; 329 commands->Add_Tail (progress_meter); 330 331 progress_meter.Set_Maximum(100); // Max is 100% 332 progress_meter.Set_Value(0); // Current is 0% 333 334 /* 335 ** Wait for all the blocks to arrive 336 */ 337 338 do { 339 #ifdef WIN32 340 /* 341 ** If we have just received input focus again after running in the background then 342 ** we need to redraw. 343 */ 344 if (AllSurfaces.SurfacesRestored) { 345 AllSurfaces.SurfacesRestored=FALSE; 346 display = REDRAW_ALL; 347 } 348 #endif 349 350 #ifdef WOLAPI_INTEGRATION 351 if( Session.Type == GAME_INTERNET && pWolapi && ( ::timeGetTime() > pWolapi->dwTimeNextWolapiPump ) ) 352 { 353 pWolapi->pChat->PumpMessages(); 354 pWolapi->dwTimeNextWolapiPump = ::timeGetTime() + WOLAPIPUMPWAIT; 355 } 356 #endif 357 358 if (display){ 359 360 if (display >= REDRAW_BACKGROUND){ 361 362 Hide_Mouse(); 363 /* 364 ** Redraw backgound & dialog box 365 */ 366 Load_Title_Page(true); 367 Set_Palette(CCPalette); 368 369 Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); 370 371 /* 372 ** Dialog & Field labels 373 */ 374 Draw_Caption (TXT_NONE, d_dialog_x, d_dialog_y, d_dialog_w); 375 376 Fancy_Text_Print(info_string, d_dialog_cx-width/2, d_dialog_y + 25*RESFACTOR, 377 GadgetClass::Get_Color_Scheme(), TBLACK, 378 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 379 380 Show_Mouse(); 381 382 } 383 384 if (display >= REDRAW_BUTTONS){ 385 386 commands->Draw_All(); 387 388 } 389 390 if (display >= REDRAW_PROGRESS){ 391 progress_meter.Draw_Me(true); 392 } 393 394 display = REDRAW_NONE; 395 } 396 397 398 if (!gametype){ 399 NullModem.Service(); 400 401 if (NullModem.Get_Message ((void*)&receive_packet, (int*)&packet_len) > 0) { 402 403 if (receive_packet.Command == NET_FILE_CHUNK){ 404 405 if (receive_packet.BlockNumber == last_received_block + 1){ 406 407 save_file.Write ( receive_packet.RawData, receive_packet.BlockLength ); 408 total_length += receive_packet.BlockLength; 409 last_received_block ++; 410 411 update_time++; 412 if (update_time >7){ 413 progress_meter.Set_Value ( (total_length*100) / file_length ); 414 display = REDRAW_PROGRESS; 415 update_time = 0;; 416 } 417 418 if (total_length >= file_length){ 419 process = false; 420 return_code = true; 421 progress_meter.Set_Value ( 100 ); 422 progress_meter.Draw_Me(true); 423 } 424 } 425 } 426 } 427 }else{ 428 Ipx.Service(); 429 430 int receive_packet_len = sizeof (receive_packet); 431 if (Ipx.Get_Global_Message (&receive_packet, &receive_packet_len, 432 &sender_address, &product_id)){ 433 434 #ifdef WINSOCK_IPX 435 if (receive_packet.Command == NET_FILE_CHUNK && sender_address == Session.HostAddress){ 436 #else //WINSOCK_IPX 437 if (receive_packet.Command == NET_FILE_CHUNK && 438 (Winsock.Get_Connected() || sender_address == Session.HostAddress)){ 439 #endif //WINSOCK_IPX 440 441 if (receive_packet.BlockNumber == last_received_block + 1){ 442 443 save_file.Write ( receive_packet.RawData, receive_packet.BlockLength ); 444 total_length += receive_packet.BlockLength; 445 last_received_block ++; 446 447 update_time++; 448 if (update_time >7){ 449 progress_meter.Set_Value ( (total_length*100) / file_length ); 450 display = REDRAW_PROGRESS; 451 update_time = 0;; 452 } 453 454 if (total_length >= file_length){ 455 process = false; 456 return_code = true; 457 progress_meter.Set_Value ( 100 ); 458 progress_meter.Draw_Me(true); 459 } 460 } 461 } 462 } 463 } 464 465 466 if (process){ 467 input = cancelbtn.Input(); 468 469 /* 470 ---------------------------- Process input ---------------------------- 471 */ 472 switch (input) { 473 474 /* 475 ** Cancel. Just return to the main menu 476 */ 477 case (KN_ESC): 478 case (BUTTON_CANCEL | KN_BUTTON): 479 process = false; 480 return_code = false; 481 break; 482 } 483 } 484 485 486 } while ( process ); 487 488 save_file.Close(); 489 490 /* 491 ** Update the internal list of scenarios to include the downloaded one so we know about it 492 ** for the next game. 493 */ 494 Session.Read_Scenario_Descriptions(); 495 496 return (return_code); 497 } 498 499 500 501 502 503 504 /*********************************************************************************************** 505 * Send_Remote_File -- Sends a file to game clients * 506 * * 507 * * 508 * * 509 * INPUT: File name * 510 * * 511 * OUTPUT: true if file transfer was successfully completed * 512 * game type - 0 for modem/null modem, 1 otherwise * 513 * * 514 * WARNINGS: None * 515 * * 516 * HISTORY: * 517 * 8/22/96 3:09PM ST : Created * 518 *=============================================================================================*/ 519 bool Send_Remote_File ( char *file_name, int gametype ) 520 { 521 //WWDebugString ("RA95 - In Send_Remote_File\n"); 522 523 /* 524 ** Dialog & button dimensions 525 */ 526 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 527 528 int d_dialog_w = 240 *factor; // dialog width 529 int d_dialog_h = 90*factor; // dialog height 530 int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord 531 int d_dialog_y = ((200*factor - d_dialog_h) / 2); // centered y-coord 532 int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord 533 534 int d_margin1=10; 535 int d_txt6_h=15; 536 537 #if (GERMAN | FRENCH) 538 int d_cancel_w = 50*factor; 539 #else 540 int d_cancel_w = 40*factor; 541 #endif 542 int d_cancel_h = 9*factor; 543 int d_cancel_x = d_dialog_cx - d_cancel_w / 2; 544 int d_cancel_y = d_dialog_y + d_dialog_h - 20*factor; 545 546 int d_progress_w = 100*factor; 547 int d_progress_h = 10*factor; 548 int d_progress_x = (SeenBuff.Get_Width()/2) - d_progress_w/2; 549 int d_progress_y = d_dialog_y + 45*factor; 550 551 int width; 552 int height; 553 554 char *info_string = (char*)Text_String (TXT_SENDING_SCENARIO); 555 556 CDTimerClass<SystemTimerClass> response_timer; // timeout timer for waiting for responses 557 558 Fancy_Text_Print(TXT_NONE, 0, 0, GadgetClass::Get_Color_Scheme(), 559 TBLACK, TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); 560 561 Format_Window_String(info_string, SeenBuff.Get_Height(), width, height); 562 563 564 /* 565 ** Button Enumerations 566 */ 567 enum { 568 BUTTON_CANCEL = 100, 569 BUTTON_PROGRESS 570 }; 571 572 /* 573 ** Buttons 574 */ 575 //TextButtonClass *buttons; // button list 576 577 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, 578 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 579 #if (GERMAN | FRENCH) 580 d_cancel_x, d_cancel_y); 581 #else 582 d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); 583 #endif 584 585 GaugeClass progress_meter (BUTTON_PROGRESS, 586 d_progress_x, d_progress_y, d_progress_w, d_progress_h); 587 588 Fancy_Text_Print(TXT_NONE, 0, 0, GadgetClass::Get_Color_Scheme(), 589 TBLACK, TPF_CENTER|TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW); 590 591 592 typedef enum { 593 REDRAW_NONE = 0, 594 REDRAW_PROGRESS, 595 REDRAW_BUTTONS, 596 REDRAW_BACKGROUND, 597 REDRAW_ALL = REDRAW_BACKGROUND 598 } RedrawType; 599 600 601 bool process = true; 602 RedrawType display = REDRAW_ALL; // redraw level 603 KeyNumType input; 604 GadgetClass *commands; // button list 605 bool return_code; 606 int update_time = 0; 607 608 609 int file_length; 610 int block_number; 611 int max_chunk_size; 612 int total_blocks; 613 int bytes_left; 614 615 void *read_ptr; 616 617 RemoteFileTransferType send_packet; 618 SerialPacketType file_info; 619 GlobalPacketType net_file_info; 620 621 622 CCFileClass send_file (file_name); 623 624 if ( !send_file.Is_Available() ){ 625 //WWDebugString ("RA95 - Error - could not find file to send to client\n"); 626 // debugprint("RA95 - Error - could not find file to send to client\n"); 627 return (false); 628 } 629 file_length = send_file.Size(); 630 631 response_timer = RESPONSE_TIMEOUT; 632 633 /* 634 ** Send the file info to the remote machine(s) 635 */ 636 if (!gametype){ 637 file_info.Command = SERIAL_FILE_INFO; 638 strcpy (&file_info.ScenarioInfo.ShortFileName[0], file_name); 639 #ifdef FIXIT_VERSION_3 640 // If we're sending an official map, always send it to 'download.tmp'. 641 if( Is_Mission_Counterstrike( file_name ) || Is_Mission_Aftermath( file_name ) ) { 642 strcpy (&file_info.ScenarioInfo.ShortFileName[0], "DOWNLOAD.TMP"); 643 } 644 #else 645 #ifdef FIXIT_CSII // checked - ajw 9/28/98 646 // If we're sending an Aftermath map, always send it to 'download.tmp'. 647 if (Is_Mission_Aftermath(file_name)) { 648 strcpy (&file_info.ScenarioInfo.ShortFileName[0], "DOWNLOAD.TMP"); 649 } 650 #endif 651 #endif 652 file_info.ScenarioInfo.FileLength = file_length; 653 NullModem.Send_Message (&file_info, sizeof (file_info), 1); 654 while (NullModem.Num_Send() > 0 && response_timer){ 655 NullModem.Service(); 656 } 657 } else { 658 net_file_info.Command = NET_FILE_INFO; 659 strcpy (&net_file_info.ScenarioInfo.ShortFileName[0], file_name); 660 // debugprint( "Uploading '%s'\n", file_name ); 661 #ifdef FIXIT_VERSION_3 662 // If we're sending an official map, always send it to 'download.tmp'. 663 if( Is_Mission_Counterstrike( file_name ) || Is_Mission_Aftermath( file_name ) ) { 664 strcpy (&net_file_info.ScenarioInfo.ShortFileName[0], "DOWNLOAD.TMP"); 665 } 666 #else 667 #ifdef FIXIT_CSII // checked - ajw 9/28/98 668 // If we're sending an Aftermath map, always send it to 'download.tmp'. 669 if (Is_Mission_Aftermath(file_name)) { 670 strcpy (&file_info.ScenarioInfo.ShortFileName[0], "DOWNLOAD.TMP"); 671 // There was a bug here: s/b net_file_info. This means that players that don't have Aftermath could have been 672 // accumulating Aftermath maps all this time!!! (File wasn't getting renamed to "DOWNLOAD.TMP".) 673 } 674 #endif 675 #endif 676 // debugprint( "ShortFileName is '%s'\n", net_file_info.ScenarioInfo.ShortFileName ); 677 net_file_info.ScenarioInfo.FileLength = file_length; 678 679 for (int i=0 ; i<Session.RequestCount ; i++){ 680 Ipx.Send_Global_Message (&net_file_info, sizeof (GlobalPacketType), 681 1, &(Session.Players[Session.ScenarioRequests[i]]->Address) ); 682 } 683 684 while (Ipx.Global_Num_Send() > 0 && response_timer) { 685 Ipx.Service(); 686 } 687 } 688 689 690 max_chunk_size = MAX_SEND_FILE_PACKET_SIZE; 691 total_blocks = (file_length + max_chunk_size-1) / max_chunk_size; 692 bytes_left = file_length; 693 694 send_file.Open ( READ ); 695 696 697 commands = &cancelbtn; 698 commands->Add_Tail (progress_meter); 699 700 progress_meter.Set_Maximum(100); // Max is 100% 701 progress_meter.Set_Value(0); // Current is 0% 702 703 704 block_number = 0; 705 706 while ( process ){ 707 708 #ifdef WIN32 709 /* 710 ** If we have just received input focus again after running in the background then 711 ** we need to redraw. 712 */ 713 if (AllSurfaces.SurfacesRestored) { 714 AllSurfaces.SurfacesRestored=FALSE; 715 display = REDRAW_ALL; 716 } 717 #endif 718 719 #ifdef WOLAPI_INTEGRATION 720 if( Session.Type == GAME_INTERNET && pWolapi && ( ::timeGetTime() > pWolapi->dwTimeNextWolapiPump ) ) 721 { 722 pWolapi->pChat->PumpMessages(); 723 pWolapi->dwTimeNextWolapiPump = ::timeGetTime() + WOLAPIPUMPWAIT; 724 } 725 #endif 726 727 if (display){ 728 729 if (display >= REDRAW_BACKGROUND){ 730 731 Hide_Mouse(); 732 /* 733 ** Redraw backgound & dialog box 734 */ 735 Load_Title_Page(true); 736 Set_Palette(CCPalette); 737 738 Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); 739 740 /* 741 ** Dialog & Field labels 742 */ 743 Draw_Caption (TXT_NONE, d_dialog_x, d_dialog_y, d_dialog_w); 744 745 Fancy_Text_Print(info_string, d_dialog_cx-width/2, d_dialog_y + 25*factor, 746 GadgetClass::Get_Color_Scheme(), TBLACK, 747 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 748 749 Show_Mouse(); 750 751 } 752 753 if (display >= REDRAW_BUTTONS){ 754 755 commands->Draw_All(); 756 757 } 758 759 if (display >= REDRAW_PROGRESS){ 760 progress_meter.Draw_Me(true); 761 } 762 763 display = REDRAW_NONE; 764 } 765 766 767 if (!gametype){ 768 NullModem.Service(); 769 770 771 if (block_number < total_blocks){ 772 773 if ( NullModem.Num_Send() <2 ){ 774 775 send_packet.Command = SERIAL_FILE_CHUNK; 776 send_packet.BlockNumber = block_number; 777 send_packet.BlockLength = MIN (file_length, max_chunk_size); 778 779 file_length -= send_packet.BlockLength; 780 781 read_ptr = &send_packet.RawData[0]; 782 783 if (send_file.Read (read_ptr , send_packet.BlockLength) == send_packet.BlockLength){ 784 NullModem.Send_Message ((void*)&send_packet, sizeof(send_packet), 1); 785 } 786 787 block_number++; 788 789 update_time++; 790 if (update_time >7){ 791 progress_meter.Set_Value ( (block_number*100) / total_blocks ); 792 display = REDRAW_PROGRESS; 793 update_time = 0;; 794 } 795 796 } 797 }else{ 798 if (NullModem.Num_Send() == 0){ 799 process = false; 800 return_code = true; 801 progress_meter.Set_Value ( 100 ); 802 progress_meter.Draw_Me(true); 803 804 } 805 } 806 807 808 }else{ 809 Ipx.Service(); 810 811 if (block_number < total_blocks){ 812 813 if ( Ipx.Global_Num_Send() == 0 ){ 814 815 send_packet.Command = SERIAL_FILE_CHUNK; 816 send_packet.BlockNumber = block_number; 817 send_packet.BlockLength = MIN (file_length, max_chunk_size); 818 819 file_length -= send_packet.BlockLength; 820 821 read_ptr = &send_packet.RawData[0]; 822 823 if (send_file.Read (read_ptr , send_packet.BlockLength) == send_packet.BlockLength){ 824 for (int i=0 ; i<Session.RequestCount ; i++){ 825 Ipx.Send_Global_Message (&send_packet, sizeof (send_packet), 826 1, &(Session.Players[Session.ScenarioRequests[i]]->Address) ); 827 } 828 } 829 830 block_number++; 831 832 update_time++; 833 if (update_time >7){ 834 progress_meter.Set_Value ( (block_number*100) / total_blocks ); 835 display = REDRAW_PROGRESS; 836 update_time = 0;; 837 } 838 839 } 840 }else{ 841 if (Ipx.Global_Num_Send() == 0){ 842 process = false; 843 return_code = true; 844 progress_meter.Set_Value ( 100 ); 845 progress_meter.Draw_Me(true); 846 } 847 } 848 849 850 851 } 852 853 854 if (process){ 855 input = cancelbtn.Input(); 856 857 /* 858 ---------------------------- Process input ---------------------------- 859 */ 860 switch (input) { 861 862 /* 863 ** Cancel. Just return to the main menu 864 */ 865 case (KN_ESC): 866 case (BUTTON_CANCEL | KN_BUTTON): 867 process = false; 868 return_code = false; 869 break; 870 } 871 } 872 873 } 874 875 return (return_code); 876 } 877 #endif