MPLAYER.CPP (52637B)
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 /* $Header: F:\projects\c&c\vcs\code\mplayer.cpv 1.9 16 Oct 1995 16:51:08 JOE_BOSTIC $ */ 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 : MPLAYER.CPP * 24 * * 25 * Programmer : Bill Randolph * 26 * * 27 * Start Date : April 14, 1995 * 28 * * 29 * Last Update : July 5, 1995 [BRR] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * Select_MPlayer_Game -- prompts user for NULL-Modem, Modem, or Network game * 34 * Read_MultiPlayer_Settings -- reads multi-player settings from conquer.ini * 35 * Write_MultiPlayer_Settings -- writes multi-player settings to conquer.ini * 36 * Read_Scenario_Descriptions -- reads multi-player scenario #'s # descriptions * 37 * Free_Scenario_Descriptions -- frees memory for the scenario descriptions * 38 * Computer_Message -- "sends" a message from the computer * 39 * Garble_Message -- "garbles" a message * 40 * Surrender_Dialog -- Prompts user for surrendering * 41 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 42 43 #include "function.h" 44 #include "tcpip.h" 45 46 static void Garble_Message(char *buf); 47 48 int Choose_Internet_Game(void); 49 int Get_Internet_Host_Or_Join(void); 50 int Get_IP_Address(void); 51 void Show_Internet_Connection_Progress(void); 52 53 /*********************************************************************************************** 54 * Select_MPlayer_Game -- prompts user for NULL-Modem, Modem, or Network game * 55 * * 56 * INPUT: * 57 * none. * 58 * * 59 * OUTPUT: * 60 * GAME_NORMAL, GAME_MODEM, etc. * 61 * * 62 * WARNINGS: * 63 * none. * 64 * * 65 * HISTORY: * 66 * 02/14/1995 BR : Created. * 67 *=============================================================================================*/ 68 GameType Select_MPlayer_Game (void) 69 { 70 //PG_TO_FIX 71 return GAME_NORMAL; 72 #if (0) 73 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 74 bool ipx_avail = FALSE; 75 int number_of_buttons; 76 /*........................................................................ 77 Dialog & button dimensions 78 ........................................................................*/ 79 int d_dialog_w = 190*factor; 80 int d_dialog_h = 26*4*factor; 81 int d_dialog_x = ((320*factor - d_dialog_w) / 2); 82 // d_dialog_y = ((200 - d_dialog_h) / 2), 83 int d_dialog_y = ((136*factor - d_dialog_h) / 2); 84 int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); 85 86 int d_txt6_h = 11 * factor; 87 int d_margin = 7 *factor; 88 89 int d_modemserial_w = 80*factor; 90 int d_modemserial_h = 9*factor; 91 int d_modemserial_x = d_dialog_cx - d_modemserial_w / 2; 92 int d_modemserial_y = d_dialog_y + d_margin + d_txt6_h + d_margin; 93 #if (0) 94 int d_internet_w = 80*factor; 95 int d_internet_h = 9*factor; 96 int d_internet_x = d_dialog_cx - d_internet_w / 2; 97 int d_internet_y = d_modemserial_y + d_modemserial_h + 2*factor; 98 #endif //(0) 99 int d_ipx_w = 80*factor; 100 int d_ipx_h = 9*factor; 101 int d_ipx_x = d_dialog_cx - d_ipx_w / 2; 102 int d_ipx_y = d_modemserial_y + d_modemserial_h + 2*factor; 103 // int d_ipx_y = d_internet_y + d_internet_h + 2*factor; 104 105 int d_cancel_w = 60*factor; 106 int d_cancel_h = 9*factor; 107 int d_cancel_x = d_dialog_cx - d_cancel_w / 2; 108 int d_cancel_y = d_ipx_y + d_ipx_h + d_margin; 109 110 CountDownTimerClass delay; 111 112 /*........................................................................ 113 Button enumerations: 114 ........................................................................*/ 115 enum { 116 BUTTON_MODEMSERIAL = 100, 117 #if (0) 118 BUTTON_INTERNET, 119 #endif //(0) 120 BUTTON_IPX, 121 BUTTON_CANCEL, 122 123 NUM_OF_BUTTONS = 3, 124 }; 125 number_of_buttons = NUM_OF_BUTTONS; 126 /*........................................................................ 127 Redraw values: in order from "top" to "bottom" layer of the dialog 128 ........................................................................*/ 129 typedef enum { 130 REDRAW_NONE = 0, 131 REDRAW_BUTTONS, // includes map interior & coord values 132 REDRAW_BACKGROUND, // includes box, map bord, key, coord labels, btns 133 REDRAW_ALL = REDRAW_BACKGROUND 134 } RedrawType; 135 /*........................................................................ 136 Dialog variables: 137 ........................................................................*/ 138 KeyNumType input; // input from user 139 bool process; // loop while true 140 RedrawType display; // true = re-draw everything 141 GameType retval; // return value 142 int selection; 143 bool pressed; 144 int curbutton; 145 TextButtonClass *buttons[NUM_OF_BUTTONS]; 146 147 /*........................................................................ 148 Buttons 149 ........................................................................*/ 150 ControlClass *commands = NULL; // the button list 151 152 // 153 // If neither IPX or winsock are active then do only the modem serial dialog 154 // 155 if (Ipx.Is_IPX()){ 156 ipx_avail = TRUE; 157 } 158 159 160 TextButtonClass modemserialbtn (BUTTON_MODEMSERIAL, TXT_MODEM_SERIAL, 161 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 162 d_modemserial_x, d_modemserial_y, d_modemserial_w, d_modemserial_h); 163 #if (0) 164 TextButtonClass internetbtn (BUTTON_INTERNET, TXT_INTERNET, 165 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 166 d_internet_x, d_internet_y, d_internet_w, d_internet_h); 167 #endif //(0) 168 TextButtonClass ipxbtn (BUTTON_IPX, TXT_NETWORK, 169 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 170 d_ipx_x, d_ipx_y, d_ipx_w, d_ipx_h); 171 172 TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, 173 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 174 d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); 175 176 /* 177 ------------------------------- Initialize ------------------------------- 178 */ 179 Set_Logic_Page(SeenBuff); 180 181 /* 182 ............................ Create the list ............................. 183 */ 184 commands = &modemserialbtn; 185 #if (0) 186 internetbtn.Add_Tail(*commands); 187 #endif //(0) 188 if (ipx_avail){ 189 ipxbtn.Add_Tail(*commands); 190 } 191 cancelbtn.Add_Tail(*commands); 192 193 /* 194 ......................... Fill array of button ptrs ...................... 195 */ 196 curbutton = 0; 197 buttons[0] = &modemserialbtn; 198 #if (0) 199 buttons[1] = &internetbtn; 200 #endif //(0) 201 if (ipx_avail){ 202 buttons[1] = &ipxbtn; 203 buttons[2] = &cancelbtn; 204 }else{ 205 buttons[1] = &cancelbtn; 206 number_of_buttons--; 207 } 208 209 buttons[curbutton]->Turn_On(); 210 211 Keyboard::Clear(); 212 213 Fancy_Text_Print(TXT_NONE, 0, 0, CC_GREEN, TBLACK, 214 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 215 216 /* 217 -------------------------- Main Processing Loop -------------------------- 218 */ 219 display = REDRAW_ALL; 220 process = true; 221 pressed = false; 222 while (process) { 223 /* 224 ** If we have just received input focus again after running in the background then 225 ** we need to redraw. 226 */ 227 if (AllSurfaces.SurfacesRestored){ 228 AllSurfaces.SurfacesRestored=FALSE; 229 display=REDRAW_ALL; 230 } 231 232 /* 233 ........................ Invoke game callback ......................... 234 */ 235 Call_Back(); 236 /* 237 ...................... Refresh display if needed ...................... 238 */ 239 if (display) { 240 Hide_Mouse(); 241 if (display >= REDRAW_BACKGROUND) { 242 /* 243 ..................... Refresh the backdrop ...................... 244 */ 245 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 246 Blit_Hid_Page_To_Seen_Buff(); 247 /* 248 ..................... Draw the background ....................... 249 */ 250 Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); 251 Draw_Caption (TXT_SELECT_MPLAYER_GAME, d_dialog_x, d_dialog_y, d_dialog_w); 252 } 253 /* 254 .......................... Redraw buttons .......................... 255 */ 256 if (display >= REDRAW_BUTTONS) { 257 commands->Flag_List_To_Redraw(); 258 } 259 Show_Mouse(); 260 display = REDRAW_NONE; 261 } 262 263 /* 264 ........................... Get user input ............................ 265 */ 266 input = commands->Input(); 267 268 /* 269 ............................ Process input ............................ 270 */ 271 switch (input) { 272 case (BUTTON_MODEMSERIAL | KN_BUTTON): 273 selection = BUTTON_MODEMSERIAL; 274 pressed = true; 275 break; 276 277 #if (0) 278 case (BUTTON_INTERNET | KN_BUTTON): 279 selection = BUTTON_INTERNET; 280 pressed = true; 281 break; 282 #endif //(0) 283 284 case (BUTTON_IPX | KN_BUTTON): 285 selection = BUTTON_IPX; 286 pressed = true; 287 break; 288 289 case (KN_ESC): 290 case (BUTTON_CANCEL | KN_BUTTON): 291 selection = BUTTON_CANCEL; 292 pressed = true; 293 break; 294 295 case KN_UP: 296 buttons[curbutton]->Turn_Off(); 297 buttons[curbutton]->Flag_To_Redraw(); 298 curbutton--; 299 if (curbutton < 0) 300 curbutton = (number_of_buttons - 1); 301 buttons[curbutton]->Turn_On(); 302 buttons[curbutton]->Flag_To_Redraw(); 303 break; 304 305 case KN_DOWN: 306 buttons[curbutton]->Turn_Off(); 307 buttons[curbutton]->Flag_To_Redraw(); 308 curbutton++; 309 if (curbutton > (number_of_buttons - 1) ) 310 curbutton = 0; 311 buttons[curbutton]->Turn_On(); 312 buttons[curbutton]->Flag_To_Redraw(); 313 break; 314 315 case KN_RETURN: 316 selection = curbutton + BUTTON_MODEMSERIAL; 317 if (!ipx_avail) selection--; 318 pressed = true; 319 break; 320 321 default: 322 break; 323 } 324 325 if (pressed) { 326 // 327 // to make sure the selection is correct in case they used the mouse 328 // 329 buttons[curbutton]->Turn_Off(); 330 buttons[curbutton]->Flag_To_Redraw(); 331 curbutton = selection - BUTTON_MODEMSERIAL; 332 buttons[curbutton]->Turn_On(); 333 // buttons[curbutton]->Flag_To_Redraw(); 334 buttons[curbutton]->IsPressed = true; 335 buttons[curbutton]->Draw_Me(true); 336 337 switch (selection) { 338 case (BUTTON_MODEMSERIAL): 339 340 // 341 // Pop up the modem/serial/com port dialog 342 // 343 retval = Select_Serial_Dialog(); 344 345 if (retval != GAME_NORMAL) { 346 process = false; 347 } else { 348 buttons[curbutton]->IsPressed = false; 349 display = REDRAW_ALL; 350 } 351 break; 352 353 #if (0) 354 case (BUTTON_INTERNET): 355 //#define ONLY_FOR_E3 356 #ifdef ONLY_FOR_E3 357 Call_Back(); 358 Show_Internet_Connection_Progress(); //changed to do nothing 359 Hide_Mouse(); 360 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 361 Blit_Hid_Page_To_Seen_Buff(); 362 Show_Mouse(); 363 Call_Back(); 364 CCMessageBox().Process("Error! - Unable to ping KANE.WESTWOOD.COM"); 365 366 buttons[curbutton]->IsPressed = false; 367 display = REDRAW_ALL; 368 369 370 #endif //ONLY_FOR_E3 371 372 373 #ifdef FORCE_WINSOCK 374 if (Winsock.Init()){ 375 Read_MultiPlayer_Settings (); 376 int result = Choose_Internet_Game(); 377 378 if (!result){ 379 Winsock.Close(); 380 buttons[curbutton]->IsPressed = false; 381 display = REDRAW_ALL; 382 break; 383 } 384 385 result = Get_Internet_Host_Or_Join(); 386 if (result == 1){ 387 Winsock.Close(); 388 buttons[curbutton]->IsPressed = false; 389 display = REDRAW_ALL; 390 break; 391 } 392 Server = !result; 393 394 if (Server){ 395 #if (0) 396 ModemGameToPlay = INTERNET_HOST; 397 Winsock.Start_Server(); 398 #else 399 result = Get_IP_Address(); 400 if (!result){ 401 Winsock.Close(); 402 buttons[curbutton]->IsPressed = false; 403 display = REDRAW_ALL; 404 break; 405 } 406 Winsock.Set_Host_Address(PlanetWestwoodIPAddress); 407 Winsock.Start_Server(); 408 #endif 409 410 }else{ 411 ModemGameToPlay = INTERNET_JOIN; 412 result = Get_IP_Address(); 413 if (!result){ 414 Winsock.Close(); 415 buttons[curbutton]->IsPressed = false; 416 display = REDRAW_ALL; 417 break; 418 } 419 Winsock.Set_Host_Address(PlanetWestwoodIPAddress); 420 Winsock.Start_Client(); 421 } 422 423 //CountDownTimerClass connect_timeout; 424 //connect_timeout.Set(15*60); 425 426 ////Show_Internet_Connection_Progress(); 427 428 if (!Winsock.Get_Connected()){ 429 Winsock.Close(); 430 return(GAME_NORMAL); 431 } 432 433 SerialSettingsType *settings; 434 settings = &SerialDefaults; 435 Init_Null_Modem(settings); 436 if (Server){ 437 if (Com_Scenario_Dialog()){ 438 return (GAME_INTERNET); 439 }else{ 440 Winsock.Close(); 441 return (GAME_NORMAL); 442 } 443 }else{ 444 if (Com_Show_Scenario_Dialog()){ 445 return (GAME_INTERNET); 446 }else{ 447 Winsock.Close(); 448 return (GAME_NORMAL); 449 } 450 } 451 } 452 #endif //FORCE_WINSOCK 453 break; 454 455 #endif //(0) 456 457 case (BUTTON_IPX): 458 retval = GAME_IPX; 459 process = false; 460 break; 461 462 case (BUTTON_CANCEL): 463 retval = GAME_NORMAL; 464 process = false; 465 break; 466 } 467 468 pressed = false; 469 } 470 } 471 return(retval); 472 #endif 473 } 474 475 476 /*********************************************************************************************** 477 * Read_MultiPlayer_Settings -- reads multi-player settings from conquer.ini * 478 * * 479 * INPUT: * 480 * none. * 481 * * 482 * OUTPUT: * 483 * none. * 484 * * 485 * WARNINGS: * 486 * none. * 487 * * 488 * HISTORY: * 489 * 02/14/1995 BR : Created. * 490 *=============================================================================================*/ 491 void Read_MultiPlayer_Settings (void) 492 { 493 //PG_TO_FIX 494 #if (0) 495 char *buffer; // INI staging buffer pointer. 496 char *tbuffer; // Accumulation buffer of trigger IDs. 497 int len; // Length of data in buffer. 498 char *tokenptr; // ptr to token 499 PhoneEntryClass *phone; // a phone book entry 500 char *entry; // a phone book entry 501 char buf[128]; // buffer for parsing INI entry 502 int i; 503 CELL cell; 504 505 /*------------------------------------------------------------------------ 506 Fetch working pointer to the INI staging buffer. Make sure that the buffer 507 is cleared out before proceeding. (Don't use the HidPage for this, since 508 the HidPage may be needed for various uncompressions during the INI 509 parsing.) 510 ------------------------------------------------------------------------*/ 511 buffer = (char *)_ShapeBuffer; 512 memset(buffer, '\0', _ShapeBufferSize); 513 514 /*------------------------------------------------------------------------ 515 Clear the initstring entries 516 ------------------------------------------------------------------------*/ 517 for (i = 0; i < InitStrings.Count(); i++) { 518 delete[] InitStrings[i]; 519 } 520 InitStrings.Clear(); 521 522 /*------------------------------------------------------------------------ 523 Clear the dialing entries 524 ------------------------------------------------------------------------*/ 525 for (i = 0; i < PhoneBook.Count(); i++) { 526 delete PhoneBook[i]; 527 } 528 PhoneBook.Clear(); 529 530 /*------------------------------------------------------------------------ 531 Create filename and read the file. 532 ------------------------------------------------------------------------*/ 533 CCFileClass file ("CONQUER.INI"); 534 if (!file.Is_Available()) { 535 return; 536 } else { 537 file.Read(buffer, _ShapeBufferSize-1); 538 } 539 file.Close(); 540 541 if (!Special.IsFromWChat){ 542 /*------------------------------------------------------------------------ 543 Get the player's last-used Handle 544 ------------------------------------------------------------------------*/ 545 WWGetPrivateProfileString("MultiPlayer", "Handle", "Noname", MPlayerName, 546 sizeof(MPlayerName), buffer); 547 548 /*------------------------------------------------------------------------ 549 Get the player's last-used Color 550 ------------------------------------------------------------------------*/ 551 MPlayerPrefColor = WWGetPrivateProfileInt("MultiPlayer", "Color", 0, buffer); 552 MPlayerHouse = (HousesType)WWGetPrivateProfileInt("MultiPlayer", "Side", 553 HOUSE_GOOD, buffer); 554 CurPhoneIdx = WWGetPrivateProfileInt("MultiPlayer", "PhoneIndex", -1, buffer); 555 }else{ 556 CurPhoneIdx = -1; 557 } 558 559 #if 1 560 TrapCheckHeap = WWGetPrivateProfileInt( "MultiPlayer", "CheckHeap", 0, buffer); 561 #endif 562 563 /*------------------------------------------------------------------------ 564 Read in default serial settings 565 ------------------------------------------------------------------------*/ 566 WWGetPrivateProfileString ("SerialDefaults", "ModemName", "NoName", SerialDefaults.ModemName, MODEM_NAME_MAX, buffer); 567 if (!strcmp ( SerialDefaults.ModemName, "NoName")) { 568 SerialDefaults.ModemName[0] = 0; 569 } 570 WWGetPrivateProfileString ("SerialDefaults", "Port", "0", buf, 5, buffer); 571 sscanf (buf, "%x", &SerialDefaults.Port); 572 SerialDefaults.IRQ = WWGetPrivateProfileInt("SerialDefaults", "IRQ", -1, buffer); 573 SerialDefaults.Baud = WWGetPrivateProfileInt("SerialDefaults", "Baud", -1, buffer); 574 SerialDefaults.Init = WWGetPrivateProfileInt("SerialDefaults", "Init", 0, buffer); 575 SerialDefaults.Compression = WWGetPrivateProfileInt ("SerialDefaults", "Compression", 0, buffer); 576 SerialDefaults.ErrorCorrection = WWGetPrivateProfileInt ("SerialDefaults", "ErrorCorrection", 0, buffer); 577 SerialDefaults.HardwareFlowControl = WWGetPrivateProfileInt ("SerialDefaults", "HardwareFlowControl", 1, buffer); 578 WWGetPrivateProfileString ("SerialDefaults", "DialMethod", "T", 579 buf, 2, buffer); 580 581 582 // find dial method 583 584 for (i = 0; i < DIAL_METHODS; i++) { 585 if ( !strcmpi( buf, DialMethodCheck[ i ]) ) { 586 SerialDefaults.DialMethod = (DialMethodType)i; 587 break; 588 } 589 } 590 591 // if method not found set to touch tone 592 593 if (i == DIAL_METHODS) { 594 SerialDefaults.DialMethod = DIAL_TOUCH_TONE; 595 } 596 597 SerialDefaults.InitStringIndex = 598 WWGetPrivateProfileInt("SerialDefaults", 599 "InitStringIndex", 0, buffer); 600 601 SerialDefaults.CallWaitStringIndex = 602 WWGetPrivateProfileInt("SerialDefaults", 603 "CallWaitStringIndex", CALL_WAIT_CUSTOM, 604 buffer); 605 606 WWGetPrivateProfileString ("SerialDefaults", "CallWaitString", "", 607 SerialDefaults.CallWaitString, CWAITSTRBUF_MAX, buffer); 608 609 if (SerialDefaults.IRQ == 0 || 610 SerialDefaults.Baud == 0) { 611 612 SerialDefaults.Port = 0; 613 SerialDefaults.IRQ = -1; 614 SerialDefaults.Baud = -1; 615 } 616 617 /*------------------------------------------------------------------------ 618 Set 'tbuffer' to point past the actual INI data 619 ------------------------------------------------------------------------*/ 620 len = strlen(buffer) + 2; 621 tbuffer = buffer + len; 622 623 /*------------------------------------------------------------------------ 624 Read all Base-Scenario names into 'tbuffer' 625 ------------------------------------------------------------------------*/ 626 WWGetPrivateProfileString("InitStrings", NULL, NULL, tbuffer, 627 ShapeBufferSize-len, buffer); 628 629 /*------------------------------------------------------------------------ 630 Read in & store each entry 631 ------------------------------------------------------------------------*/ 632 while (*tbuffer != '\0') { 633 entry = new char[ INITSTRBUF_MAX ]; 634 635 entry[0] = 0; 636 637 WWGetPrivateProfileString("InitStrings", tbuffer, NULL, entry, 638 INITSTRBUF_MAX, buffer); 639 640 strupr( entry ); 641 642 InitStrings.Add( entry ); 643 644 tbuffer += strlen(tbuffer) + 1; 645 } 646 647 // if no entries then have at least one 648 649 if ( tbuffer == (buffer + len) ) { 650 entry = new char[ INITSTRBUF_MAX ]; 651 strcpy( entry, "ATZ" ); 652 InitStrings.Add( entry ); 653 SerialDefaults.InitStringIndex = 0; 654 } else { 655 len = strlen(buffer) + 2; 656 } 657 658 /*------------------------------------------------------------------------ 659 Repeat the process for the phonebook 660 ------------------------------------------------------------------------*/ 661 tbuffer = buffer + len; 662 663 /*------------------------------------------------------------------------ 664 Read in all phone book listings. 665 Format: Name=PhoneNum,Port,IRQ,Baud,InitString 666 ------------------------------------------------------------------------*/ 667 668 /*........................................................................ 669 Read the entry names in 670 ........................................................................*/ 671 WWGetPrivateProfileString("PhoneBook", NULL, NULL, tbuffer, 672 ShapeBufferSize-len, buffer); 673 674 while (*tbuffer != '\0') { 675 /*..................................................................... 676 Create a new phone book entry 677 .....................................................................*/ 678 phone = new PhoneEntryClass(); 679 680 /*..................................................................... 681 Read the entire entry in 682 .....................................................................*/ 683 WWGetPrivateProfileString("PhoneBook", tbuffer, NULL, buf, 128, buffer); 684 685 /*..................................................................... 686 Extract name, phone # & serial port settings 687 .....................................................................*/ 688 tokenptr = strtok( buf, "|" ); 689 if (tokenptr) { 690 strcpy( phone->Name, tokenptr ); 691 strupr( phone->Name ); 692 } else { 693 phone->Name[0] = 0; 694 } 695 696 tokenptr = strtok( NULL, "|" ); 697 if (tokenptr) { 698 strcpy( phone->Number, tokenptr ); 699 strupr( phone->Number ); 700 } else { 701 phone->Number[0] = 0; 702 } 703 704 tokenptr = strtok( NULL, "|" ); 705 if (tokenptr) { 706 sscanf( tokenptr, "%x", &phone->Settings.Port ); 707 } else { 708 phone->Settings.Port = 0; 709 } 710 711 tokenptr = strtok( NULL, "|" ); 712 if (tokenptr) { 713 phone->Settings.IRQ = atoi( tokenptr ); 714 } else { 715 phone->Settings.IRQ = -1; 716 } 717 718 tokenptr = strtok( NULL, "|" ); 719 if (tokenptr) { 720 phone->Settings.Baud = atoi( tokenptr ); 721 } else { 722 phone->Settings.Baud = -1; 723 } 724 725 tokenptr = strtok( NULL, "|" ); 726 if (tokenptr) { 727 phone->Settings.Compression = atoi( tokenptr ); 728 } else { 729 phone->Settings.Compression = 0; 730 } 731 732 tokenptr = strtok( NULL, "|" ); 733 if (tokenptr) { 734 phone->Settings.ErrorCorrection = atoi( tokenptr ); 735 } else { 736 phone->Settings.ErrorCorrection = 0; 737 } 738 739 tokenptr = strtok( NULL, "|" ); 740 if (tokenptr) { 741 phone->Settings.HardwareFlowControl = atoi( tokenptr ); 742 } else { 743 phone->Settings.HardwareFlowControl = 1; 744 } 745 746 747 tokenptr = strtok( NULL, "|" ); 748 if (tokenptr) { 749 strcpy( buf, tokenptr ); 750 751 // find dial method 752 753 for (i = 0; i < DIAL_METHODS; i++) { 754 if ( !strcmpi( buf, DialMethodCheck[ i ]) ) { 755 phone->Settings.DialMethod = (DialMethodType)i; 756 break; 757 } 758 } 759 760 // if method not found set to touch tone 761 762 if (i == DIAL_METHODS) { 763 phone->Settings.DialMethod = DIAL_TOUCH_TONE; 764 } 765 } else { 766 phone->Settings.DialMethod = DIAL_TOUCH_TONE; 767 } 768 769 tokenptr = strtok( NULL, "|" ); 770 if (tokenptr) { 771 phone->Settings.InitStringIndex = atoi( tokenptr ); 772 } else { 773 phone->Settings.InitStringIndex = 0; 774 } 775 776 tokenptr = strtok( NULL, "|" ); 777 if (tokenptr) { 778 phone->Settings.CallWaitStringIndex = atoi( tokenptr ); 779 } else { 780 phone->Settings.CallWaitStringIndex = CALL_WAIT_CUSTOM; 781 } 782 783 tokenptr = strtok( NULL, "|" ); 784 if (tokenptr) { 785 strcpy (phone->Settings.CallWaitString, tokenptr); 786 } else { 787 phone->Settings.CallWaitString[0] = 0; 788 } 789 790 /*..................................................................... 791 Add it to our list 792 .....................................................................*/ 793 PhoneBook.Add(phone); 794 795 tbuffer += strlen(tbuffer) + 1; 796 } 797 798 /*------------------------------------------------------------------------ 799 Read special recording playback values, to help find sync bugs 800 ------------------------------------------------------------------------*/ 801 if (PlaybackGame) { 802 TrapFrame = WWGetPrivateProfileInt ("SyncBug","Frame",0x7fffffff, buffer); 803 804 TrapObjType = (RTTIType)WWGetPrivateProfileInt ("SyncBug","Type",RTTI_NONE, buffer); 805 WWGetPrivateProfileString ("SyncBug","Type","NONE",buf,80,buffer); 806 if (!stricmp(buf,"AIRCRAFT")) 807 TrapObjType = RTTI_AIRCRAFT; 808 else if (!stricmp(buf,"ANIM")) 809 TrapObjType = RTTI_ANIM; 810 else if (!stricmp(buf,"BUILDING")) 811 TrapObjType = RTTI_BUILDING; 812 else if (!stricmp(buf,"BULLET")) 813 TrapObjType = RTTI_BULLET; 814 else if (!stricmp(buf,"INFANTRY")) 815 TrapObjType = RTTI_INFANTRY; 816 else if (!stricmp(buf,"UNIT")) 817 TrapObjType = RTTI_UNIT; 818 else { 819 TrapObjType = RTTI_NONE; 820 } 821 822 WWGetPrivateProfileString ("SyncBug","Coord","0",buf,80,buffer); 823 sscanf(buf,"%x",&TrapCoord); 824 825 WWGetPrivateProfileString ("SyncBug","this","0",buf,80,buffer); 826 sscanf(buf,"%x",&TrapThis); 827 828 WWGetPrivateProfileString ("SyncBug","Cell","0",buf,80,buffer); 829 cell = atoi(buf); 830 if (cell) { 831 TrapCell = &(Map[cell]); 832 } 833 } 834 #endif 835 } 836 837 838 /*********************************************************************************************** 839 * Write_MultiPlayer_Settings -- writes multi-player settings to conquer.ini * 840 * * 841 * INPUT: * 842 * none. * 843 * * 844 * OUTPUT: * 845 * none. * 846 * * 847 * WARNINGS: * 848 * none. * 849 * * 850 * HISTORY: * 851 * 02/14/1995 BR : Created. * 852 *=============================================================================================*/ 853 void Write_MultiPlayer_Settings (void) 854 { 855 //PG_TO_FIX 856 #if(0) 857 char * buffer; // INI staging buffer pointer. 858 CCFileClass file; 859 int i; 860 char entrytext[4]; 861 char buf[128]; // buffer for parsing INI entry 862 863 /*------------------------------------------------------------------------ 864 Get a working pointer to the INI staging buffer. Make sure that the buffer 865 starts cleared out of any data. 866 ------------------------------------------------------------------------*/ 867 buffer = (char *)_ShapeBuffer; 868 memset(buffer, '\0', _ShapeBufferSize); 869 870 file.Set_Name("CONQUER.INI"); 871 if (file.Is_Available()) { 872 file.Open(READ); 873 file.Read(buffer, _ShapeBufferSize-1); 874 file.Close(); 875 } 876 877 /*------------------------------------------------------------------------ 878 Save the player's last-used Handle & Color 879 ------------------------------------------------------------------------*/ 880 WWWritePrivateProfileInt("MultiPlayer", "PhoneIndex", CurPhoneIdx, buffer); 881 WWWritePrivateProfileInt ("MultiPlayer", "Color", MPlayerPrefColor, buffer); 882 WWWritePrivateProfileInt ("MultiPlayer", "Side", MPlayerHouse, buffer); 883 WWWritePrivateProfileString("MultiPlayer", "Handle", MPlayerName, buffer); 884 885 /*------------------------------------------------------------------------ 886 Clear all existing SerialDefault entries. 887 ------------------------------------------------------------------------*/ 888 WWWritePrivateProfileString ("SerialDefaults", NULL, NULL, buffer); 889 890 /*------------------------------------------------------------------------ 891 Save default serial settings in opposite order you want to see them 892 ------------------------------------------------------------------------*/ 893 WWWritePrivateProfileString("SerialDefaults", "CallWaitString", 894 SerialDefaults.CallWaitString, buffer); 895 WWWritePrivateProfileInt ("SerialDefaults", "CallWaitStringIndex", SerialDefaults.CallWaitStringIndex, buffer); 896 WWWritePrivateProfileInt ("SerialDefaults", "InitStringIndex", SerialDefaults.InitStringIndex, buffer); 897 WWWritePrivateProfileInt ("SerialDefaults", "Init", SerialDefaults.Init, buffer); 898 WWWritePrivateProfileString("SerialDefaults", "DialMethod", 899 DialMethodCheck[ SerialDefaults.DialMethod ], buffer); 900 WWWritePrivateProfileInt ("SerialDefaults", "Baud", SerialDefaults.Baud, buffer); 901 WWWritePrivateProfileInt ("SerialDefaults", "IRQ", SerialDefaults.IRQ, buffer); 902 sprintf(buf, "%x", SerialDefaults.Port); 903 WWWritePrivateProfileString("SerialDefaults", "Port", buf, buffer); 904 WWWritePrivateProfileString("SerialDefaults", "ModemName", SerialDefaults.ModemName, buffer); 905 WWWritePrivateProfileInt ("SerialDefaults", "Compression", SerialDefaults.Compression , buffer); 906 WWWritePrivateProfileInt ("SerialDefaults", "ErrorCorrection", SerialDefaults.ErrorCorrection, buffer); 907 WWWritePrivateProfileInt ("SerialDefaults", "HardwareFlowControl", SerialDefaults.HardwareFlowControl, buffer); 908 909 /*------------------------------------------------------------------------ 910 Clear all existing InitString entries. 911 ------------------------------------------------------------------------*/ 912 WWWritePrivateProfileString ("InitStrings", NULL, NULL, buffer); 913 914 /*------------------------------------------------------------------------ 915 Save all InitString entries. In descending order so they come out in 916 ascending order. 917 ------------------------------------------------------------------------*/ 918 for (i = (InitStrings.Count() - 1); i >= 0; i--) { 919 sprintf( buf, "%03d", i); 920 WWWritePrivateProfileString ("InitStrings", buf, InitStrings[i], buffer); 921 } 922 923 /*------------------------------------------------------------------------ 924 Clear all existing Phone Book entries. 925 ------------------------------------------------------------------------*/ 926 WWWritePrivateProfileString ("PhoneBook", NULL, NULL, buffer); 927 928 /*------------------------------------------------------------------------ 929 Save all Phone Book entries. 930 Format: Entry=Name,PhoneNum,Port,IRQ,Baud,InitString 931 ------------------------------------------------------------------------*/ 932 for (i = (PhoneBook.Count() - 1); i >= 0; i--) { 933 sprintf(buf,"%s|%s|%x|%d|%d|%d|%d|%d|%s|%d|%d|%s", 934 PhoneBook[i]->Name, 935 PhoneBook[i]->Number, 936 PhoneBook[i]->Settings.Port, 937 PhoneBook[i]->Settings.IRQ, 938 PhoneBook[i]->Settings.Baud, 939 PhoneBook[i]->Settings.Compression, 940 PhoneBook[i]->Settings.ErrorCorrection, 941 PhoneBook[i]->Settings.HardwareFlowControl, 942 DialMethodCheck[ PhoneBook[i]->Settings.DialMethod ], 943 PhoneBook[i]->Settings.InitStringIndex, 944 PhoneBook[i]->Settings.CallWaitStringIndex, 945 PhoneBook[i]->Settings.CallWaitString); 946 sprintf( entrytext, "%03d", i ); 947 WWWritePrivateProfileString ("PhoneBook", entrytext, buf, buffer); 948 } 949 950 /*------------------------------------------------------------------------ 951 Write the INI data out to a file. 952 ------------------------------------------------------------------------*/ 953 file.Open(WRITE); 954 file.Write(buffer,strlen(buffer)); 955 file.Close(); 956 #endif 957 } 958 959 960 /*********************************************************************************************** 961 * Read_Scenario_Descriptions -- reads multi-player scenario #'s # descriptions * 962 * * 963 * INPUT: * 964 * none. * 965 * * 966 * OUTPUT: * 967 * none. * 968 * * 969 * WARNINGS: * 970 * none. * 971 * * 972 * HISTORY: * 973 * 02/14/1995 BR : Created. * 974 *=============================================================================================*/ 975 void Read_Scenario_Descriptions (void) 976 { 977 char *buffer; // INI staging buffer pointer. 978 CCFileClass file; 979 int i; 980 char fname[20]; 981 982 /*------------------------------------------------------------------------ 983 Clear the scenario description lists 984 ------------------------------------------------------------------------*/ 985 MPlayerScenarios.Clear(); 986 MPlayerFilenum.Clear(); 987 988 /*------------------------------------------------------------------------ 989 Loop through all possible scenario numbers; if a file is available, add 990 its number to the FileNum list. 991 ------------------------------------------------------------------------*/ 992 for (i = 0; i < 100; i++) { 993 Set_Scenario_Name(ScenarioName, i, SCEN_PLAYER_MPLAYER, 994 SCEN_DIR_EAST, SCEN_VAR_A); 995 sprintf(fname,"%s.INI",ScenarioName); 996 file.Set_Name (fname); 997 998 if (file.Is_Available()) { 999 MPlayerFilenum.Add(i); 1000 } 1001 } 1002 1003 /*------------------------------------------------------------------------ 1004 Now, for every file in the FileNum list, read in the INI file, and extract 1005 its description. 1006 ------------------------------------------------------------------------*/ 1007 for (i = 0; i < MPlayerFilenum.Count(); i++) { 1008 /*..................................................................... 1009 Fetch working pointer to the INI staging buffer. Make sure that the 1010 buffer is cleared out before proceeding. 1011 .....................................................................*/ 1012 buffer = (char *)_ShapeBuffer; 1013 memset(buffer, '\0', _ShapeBufferSize); 1014 1015 /*..................................................................... 1016 Create filename and read the file. 1017 .....................................................................*/ 1018 Set_Scenario_Name(ScenarioName, MPlayerFilenum[i], SCEN_PLAYER_MPLAYER, 1019 SCEN_DIR_EAST, SCEN_VAR_A); 1020 sprintf(fname,"%s.INI",ScenarioName); 1021 file.Set_Name (fname); 1022 file.Read(buffer, _ShapeBufferSize-1); 1023 file.Close(); 1024 1025 /*..................................................................... 1026 Extract description & add it to the list. 1027 .....................................................................*/ 1028 WWGetPrivateProfileString("Basic", "Name", "Nulls-Ville", 1029 MPlayerDescriptions[i], 40, buffer); 1030 MPlayerScenarios.Add(MPlayerDescriptions[i]); 1031 } 1032 } 1033 1034 1035 /*********************************************************************************************** 1036 * Free_Scenario_Descriptions -- frees memory for the scenario descriptions * 1037 * * 1038 * INPUT: * 1039 * none. * 1040 * * 1041 * OUTPUT: * 1042 * none. * 1043 * * 1044 * WARNINGS: * 1045 * none. * 1046 * * 1047 * HISTORY: * 1048 * 06/05/1995 BRR : Created. * 1049 *=============================================================================================*/ 1050 void Free_Scenario_Descriptions(void) 1051 { 1052 /*------------------------------------------------------------------------ 1053 Clear the scenario descriptions & filenames 1054 ------------------------------------------------------------------------*/ 1055 MPlayerScenarios.Clear(); 1056 MPlayerFilenum.Clear(); 1057 1058 //PG_TO_FIX 1059 #if (0) 1060 int i; 1061 1062 /*------------------------------------------------------------------------ 1063 Clear the initstring entries 1064 ------------------------------------------------------------------------*/ 1065 for (i = 0; i < InitStrings.Count(); i++) { 1066 delete InitStrings[i]; 1067 } 1068 InitStrings.Clear(); 1069 1070 /*------------------------------------------------------------------------ 1071 Clear the dialing entries 1072 ------------------------------------------------------------------------*/ 1073 for (i = 0; i < PhoneBook.Count(); i++) { 1074 delete PhoneBook[i]; 1075 } 1076 PhoneBook.Clear(); 1077 #endif 1078 } 1079 1080 1081 /*************************************************************************** 1082 * Computer_Message -- "sends" a message from the computer * 1083 * * 1084 * INPUT: * 1085 * none. * 1086 * * 1087 * OUTPUT: * 1088 * none. * 1089 * * 1090 * WARNINGS: * 1091 * none. * 1092 * * 1093 * HISTORY: * 1094 * 06/06/1995 BRR : Created. * 1095 *=========================================================================*/ 1096 void Computer_Message(void) 1097 { 1098 int color; 1099 char txt[160]; 1100 HousesType house; 1101 HouseClass *ptr; 1102 1103 /*------------------------------------------------------------------------ 1104 Find the computer house that the message will be from 1105 ------------------------------------------------------------------------*/ 1106 for (house = HOUSE_MULTI1; house < (HOUSE_MULTI1 + MPlayerMax); house++) { 1107 ptr = HouseClass::As_Pointer(house); 1108 1109 if (!ptr || ptr->IsHuman || ptr->IsDefeated) { 1110 continue; 1111 } 1112 1113 /*..................................................................... 1114 Decode this house's color 1115 .....................................................................*/ 1116 color = MPlayerTColors[ptr->RemapColor]; 1117 1118 /*..................................................................... 1119 We now have a 1/4 chance of echoing one of the human players' messages 1120 back. 1121 .....................................................................*/ 1122 if (IRandom(0,3) == 2) { 1123 /*.................................................................. 1124 Now we have a 1/3 chance of garbling the human message. 1125 ..................................................................*/ 1126 if (IRandom(0,2) == 1) { 1127 Garble_Message(LastMessage); 1128 } 1129 1130 /*.................................................................. 1131 Only add the message if there is one to add. 1132 ..................................................................*/ 1133 if (strlen(LastMessage)) { 1134 sprintf(txt,"%s %s",Text_String(TXT_FROM_COMPUTER),LastMessage); 1135 Messages.Add_Message(txt, color, 1136 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0); 1137 } 1138 } else { 1139 sprintf(txt,"%s %s",Text_String(TXT_FROM_COMPUTER), 1140 Text_String(TXT_COMP_MSG1 + IRandom(0,12))); 1141 Messages.Add_Message(txt, color, 1142 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0); 1143 } 1144 1145 return; 1146 } 1147 } 1148 1149 1150 /*************************************************************************** 1151 * Garble_Message -- "garbles" a message * 1152 * * 1153 * INPUT: * 1154 * buf buffer to garble; stores output message * 1155 * * 1156 * OUTPUT: * 1157 * none. * 1158 * * 1159 * WARNINGS: * 1160 * none. * 1161 * * 1162 * HISTORY: * 1163 * 06/06/1995 BRR : Created. * 1164 *=========================================================================*/ 1165 static void Garble_Message(char *buf) 1166 { 1167 char txt[80]; 1168 char punct[20]; // for punctuation 1169 char *p; // working ptr 1170 int numwords; // # words in the phrase 1171 char *words[40]; // ptrs to various words in the phrase 1172 int i,j; 1173 1174 /*------------------------------------------------------------------------ 1175 Pull off any trailing punctuation 1176 ------------------------------------------------------------------------*/ 1177 p = buf + strlen(buf) - 1; 1178 while (1) { 1179 if (p < buf) 1180 break; 1181 if (p[0]=='!' || p[0]=='.' || p[0]=='?') { 1182 p--; 1183 } else { 1184 p++; 1185 break; 1186 } 1187 if (strlen(p) >= (sizeof(punct) - 1) ) { 1188 break; 1189 } 1190 } 1191 strcpy (punct, p); 1192 p[0] = 0; 1193 1194 for (i = 0; i < 40; i++) { 1195 words[i] = NULL; 1196 } 1197 1198 /*------------------------------------------------------------------------ 1199 Copy the original buffer 1200 ------------------------------------------------------------------------*/ 1201 strcpy(txt,buf); 1202 1203 /*------------------------------------------------------------------------ 1204 Split it up into words 1205 ------------------------------------------------------------------------*/ 1206 p = strtok (txt, " "); 1207 numwords = 0; 1208 while (p) { 1209 words[numwords] = p; 1210 numwords++; 1211 p = strtok (NULL, " "); 1212 } 1213 1214 /*------------------------------------------------------------------------ 1215 Now randomly put the words back. Don't use the real random-number 1216 generator, since different machines will have different LastMessage's, 1217 and will go out of sync. 1218 ------------------------------------------------------------------------*/ 1219 buf[0] = 0; 1220 for (i = 0; i < numwords; i++) { 1221 j = Sim_IRandom(0,numwords); 1222 if (words[j] == NULL) { // this word has been used already 1223 i--; 1224 continue; 1225 } 1226 strcat(buf,words[j]); 1227 words[j] = NULL; 1228 if (i < numwords-1) 1229 strcat(buf," "); 1230 } 1231 strcat(buf,punct); 1232 } 1233 1234 1235 /*************************************************************************** 1236 * Surrender_Dialog -- Prompts user for surrendering * 1237 * * 1238 * INPUT: * 1239 * none. * 1240 * * 1241 * OUTPUT: * 1242 * 0 = user cancels, 1 = user wants to surrender. * 1243 * * 1244 * WARNINGS: * 1245 * none. * 1246 * * 1247 * HISTORY: * 1248 * 07/05/1995 BRR : Created. * 1249 *=========================================================================*/ 1250 int Surrender_Dialog(void) 1251 { 1252 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 1253 /*........................................................................ 1254 Dialog & button dimensions 1255 ........................................................................*/ 1256 int d_dialog_w = 170*factor; // dialog width 1257 int d_dialog_h = 53*factor; // dialog height 1258 int d_dialog_x = ((320*factor - d_dialog_w) / 2); // centered x-coord 1259 int d_dialog_y = ((200*factor - d_dialog_h) / 2); // centered y-coord 1260 int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // coord of x-center 1261 1262 int d_txt6_h = 6*factor+1; // ht of 6-pt text 1263 int d_margin = 5*factor; // margin width/height 1264 int d_topmargin = 20*factor; // top margin 1265 1266 int d_ok_w = 45*factor; // ok width 1267 int d_ok_h = 9*factor; // ok height 1268 int d_ok_x = d_dialog_cx - d_ok_w - 5*factor; // ok x 1269 int d_ok_y = d_dialog_y + d_dialog_h - d_ok_h - d_margin; // ok y 1270 1271 int d_cancel_w = 45*factor; // cancel width 1272 int d_cancel_h = 9*factor; // cancel height 1273 int d_cancel_x = d_dialog_cx + 5*factor; // cancel x 1274 int d_cancel_y = d_dialog_y + d_dialog_h - d_cancel_h - d_margin; // cancel y 1275 1276 1277 /*........................................................................ 1278 Button enumerations 1279 ........................................................................*/ 1280 enum { 1281 BUTTON_OK = 100, 1282 BUTTON_CANCEL, 1283 }; 1284 1285 /*........................................................................ 1286 Redraw values: in order from "top" to "bottom" layer of the dialog 1287 ........................................................................*/ 1288 typedef enum { 1289 REDRAW_NONE = 0, 1290 REDRAW_BUTTONS, 1291 REDRAW_BACKGROUND, 1292 REDRAW_ALL = REDRAW_BACKGROUND 1293 } RedrawType; 1294 1295 /*........................................................................ 1296 Dialog variables 1297 ........................................................................*/ 1298 RedrawType display; // requested redraw level 1299 bool process; // loop while true 1300 KeyNumType input; 1301 int retcode; 1302 1303 /*........................................................................ 1304 Buttons 1305 ........................................................................*/ 1306 ControlClass *commands = NULL; // the button list 1307 1308 TextButtonClass okbtn (BUTTON_OK, TXT_OK, 1309 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1310 d_ok_x, d_ok_y, d_ok_w, d_ok_h); 1311 1312 TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, 1313 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1314 d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); 1315 1316 /* 1317 ------------------------------- Initialize ------------------------------- 1318 */ 1319 Set_Logic_Page(SeenBuff); 1320 1321 /* 1322 ......................... Create the button list ......................... 1323 */ 1324 commands = &okbtn; 1325 cancelbtn.Add_Tail(*commands); 1326 1327 /* 1328 -------------------------- Main Processing Loop -------------------------- 1329 */ 1330 display = REDRAW_ALL; 1331 process = true; 1332 while (process) { 1333 1334 /* 1335 ** If we have just received input focus again after running in the background then 1336 ** we need to redraw. 1337 */ 1338 if (AllSurfaces.SurfacesRestored){ 1339 AllSurfaces.SurfacesRestored=FALSE; 1340 display=REDRAW_ALL; 1341 } 1342 1343 /* 1344 ........................ Invoke game callback ......................... 1345 */ 1346 if (Main_Loop()) { 1347 retcode = 0; 1348 process = false; 1349 } 1350 1351 /* 1352 ...................... Refresh display if needed ...................... 1353 */ 1354 if (display) { 1355 1356 /* 1357 ...................... Display the dialog box ...................... 1358 */ 1359 Hide_Mouse(); 1360 if (display >= REDRAW_BACKGROUND) { 1361 Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); 1362 Draw_Caption(TXT_NONE, d_dialog_x, d_dialog_y, d_dialog_w); 1363 1364 /* 1365 ....................... Draw the captions ....................... 1366 */ 1367 Fancy_Text_Print(Text_String(TXT_SURRENDER), 1368 d_dialog_cx, d_dialog_y + d_topmargin, 1369 CC_GREEN, TBLACK, 1370 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 1371 } 1372 1373 /* 1374 ........................ Redraw the buttons ........................ 1375 */ 1376 if (display >= REDRAW_BUTTONS) { 1377 commands->Flag_List_To_Redraw(); 1378 } 1379 Show_Mouse(); 1380 display = REDRAW_NONE; 1381 } 1382 1383 /* 1384 ........................... Get user input ............................ 1385 */ 1386 input = commands->Input(); 1387 1388 /* 1389 ............................ Process input ............................ 1390 */ 1391 switch (input) { 1392 case (KN_RETURN): 1393 case (BUTTON_OK | KN_BUTTON): 1394 retcode = 1; 1395 process = false; 1396 break; 1397 1398 case (KN_ESC): 1399 case (BUTTON_CANCEL | KN_BUTTON): 1400 retcode = 0; 1401 process = false; 1402 break; 1403 1404 default: 1405 break; 1406 } 1407 } 1408 1409 /* 1410 --------------------------- Redraw the display --------------------------- 1411 */ 1412 HiddenPage.Clear(); 1413 Map.Flag_To_Redraw(true); 1414 Map.Render(); 1415 1416 return (retcode); 1417 }