NULLDLG.CPP (261656B)
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\nulldlg.cpv 1.9 16 Oct 1995 16:52:12 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 : NULLDLG.CPP * 24 * * 25 * Programmer : Bill R. Randolph * 26 * * 27 * Start Date : 04/29/95 * 28 * * 29 * Last Update : April 29, 1995 [BRR] * 30 * * 31 *-------------------------------------------------------------------------* 32 * Functions: * 33 * Init_Null_Modem -- Initializes Null Modem communications * 34 * Shutdown_Modem -- Shuts down modem/null-modem communications * 35 * Test_Null_Modem -- Null-Modem test routine * 36 * Reconnect_Null_Modem -- allows user to reconnect * 37 * Destroy_Null_Connection -- destroys the given connection * 38 * Select_Serial_Dialog -- Serial Communications menu dialog * 39 * Com_Settings_Dialog -- Lets user select serial port settings * 40 * Com_Scenario_Dialog -- Serial game scenario selection dialog * 41 * Phone_Dialog -- Lets user edit phone directory & dial * 42 * Build_InitString_Listbox -- [re]builds the initstring entry listbox * 43 * Init_String_Compare -- for qsort * 44 * Build_Phone_Listbox -- [re]builds the phone entry listbox * 45 * Phone_Compare -- for qsort * 46 * Edit_Phone_Dialog -- lets user edit a phone book entry * 47 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 48 #include "function.h" 49 #include "wincomm.h" 50 #include "modemreg.h" 51 #include "tcpip.h" 52 53 //PG_TO_FIX 54 #if (0) 55 ModemRegistryEntryClass *ModemRegistry = NULL; //Ptr to modem registry data 56 57 // 58 // how much time (ticks) to go by before thinking other system 59 // is not responding. 60 // 61 #define PACKET_SENDING_TIMEOUT 1800 62 #define PACKET_CANCEL_TIMEOUT 900 63 64 // 65 // how much time (ticks) to go by before sending another packet 66 // of game options or serial connect. 67 // 68 #define PACKET_RETRANS_TIME 30 69 #define PACKET_REDRAW_TIME 60 70 71 72 static int Reconnect_Null_Modem( void ); 73 static int Com_Settings_Dialog( SerialSettingsType *settings ); 74 static int Phone_Dialog (void); 75 static void Build_Init_String_Listbox (ListClass *list, EditClass *edit, char *buf, int *index); 76 static int Init_String_Compare (const void *p1, const void *p2); 77 static void Build_Phone_Listbox (ListClass *list, EditClass *edit, char *buf); 78 static int Phone_Compare (const void *p1, const void *p2); 79 static int Edit_Phone_Dialog (PhoneEntryClass *phone); 80 static bool Dial_Modem( SerialSettingsType *settings, bool reconnect ); 81 static bool Answer_Modem( SerialSettingsType *settings, bool reconnect ); 82 static void Modem_Echo( char c ); 83 84 void Smart_Printf( char *format, ... ); 85 void Hex_Dump_Data( char *buffer, int length ); 86 void itoh( int i, char *s); 87 88 89 static SerialPacketType SendPacket; 90 static SerialPacketType ReceivePacket; 91 char TheirName[MPLAYER_NAME_MAX]; 92 unsigned char TheirColor; 93 HousesType TheirHouse; 94 unsigned char TheirID; 95 static char DialString[ CWAITSTRBUF_MAX + PhoneEntryClass::PHONE_MAX_NUM - 1 ]; 96 static SerialSettingsType *DialSettings; 97 98 #define SHOW_MONO 0 99 100 /*************************************************************************** 101 * Init_Null_Modem -- Initializes Null Modem communications * 102 * * 103 * INPUT: * 104 * none. * 105 * * 106 * OUTPUT: * 107 * true = OK, false = error * 108 * * 109 * WARNINGS: * 110 * none. * 111 * * 112 * HISTORY: * 113 * 04/29/1995 BRR : Created. * 114 *=========================================================================*/ 115 int Init_Null_Modem( SerialSettingsType *settings ) 116 { 117 118 if ( NullModem.Init( settings->Port, settings->IRQ, 119 settings->ModemName, 120 settings->Baud, 0, 8, 1, 121 settings->HardwareFlowControl ) ) { 122 123 124 return(true); 125 } else { 126 return(false); 127 } 128 } 129 130 131 /*************************************************************************** 132 * Shutdown_Modem -- Shuts down modem/null-modem communications * 133 * * 134 * INPUT: * 135 * none. * 136 * * 137 * OUTPUT: * 138 * none. * 139 * * 140 * WARNINGS: * 141 * none. * 142 * * 143 * HISTORY: * 144 * 04/29/1995 BRR : Created. * 145 *=========================================================================*/ 146 void Shutdown_Modem( void ) 147 { 148 if (!PlaybackGame) { 149 if (GameToPlay == GAME_MODEM) { 150 NullModem.Hangup_Modem(); 151 } 152 } 153 154 // 155 // close port 156 // 157 NullModem.Shutdown(); 158 } 159 160 161 /*************************************************************************** 162 * Modem_Signoff -- sends EXIT event * 163 * * 164 * INPUT: * 165 * none. * 166 * * 167 * OUTPUT: * 168 * none. * 169 * * 170 * WARNINGS: * 171 * none. * 172 * * 173 * HISTORY: * 174 * 08/03/1995 DRD : Created. * 175 *=========================================================================*/ 176 void Modem_Signoff( void ) 177 { 178 unsigned long starttime; 179 EventClass event; 180 181 if (!PlaybackGame) { 182 /*------------------------------------------------------------------------ 183 Send a sign-off packet 184 ------------------------------------------------------------------------*/ 185 event.Type = EventClass::EXIT; 186 NullModem.Send_Message (&event,sizeof(EventClass),0); 187 NullModem.Send_Message (&event,sizeof(EventClass),0); 188 189 starttime = TickCount.Time(); 190 while( (TickCount.Time() - starttime) < 30) { 191 NullModem.Service(); 192 } 193 } 194 } 195 196 197 /*************************************************************************** 198 * Test_Null_Modem -- Null-Modem test routine * 199 * * 200 * INPUT: * 201 * none. * 202 * * 203 * OUTPUT: * 204 * 0 = failure to connect; 1 = I'm the game owner, 2 = I'm not * 205 * * 206 * WARNINGS: * 207 * none. * 208 * * 209 * HISTORY: * 210 * 04/29/1995 BRR : Created. * 211 *=========================================================================*/ 212 int Test_Null_Modem( void ) 213 { 214 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 215 /*........................................................................ 216 Button Enumerations 217 ........................................................................*/ 218 enum { 219 BUTTON_CANCEL = 100, 220 }; 221 222 /*........................................................................ 223 Dialog variables 224 ........................................................................*/ 225 bool process = true; // process while true 226 KeyNumType input; 227 228 int retval; 229 unsigned long starttime; 230 int packetlen; 231 232 int x,y,width,height; // dialog dimensions 233 char buffer[80*3]; 234 235 /*........................................................................ 236 Buttons 237 ........................................................................*/ 238 GadgetClass *commands; // button list 239 240 /* 241 ** Determine the dimensions of the text to be used for the dialog box. 242 ** These dimensions will control how the dialog box looks. 243 */ 244 strcpy( buffer, Text_String( TXT_WAITING_CONNECT ) ); 245 Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); 246 Format_Window_String(buffer, 200*factor, width, height); 247 248 width = MAX(width, 50*factor); 249 width += 40*factor; 250 height += 60*factor; 251 252 x = (320*factor - width) / 2; 253 y = (200*factor - height) / 2; 254 255 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, 256 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 257 x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8 *factor)) >> 1), 258 y + height - (FontHeight + FontYSpacing + 2*factor) - 5*factor); 259 260 /* 261 ------------------------------- Initialize ------------------------------- 262 */ 263 Set_Logic_Page(SeenBuff); 264 process = true; 265 266 /* 267 ............................ Create the list ............................. 268 */ 269 commands = &cancelbtn; 270 271 commands->Flag_List_To_Redraw(); 272 273 /* 274 ............................ Draw the dialog ............................. 275 */ 276 Hide_Mouse(); 277 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 278 Blit_Hid_Page_To_Seen_Buff(); 279 280 Dialog_Box(x, y, width, height); 281 Draw_Caption(TXT_NONE, x, y, width); 282 283 Fancy_Text_Print(buffer, x + 20*factor, y + 25*factor, CC_GREEN, TBLACK, 284 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 285 286 commands->Draw_All(); 287 while (Get_Mouse_State() > 0) Show_Mouse(); 288 289 /* 290 ** This is supposed to be a direct connection so hang up any modem on this port 291 ** just to annoy British Telecom 292 */ 293 /* 294 ** Go into break mode 295 */ 296 SetCommBreak(SerialPort->Get_Port_Handle()); 297 298 /* 299 ** Send hangup command 300 */ 301 SerialPort->Write_To_Serial_Port ((unsigned char*)"ATH\r", strlen("ATH\r")); 302 CountDownTimerClass time; 303 time.Set(2*60); 304 while (time.Time()){} 305 306 /* 307 ** Back out of break mode 308 */ 309 ClearCommBreak(SerialPort->Get_Port_Handle()); 310 311 /* 312 ** Drop DTR as well - just in case the modem still hasnt got the message 313 */ 314 EscapeCommFunction(SerialPort->Get_Port_Handle(), CLRDTR); 315 316 317 /*------------------------------------------------------------------------ 318 Check for a packet. If we detect one, the other system has already been 319 started. Wait 1/2 sec for him to receive my ACK, then exit with success. 320 Note: The initial time must be a little longer than the resend delay. 321 Just in case we just missed the packet. 322 ------------------------------------------------------------------------*/ 323 starttime = TickCount.Time(); 324 while ( TickCount.Time() - starttime < 80) { 325 NullModem.Service(); 326 if ( NullModem.Get_Message( &ReceivePacket, &packetlen ) > 0) { 327 if (ReceivePacket.Command == SERIAL_CONNECT) { 328 //Smart_Printf( "Received SERIAL_CONNECT %d, ID %d \n", ReceivePacket.Seed, ReceivePacket.ID ); 329 starttime = TickCount.Time(); 330 while (TickCount.Time() - starttime < 30) 331 NullModem.Service(); 332 process = false; 333 retval = 2; 334 break; 335 } 336 } 337 } 338 339 /*------------------------------------------------------------------------ 340 Send a packet across. As long as Num_Send() is non-zero, the other system 341 hasn't received it yet. 342 ------------------------------------------------------------------------*/ 343 if (process) { 344 memset (&SendPacket, 0, sizeof(SerialPacketType)); 345 SendPacket.Command = SERIAL_CONNECT; 346 // 347 // put time from start of game for determining the host in case of tie. 348 // 349 SendPacket.Seed = TickCount.Time(); 350 SendPacket.ID = (int) buffer; // address of buffer for more uniqueness. 351 352 //Smart_Printf( "Sending SERIAL_CONNECT %d, ID %d \n", SendPacket.Seed, SendPacket.ID ); 353 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 354 355 starttime = TickCount.Time(); 356 while (TickCount.Time() - starttime < 80) { 357 NullModem.Service(); 358 if (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { 359 if (ReceivePacket.Command == SERIAL_CONNECT) { 360 //Smart_Printf( "Received2 SERIAL_CONNECT %d, ID %d \n", ReceivePacket.Seed, ReceivePacket.ID ); 361 starttime = TickCount.Time(); 362 while (TickCount.Time() - starttime < 30) 363 NullModem.Service(); 364 365 // 366 // whoever has the highest time is the host 367 // 368 if (ReceivePacket.Seed > SendPacket.Seed) { 369 process = false; 370 retval = 2; 371 } else { 372 if (ReceivePacket.Seed == SendPacket.Seed) { 373 if (ReceivePacket.ID > SendPacket.ID) { 374 process = false; 375 retval = 2; 376 } else 377 // 378 // if they are equal then it's a loopback cable or a modem 379 // 380 if (ReceivePacket.ID == SendPacket.ID) { 381 process = false; 382 retval = 3; 383 } 384 } 385 } 386 387 break; 388 } 389 } 390 } 391 } 392 393 starttime = TickCount.Time(); 394 395 /* 396 -------------------------- Main Processing Loop -------------------------- 397 */ 398 while (process) { 399 400 /* 401 ** If we have just received input focus again after running in the background then 402 ** we need to redraw. 403 */ 404 if (AllSurfaces.SurfacesRestored){ 405 AllSurfaces.SurfacesRestored=FALSE; 406 commands->Draw_All(); 407 } 408 409 /* 410 ........................ Invoke game callback ......................... 411 */ 412 Call_Back(); 413 414 /* 415 ........................... Get user input ............................ 416 */ 417 input = commands->Input(); 418 419 /* 420 ............................ Process input ............................ 421 */ 422 switch (input) { 423 case (KN_ESC): 424 case (BUTTON_CANCEL | KN_BUTTON): 425 //Smart_Printf( "Canceled waiting for SERIAL_CONNECT\n" ); 426 retval = 0; 427 process = false; 428 break; 429 430 default: 431 break; 432 } 433 /*..................................................................... 434 Service the connection. 435 .....................................................................*/ 436 NullModem.Service(); 437 if (NullModem.Num_Send() == 0) { 438 //Smart_Printf( "No more messages to send.\n" ); 439 if (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { 440 if (ReceivePacket.Command == SERIAL_CONNECT) { 441 //Smart_Printf( "Received3 SERIAL_CONNECT %d, ID %d \n", ReceivePacket.Seed, ReceivePacket.ID ); 442 starttime = TickCount.Time(); 443 while (TickCount.Time() - starttime < 30) 444 NullModem.Service(); 445 446 // 447 // whoever has the highest time is the host 448 // 449 if (ReceivePacket.Seed > SendPacket.Seed) { 450 process = false; 451 retval = 2; 452 } else { 453 454 if (ReceivePacket.Seed == SendPacket.Seed) { 455 if (ReceivePacket.ID > SendPacket.ID) { 456 process = false; 457 retval = 2; 458 } else { 459 460 // 461 // if they are equal then it's a loopback cable or a modem 462 // 463 if (ReceivePacket.ID == SendPacket.ID) { 464 process = false; 465 retval = 3; 466 } 467 } 468 } 469 } 470 471 } else { 472 retval = 0; 473 process = false; 474 } 475 } else { 476 retval = 1; 477 process = false; 478 } 479 } 480 481 if (TickCount.Time() - starttime > 3600) { // only wait 1 minute 482 retval = 0; 483 process = false; 484 } 485 } /* end of while */ 486 487 return( retval ); 488 489 } 490 491 492 /*************************************************************************** 493 * Reconnect_Modem -- allows user to reconnect * 494 * * 495 * INPUT: * 496 * none. * 497 * * 498 * OUTPUT: * 499 * 0 = failure to connect; 1 = connect OK * 500 * * 501 * WARNINGS: * 502 * none. * 503 * * 504 * HISTORY: * 505 * 04/29/1995 BRR : Created. * 506 *=========================================================================*/ 507 int Reconnect_Modem( void ) 508 { 509 int status; 510 int modemstatus; 511 512 513 switch (ModemGameToPlay) { 514 case (MODEM_NULL_HOST): 515 case (MODEM_NULL_JOIN): 516 status = Reconnect_Null_Modem(); 517 break; 518 519 case (MODEM_DIALER): 520 modemstatus = NullModem.Get_Modem_Status(); 521 if ( (modemstatus & CD_SET) ) { 522 //Smart_Printf( "Dial Modem connection error! Attempting reconnect....\n" ); 523 status = Reconnect_Null_Modem(); 524 } else { 525 status = Dial_Modem( DialSettings, true ); 526 } 527 break; 528 529 case (MODEM_ANSWERER): 530 modemstatus = NullModem.Get_Modem_Status(); 531 if ( (modemstatus & CD_SET) ) { 532 //Smart_Printf( "Answer Modem connection error! Attempting reconnect....\n" ); 533 status = Reconnect_Null_Modem(); 534 } else { 535 status = Answer_Modem( DialSettings, true ); 536 } 537 break; 538 } 539 540 return( status ); 541 } 542 543 544 /*************************************************************************** 545 * Reconnect_Null_Modem -- allows user to reconnect * 546 * * 547 * INPUT: * 548 * none. * 549 * * 550 * OUTPUT: * 551 * 0 = failure to connect; 1 = connect OK * 552 * * 553 * WARNINGS: * 554 * none. * 555 * * 556 * HISTORY: * 557 * 04/29/1995 BRR : Created. * 558 *=========================================================================*/ 559 static int Reconnect_Null_Modem( void ) 560 { 561 /*........................................................................ 562 Button Enumerations 563 ........................................................................*/ 564 enum { 565 BUTTON_CANCEL = 100, 566 }; 567 568 /*........................................................................ 569 Dialog variables 570 ........................................................................*/ 571 bool process = true; // process while true 572 KeyNumType input; 573 574 int retval; 575 unsigned long starttime; 576 unsigned long lastmsgtime; 577 int packetlen; 578 579 int x,y,width,height; // dialog dimensions 580 char buffer[80*3]; 581 582 /*........................................................................ 583 Buttons 584 ........................................................................*/ 585 GadgetClass *commands; // button list 586 587 588 /* 589 ** Determine the dimensions of the text to be used for the dialog box. 590 ** These dimensions will control how the dialog box looks. 591 */ 592 strcpy( buffer, Text_String( TXT_NULL_CONNERR_CHECK_CABLES ) ); 593 Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); 594 Format_Window_String(buffer, 200, width, height); 595 596 width = MAX(width, 50); 597 width += 40; 598 height += 60; 599 600 x = (320 - width) / 2; 601 y = (200 - height) / 2; 602 603 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, 604 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 605 x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8)) >> 1), 606 y + height - (FontHeight + FontYSpacing + 2) - 5); 607 608 /* 609 ------------------------------- Initialize ------------------------------- 610 */ 611 Set_Logic_Page(SeenBuff); 612 process = true; 613 614 /* 615 ............................ Create the list ............................. 616 */ 617 commands = &cancelbtn; 618 619 commands->Flag_List_To_Redraw(); 620 621 /* 622 ............................ Draw the dialog ............................. 623 */ 624 Hide_Mouse(); 625 626 Dialog_Box(x, y, width, height); 627 Draw_Caption(TXT_NONE, x, y, width); 628 629 Fancy_Text_Print(buffer, x + 20, y + 25, CC_GREEN, TBLACK, 630 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 631 632 commands->Draw_All(); 633 Show_Mouse(); 634 635 /* 636 -------------------------- Main Processing Loop -------------------------- 637 */ 638 starttime = lastmsgtime = TickCount.Time(); 639 while (process) { 640 641 /* 642 ** If we have just received input focus again after running in the background then 643 ** we need to redraw. 644 */ 645 if (AllSurfaces.SurfacesRestored){ 646 AllSurfaces.SurfacesRestored=FALSE; 647 commands->Draw_All(); 648 } 649 650 /* 651 ........................ Invoke game callback ......................... 652 */ 653 Call_Back(); 654 655 /* 656 ........................... Get user input ............................ 657 */ 658 input = commands->Input(); 659 660 /* 661 ............................ Process input ............................ 662 */ 663 switch (input) { 664 case (KN_ESC): 665 case (BUTTON_CANCEL | KN_BUTTON): 666 retval = false; 667 process = false; 668 break; 669 670 default: 671 break; 672 } 673 /*..................................................................... 674 Service the connection. 675 .....................................................................*/ 676 NullModem.Service(); 677 678 /*..................................................................... 679 Resend our message if it's time 680 .....................................................................*/ 681 if (TickCount.Time() - starttime > PACKET_RETRANS_TIME) { 682 starttime = TickCount.Time(); 683 SendPacket.Command = SERIAL_CONNECT; 684 SendPacket.ID = MPlayerLocalID; 685 //Smart_Printf( "Sending a SERIAL_CONNECT packet !!!!!!!!\n" ); 686 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 0); 687 } 688 689 /*..................................................................... 690 Check for an incoming message 691 .....................................................................*/ 692 if (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { 693 694 lastmsgtime = TickCount.Time(); 695 696 if (ReceivePacket.Command == SERIAL_CONNECT) { 697 //Smart_Printf( "Received a SERIAL_CONNECT packet !!!!!!!!\n" ); 698 699 // are we getting our own packets back?? 700 701 if (ReceivePacket.ID == MPlayerLocalID) { 702 CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); 703 retval = false; 704 process = false; 705 break; 706 } 707 708 /*............................................................... 709 OK, we got our message; now we have to make certain the other 710 guy gets his, so send him one with an ACK required. 711 ...............................................................*/ 712 SendPacket.Command = SERIAL_CONNECT; 713 SendPacket.ID = MPlayerLocalID; 714 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 715 starttime = TickCount.Time(); 716 while (TickCount.Time() - starttime < 60) 717 NullModem.Service(); 718 retval = true; 719 process = false; 720 } 721 } 722 723 // 724 // timeout if we do not get any packets 725 // 726 if (TickCount.Time() - lastmsgtime > PACKET_CANCEL_TIMEOUT) { 727 retval = false; 728 process = false; 729 } 730 731 } /* end of while */ 732 733 return( retval ); 734 735 } 736 737 738 /*********************************************************************************************** 739 * Destroy_Null_Connection -- destroys the given connection * 740 * * 741 * Call this routine when a connection goes bad, or another player signs off. * 742 * * 743 * INPUT: * 744 * id connection ID to destroy * 745 * error 0 = user signed off; 1 = connection error * 746 * * 747 * OUTPUT: * 748 * none. * 749 * * 750 * WARNINGS: * 751 * none. * 752 * * 753 * HISTORY: * 754 * 07/31/1995 DRD : Created. * 755 *=============================================================================================*/ 756 void Destroy_Null_Connection(int id, int error) 757 { 758 int i,j,idx; 759 HousesType house; 760 HouseClass *housep; 761 char txt[80]; 762 763 764 if ( MPlayerCount == 1 ) { 765 return; 766 } 767 768 // find index for id 769 770 idx = -1; 771 for (i = 0; i < MPlayerCount; i++) { 772 if (MPlayerID[i] == (unsigned char)id) { 773 idx = i; 774 break; 775 } 776 } 777 778 if (idx == -1) { 779 return; 780 } 781 782 /*------------------------------------------------------------------------ 783 Create a message to display to the user 784 ------------------------------------------------------------------------*/ 785 txt[0] = '\0'; 786 if (error == 1) { 787 sprintf(txt,Text_String(TXT_CONNECTION_LOST), MPlayerNames[idx] ); 788 } 789 else if (error == 0) { 790 sprintf(txt,Text_String(TXT_LEFT_GAME), MPlayerNames[idx] ); 791 } 792 else if (error == -1) { 793 NullModem.Delete_Connection(); 794 } 795 796 if (strlen(txt)) { 797 Messages.Add_Message (txt, 798 MPlayerTColors[MPlayerID_To_ColorIndex((unsigned char)id)], 799 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0); 800 Map.Flag_To_Redraw(false); 801 } 802 803 for (i = 0; i < MPlayerCount; i++) { 804 if (MPlayerID[i] == (unsigned char)id) { 805 /*.................................................................. 806 Turn the player's house over to the computer's AI 807 ..................................................................*/ 808 house = MPlayerHouses[i]; 809 housep = HouseClass::As_Pointer (house); 810 housep->IsHuman = false; 811 812 /*.................................................................. 813 Move arrays back by one 814 ..................................................................*/ 815 for (j = i; j < MPlayerCount - 1; j++) { 816 MPlayerID[j] = MPlayerID[j + 1]; 817 MPlayerHouses[j] = MPlayerHouses[j + 1]; 818 strcpy (MPlayerNames[j], MPlayerNames[j+1]); 819 TheirProcessTime[j] = TheirProcessTime[j+1]; 820 } 821 } 822 } 823 824 MPlayerCount--; 825 826 /*------------------------------------------------------------------------ 827 If we're the last player left, tell the user. 828 ------------------------------------------------------------------------*/ 829 if (MPlayerCount == 1) { 830 sprintf(txt,"%s",Text_String(TXT_JUST_YOU_AND_ME)); 831 Messages.Add_Message (txt, 832 MPlayerTColors[MPlayerID_To_ColorIndex((unsigned char)id)], 833 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0); 834 Map.Flag_To_Redraw(false); 835 } 836 837 } /* end of Destroy_Null_Connection */ 838 839 840 /*************************************************************************** 841 * Select_Serial_Dialog -- Serial Communications menu dialog * 842 * * 843 * INPUT: * 844 * none. * 845 * * 846 * OUTPUT: * 847 * GAME_MODEM user wants to play a modem game * 848 * GAME_NULL_MODEM user wants to play a null-modem game * 849 * GAME_NORMAL user hit Cancel * 850 * * 851 * WARNINGS: * 852 * none. * 853 * * 854 * HISTORY: * 855 * 04/29/1995 BRR : Created. * 856 *=========================================================================*/ 857 GameType Select_Serial_Dialog( void ) 858 { 859 int rc; 860 // int value, i; 861 int com = -1, baud = -1; 862 int error = 0; 863 864 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 865 /*........................................................................ 866 Dialog & button dimensions 867 ........................................................................*/ 868 int d_dialog_w = 160 *factor; // dialog width 869 int d_dialog_h = 94 *factor; // dialog height 870 int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord 871 // D_DIALOG_Y = ((200 - D_DIALOG_H) / 2), // dialog y-coord 872 int d_dialog_y = ((136*factor - d_dialog_h) / 2); // dialog y-coord 873 int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord 874 875 int d_txt6_h = 11*factor; // ht of 6-pt text 876 int d_margin = 7; // margin width/height 877 878 int d_dial_w = 90 *factor; 879 int d_dial_h = 9 *factor; 880 int d_dial_x = d_dialog_cx - d_dial_w / 2; 881 int d_dial_y = d_dialog_y + d_margin + d_txt6_h + d_margin; 882 883 int d_answer_w = 90 *factor; 884 int d_answer_h = 9 *factor; 885 int d_answer_x = d_dialog_cx - d_answer_w / 2; 886 int d_answer_y = d_dial_y + d_dial_h + 2; 887 888 int d_nullmodem_w = 90 *factor; 889 int d_nullmodem_h = 9 *factor; 890 int d_nullmodem_x = d_dialog_cx - d_nullmodem_w / 2; 891 int d_nullmodem_y = d_answer_y + d_answer_h + 2; 892 893 int d_settings_w = 90 *factor; 894 int d_settings_h = 9 *factor; 895 int d_settings_x = d_dialog_cx - d_settings_w / 2; 896 int d_settings_y = d_nullmodem_y + d_nullmodem_h + 2; 897 898 #if (GERMAN | FRENCH) 899 int d_cancel_w = 50 *factor; 900 #else 901 int d_cancel_w = 40 *factor; 902 #endif 903 int d_cancel_h = 9 *factor; 904 int d_cancel_x = d_dialog_cx - d_cancel_w / 2; 905 int d_cancel_y = d_settings_y + d_settings_h + d_margin; 906 907 /*........................................................................ 908 Button Enumerations 909 ........................................................................*/ 910 enum { 911 BUTTON_DIAL = 100, 912 BUTTON_ANSWER, 913 BUTTON_NULLMODEM, 914 BUTTON_SETTINGS, 915 BUTTON_CANCEL, 916 917 NUM_OF_BUTTONS = 5, 918 }; 919 920 /*........................................................................ 921 Redraw values: in order from "top" to "bottom" layer of the dialog 922 ........................................................................*/ 923 typedef enum { 924 REDRAW_NONE = 0, 925 REDRAW_BUTTONS, 926 REDRAW_BACKGROUND, 927 REDRAW_ALL = REDRAW_BACKGROUND 928 } RedrawType; 929 930 /*........................................................................ 931 Dialog variables 932 ........................................................................*/ 933 RedrawType display = REDRAW_ALL; // redraw level 934 bool process = true; // process while true 935 KeyNumType input; 936 char namebuf[MPLAYER_NAME_MAX] = {0}; // buffer for player's name 937 int tabs[] = {77 * factor}; // tabs for player list box 938 GameType retval; // return value 939 940 int selection; 941 bool pressed; 942 int curbutton; 943 TextButtonClass *buttons[NUM_OF_BUTTONS]; 944 945 SerialSettingsType *settings; 946 bool selectsettings = false; 947 948 949 /*........................................................................ 950 Buttons 951 ........................................................................*/ 952 GadgetClass *commands; // button list 953 954 TextButtonClass dialbtn(BUTTON_DIAL, TXT_DIAL_MODEM, 955 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 956 d_dial_x, d_dial_y, d_dial_w, d_dial_h); 957 958 TextButtonClass answerbtn(BUTTON_ANSWER, TXT_ANSWER_MODEM, 959 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 960 d_answer_x, d_answer_y, d_answer_w, d_answer_h); 961 962 TextButtonClass nullmodembtn(BUTTON_NULLMODEM, TXT_NULL_MODEM, 963 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 964 d_nullmodem_x, d_nullmodem_y, d_nullmodem_w, d_nullmodem_h); 965 966 TextButtonClass settingsbtn(BUTTON_SETTINGS, TXT_SETTINGS, 967 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 968 d_settings_x, d_settings_y, d_settings_w, d_settings_h); 969 970 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, 971 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 972 //#if (GERMAN | FRENCH) 973 // d_cancel_x, d_cancel_y); 974 //#else 975 d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); 976 //#endif 977 978 /* 979 ------------------------------- Initialize ------------------------------- 980 */ 981 Set_Logic_Page(SeenBuff); 982 983 /*........................................................................ 984 Read the CC.INI file to extract default serial settings, scenario numbers 985 & descriptions, and the phone list. 986 ........................................................................*/ 987 Read_MultiPlayer_Settings (); 988 989 if (SerialDefaults.Port == 0 || 990 SerialDefaults.IRQ == -1 || 991 SerialDefaults.Baud == -1) { 992 selectsettings = true; 993 } else { 994 if ( NullModem.Detect_Port( &SerialDefaults ) != PORT_VALID ) { 995 selectsettings = true; 996 } 997 } 998 999 /* 1000 ............................ Create the list ............................. 1001 */ 1002 commands = &dialbtn; 1003 answerbtn.Add_Tail(*commands); 1004 nullmodembtn.Add_Tail(*commands); 1005 settingsbtn.Add_Tail(*commands); 1006 cancelbtn.Add_Tail(*commands); 1007 1008 /* 1009 ......................... Fill array of button ptrs ...................... 1010 */ 1011 curbutton = 0; 1012 buttons[0] = &dialbtn; 1013 buttons[1] = &answerbtn; 1014 buttons[2] = &nullmodembtn; 1015 buttons[3] = &settingsbtn; 1016 buttons[4] = &cancelbtn; 1017 buttons[curbutton]->Turn_On(); 1018 1019 Keyboard::Clear(); 1020 1021 Fancy_Text_Print(TXT_NONE, 0, 0, CC_GREEN, TBLACK, 1022 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 1023 1024 Debug_Smart_Print = true; 1025 1026 MPlayerLocalID = 0xff; // set to invalid value 1027 1028 /* 1029 -------------------------- Main Processing Loop -------------------------- 1030 */ 1031 display = REDRAW_ALL; 1032 process = true; 1033 pressed = false; 1034 while (process) { 1035 1036 /* 1037 ** If we have just received input focus again after running in the background then 1038 ** we need to redraw. 1039 */ 1040 if (AllSurfaces.SurfacesRestored){ 1041 AllSurfaces.SurfacesRestored=FALSE; 1042 display=REDRAW_ALL; 1043 } 1044 1045 /* 1046 ........................ Invoke game callback ......................... 1047 */ 1048 Call_Back(); 1049 1050 /* 1051 ...................... Refresh display if needed ...................... 1052 */ 1053 if (display) { 1054 Hide_Mouse(); 1055 if (display >= REDRAW_BACKGROUND) { 1056 /* 1057 ..................... Refresh the backdrop ...................... 1058 */ 1059 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 1060 Blit_Hid_Page_To_Seen_Buff(); 1061 /* 1062 ..................... Draw the background ....................... 1063 */ 1064 Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); 1065 1066 /* 1067 ..................... Redraw the buttons ....................... 1068 */ 1069 commands->Draw_All(); 1070 /* 1071 ....................... Draw the labels ......................... 1072 */ 1073 Draw_Caption (TXT_SELECT_SERIAL_GAME, d_dialog_x, d_dialog_y, d_dialog_w); 1074 } 1075 Show_Mouse(); 1076 display = REDRAW_NONE; 1077 } 1078 1079 /* 1080 ........................... Get user input ............................ 1081 */ 1082 input = commands->Input(); 1083 1084 /* 1085 ............................ Process input ............................ 1086 */ 1087 switch (input) { 1088 case (BUTTON_DIAL | KN_BUTTON): 1089 selection = BUTTON_DIAL; 1090 pressed = true; 1091 break; 1092 1093 case (BUTTON_ANSWER | KN_BUTTON): 1094 selection = BUTTON_ANSWER; 1095 pressed = true; 1096 break; 1097 1098 case (BUTTON_NULLMODEM | KN_BUTTON): 1099 selection = BUTTON_NULLMODEM; 1100 pressed = true; 1101 break; 1102 1103 case (BUTTON_SETTINGS | KN_BUTTON): 1104 selection = BUTTON_SETTINGS; 1105 pressed = true; 1106 break; 1107 1108 case (KN_ESC): 1109 case (BUTTON_CANCEL | KN_BUTTON): 1110 selection = BUTTON_CANCEL; 1111 pressed = true; 1112 break; 1113 1114 case (KN_UP): 1115 buttons[curbutton]->Turn_Off(); 1116 buttons[curbutton]->Flag_To_Redraw(); 1117 curbutton--; 1118 if (curbutton < 0) 1119 curbutton = (NUM_OF_BUTTONS - 1); 1120 buttons[curbutton]->Turn_On(); 1121 buttons[curbutton]->Flag_To_Redraw(); 1122 break; 1123 1124 case (KN_DOWN): 1125 buttons[curbutton]->Turn_Off(); 1126 buttons[curbutton]->Flag_To_Redraw(); 1127 curbutton++; 1128 if (curbutton > (NUM_OF_BUTTONS - 1) ) 1129 curbutton = 0; 1130 buttons[curbutton]->Turn_On(); 1131 buttons[curbutton]->Flag_To_Redraw(); 1132 break; 1133 1134 case (KN_RETURN): 1135 selection = curbutton + BUTTON_DIAL; 1136 pressed = true; 1137 break; 1138 1139 default: 1140 break; 1141 } 1142 1143 if (pressed) { 1144 // 1145 // to make sure the selection is correct in case they used the mouse 1146 // 1147 buttons[curbutton]->Turn_Off(); 1148 buttons[curbutton]->Flag_To_Redraw(); 1149 curbutton = selection - BUTTON_DIAL; 1150 buttons[curbutton]->Turn_On(); 1151 buttons[curbutton]->IsPressed = true; 1152 buttons[curbutton]->Draw_Me(true); 1153 1154 switch (selection) { 1155 case (BUTTON_DIAL): 1156 1157 if (selectsettings) { 1158 CCMessageBox().Process(TXT_SELECT_SETTINGS); 1159 } 1160 1161 /* 1162 ** Remote-connect 1163 */ 1164 else if ( Phone_Dialog() ) { 1165 if (PhoneBook[CurPhoneIdx]->Settings.Port == 0) { 1166 settings = &SerialDefaults; 1167 } else { 1168 settings = &(PhoneBook[CurPhoneIdx]->Settings); 1169 } 1170 1171 if (SerialPort){ 1172 delete SerialPort; 1173 } 1174 SerialPort = new WinModemClass; 1175 1176 if ( Init_Null_Modem( settings ) ) { 1177 1178 if (settings->CallWaitStringIndex == CALL_WAIT_CUSTOM) { 1179 strcpy( DialString, settings->CallWaitString ); 1180 } else { 1181 strcpy( DialString, 1182 CallWaitStrings[ settings->CallWaitStringIndex ] ); 1183 } 1184 strcat( DialString, PhoneBook[ CurPhoneIdx ]->Number ); 1185 1186 if ( Dial_Modem( settings, false ) ) { 1187 ModemGameToPlay = MODEM_DIALER; 1188 if ( Com_Scenario_Dialog() ) { 1189 retval = GAME_MODEM; 1190 process = false; 1191 } 1192 } 1193 1194 if (process) { // restore to default 1195 NullModem.Change_IRQ_Priority( 0 ); 1196 } 1197 } else { 1198 CCMessageBox().Process(TXT_SELECT_SETTINGS); 1199 } 1200 } 1201 1202 if (process) { 1203 buttons[curbutton]->IsPressed = false; 1204 buttons[curbutton]->Flag_To_Redraw(); 1205 } 1206 1207 display = REDRAW_ALL; 1208 break; 1209 1210 case (BUTTON_ANSWER): 1211 1212 if (selectsettings) { 1213 CCMessageBox().Process(TXT_SELECT_SETTINGS); 1214 } else { 1215 /* 1216 ** Remote-connect 1217 */ 1218 settings = &SerialDefaults; 1219 1220 if (SerialPort){ 1221 delete SerialPort; 1222 } 1223 SerialPort = new WinModemClass; 1224 1225 if ( Init_Null_Modem( settings ) ) { 1226 if ( Answer_Modem( settings, false ) ) { 1227 ModemGameToPlay = MODEM_ANSWERER; 1228 if ( Com_Show_Scenario_Dialog() ) { 1229 retval = GAME_MODEM; 1230 process = false; 1231 } 1232 } 1233 1234 if (process) { // restore to default 1235 NullModem.Change_IRQ_Priority( 0 ); 1236 } 1237 } else { 1238 CCMessageBox().Process(TXT_SELECT_SETTINGS); 1239 } 1240 } 1241 1242 if (process) { 1243 buttons[curbutton]->IsPressed = false; 1244 buttons[curbutton]->Flag_To_Redraw(); 1245 } 1246 1247 display = REDRAW_ALL; 1248 break; 1249 1250 case (BUTTON_NULLMODEM): 1251 1252 if (selectsettings) { 1253 CCMessageBox().Process(TXT_SELECT_SETTINGS); 1254 } else { 1255 /* 1256 ** Otherwise, remote-connect; save values if we're recording 1257 */ 1258 1259 if (SerialPort){ 1260 delete SerialPort; 1261 } 1262 SerialPort = new WinNullModemClass; 1263 1264 if ( Init_Null_Modem( &SerialDefaults ) ) { 1265 rc = Test_Null_Modem(); 1266 switch (rc) { 1267 case (1): 1268 ModemGameToPlay = MODEM_NULL_HOST; 1269 if ( Com_Scenario_Dialog() ) { 1270 retval = GAME_NULL_MODEM; 1271 process = false; 1272 } 1273 break; 1274 1275 case (2): 1276 ModemGameToPlay = MODEM_NULL_JOIN; 1277 if ( Com_Show_Scenario_Dialog() ) { 1278 retval = GAME_NULL_MODEM; 1279 process = false; 1280 } 1281 break; 1282 1283 case (3): 1284 CCMessageBox().Process( TXT_MODEM_OR_LOOPBACK ); 1285 break; 1286 } 1287 1288 if (process) { // restore to default 1289 NullModem.Change_IRQ_Priority( 0 ); 1290 } 1291 } else { 1292 CCMessageBox().Process(TXT_SELECT_SETTINGS); 1293 } 1294 } 1295 1296 if (process) { 1297 buttons[curbutton]->IsPressed = false; 1298 buttons[curbutton]->Flag_To_Redraw(); 1299 } 1300 1301 display = REDRAW_ALL; 1302 break; 1303 1304 case (BUTTON_SETTINGS): 1305 if ( Com_Settings_Dialog( &SerialDefaults ) ) { 1306 Write_MultiPlayer_Settings (); 1307 1308 selectsettings = true; 1309 1310 if (SerialDefaults.Port != 0 && 1311 SerialDefaults.IRQ != -1 && 1312 SerialDefaults.Baud != -1) { 1313 if ( NullModem.Detect_Port( &SerialDefaults ) == PORT_VALID) { 1314 selectsettings = false; 1315 } 1316 } 1317 } 1318 1319 buttons[curbutton]->IsPressed = false; 1320 buttons[curbutton]->Flag_To_Redraw(); 1321 display = REDRAW_ALL; 1322 break; 1323 1324 case (BUTTON_CANCEL): 1325 retval = GAME_NORMAL; 1326 process = false; 1327 break; 1328 } 1329 1330 pressed = false; 1331 } 1332 } /* end of while */ 1333 1334 #if 0 1335 if (retval == GAME_NORMAL) { 1336 Debug_Smart_Print = false; 1337 } 1338 #endif 1339 1340 Debug_Smart_Print = false; 1341 1342 return( retval ); 1343 } 1344 1345 1346 1347 1348 /*********************************************************************************************** 1349 * Advanced_Modem_Settings -- Allows to user to set additional modem settings * 1350 * * 1351 * * 1352 * * 1353 * INPUT: current settings * 1354 * * 1355 * OUTPUT: modified settings * 1356 * * 1357 * WARNINGS: None * 1358 * * 1359 * HISTORY: * 1360 * 12/16/96 2:29PM ST : Created * 1361 *=============================================================================================*/ 1362 Advanced_Modem_Settings (SerialSettingsType *settings) 1363 { 1364 1365 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 1366 /*........................................................................ 1367 Dialog & button dimensions 1368 ........................................................................*/ 1369 int d_dialog_w = 340; // dialog width 1370 int d_dialog_h = 170; // dialog height 1371 int d_dialog_x = 320 - d_dialog_w/2; // dialog x-coord 1372 int d_dialog_y = 200 - d_dialog_h/ 2; // dialog y-coord 1373 1374 1375 int d_compression_w = 50; 1376 int d_compression_h = 18; 1377 int d_compression_x = d_dialog_x + d_dialog_w/2 +40; 1378 int d_compression_y = d_dialog_y + 30; 1379 1380 int d_errorcorrection_w = 50; 1381 int d_errorcorrection_h = 18; 1382 int d_errorcorrection_x = d_dialog_x + d_dialog_w/2 +40; 1383 int d_errorcorrection_y = d_dialog_y + 52; 1384 1385 int d_hardwareflowcontrol_w = 50; 1386 int d_hardwareflowcontrol_h = 18; 1387 int d_hardwareflowcontrol_x = d_dialog_x + d_dialog_w/2 +40; 1388 int d_hardwareflowcontrol_y = d_dialog_y + 74; 1389 1390 int d_default_w = 100; 1391 int d_default_h = 18; 1392 int d_default_x = d_dialog_x + d_dialog_w / 2 - d_default_w / 2; 1393 int d_default_y = d_dialog_y + 110; 1394 1395 int d_ok_w = 100; 1396 int d_ok_h = 18; 1397 int d_ok_x = d_dialog_x + d_dialog_w/2 - d_ok_w / 2; 1398 int d_ok_y = d_dialog_y + d_dialog_h - 24; 1399 1400 enum { 1401 BUTTON_COMPRESSION = 100, 1402 BUTTON_ERROR_CORRECTION, 1403 BUTTON_HARDWARE_FLOW_CONTROL, 1404 BUTTON_DEFAULT, 1405 BUTTON_OK, 1406 }; 1407 1408 typedef enum { 1409 REDRAW_NONE = 0, 1410 REDRAW_BUTTONS, 1411 REDRAW_BACKGROUND, 1412 REDRAW_ALL = REDRAW_BACKGROUND, 1413 } RedrawType; 1414 1415 /* 1416 ** Yes/No strings 1417 */ 1418 char compress_text [16]; 1419 char correction_text [16]; 1420 char flowcontrol_text[16]; 1421 1422 1423 /* 1424 ** Initialise the button text 1425 */ 1426 strcpy (compress_text, settings->Compression ? Text_String (TXT_ON) : Text_String (TXT_OFF) ); 1427 strcpy (correction_text, settings->ErrorCorrection ? 1428 Text_String (TXT_ON) : Text_String (TXT_OFF) ); 1429 strcpy (flowcontrol_text, settings->HardwareFlowControl ? 1430 Text_String (TXT_ON) : Text_String (TXT_OFF) ); 1431 1432 1433 /* 1434 ** Create the buttons 1435 */ 1436 TextButtonClass compressionbutton(BUTTON_COMPRESSION, compress_text, 1437 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1438 d_compression_x, d_compression_y, d_compression_w, d_compression_h); 1439 1440 TextButtonClass errorcorrectionbutton(BUTTON_ERROR_CORRECTION, correction_text, 1441 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1442 d_errorcorrection_x, d_errorcorrection_y, d_errorcorrection_w, d_errorcorrection_h); 1443 1444 TextButtonClass hardwareflowcontrolbutton(BUTTON_HARDWARE_FLOW_CONTROL, flowcontrol_text, 1445 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1446 d_hardwareflowcontrol_x, d_hardwareflowcontrol_y, d_hardwareflowcontrol_w, d_hardwareflowcontrol_h); 1447 1448 TextButtonClass defaultbutton(BUTTON_DEFAULT, TXT_DEFAULT, 1449 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1450 d_default_x, d_default_y, d_default_w, d_default_h); 1451 1452 TextButtonClass okbutton(BUTTON_OK, TXT_OK, 1453 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1454 d_ok_x, d_ok_y, d_ok_w, d_ok_h); 1455 1456 1457 /* 1458 ** Misc. variables. 1459 */ 1460 RedrawType display = REDRAW_ALL; // redraw level 1461 BOOL process = true; // process while true 1462 KeyNumType input; 1463 GadgetClass *commands; // button list 1464 1465 1466 commands = &okbutton; 1467 defaultbutton.Add_Tail(*commands); 1468 compressionbutton.Add_Tail(*commands); 1469 errorcorrectionbutton.Add_Tail(*commands); 1470 hardwareflowcontrolbutton.Add_Tail(*commands); 1471 1472 1473 /* 1474 ** Main process loop 1475 */ 1476 while (process) { 1477 1478 /* 1479 ** If we have just received input focus again after running in the background then 1480 ** we need to redraw. 1481 */ 1482 if (AllSurfaces.SurfacesRestored){ 1483 AllSurfaces.SurfacesRestored=FALSE; 1484 display=REDRAW_ALL; 1485 } 1486 1487 /* 1488 ........................ Invoke game callback ......................... 1489 */ 1490 Call_Back(); 1491 1492 /* 1493 ...................... Refresh display if needed ...................... 1494 */ 1495 if (display) { 1496 Hide_Mouse(); 1497 /* 1498 .................. Redraw backgound & dialog box ................... 1499 */ 1500 if (display >= REDRAW_BACKGROUND) { 1501 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 1502 Blit_Hid_Page_To_Seen_Buff(); 1503 Set_Palette(Palette); 1504 1505 Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); 1506 1507 // init font variables 1508 1509 Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, 1510 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 1511 1512 /*............................................................... 1513 Dialog & Field labels 1514 ...............................................................*/ 1515 Draw_Caption (TXT_MODEM_INITIALISATION, d_dialog_x, d_dialog_y, d_dialog_w); 1516 1517 Fancy_Text_Print( TXT_DATA_COMPRESSION, 1518 d_compression_x - 26, d_compression_y + 2, 1519 CC_GREEN, TBLACK, 1520 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 1521 1522 Fancy_Text_Print( TXT_ERROR_CORRECTION, 1523 d_errorcorrection_x - 26, d_errorcorrection_y +2, 1524 CC_GREEN, TBLACK, 1525 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 1526 1527 Fancy_Text_Print( TXT_HARDWARE_FLOW_CONTROL, 1528 d_hardwareflowcontrol_x -26, d_hardwareflowcontrol_y +2, 1529 CC_GREEN, TBLACK, 1530 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 1531 } 1532 1533 /* 1534 .......................... Redraw buttons .......................... 1535 */ 1536 if (display >= REDRAW_BUTTONS) { 1537 compressionbutton.Flag_To_Redraw(); 1538 errorcorrectionbutton.Flag_To_Redraw(); 1539 hardwareflowcontrolbutton.Flag_To_Redraw(); 1540 } 1541 1542 Show_Mouse(); 1543 display = REDRAW_NONE; 1544 } 1545 1546 /* 1547 ........................... Get user input ............................ 1548 */ 1549 input = commands->Input(); 1550 1551 /* 1552 ---------------------------- Process input ---------------------------- 1553 */ 1554 switch (input) { 1555 case (BUTTON_COMPRESSION | KN_BUTTON): 1556 settings->Compression = settings->Compression ^ 1; 1557 strcpy (compress_text, settings->Compression ? 1558 Text_String (TXT_ON) : Text_String (TXT_OFF) ); 1559 break; 1560 1561 case (BUTTON_ERROR_CORRECTION | KN_BUTTON): 1562 settings->ErrorCorrection = settings->ErrorCorrection ^ 1; 1563 strcpy (correction_text, settings->ErrorCorrection ? 1564 Text_String (TXT_ON) : Text_String (TXT_OFF) ); 1565 break; 1566 1567 case (BUTTON_HARDWARE_FLOW_CONTROL | KN_BUTTON): 1568 settings->HardwareFlowControl = settings->HardwareFlowControl ^ 1; 1569 strcpy (flowcontrol_text, settings->HardwareFlowControl ? 1570 Text_String (TXT_ON) : Text_String (TXT_OFF) ); 1571 break; 1572 1573 case (BUTTON_DEFAULT | KN_BUTTON): 1574 settings->Compression = false; 1575 settings->ErrorCorrection = false; 1576 settings->HardwareFlowControl = true; 1577 1578 strcpy (compress_text, settings->Compression ? 1579 Text_String (TXT_ON) : Text_String (TXT_OFF) ); 1580 1581 strcpy (correction_text, settings->ErrorCorrection ? 1582 Text_String (TXT_ON) : Text_String (TXT_OFF) ); 1583 1584 strcpy (flowcontrol_text, settings->HardwareFlowControl ? 1585 Text_String (TXT_ON) : Text_String (TXT_OFF) ); 1586 1587 if (display < REDRAW_BUTTONS) display = REDRAW_BUTTONS; 1588 break; 1589 1590 case (BUTTON_OK | KN_BUTTON): 1591 process = false; 1592 break; 1593 } 1594 } 1595 } 1596 1597 1598 1599 1600 /*************************************************************************** 1601 * Com_Settings_Dialog -- Lets user select serial port settings * 1602 * * 1603 * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * 1604 * ³ Settings ³ * 1605 * ³ ³ * 1606 * ³ Port:____ IRQ:__ Baud:______ ³ * 1607 * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ * 1608 * ³ ³ ³ ³ ³ ³ ³ ³ * 1609 * ³ ³ ³ ³ ³ ³ ³ ³ * 1610 * ³ ³ ³ ³ ³ ³ ³ ³ * 1611 * ³ ³ ³ ³ ³ ³ ³ ³ * 1612 * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * 1613 * ³ ³ * 1614 * ³ Initialization: [Add] [Delete] ³ * 1615 * ³ _____________________________ ³ * 1616 * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ * 1617 * ³ ³ ³ ³ * 1618 * ³ ³ ³ ³ * 1619 * ³ ³ ³ ³ * 1620 * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * 1621 * ³ ³ * 1622 * ³ Call Waiting: ³ * 1623 * ³ _______________ ³ * 1624 * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ [Tone Dialing] ³ * 1625 * ³ ³ ³ ³ * 1626 * ³ ³ ³ [Pulse Dialing] ³ * 1627 * ³ ³ ³ ³ * 1628 * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * 1629 * ³ ³ * 1630 * ³ [OK] [Cancel] ³ * 1631 * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * 1632 * * 1633 * INPUT: * 1634 * settings ptr to SerialSettingsType structure * 1635 * * 1636 * OUTPUT: * 1637 * true = OK, false = Cancel * 1638 * * 1639 * WARNINGS: * 1640 * none. * 1641 * * 1642 * HISTORY: * 1643 * 04/29/1995 BRR : Created. * 1644 *=========================================================================*/ 1645 static int Com_Settings_Dialog( SerialSettingsType *settings ) 1646 { 1647 /* ###Change collision detected! C:\PROJECTS\CODE\NULLDLG.CPP... */ 1648 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 1649 /*........................................................................ 1650 Dialog & button dimensions 1651 ........................................................................*/ 1652 int d_dialog_w = 301 *factor; // dialog width 1653 int d_dialog_h = 200 *factor; // dialog height 1654 int d_dialog_x = ((320 *factor - d_dialog_w) / 2); // dialog x-coord 1655 int d_dialog_y = ((200 *factor - d_dialog_h) / 2); // dialog y-coord 1656 int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord 1657 1658 int d_txt6_h = 6 *factor +1; // ht of 6-pt text 1659 int d_margin = 5 *factor; // margin width/height 1660 1661 #ifdef EDIT_IRQ 1662 int d_portlist_w = 80 *factor; 1663 int d_portlist_h = 35 *factor; 1664 int d_portlist_x = d_dialog_x + (d_dialog_w / 6) - (d_portlist_w / 2); 1665 int d_portlist_y = d_dialog_y + ((d_margin + d_txt6_h) * 2) + d_margin + 10 *factor; 1666 1667 int d_port_w = ((PORTBUF_MAX - 1) * 6 *factor) + 4 *factor; 1668 int d_port_h = 9 *factor; 1669 int d_port_x = d_portlist_x + 31 *factor; 1670 int d_port_y = d_portlist_y - d_margin - d_txt6_h; 1671 1672 1673 int d_irqlist_w = 80 *factor; 1674 int d_irqlist_h = 35 *factor; 1675 int d_irqlist_x = d_dialog_x + (d_dialog_w / 2) - (d_irqlist_w / 2); 1676 int d_irqlist_y = d_portlist_y; 1677 1678 int d_irq_w = ((IRQBUF_MAX - 1) * 6 *factor) + 3 *factor; 1679 int d_irq_h = 9 *factor; 1680 int d_irq_x = d_irqlist_x + 25 *factor; 1681 int d_irq_y = d_irqlist_y - d_margin - d_txt6_h; 1682 1683 int d_baudlist_w = 80 *factor; 1684 int d_baudlist_h = 35 *factor; 1685 int d_baudlist_x = d_dialog_x + ((d_dialog_w * 5) / 6) - (d_baudlist_w / 2); 1686 int d_baudlist_y = d_portlist_y; 1687 1688 int d_baud_w = ((BAUDBUF_MAX - 1) * 6 *factor) + 3 *factor; 1689 int d_baud_h = 9 *factor; 1690 int d_baud_x = d_baudlist_x + 31 *factor; 1691 int d_baud_y = d_baudlist_y - d_margin - d_txt6_h; 1692 1693 #endif //EDIT_IRQ 1694 int d_initstrlist_w = ((INITSTRBUF_MAX - 1) * 6 *factor) + 8 + 3 *factor; 1695 int d_initstrlist_h = 21 *factor; 1696 int d_initstrlist_x = d_dialog_cx - (d_initstrlist_w / 2); 1697 int d_initstrlist_y = d_dialog_y + ((d_margin + d_txt6_h) * 2) + d_margin + 10 *factor + 1698 35*factor + 1699 ((d_margin + d_txt6_h) * 2) + d_margin + 4 *factor; 1700 1701 int d_initstr_w = ((INITSTRBUF_MAX - 1) * 6 *factor) + 3 *factor; 1702 int d_initstr_h = 9 *factor; 1703 int d_initstr_x = d_initstrlist_x; 1704 int d_initstr_y = d_initstrlist_y - d_margin - d_txt6_h; 1705 1706 #ifndef EDIT_IRQ 1707 int d_portlist_w = 80 *factor + 80; 1708 int d_portlist_h = 35 *factor; 1709 int d_portlist_x = d_initstrlist_x; 1710 int d_portlist_y = d_dialog_y + ((d_margin + d_txt6_h) * 2) + d_margin + 10 *factor; 1711 1712 int d_port_w = d_portlist_w; 1713 int d_port_h = 9 *factor; 1714 int d_port_x = d_portlist_x; // + 31 *factor; 1715 int d_port_y = d_portlist_y - d_margin - d_txt6_h; 1716 1717 int d_baudlist_w = 80 *factor; 1718 int d_baudlist_h = 35 *factor; 1719 int d_baudlist_x = d_dialog_x + ((d_dialog_w * 5) / 6) - (d_baudlist_w / 2); 1720 d_baudlist_x -= 32; 1721 //int d_baudlist_x = d_portlist_x + d_portlist_w + 20 * factor; 1722 int d_baudlist_y = d_portlist_y; 1723 1724 int d_baud_w = ((BAUDBUF_MAX - 1) * 6 *factor) + 3 *factor; 1725 int d_baud_h = 9 *factor; 1726 int d_baud_x = d_baudlist_x + 31 *factor; 1727 int d_baud_y = d_baudlist_y - d_margin - d_txt6_h; 1728 1729 int d_inittype_w = 30*factor; 1730 int d_inittype_h = 9*factor; 1731 int d_inittype_x = d_dialog_x + ((d_dialog_w * 5) / 6) - (d_inittype_w / 2); 1732 int d_inittype_y = d_baud_y + 20*factor; 1733 1734 #endif //EDIT_IRQ 1735 1736 int d_add_w = 45 *factor; 1737 int d_add_h = 9 *factor; 1738 #ifdef FRENCH 1739 int d_add_x = (d_dialog_cx - (d_add_w / 2))+34*factor; 1740 #else 1741 int d_add_x = d_dialog_cx - (d_add_w / 2); 1742 #endif 1743 int d_add_y = d_initstr_y - d_add_h - 3*factor; 1744 1745 int d_delete_w = 45 *factor; 1746 int d_delete_h = 9 *factor; 1747 1748 #ifdef FRENCH 1749 int d_delete_x = 14*factor + d_dialog_x + ((d_dialog_w * 3) / 4) - (d_delete_w / 2); 1750 #else 1751 int d_delete_x = d_dialog_x + ((d_dialog_w * 3) / 4) - (d_delete_w / 2); 1752 #endif 1753 int d_delete_y = d_initstr_y - d_add_h - 3 *factor; 1754 1755 int d_cwaitstrlist_w = (((CWAITSTRBUF_MAX - 1) + 9) * 6 *factor) + 3 *factor; 1756 int d_cwaitstrlist_h = 27 *factor; 1757 int d_cwaitstrlist_x = d_initstrlist_x; 1758 int d_cwaitstrlist_y = d_initstrlist_y + d_initstrlist_h + ((d_margin + d_txt6_h) * 2) + 2 *factor; 1759 1760 int d_cwaitstr_w = ((CWAITSTRBUF_MAX - 1) * 6 *factor) + 3 *factor; 1761 int d_cwaitstr_h = 9 *factor; 1762 int d_cwaitstr_x = d_cwaitstrlist_x; 1763 int d_cwaitstr_y = d_cwaitstrlist_y - d_margin - d_txt6_h; 1764 1765 int d_tone_w = 80 *factor; 1766 int d_tone_h = 9 *factor; 1767 int d_tone_x = d_dialog_x + ((d_dialog_w * 3) / 4) - (d_tone_w / 2); 1768 int d_tone_y = d_cwaitstrlist_y; 1769 1770 int d_pulse_w = 80 *factor; 1771 int d_pulse_h = 9 *factor; 1772 int d_pulse_x = d_dialog_x + ((d_dialog_w * 3) / 4) - (d_pulse_w / 2); 1773 int d_pulse_y = d_tone_y + d_tone_h + d_margin; 1774 1775 int d_save_w = 40 *factor; 1776 int d_save_h = 9 *factor; 1777 int d_save_x = d_dialog_x + (d_dialog_w / 5) - (d_save_w / 2); 1778 int d_save_y = d_dialog_y + d_dialog_h - d_save_h - d_margin - 2 *factor; 1779 1780 #if (GERMAN | FRENCH) 1781 int d_cancel_w = 50 *factor; 1782 #else 1783 int d_cancel_w = 40 *factor; 1784 #endif 1785 int d_cancel_h = 9 *factor; 1786 int d_cancel_x = d_dialog_x + ((d_dialog_w * 4) / 5) - (d_cancel_w / 2); 1787 int d_cancel_y = d_dialog_y + d_dialog_h - d_cancel_h - d_margin - 2 *factor; 1788 1789 #if (GERMAN | FRENCH) 1790 int d_advanced_w = 50*factor; 1791 #else 1792 int d_advanced_w = 40*factor; 1793 #endif 1794 int d_advanced_h = 9*factor; 1795 int d_advanced_x = d_dialog_x + ((d_dialog_w) / 2) - (d_advanced_w / 2); 1796 int d_advanced_y = d_dialog_y + d_dialog_h - d_advanced_h - d_margin - 2 *factor; 1797 1798 1799 1800 /*........................................................................ 1801 Button Enumerations 1802 ........................................................................*/ 1803 enum { 1804 BUTTON_PORT = 100, 1805 BUTTON_PORTLIST, 1806 BUTTON_IRQ, 1807 BUTTON_IRQLIST, 1808 BUTTON_BAUD, 1809 BUTTON_BAUDLIST, 1810 BUTTON_INITSTR, 1811 BUTTON_INITSTRLIST, 1812 BUTTON_ADD, 1813 BUTTON_DELETE, 1814 BUTTON_CWAITSTR, 1815 BUTTON_CWAITSTRLIST, 1816 BUTTON_TONE, 1817 BUTTON_PULSE, 1818 BUTTON_SAVE, 1819 BUTTON_ADVANCED, 1820 BUTTON_INITTYPE, 1821 BUTTON_CANCEL, 1822 }; 1823 1824 /*........................................................................ 1825 Redraw values: in order from "top" to "bottom" layer of the dialog 1826 ........................................................................*/ 1827 typedef enum { 1828 REDRAW_NONE = 0, 1829 REDRAW_BUTTONS, 1830 REDRAW_BACKGROUND, 1831 REDRAW_ALL = REDRAW_BACKGROUND 1832 } RedrawType; 1833 1834 static char *portname[4] = { 1835 "COM1 - 3F8", 1836 "COM2 - 2F8", 1837 "COM3 - 3E8", 1838 "COM4 - 2E8" 1839 }; 1840 1841 static char custom_port[10 + MODEM_NAME_MAX] = {"CUSTOM - ????"}; 1842 1843 #ifdef EDIT_IRQ 1844 static char *irqname[5] = { 1845 "2 / 9", 1846 "3 - [COM2 & 4]", 1847 "4 - [COM1 & 3]", 1848 "5", 1849 "CUSTOM - ??" 1850 }; 1851 1852 static int _irqidx[4] = { 1853 2, 1854 1, 1855 2, 1856 1 1857 }; 1858 #endif // EDIT_IRQ 1859 1860 static char modemnames[10][MODEM_NAME_MAX]; 1861 1862 static char *baudname[5] = { 1863 "14400", 1864 "19200", 1865 "28800", 1866 "38400", 1867 "57600", 1868 }; 1869 1870 static char *init_types[2] = { 1871 "Normal", 1872 "Full", 1873 }; 1874 1875 /*........................................................................ 1876 Dialog variables 1877 ........................................................................*/ 1878 RedrawType display = REDRAW_ALL; // redraw level 1879 BOOL process = true; // process while true 1880 KeyNumType input; 1881 char * item; // general-purpose string 1882 char * temp; // general-purpose string 1883 1884 char portbuf[ PORTBUF_MAX ] = {0}; // buffer for port 1885 #ifdef EDIT_IRQ 1886 char irqbuf[ IRQBUF_MAX ] = {0}; // buffer for irq 1887 #endif //EDIT_IRQ 1888 char baudbuf[ BAUDBUF_MAX ] = {0}; // buffer for baud 1889 char initstrbuf[ INITSTRBUF_MAX ] = {0}; // buffer for init string 1890 char cwaitstrbuf[ CWAITSTRBUF_MAX ] = {0}; // buffer for call waiting string 1891 1892 int port_index = 1; // index of currently-selected port (default = com2) 1893 int port_custom_index = 4; //index of custom entry in port list 1894 #ifdef EDIT_IRQ 1895 int irq_index = 1; // index of currently-selected irq (default = 3) 1896 #endif //EDIT_IRQ 1897 int baud_index = 1; // index of currently-selected baud (default = 19200) 1898 int initstr_index = 0; // index of currently-selected modem init (default = "ATZ") 1899 int cwaitstr_index = CALL_WAIT_CUSTOM; // index of currently-selected call waiting (default = "") 1900 int rc = 0; // -1 = user cancelled, 1 = New 1901 int i; // loop counter 1902 int pos; 1903 int len; 1904 int firsttime = 1; 1905 SerialSettingsType tempsettings; 1906 DetectPortType dpstatus; 1907 char init_text[32]; 1908 1909 void const *up_button; 1910 void const *down_button; 1911 1912 if (InMainLoop){ 1913 up_button = Hires_Retrieve("BTN-UP.SHP"); 1914 down_button = Hires_Retrieve("BTN-DN.SHP"); 1915 }else{ 1916 up_button = Hires_Retrieve("BTN-UP2.SHP"); 1917 down_button = Hires_Retrieve("BTN-DN2.SHP"); 1918 } 1919 1920 1921 /*........................................................................ 1922 Buttons 1923 ........................................................................*/ 1924 GadgetClass *commands; // button list 1925 1926 EditClass port_edt (BUTTON_PORT, 1927 portbuf, PORTBUF_MAX, 1928 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1929 d_port_x, d_port_y, d_port_w, d_port_h, EditClass::ALPHANUMERIC); 1930 1931 ListClass portlist(BUTTON_PORTLIST, 1932 d_portlist_x, d_portlist_y, d_portlist_w, d_portlist_h, 1933 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1934 up_button, 1935 down_button); 1936 1937 #ifdef EDIT_IRQ 1938 EditClass irq_edt (BUTTON_IRQ, 1939 irqbuf, IRQBUF_MAX, 1940 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1941 d_irq_x, d_irq_y, d_irq_w, d_irq_h, EditClass::NUMERIC); 1942 1943 ListClass irqlist(BUTTON_IRQLIST, 1944 d_irqlist_x, d_irqlist_y, d_irqlist_w, d_irqlist_h, 1945 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1946 up_button, 1947 down_button); 1948 #endif //EDIT_IRQ 1949 1950 EditClass baud_edt (BUTTON_BAUD, 1951 baudbuf, BAUDBUF_MAX, 1952 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1953 d_baud_x, d_baud_y, d_baud_w, d_baud_h, EditClass::NUMERIC); 1954 1955 ListClass baudlist(BUTTON_BAUDLIST, 1956 d_baudlist_x, d_baudlist_y, d_baudlist_w, d_baudlist_h, 1957 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1958 up_button, 1959 down_button); 1960 1961 EditClass initstr_edt (BUTTON_INITSTR, 1962 initstrbuf, INITSTRBUF_MAX, 1963 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1964 d_initstr_x, d_initstr_y, d_initstr_w, d_initstr_h, EditClass::ALPHANUMERIC); 1965 1966 ListClass initstrlist(BUTTON_INITSTRLIST, 1967 d_initstrlist_x, d_initstrlist_y, d_initstrlist_w, d_initstrlist_h, 1968 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1969 up_button, 1970 down_button); 1971 1972 TextButtonClass addbtn(BUTTON_ADD, TXT_ADD, 1973 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1974 //#ifdef FRENCH 1975 // d_add_x, d_add_y); 1976 //#else 1977 d_add_x, d_add_y, d_add_w, d_add_h); 1978 //#endif 1979 1980 TextButtonClass deletebtn(BUTTON_DELETE, TXT_DELETE_BUTTON, 1981 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1982 //#ifdef FRENCH 1983 // d_delete_x, d_delete_y); 1984 //#else 1985 d_delete_x, d_delete_y, d_delete_w, d_delete_h); 1986 //#endif 1987 1988 EditClass cwaitstr_edt (BUTTON_CWAITSTR, 1989 cwaitstrbuf, CWAITSTRBUF_MAX, 1990 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1991 d_cwaitstr_x, d_cwaitstr_y, d_cwaitstr_w, d_cwaitstr_h, EditClass::ALPHANUMERIC); 1992 1993 ListClass cwaitstrlist(BUTTON_CWAITSTRLIST, 1994 d_cwaitstrlist_x, d_cwaitstrlist_y, d_cwaitstrlist_w, d_cwaitstrlist_h, 1995 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 1996 up_button, 1997 down_button); 1998 1999 TextButtonClass tonebtn(BUTTON_TONE, TXT_TONE_BUTTON, 2000 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 2001 d_tone_x, d_tone_y, d_tone_w, d_tone_h); 2002 2003 TextButtonClass pulsebtn(BUTTON_PULSE, TXT_PULSE_BUTTON, 2004 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 2005 d_pulse_x, d_pulse_y, d_pulse_w, d_pulse_h); 2006 2007 TextButtonClass savebtn(BUTTON_SAVE, TXT_SAVE_BUTTON, 2008 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 2009 //#if (GERMAN | FRENCH) 2010 // d_save_x, d_save_y); 2011 //#else 2012 d_save_x, d_save_y, d_save_w, d_save_h); 2013 //#endif 2014 2015 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, 2016 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 2017 //#if (GERMAN | FRENCH) 2018 // d_cancel_x, d_cancel_y); 2019 //#else 2020 d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); 2021 //#endif 2022 #if (0) 2023 TextButtonClass inittypebutton(BUTTON_INITTYPE, init_text, 2024 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 2025 d_inittype_x, d_inittype_y, d_inittype_w, d_inittype_h); 2026 #endif //(0) 2027 2028 TextButtonClass advancedbutton(BUTTON_ADVANCED, TXT_ADVANCED, 2029 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 2030 d_advanced_x, d_advanced_y, d_advanced_w, d_advanced_h); 2031 2032 /* 2033 ----------------------------- Various Inits ------------------------------ 2034 */ 2035 memcpy( &tempsettings, settings, sizeof(SerialSettingsType) ); 2036 2037 strcpy (init_text, init_types[tempsettings.Init]); 2038 2039 if (tempsettings.Port == 0) { 2040 tempsettings.Port = 0x2f8; 2041 } 2042 2043 if (tempsettings.IRQ == -1) { 2044 tempsettings.IRQ = 3; 2045 } 2046 2047 if (tempsettings.Baud == -1) { 2048 tempsettings.Baud = 19200; 2049 } 2050 2051 /*........................................................................ 2052 Set the current indices 2053 ........................................................................*/ 2054 2055 #ifdef EDIT_IRQ 2056 switch ( tempsettings.IRQ ) { 2057 case ( 2 ): 2058 irq_index = 0; 2059 strcpy (irqbuf, "2"); 2060 break; 2061 2062 case ( 3 ): 2063 irq_index = 1; 2064 strcpy (irqbuf, "3"); 2065 break; 2066 2067 case ( 4 ): 2068 irq_index = 2; 2069 strcpy (irqbuf, "4"); 2070 break; 2071 2072 case ( 5 ): 2073 irq_index = 3; 2074 strcpy (irqbuf, "5"); 2075 break; 2076 2077 default: 2078 irq_index = 4; 2079 sprintf (irqbuf, "%d", tempsettings.IRQ); 2080 temp = strchr( irqname[4], '-' ); 2081 if ( temp ) { 2082 pos = (int)(temp - irqname[4]) + 2; 2083 len = strlen( irqbuf ); 2084 strncpy( irqname[4] + pos, irqbuf, len ); 2085 *(irqname[4] + pos + len) = 0; 2086 } 2087 break; 2088 } 2089 #endif //EDIT_IRQ 2090 2091 if (tempsettings.Baud == 14400) { 2092 baud_index = 0; 2093 } else { 2094 if (tempsettings.Baud == 19200) { 2095 baud_index = 1; 2096 } else { 2097 if (tempsettings.Baud == 28800) { 2098 baud_index = 2; 2099 } else { 2100 if (tempsettings.Baud == 38400) { 2101 baud_index = 3; 2102 } else { 2103 baud_index = 4; 2104 } 2105 } 2106 } 2107 } 2108 2109 sprintf (baudbuf, "%d", tempsettings.Baud); 2110 2111 /*........................................................................ 2112 Set up the port list box & edit box 2113 ........................................................................*/ 2114 for (i = 0; i < 4; i++) { 2115 portlist.Add_Item( portname[ i ] ); 2116 } 2117 2118 /* 2119 ** Loop through the first 10 possible modem entries in the registry. Frankly, its just 2120 ** tough luck if the user has more than 10 modems attached! 2121 */ 2122 if (ModemRegistry) { 2123 delete ModemRegistry; 2124 } 2125 int modems_found = 0; 2126 for (i=0 ; i<10 ; i++) { 2127 ModemRegistry = new ModemRegistryEntryClass (i); 2128 if (ModemRegistry->Get_Modem_Name()) { 2129 strncpy (modemnames[modems_found], ModemRegistry->Get_Modem_Name(), MODEM_NAME_MAX); 2130 portlist.Add_Item( modemnames [modems_found++] ); 2131 port_custom_index ++; 2132 } 2133 delete ModemRegistry; 2134 } 2135 ModemRegistry = NULL; 2136 2137 portlist.Add_Item ( custom_port ); 2138 2139 2140 /* 2141 ** Work out the current port index 2142 */ 2143 port_index = -1; 2144 2145 if (tempsettings.ModemName[0]) { 2146 for ( i=0 ; i<port_custom_index ; i++) { 2147 if (!stricmp (portlist.Get_Item(i), tempsettings.ModemName)) { 2148 port_index = i; 2149 strcpy (portbuf, tempsettings.ModemName); 2150 break; 2151 } 2152 } 2153 /* 2154 ** The modem name specified wasnt in the registry so add it as a custom entry 2155 */ 2156 if (port_index == -1) { 2157 temp = strchr( custom_port, '-' ); 2158 if ( temp ) { 2159 pos = (int)(temp - custom_port) + 2; 2160 len = strlen( tempsettings.ModemName ); 2161 strncpy( custom_port + pos, tempsettings.ModemName, len ); 2162 *(custom_port + pos + len) = 0; 2163 strcpy (portbuf, tempsettings.ModemName); 2164 port_index = port_custom_index; 2165 } 2166 } 2167 } 2168 2169 if (port_index == -1) { 2170 switch ( tempsettings.Port ) { 2171 case ( 0x3f8 ): 2172 port_index = 0; 2173 strcpy (portbuf, "COM1"); 2174 break; 2175 2176 case ( 0x2f8 ): 2177 port_index = 1; 2178 strcpy (portbuf, "COM2"); 2179 break; 2180 2181 case ( 0x3e8 ): 2182 port_index = 2; 2183 strcpy (portbuf, "COM3"); 2184 break; 2185 2186 case ( 0x2e8 ): 2187 port_index = 3; 2188 strcpy (portbuf, "COM4"); 2189 break; 2190 2191 default: 2192 port_index = port_custom_index; 2193 sprintf (portbuf, "%x", tempsettings.Port); 2194 temp = strchr( custom_port, '-' ); 2195 if ( temp ) { 2196 pos = (int)(temp - custom_port) + 2; 2197 len = strlen( portbuf ); 2198 strncpy( custom_port + pos, portbuf, len ); 2199 *(custom_port + pos + len) = 0; 2200 } 2201 break; 2202 } 2203 } 2204 2205 portlist.Set_Selected_Index( port_index ); 2206 2207 /* 2208 ** Set up the port edit box 2209 */ 2210 port_edt.Set_Text( portbuf, PORTBUF_MAX ); 2211 2212 /*........................................................................ 2213 Set up the IRQ list box & edit box 2214 ........................................................................*/ 2215 #ifdef EDIT_IRQ 2216 for (i = 0; i < 5; i++) { 2217 irqlist.Add_Item( irqname[ i ] ); 2218 } 2219 2220 irqlist.Set_Selected_Index( irq_index ); 2221 irq_edt.Set_Text( irqbuf, IRQBUF_MAX ); 2222 #endif //EDIT_IRQ 2223 2224 /*........................................................................ 2225 Set up the baud rate list box & edit box 2226 ........................................................................*/ 2227 for (i = 0; i < 5; i++) { 2228 baudlist.Add_Item( baudname[ i ] ); 2229 } 2230 2231 baudlist.Set_Selected_Index( baud_index ); 2232 baud_edt.Set_Text( baudbuf, BAUDBUF_MAX ); 2233 2234 initstr_index = tempsettings.InitStringIndex; 2235 Build_Init_String_Listbox(&initstrlist, &initstr_edt, initstrbuf, &initstr_index); 2236 2237 /*........................................................................ 2238 Set up the cwait rate list box & edit box 2239 ........................................................................*/ 2240 2241 cwaitstr_index = tempsettings.CallWaitStringIndex; 2242 for (i = 0; i < CALL_WAIT_STRINGS_NUM; i++) { 2243 if ( i == CALL_WAIT_CUSTOM ) { 2244 item = CallWaitStrings[ i ]; 2245 temp = strchr( item, '-' ); 2246 if ( temp ) { 2247 pos = (int)(temp - item) + 2; 2248 len = strlen( tempsettings.CallWaitString ); 2249 strncpy( item + pos, tempsettings.CallWaitString, len ); 2250 *(item + pos + len) = 0; 2251 if (i == cwaitstr_index) { 2252 strncpy( cwaitstrbuf, item + pos, CWAITSTRBUF_MAX ); 2253 } 2254 } 2255 } else { 2256 if (i == cwaitstr_index) { 2257 strncpy( cwaitstrbuf, CallWaitStrings[ i ], CWAITSTRBUF_MAX ); 2258 } 2259 } 2260 cwaitstrlist.Add_Item( CallWaitStrings[ i ] ); 2261 } 2262 2263 cwaitstrlist.Set_Selected_Index( cwaitstr_index ); 2264 cwaitstr_edt.Set_Text( cwaitstrbuf, CWAITSTRBUF_MAX ); 2265 2266 /*........................................................................ 2267 Build the button list 2268 ........................................................................*/ 2269 commands = &cancelbtn; 2270 port_edt.Add_Tail(*commands); 2271 portlist.Add_Tail(*commands); 2272 #ifdef EDIT_IRQ 2273 irq_edt.Add_Tail(*commands); 2274 irqlist.Add_Tail(*commands); 2275 #endif // EDIT_IRQ 2276 baud_edt.Add_Tail(*commands); 2277 baudlist.Add_Tail(*commands); 2278 //inittypebutton.Add_Tail(*commands); 2279 initstr_edt.Add_Tail(*commands); 2280 initstrlist.Add_Tail(*commands); 2281 addbtn.Add_Tail(*commands); 2282 deletebtn.Add_Tail(*commands); 2283 cwaitstr_edt.Add_Tail(*commands); 2284 cwaitstrlist.Add_Tail(*commands); 2285 tonebtn.Add_Tail(*commands); 2286 pulsebtn.Add_Tail(*commands); 2287 savebtn.Add_Tail(*commands); 2288 advancedbutton.Add_Tail(*commands); 2289 2290 2291 if (tempsettings.DialMethod == DIAL_TOUCH_TONE) { 2292 tonebtn.Turn_On(); 2293 } else { 2294 pulsebtn.Turn_On(); 2295 } 2296 /* 2297 ---------------------------- Processing loop ----------------------------- 2298 */ 2299 while (process) { 2300 2301 /* 2302 ** If we have just received input focus again after running in the background then 2303 ** we need to redraw. 2304 */ 2305 if (AllSurfaces.SurfacesRestored){ 2306 AllSurfaces.SurfacesRestored=FALSE; 2307 display=REDRAW_ALL; 2308 } 2309 2310 /* 2311 ........................ Invoke game callback ......................... 2312 */ 2313 Call_Back(); 2314 2315 /* 2316 ** Dont allow editing of non-custom ports to fix the problem of the cursor appearing 2317 ** outside the edit box. 2318 */ 2319 if (port_index == port_custom_index) { 2320 port_edt.Set_Read_Only(false); 2321 }else{ 2322 port_edt.Set_Read_Only(true); 2323 } 2324 2325 /* 2326 ...................... Refresh display if needed ...................... 2327 */ 2328 if (display) { 2329 Hide_Mouse(); 2330 /* 2331 .................. Redraw backgound & dialog box ................... 2332 */ 2333 if (display >= REDRAW_BACKGROUND) { 2334 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 2335 Blit_Hid_Page_To_Seen_Buff(); 2336 Set_Palette(Palette); 2337 2338 Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); 2339 2340 // init font variables 2341 2342 Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, 2343 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 2344 2345 /*............................................................... 2346 Dialog & Field labels 2347 ...............................................................*/ 2348 Draw_Caption (TXT_SETTINGS, d_dialog_x, d_dialog_y, d_dialog_w); 2349 2350 Fancy_Text_Print( TXT_PORT_COLON, 2351 d_port_x - 3, d_port_y + 1 *factor, 2352 CC_GREEN, TBLACK, 2353 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 2354 2355 #ifdef EDIT_IRQ 2356 Fancy_Text_Print( TXT_IRQ_COLON, 2357 d_irq_x - 3, d_irq_y + 1 *factor, 2358 CC_GREEN, TBLACK, 2359 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 2360 #endif //EDIT_IRQ 2361 2362 Fancy_Text_Print( TXT_BAUD_COLON, 2363 d_baud_x - 3, d_baud_y + 1 *factor, 2364 CC_GREEN, TBLACK, 2365 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 2366 2367 Fancy_Text_Print( TXT_INIT_STRING, 2368 d_initstr_x, d_initstr_y - d_txt6_h - 3 *factor, 2369 CC_GREEN, TBLACK, 2370 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 2371 2372 Fancy_Text_Print( TXT_CWAIT_STRING, 2373 d_cwaitstr_x, d_cwaitstr_y - d_txt6_h - 3 *factor, 2374 CC_GREEN, TBLACK, 2375 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 2376 #if (0) 2377 Fancy_Text_Print ( "Modem Init", 2378 d_inittype_x, d_inittype_y - d_txt6_h - d_margin, 2379 CC_GREEN, TBLACK, 2380 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 2381 #endif //(0) 2382 } 2383 2384 /* 2385 .......................... Redraw buttons .......................... 2386 */ 2387 if (display >= REDRAW_BUTTONS) { 2388 cancelbtn.Flag_To_Redraw(); 2389 port_edt.Flag_To_Redraw(); 2390 portlist.Flag_To_Redraw(); 2391 #ifdef EDIT_IRQ 2392 irq_edt.Flag_To_Redraw(); 2393 irqlist.Flag_To_Redraw(); 2394 #endif // EDIT_IRQ 2395 baud_edt.Flag_To_Redraw(); 2396 baudlist.Flag_To_Redraw(); 2397 //inittypebutton.Flag_To_Redraw(); 2398 advancedbutton.Flag_To_Redraw(); 2399 initstr_edt.Flag_To_Redraw(); 2400 initstrlist.Flag_To_Redraw(); 2401 addbtn.Flag_To_Redraw(); 2402 deletebtn.Flag_To_Redraw(); 2403 cwaitstr_edt.Flag_To_Redraw(); 2404 cwaitstrlist.Flag_To_Redraw(); 2405 tonebtn.Flag_To_Redraw(); 2406 pulsebtn.Flag_To_Redraw(); 2407 savebtn.Flag_To_Redraw(); 2408 } 2409 2410 Show_Mouse(); 2411 display = REDRAW_NONE; 2412 } 2413 2414 /* 2415 ........................... Get user input ............................ 2416 */ 2417 input = commands->Input(); 2418 2419 if ( firsttime ) { 2420 port_edt.Set_Focus(); 2421 port_edt.Flag_To_Redraw(); 2422 input = commands->Input(); 2423 firsttime = 0; 2424 } 2425 2426 /* 2427 ---------------------------- Process input ---------------------------- 2428 */ 2429 switch (input) { 2430 #if (0) 2431 case (BUTTON_INITTYPE | KN_BUTTON): 2432 tempsettings.Init = !tempsettings.Init; 2433 strcpy (init_text, init_types[tempsettings.Init]); 2434 inittypebutton.Flag_To_Redraw(); 2435 break; 2436 2437 2438 #endif //(0) 2439 2440 case (BUTTON_ADVANCED | KN_BUTTON): 2441 Advanced_Modem_Settings (&tempsettings); 2442 display = REDRAW_ALL; 2443 break; 2444 2445 2446 case (BUTTON_PORT | KN_BUTTON): 2447 item = (char *)portlist.Current_Item(); 2448 if (port_index < 4) { 2449 temp = strchr( item, ' ' ); 2450 if ( !temp ) { 2451 strncpy( portbuf, item, PORTBUF_MAX ); 2452 } else { 2453 pos = (int)(temp - item); 2454 strncpy( portbuf, item, pos ); 2455 portbuf[pos] = 0; 2456 } 2457 port_edt.Set_Text( portbuf, PORTBUF_MAX ); 2458 port_edt.Flag_To_Redraw(); 2459 #ifdef EDIT_IRQ 2460 irq_edt.Set_Focus(); 2461 irq_edt.Flag_To_Redraw(); 2462 #endif //EDIT_IRQ 2463 } else { 2464 strupr( portbuf ); 2465 if ( stricmp(portbuf, "3F8") == 0 ) { 2466 port_index = 0; 2467 portlist.Set_Selected_Index( port_index ); 2468 strcpy (portbuf, "COM1"); 2469 display = REDRAW_BUTTONS; 2470 } 2471 else if ( stricmp(portbuf, "2F8") == 0 ) { 2472 port_index = 1; 2473 portlist.Set_Selected_Index( port_index ); 2474 strcpy (portbuf, "COM2"); 2475 display = REDRAW_BUTTONS; 2476 } 2477 else if ( stricmp(portbuf, "3E8") == 0 ) { 2478 port_index = 2; 2479 portlist.Set_Selected_Index( port_index ); 2480 strcpy (portbuf, "COM3"); 2481 display = REDRAW_BUTTONS; 2482 } 2483 else if ( stricmp(portbuf, "2E8") == 0 ) { 2484 port_index = 3; 2485 portlist.Set_Selected_Index( port_index ); 2486 strcpy (portbuf, "COM4"); 2487 display = REDRAW_BUTTONS; 2488 } 2489 else if ( strncmp(portbuf, "COM", 3) == 0 ) { 2490 display = REDRAW_BUTTONS; 2491 2492 switch ( (portbuf[3] - '0') ) { 2493 case 1: 2494 port_index = 0; 2495 break; 2496 2497 case 2: 2498 port_index = 1; 2499 break; 2500 2501 case 3: 2502 port_index = 2; 2503 break; 2504 2505 case 4: 2506 port_index = 3; 2507 break; 2508 2509 default: 2510 if (portbuf[3] <= '9' && portbuf[3] >'0') { 2511 portbuf[4] = 0; 2512 port_index = port_custom_index; 2513 temp = strchr( item, '-' ); 2514 if ( temp ) { 2515 pos = (int)(temp - item) + 2; 2516 len = strlen( portbuf ); 2517 strncpy( item + pos, portbuf, len ); 2518 *(item + pos + len) = 0; 2519 display = REDRAW_BUTTONS; 2520 } 2521 break; 2522 } 2523 CCMessageBox().Process( TXT_INVALID_PORT_ADDRESS ); 2524 port_edt.Set_Focus(); 2525 display = REDRAW_ALL; 2526 break; 2527 } 2528 2529 portlist.Set_Selected_Index( port_index ); 2530 } else { 2531 temp = strchr( item, '-' ); 2532 if ( temp ) { 2533 pos = (int)(temp - item) + 2; 2534 len = strlen( portbuf ); 2535 strncpy( item + pos, portbuf, len ); 2536 *(item + pos + len) = 0; 2537 display = REDRAW_BUTTONS; 2538 } 2539 } 2540 2541 #ifdef EDIT_IRQ 2542 if (display == REDRAW_BUTTONS) { 2543 irq_edt.Set_Focus(); 2544 irq_edt.Flag_To_Redraw(); 2545 } 2546 #endif //EDIT_IRQ 2547 } 2548 break; 2549 2550 case (BUTTON_PORTLIST | KN_BUTTON): 2551 if (portlist.Current_Index() != port_index) { 2552 port_index = portlist.Current_Index(); 2553 item = (char *)portlist.Current_Item(); 2554 if (port_index < 4) { 2555 temp = strchr( item, ' ' ); 2556 if ( !temp ) { 2557 strncpy( portbuf, item, PORTBUF_MAX ); 2558 } else { 2559 pos = (int)(temp - item); 2560 strncpy( portbuf, item, pos ); 2561 portbuf[pos] = 0; 2562 } 2563 port_edt.Clear_Focus(); 2564 2565 // auto select the irq for port 2566 2567 #ifdef EDIT_IRQ 2568 irq_index = _irqidx[ port_index ]; 2569 irqlist.Set_Selected_Index( irq_index ); 2570 item = (char *)irqlist.Current_Item(); 2571 temp = strchr( item, ' ' ); 2572 if ( !temp ) { 2573 strncpy( irqbuf, item, 2 ); 2574 } else { 2575 pos = (int)(temp - item); 2576 strncpy( irqbuf, item, pos ); 2577 irqbuf[pos] = 0; 2578 } 2579 irq_edt.Clear_Focus(); 2580 #endif //EDIT_IRQ 2581 } else { 2582 if (port_index == port_custom_index) { 2583 /* 2584 ** This is the custom entry 2585 */ 2586 temp = strchr( item, '-' ); 2587 if ( temp ) { 2588 pos = (int)(temp - item) + 2; 2589 if ( *(item + pos) == '?' ) { 2590 portbuf[0] = 0; 2591 } else { 2592 strncpy( portbuf, item + pos, PORTBUF_MAX ); 2593 } 2594 } 2595 port_edt.Set_Focus(); 2596 }else{ 2597 /* 2598 ** Must be a modem name entry so just copy iy 2599 */ 2600 strncpy (portbuf, item, PORTBUF_MAX); 2601 } 2602 2603 } 2604 port_edt.Set_Text( portbuf, PORTBUF_MAX ); 2605 display = REDRAW_BUTTONS; 2606 } else { 2607 if (port_index < port_custom_index) { 2608 port_edt.Clear_Focus(); 2609 } else { 2610 port_edt.Set_Focus(); 2611 } 2612 display = REDRAW_BUTTONS; 2613 } 2614 break; 2615 2616 #ifdef EDIT_IRQ 2617 case (BUTTON_IRQ | KN_BUTTON): 2618 item = (char *)irqlist.Current_Item(); 2619 if (irq_index < 4) { 2620 temp = strchr( item, ' ' ); 2621 if ( !temp ) { 2622 strncpy( irqbuf, item, IRQBUF_MAX ); 2623 } else { 2624 pos = (int)(temp - item); 2625 strncpy( irqbuf, item, pos ); 2626 irqbuf[pos] = 0; 2627 } 2628 irq_edt.Set_Text( irqbuf, IRQBUF_MAX ); 2629 irq_edt.Flag_To_Redraw(); 2630 } else { 2631 temp = strchr( item, '-' ); 2632 if ( temp ) { 2633 pos = (int)(temp - item) + 2; 2634 len = strlen( irqbuf ); 2635 strncpy( item + pos, irqbuf, len ); 2636 *(item + pos + len) = 0; 2637 display = REDRAW_BUTTONS; 2638 } 2639 } 2640 baud_edt.Set_Focus(); 2641 baud_edt.Flag_To_Redraw(); 2642 break; 2643 2644 case (BUTTON_IRQLIST | KN_BUTTON): 2645 if (irqlist.Current_Index() != irq_index) { 2646 irq_index = irqlist.Current_Index(); 2647 item = (char *)irqlist.Current_Item(); 2648 if (irq_index < 4) { 2649 temp = strchr( item, ' ' ); 2650 if ( !temp ) { 2651 strncpy( irqbuf, item, IRQBUF_MAX ); 2652 } else { 2653 pos = (int)(temp - item); 2654 strncpy( irqbuf, item, pos ); 2655 irqbuf[pos] = 0; 2656 } 2657 irq_edt.Clear_Focus(); 2658 } else { 2659 temp = strchr( item, '-' ); 2660 if ( temp ) { 2661 pos = (int)(temp - item) + 2; 2662 if ( *(item + pos) == '?' ) { 2663 irqbuf[0] = 0; 2664 } else { 2665 strncpy( irqbuf, item + pos, IRQBUF_MAX ); 2666 } 2667 } 2668 irq_edt.Set_Focus(); 2669 } 2670 irq_edt.Set_Text( irqbuf, IRQBUF_MAX ); 2671 } else { 2672 if (irq_index < 4) { 2673 irq_edt.Clear_Focus(); 2674 } else { 2675 irq_edt.Set_Focus(); 2676 } 2677 } 2678 display = REDRAW_BUTTONS; 2679 break; 2680 #endif //EDIT_IRQ 2681 2682 case (BUTTON_BAUD | KN_BUTTON): 2683 item = (char *)baudlist.Current_Item(); 2684 strncpy( baudbuf, item, BAUDBUF_MAX ); 2685 baud_edt.Set_Text( baudbuf, BAUDBUF_MAX ); 2686 initstr_edt.Set_Focus(); 2687 initstr_edt.Flag_To_Redraw(); 2688 display = REDRAW_BUTTONS; 2689 break; 2690 2691 case (BUTTON_BAUDLIST | KN_BUTTON): 2692 if (baudlist.Current_Index() != baud_index) { 2693 baud_index = baudlist.Current_Index(); 2694 item = (char *)baudlist.Current_Item(); 2695 strncpy( baudbuf, item, BAUDBUF_MAX ); 2696 baud_edt.Set_Text( baudbuf, BAUDBUF_MAX ); 2697 baud_edt.Clear_Focus(); 2698 display = REDRAW_BUTTONS; 2699 } 2700 break; 2701 2702 #if 0 2703 case (BUTTON_INITSTR | KN_BUTTON): 2704 strupr( initstrbuf ); 2705 strncpy( InitStrings[ initstr_index ], initstrbuf, INITSTRBUF_MAX ); 2706 Build_Init_String_Listbox(&initstrlist, &initstr_edt, initstrbuf, 2707 &initstr_index); 2708 cwaitstr_edt.Set_Focus(); 2709 cwaitstr_edt.Flag_To_Redraw(); 2710 display = REDRAW_BUTTONS; 2711 break; 2712 #endif 2713 2714 case (BUTTON_INITSTRLIST | KN_BUTTON): 2715 if (initstrlist.Current_Index() != initstr_index) { 2716 initstr_index = initstrlist.Current_Index(); 2717 item = (char *)initstrlist.Current_Item(); 2718 strncpy( initstrbuf, item, INITSTRBUF_MAX ); 2719 initstr_edt.Set_Text( initstrbuf, INITSTRBUF_MAX ); 2720 } 2721 initstr_edt.Set_Focus(); 2722 initstr_edt.Flag_To_Redraw(); 2723 display = REDRAW_BUTTONS; 2724 break; 2725 2726 /*------------------------------------------------------------------ 2727 Add a new InitString entry 2728 ------------------------------------------------------------------*/ 2729 case (BUTTON_ADD | KN_BUTTON): 2730 2731 item = new char[ INITSTRBUF_MAX ]; 2732 memset (item, 0, INITSTRBUF_MAX); 2733 2734 strupr ( initstrbuf ); 2735 strncpy ( item, initstrbuf, INITSTRBUF_MAX-1 ); 2736 2737 InitStrings.Add ( item ); 2738 Build_Init_String_Listbox (&initstrlist, &initstr_edt, initstrbuf, 2739 &initstr_index); 2740 /*............................................................ 2741 Set the current listbox index to the newly-added item. 2742 ............................................................*/ 2743 for (i = 0; i < InitStrings.Count(); i++) { 2744 if (item == InitStrings[i]) { 2745 initstr_index = i; 2746 strcpy( initstrbuf, InitStrings[ initstr_index ] ); 2747 initstr_edt.Set_Text( initstrbuf, INITSTRBUF_MAX ); 2748 initstrlist.Set_Selected_Index( initstr_index ); 2749 } 2750 } 2751 initstr_edt.Set_Focus(); 2752 initstr_edt.Flag_To_Redraw(); 2753 display = REDRAW_BUTTONS; 2754 break; 2755 2756 /*------------------------------------------------------------------ 2757 Delete the current InitString entry 2758 ------------------------------------------------------------------*/ 2759 case (BUTTON_DELETE | KN_BUTTON): 2760 2761 if ( InitStrings.Count() && initstr_index != -1) { 2762 InitStrings.Delete( initstr_index ); 2763 Build_Init_String_Listbox(&initstrlist, &initstr_edt, initstrbuf, 2764 &initstr_index); 2765 } 2766 break; 2767 2768 case (BUTTON_CWAITSTR | KN_BUTTON): 2769 item = (char *)cwaitstrlist.Current_Item(); 2770 if (cwaitstr_index < 3) { 2771 } else { 2772 temp = strchr( item, '-' ); 2773 if ( temp ) { 2774 pos = (int)(temp - item) + 2; 2775 len = strlen( cwaitstrbuf ); 2776 strncpy( item + pos, cwaitstrbuf, len ); 2777 *(item + pos + len) = 0; 2778 display = REDRAW_BUTTONS; 2779 } 2780 } 2781 break; 2782 2783 case (BUTTON_CWAITSTRLIST | KN_BUTTON): 2784 if (cwaitstrlist.Current_Index() != cwaitstr_index) { 2785 cwaitstr_index = cwaitstrlist.Current_Index(); 2786 item = (char *)cwaitstrlist.Current_Item(); 2787 if (cwaitstr_index < 3) { 2788 strncpy( cwaitstrbuf, item, CWAITSTRBUF_MAX ); 2789 cwaitstr_edt.Clear_Focus(); 2790 } else { 2791 temp = strchr( item, '-' ); 2792 if ( temp ) { 2793 pos = (int)(temp - item) + 2; 2794 strncpy( cwaitstrbuf, item + pos, CWAITSTRBUF_MAX ); 2795 } 2796 cwaitstr_edt.Set_Focus(); 2797 } 2798 cwaitstr_edt.Set_Text( cwaitstrbuf, CWAITSTRBUF_MAX ); 2799 } else { 2800 if (cwaitstr_index < 3) { 2801 cwaitstr_edt.Clear_Focus(); 2802 } else { 2803 cwaitstr_edt.Set_Focus(); 2804 } 2805 } 2806 display = REDRAW_BUTTONS; 2807 break; 2808 2809 case (BUTTON_TONE | KN_BUTTON): 2810 tempsettings.DialMethod = DIAL_TOUCH_TONE; 2811 tonebtn.Turn_On(); 2812 pulsebtn.Turn_Off(); 2813 break; 2814 2815 case (BUTTON_PULSE | KN_BUTTON): 2816 tempsettings.DialMethod = DIAL_PULSE; 2817 tonebtn.Turn_Off(); 2818 pulsebtn.Turn_On(); 2819 break; 2820 2821 /*------------------------------------------------------------------ 2822 SAVE: save the com settings 2823 ------------------------------------------------------------------*/ 2824 case (KN_RETURN): 2825 case (BUTTON_SAVE | KN_BUTTON): 2826 switch (port_index) { 2827 case ( 0 ): 2828 tempsettings.Port = 0x3f8; 2829 tempsettings.ModemName[0] = 0; 2830 break; 2831 2832 case ( 1 ): 2833 tempsettings.Port = 0x2f8; 2834 tempsettings.ModemName[0] = 0; 2835 break; 2836 2837 case ( 2 ): 2838 tempsettings.Port = 0x3e8; 2839 tempsettings.ModemName[0] = 0; 2840 break; 2841 2842 case ( 3 ): 2843 tempsettings.Port = 0x2e8; 2844 tempsettings.ModemName[0] = 0; 2845 break; 2846 2847 default: 2848 if (port_index == port_custom_index) { 2849 strncpy ( tempsettings.ModemName, portbuf, MODEM_NAME_MAX ); 2850 tempsettings.Port = 1; 2851 } else { 2852 /* 2853 ** Must be a modem name index 2854 */ 2855 strcpy (tempsettings.ModemName, portlist.Current_Item()); 2856 tempsettings.Port = 1; 2857 } 2858 break; 2859 } 2860 2861 #ifdef EDIT_IRQ 2862 switch (irq_index) { 2863 case ( 0 ): 2864 tempsettings.IRQ = 2; 2865 break; 2866 2867 case ( 1 ): 2868 tempsettings.IRQ = 3; 2869 break; 2870 2871 case ( 2 ): 2872 tempsettings.IRQ = 4; 2873 break; 2874 2875 case ( 3 ): 2876 tempsettings.IRQ = 5; 2877 break; 2878 2879 default: 2880 sscanf( irqbuf, "%d", &tempsettings.IRQ ); 2881 break; 2882 } 2883 #endif //EDIT_IRQ 2884 2885 sscanf( baudbuf, "%d", &tempsettings.Baud ); 2886 2887 tempsettings.InitStringIndex = initstr_index; 2888 tempsettings.CallWaitStringIndex = cwaitstr_index; 2889 2890 item = CallWaitStrings[ CALL_WAIT_CUSTOM ]; 2891 temp = strchr( item, '-' ); 2892 if ( temp ) { 2893 pos = (int)(temp - item) + 2; 2894 strncpy( cwaitstrbuf, item + pos, CWAITSTRBUF_MAX ); 2895 } else { 2896 cwaitstrbuf[ 0 ] = 0; 2897 } 2898 2899 strncpy( tempsettings.CallWaitString, cwaitstrbuf, CWAITSTRBUF_MAX ); 2900 2901 dpstatus = NullModem.Detect_Port( &tempsettings ); 2902 2903 if (dpstatus == PORT_VALID) { 2904 process = false; 2905 rc = true; 2906 } 2907 else if (dpstatus == PORT_INVALID) { 2908 CCMessageBox().Process( TXT_INVALID_SETTINGS ); 2909 firsttime = 1; 2910 display = REDRAW_ALL; 2911 } 2912 else if (dpstatus == PORT_IRQ_INUSE) { 2913 CCMessageBox().Process( TXT_IRQ_ALREADY_IN_USE ); 2914 firsttime = 1; 2915 display = REDRAW_ALL; 2916 } 2917 break; 2918 2919 /*------------------------------------------------------------------ 2920 CANCEL: send a SIGN_OFF, bail out with error code 2921 ------------------------------------------------------------------*/ 2922 case (KN_ESC): 2923 case (BUTTON_CANCEL | KN_BUTTON): 2924 process = false; 2925 rc = false; 2926 break; 2927 } 2928 2929 } /* end of while */ 2930 2931 /*------------------------------------------------------------------------ 2932 Restore screen 2933 ------------------------------------------------------------------------*/ 2934 Hide_Mouse(); 2935 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 2936 Blit_Hid_Page_To_Seen_Buff(); 2937 Show_Mouse(); 2938 2939 /*------------------------------------------------------------------------ 2940 Save values into the Settings structure 2941 ------------------------------------------------------------------------*/ 2942 if (rc) { 2943 memcpy( settings, &tempsettings, sizeof(SerialSettingsType) ); 2944 } 2945 2946 return(rc); 2947 2948 } /* end of Com_Settings_Dialog */ 2949 2950 2951 /*************************************************************************** 2952 * Build_Init_String_Listbox -- [re]builds the initstring listbox * 2953 * * 2954 * This routine rebuilds the initstring list box from scratch; it also * 2955 * updates the contents of the initstring edit field. * 2956 * * 2957 * INPUT: * 2958 * list ptr to list box * 2959 * edit ptr to edit box * 2960 * buf ptr to buffer for initstring * 2961 * * 2962 * OUTPUT: * 2963 * none. * 2964 * * 2965 * WARNINGS: * 2966 * none. * 2967 * * 2968 * HISTORY: * 2969 * 06/08/1995 DRD : Created. * 2970 *=========================================================================*/ 2971 static void Build_Init_String_Listbox (ListClass *list, EditClass *edit, char *buf, int *index) 2972 { 2973 int i, curidx; 2974 char *item; 2975 2976 2977 curidx = *index; 2978 2979 /*........................................................................ 2980 Clear the list 2981 ........................................................................*/ 2982 while (list->Count()) { 2983 item = (char *)(list->Get_Item(0)); 2984 list->Remove_Item(item); 2985 delete [] item; 2986 } 2987 2988 /* 2989 ** Now sort the init string list by name then number 2990 */ 2991 qsort ((void *)(&InitStrings[0]), InitStrings.Count(), sizeof(char *), Init_String_Compare); 2992 2993 /*........................................................................ 2994 Build the list 2995 ........................................................................*/ 2996 for (i = 0; i < InitStrings.Count(); i++) { 2997 item = new char[ INITSTRBUF_MAX ]; 2998 strcpy( item, InitStrings[i] ); 2999 list->Add_Item(item); 3000 } 3001 list->Flag_To_Redraw(); 3002 3003 /*........................................................................ 3004 Init the current phone book index 3005 ........................................................................*/ 3006 if (list->Count() == 0 || curidx < -1) { 3007 curidx = -1; 3008 } else { 3009 if (curidx >= list->Count() ) { 3010 curidx = 0; 3011 } 3012 } 3013 3014 /*........................................................................ 3015 Fill in initstring edit buffer 3016 ........................................................................*/ 3017 if (curidx > -1) { 3018 strcpy (buf, InitStrings[ curidx ]); 3019 edit->Set_Text (buf, INITSTRBUF_MAX ); 3020 list->Set_Selected_Index( curidx ); 3021 } 3022 3023 *index = curidx; 3024 } 3025 3026 3027 /*************************************************************************** 3028 * Init_String_Compare -- for qsort * 3029 * * 3030 * INPUT: * 3031 * p1,p2 ptrs to elements to compare * 3032 * * 3033 * OUTPUT: * 3034 * 0 = same, -1 = (*p1) goes BEFORE (*p2), 1 = (*p1) goes AFTER (*p2) * 3035 * * 3036 * WARNINGS: * 3037 * none. * 3038 * * 3039 * HISTORY: * 3040 * 06/08/1995 DRD : Created. * 3041 *=========================================================================*/ 3042 static int Init_String_Compare (const void *p1, const void *p2) 3043 { 3044 return( strcmp( *((char **)p1), *((char **)p2) ) ); 3045 } 3046 3047 3048 /*********************************************************************************************** 3049 * Com_Scenario_Dialog -- Serial game scenario selection dialog * 3050 * * 3051 * * 3052 * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * 3053 * ³ Serial Game ³ * 3054 * ³ ³ * 3055 * ³ Your Name: __________ House: [GDI] [NOD] ³ * 3056 * ³ Credits: ______ Desired Color: [ ][ ][ ][ ] ³ * 3057 * ³ Opponent: Name ³ * 3058 * ³ ³ * 3059 * ³ Scenario ³ * 3060 * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³ * 3061 * ³ ³ Hell's Kitchen ³³ ³ * 3062 * ³ ³ Heaven's Gate ÃÄ´ ³ * 3063 * ³ ³ ... ³ ³ ³ * 3064 * ³ ³ ÃÄ´ ³ * 3065 * ³ ³ ³³ ³ * 3066 * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³ * 3067 * ³ [ Bases ] [ Crates ] ³ * 3068 * ³ [ Tiberium ] [ AI Players ] ³ * 3069 * ³ ³ * 3070 * ³ [OK] [Cancel] ³ * 3071 * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ * 3072 * ³ ³ ³ ³ * 3073 * ³ ³ ³ ³ * 3074 * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * 3075 * ³ [Send Message] ³ * 3076 * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * 3077 * * 3078 * INPUT: * 3079 * none. * 3080 * * 3081 * OUTPUT: * 3082 * true = success, false = cancel * 3083 * * 3084 * WARNINGS: * 3085 * MPlayerName & MPlayerGameName must contain this player's name. * 3086 * * 3087 * HISTORY: * 3088 * 02/14/1995 BR : Created. * 3089 *=============================================================================================*/ 3090 #define TXT_HOST_INTERNET_GAME 4567+1 3091 #define TXT_JOIN_INTERNET_GAME 4567+2 3092 int Com_Scenario_Dialog(void) 3093 { 3094 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 3095 /*........................................................................ 3096 Dialog & button dimensions 3097 ........................................................................*/ 3098 int d_dialog_w = 290*factor; // dialog width 3099 int d_dialog_h = 190*factor; // dialog height 3100 int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord 3101 int d_dialog_y = ((200*factor - d_dialog_h) / 2); // dialog y-coord 3102 int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord 3103 3104 int d_txt6_h = 6*factor+1; // ht of 6-pt text 3105 int d_margin1 = 5*factor; // margin width/height 3106 int d_margin2 = 2*factor; // margin width/height 3107 3108 int d_name_w = 70*factor; 3109 int d_name_h = 9*factor; 3110 int d_name_x = d_dialog_x + 108*factor; 3111 int d_name_y = d_dialog_y + d_margin1 + d_txt6_h + d_txt6_h + d_margin1; 3112 3113 int d_credits_w = ((CREDITSBUF_MAX - 1) * 6*factor) + 3*factor; 3114 int d_credits_h = 9*factor; 3115 int d_credits_x = d_name_x; 3116 int d_credits_y = d_name_y + d_name_h + d_margin2; 3117 3118 int d_gdi_w = 30*factor; 3119 int d_gdi_h = 9*factor; 3120 int d_gdi_x = d_dialog_cx + (d_dialog_w / 4); 3121 int d_gdi_y = d_dialog_y + d_margin1 + d_txt6_h + d_txt6_h + d_margin1; 3122 3123 int d_nod_w = 30*factor; 3124 int d_nod_h = 9*factor; 3125 int d_nod_x = d_gdi_x + d_gdi_w + (d_margin1 / 2); 3126 int d_nod_y = d_gdi_y; 3127 3128 int d_color_w = 10*factor; 3129 int d_color_h = 9*factor; 3130 int d_color_y = d_gdi_y + d_gdi_h + d_margin2; 3131 3132 int d_opponent_x = d_name_x; 3133 int d_opponent_y = d_color_y + d_color_h + d_margin2; 3134 3135 int d_scenariolist_w = 182*factor; 3136 int d_scenariolist_h = 27*factor; 3137 int d_scenariolist_x = d_dialog_cx - (d_scenariolist_w / 2); 3138 int d_scenariolist_y = d_opponent_y + d_txt6_h + 3*factor + d_txt6_h; 3139 3140 // d_count_x is calculated below after other enums 3141 int d_count_w = 25*factor; 3142 int d_count_h = 7*factor; 3143 int d_count_y = d_scenariolist_y + d_scenariolist_h + d_margin2; 3144 3145 // d_level_x is calculated below after other enums 3146 int d_level_w = 25*factor; 3147 int d_level_h = 7*factor; 3148 int d_level_y = d_count_y; 3149 3150 #if (GERMAN | FRENCH) 3151 int d_bases_w = 120*factor;//BGA:100; 3152 #else 3153 int d_bases_w = 110*factor; 3154 #endif 3155 int d_bases_h = 9*factor; 3156 int d_bases_x = d_dialog_cx - d_bases_w - d_margin2; 3157 int d_bases_y = d_count_y + d_count_h + d_margin2; 3158 3159 #if (GERMAN | FRENCH) 3160 int d_goodies_w = 120*factor; 3161 #else 3162 int d_goodies_w = 110*factor; 3163 #endif 3164 int d_goodies_h = 9*factor; 3165 int d_goodies_x = d_dialog_cx + d_margin2; 3166 int d_goodies_y = d_bases_y; 3167 3168 int d_count_x = d_dialog_cx - d_count_w - ((2 * 6*factor) + 3*factor) 3169 - ((d_bases_w - ((13 * 6*factor) + 3*factor + d_count_w)) / 2) - d_margin2; 3170 3171 int d_level_x = d_dialog_cx + (11 * 6*factor) 3172 + ((d_goodies_w - ((13 * 6*factor) + 3*factor + d_level_w)) / 2) + d_margin2; 3173 3174 #if (GERMAN | FRENCH) 3175 int d_tiberium_w = 120*factor; 3176 #else 3177 int d_tiberium_w = 110*factor; 3178 #endif 3179 int d_tiberium_h = 9*factor; 3180 int d_tiberium_x = d_dialog_cx - d_bases_w - d_margin2; 3181 int d_tiberium_y = d_bases_y + d_bases_h + d_margin2; 3182 3183 #if (GERMAN | FRENCH) 3184 int d_ghosts_w = 120*factor; 3185 #else 3186 int d_ghosts_w = 110*factor; 3187 #endif 3188 int d_ghosts_h = 9*factor; 3189 int d_ghosts_x = d_dialog_cx + d_margin2; 3190 int d_ghosts_y = d_tiberium_y; 3191 3192 int d_ok_w = 45*factor; 3193 int d_ok_h = 9*factor; 3194 int d_ok_x = d_tiberium_x + (d_tiberium_w / 2) - (d_ok_w / 2); 3195 int d_ok_y = d_tiberium_y + d_tiberium_h + d_margin1; 3196 3197 int d_cancel_w = 45*factor; 3198 int d_cancel_h = 9*factor; 3199 int d_cancel_x = d_ghosts_x + (d_ghosts_w / 2) - (d_cancel_w / 2); 3200 int d_cancel_y = d_tiberium_y + d_tiberium_h + d_margin1; 3201 3202 int d_message_w = d_dialog_w - (d_margin1 * 2); 3203 int d_message_h = 34*factor; 3204 int d_message_x = d_dialog_x + d_margin1; 3205 int d_message_y = d_cancel_y + d_cancel_h + d_margin1; 3206 3207 int d_send_w = 80*factor; 3208 int d_send_h = 9*factor; 3209 int d_send_x = d_dialog_cx - (d_send_w / 2); 3210 int d_send_y = d_message_y + d_message_h + d_margin2; 3211 3212 /*........................................................................ 3213 Button Enumerations 3214 ........................................................................*/ 3215 enum { 3216 BUTTON_NAME = 100, 3217 BUTTON_GDI, 3218 BUTTON_NOD, 3219 BUTTON_CREDITS, 3220 BUTTON_SCENARIOLIST, 3221 BUTTON_COUNT, 3222 BUTTON_LEVEL, 3223 BUTTON_BASES, 3224 BUTTON_TIBERIUM, 3225 BUTTON_GOODIES, 3226 BUTTON_GHOSTS, 3227 BUTTON_OK, 3228 BUTTON_CANCEL, 3229 BUTTON_SEND, 3230 }; 3231 3232 /*........................................................................ 3233 Redraw values: in order from "top" to "bottom" layer of the dialog 3234 ........................................................................*/ 3235 typedef enum { 3236 REDRAW_NONE = 0, 3237 REDRAW_MESSAGE, 3238 REDRAW_COLORS, 3239 REDRAW_BUTTONS, 3240 REDRAW_BACKGROUND, 3241 REDRAW_ALL = REDRAW_BACKGROUND 3242 } RedrawType; 3243 3244 /*........................................................................ 3245 Dialog variables 3246 ........................................................................*/ 3247 RedrawType display = REDRAW_ALL; // redraw level 3248 bool process = true; // process while true 3249 KeyNumType input; 3250 3251 char namebuf[MPLAYER_NAME_MAX] = {0}; // buffer for player's name 3252 char credbuf[CREDITSBUF_MAX]; // for credit edit box 3253 int old_cred; // old value in credits buffer 3254 int transmit; // 1 = re-transmit new game options 3255 int cbox_x[] = { d_gdi_x, 3256 d_gdi_x + d_color_w, 3257 d_gdi_x + (d_color_w * 2), 3258 d_gdi_x + (d_color_w * 3), 3259 d_gdi_x + (d_color_w * 4), 3260 d_gdi_x + (d_color_w * 5)}; 3261 int parms_received = 0; // 1 = game options received 3262 int changed = 0; // 1 = user has changed an option 3263 3264 int rc; 3265 int recsignedoff = false; 3266 int i; 3267 int version; 3268 char txt[80]; 3269 unsigned long starttime; 3270 unsigned long timingtime; 3271 unsigned long lastmsgtime; 3272 unsigned long lastredrawtime; 3273 unsigned long transmittime = 0; 3274 unsigned long theirresponsetime; 3275 int packetlen; 3276 static int first_time = 1; 3277 bool oppscorescreen = false; 3278 bool gameoptions = false; 3279 EventClass *event; // event ptr 3280 unsigned long msg_timeout = 1200; // init to 20 seconds 3281 3282 int message_length; 3283 int sent_so_far; 3284 unsigned short magic_number; 3285 unsigned short crc; 3286 bool ready_to_go = false; 3287 CountDownTimerClass ready_time; 3288 3289 void const *up_button; 3290 void const *down_button; 3291 3292 if (InMainLoop){ 3293 up_button = Hires_Retrieve("BTN-UP.SHP"); 3294 down_button = Hires_Retrieve("BTN-DN.SHP"); 3295 }else{ 3296 up_button = Hires_Retrieve("BTN-UP2.SHP"); 3297 down_button = Hires_Retrieve("BTN-DN2.SHP"); 3298 } 3299 3300 /*........................................................................ 3301 Buttons 3302 ........................................................................*/ 3303 GadgetClass *commands; // button list 3304 3305 EditClass name_edt (BUTTON_NAME, 3306 namebuf, MPLAYER_NAME_MAX, 3307 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 3308 d_name_x, d_name_y, d_name_w, d_name_h, EditClass::ALPHANUMERIC); 3309 3310 TextButtonClass gdibtn(BUTTON_GDI, TXT_G_D_I, 3311 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 3312 d_gdi_x, d_gdi_y, d_gdi_w, d_gdi_h); 3313 3314 TextButtonClass nodbtn(BUTTON_NOD, TXT_N_O_D, 3315 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 3316 d_nod_x, d_nod_y, d_nod_w, d_nod_h); 3317 3318 EditClass credit_edt (BUTTON_CREDITS, 3319 credbuf, CREDITSBUF_MAX, 3320 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 3321 d_credits_x, d_credits_y, d_credits_w, d_credits_h, EditClass::ALPHANUMERIC); 3322 3323 ListClass scenariolist(BUTTON_SCENARIOLIST, 3324 d_scenariolist_x, d_scenariolist_y, d_scenariolist_w, d_scenariolist_h, 3325 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 3326 up_button, 3327 down_button); 3328 3329 GaugeClass countgauge (BUTTON_COUNT, 3330 d_count_x, d_count_y, d_count_w, d_count_h); 3331 3332 GaugeClass levelgauge (BUTTON_LEVEL, 3333 d_level_x, d_level_y, d_level_w, d_level_h); 3334 3335 TextButtonClass basesbtn(BUTTON_BASES, TXT_BASES_OFF, 3336 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 3337 d_bases_x, d_bases_y, d_bases_w, d_bases_h); 3338 3339 TextButtonClass tiberiumbtn(BUTTON_TIBERIUM, TXT_TIBERIUM_OFF, 3340 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 3341 d_tiberium_x, d_tiberium_y, d_tiberium_w, d_tiberium_h); 3342 3343 TextButtonClass goodiesbtn(BUTTON_GOODIES, TXT_CRATES_OFF, 3344 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 3345 d_goodies_x, d_goodies_y, d_goodies_w, d_goodies_h); 3346 3347 TextButtonClass ghostsbtn(BUTTON_GHOSTS, TXT_AI_PLAYERS_OFF, 3348 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 3349 d_ghosts_x, d_ghosts_y, d_ghosts_w, d_ghosts_h); 3350 3351 TextButtonClass okbtn(BUTTON_OK, TXT_OK, 3352 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 3353 d_ok_x, d_ok_y, d_ok_w, d_ok_h); 3354 3355 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, 3356 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 3357 //#if (GERMAN | FRENCH) 3358 // d_cancel_x, d_cancel_y); 3359 //#else 3360 d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); 3361 //#endif 3362 3363 TextButtonClass sendbtn(BUTTON_SEND, TXT_SEND_MESSAGE, 3364 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 3365 //#if (GERMAN | FRENCH) 3366 // d_send_x, d_send_y); 3367 //#else 3368 d_send_x, d_send_y, d_send_w, d_send_h); 3369 //#endif 3370 3371 /* 3372 ------------------------- Build the button list -------------------------- 3373 */ 3374 commands = &name_edt; 3375 gdibtn.Add_Tail(*commands); 3376 nodbtn.Add_Tail(*commands); 3377 credit_edt.Add_Tail(*commands); 3378 scenariolist.Add_Tail(*commands); 3379 countgauge.Add_Tail(*commands); 3380 levelgauge.Add_Tail(*commands); 3381 basesbtn.Add_Tail(*commands); 3382 tiberiumbtn.Add_Tail(*commands); 3383 goodiesbtn.Add_Tail(*commands); 3384 ghostsbtn.Add_Tail(*commands); 3385 okbtn.Add_Tail(*commands); 3386 cancelbtn.Add_Tail(*commands); 3387 sendbtn.Add_Tail(*commands); 3388 3389 /* 3390 ----------------------------- Various Inits ------------------------------ 3391 */ 3392 /*........................................................................ 3393 Init player name & house 3394 ........................................................................*/ 3395 MPlayerColorIdx = MPlayerPrefColor; // init my preferred color 3396 strcpy (namebuf, MPlayerName); // set my name 3397 name_edt.Set_Text(namebuf,MPLAYER_NAME_MAX); 3398 name_edt.Set_Color(MPlayerTColors[MPlayerColorIdx]); 3399 3400 if (MPlayerHouse==HOUSE_GOOD) { 3401 gdibtn.Turn_On(); 3402 } else { 3403 nodbtn.Turn_On(); 3404 } 3405 3406 /*........................................................................ 3407 Init scenario values, only the first time through 3408 ........................................................................*/ 3409 if (first_time) { 3410 MPlayerCredits = 3000; // init credits & credit buffer 3411 MPlayerBases = 1; // init scenario parameters 3412 MPlayerTiberium = 0; 3413 MPlayerGoodies = 0; 3414 MPlayerGhosts = 0; 3415 Special.IsCaptureTheFlag = 0; 3416 MPlayerUnitCount = (MPlayerCountMax[MPlayerBases] + MPlayerCountMin[MPlayerBases]) / 2; 3417 first_time = 0; 3418 } 3419 3420 /*........................................................................ 3421 Init button states 3422 ........................................................................*/ 3423 if (MPlayerBases) { 3424 basesbtn.Turn_On(); 3425 basesbtn.Set_Text(TXT_BASES_ON); 3426 } 3427 if (MPlayerTiberium) { 3428 tiberiumbtn.Turn_On(); 3429 tiberiumbtn.Set_Text(TXT_TIBERIUM_ON); 3430 } 3431 if (MPlayerGoodies) { 3432 goodiesbtn.Turn_On(); 3433 goodiesbtn.Set_Text(TXT_CRATES_ON); 3434 } 3435 if (MPlayerGhosts) { 3436 ghostsbtn.Turn_On(); 3437 ghostsbtn.Set_Text(TXT_AI_PLAYERS_ON); 3438 } 3439 if (Special.IsCaptureTheFlag) { 3440 MPlayerGhosts = 0; 3441 ghostsbtn.Turn_On(); 3442 ghostsbtn.Set_Text(TXT_CAPTURE_THE_FLAG); 3443 } 3444 3445 sprintf(credbuf, "%d", MPlayerCredits); 3446 credit_edt.Set_Text(credbuf, CREDITSBUF_MAX); 3447 old_cred = MPlayerCredits; 3448 3449 levelgauge.Set_Maximum(MPLAYER_BUILD_LEVEL_MAX - 1); 3450 levelgauge.Set_Value(BuildLevel - 1); 3451 3452 countgauge.Set_Maximum(MPlayerCountMax[MPlayerBases] - MPlayerCountMin[MPlayerBases]); 3453 countgauge.Set_Value(MPlayerUnitCount - MPlayerCountMin[MPlayerBases]); 3454 3455 /*........................................................................ 3456 Init other scenario parameters 3457 ........................................................................*/ 3458 Special.IsTGrowth = MPlayerTiberium; 3459 Special.IsTSpread = MPlayerTiberium; 3460 transmit = 1; 3461 3462 /*........................................................................ 3463 Init scenario description list box 3464 ........................................................................*/ 3465 for (i = 0; i < MPlayerScenarios.Count(); i++) { 3466 scenariolist.Add_Item (strupr(MPlayerScenarios[i])); 3467 } 3468 ScenarioIdx = 0; // 1st scenario is selected 3469 3470 /*........................................................................ 3471 Init random-number generator, & create a seed to be used for all random 3472 numbers from here on out 3473 ........................................................................*/ 3474 randomize(); 3475 Seed = rand(); 3476 3477 /*........................................................................ 3478 Init the message display system 3479 ........................................................................*/ 3480 Messages.Init (d_message_x + 2*factor, d_message_y + 2*factor, 4, MAX_MESSAGE_LENGTH, d_txt6_h); 3481 3482 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 3483 Blit_Hid_Page_To_Seen_Buff(); 3484 Set_Palette(Palette); 3485 3486 extern char ModemRXString[]; 3487 3488 if (strlen(ModemRXString) > 36) 3489 ModemRXString[36] = 0; 3490 3491 if (strlen(ModemRXString) > 0) 3492 Messages.Add_Message (ModemRXString, CC_TAN, 3493 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, 0, 0); 3494 3495 ModemRXString[0] = '\0'; 3496 3497 /* 3498 ---------------------------- Init Mono Output ---------------------------- 3499 */ 3500 #if(SHOW_MONO) 3501 NullModem.Configure_Debug(sizeof (CommHeaderType),sizeof (SerialCommandType), 3502 SerialPacketNames, 106); 3503 NullModem.Mono_Debug_Print(1); 3504 #endif 3505 3506 /* 3507 ---------------------------- Processing loop ----------------------------- 3508 */ 3509 NullModem.Reset_Response_Time(); // clear response time 3510 theirresponsetime = 10000; // initialize to an invalid value 3511 timingtime = lastmsgtime = lastredrawtime = TickCount.Time(); 3512 while (Get_Mouse_State() > 0) Show_Mouse(); 3513 3514 3515 while (process) { 3516 3517 /* 3518 ** If we have just received input focus again after running in the background then 3519 ** we need to redraw. 3520 */ 3521 if (AllSurfaces.SurfacesRestored){ 3522 AllSurfaces.SurfacesRestored=FALSE; 3523 display=REDRAW_ALL; 3524 } 3525 3526 #if(SHOW_MONO) 3527 NullModem.Mono_Debug_Print(0); 3528 #endif 3529 3530 /* 3531 ........................ Invoke game callback ......................... 3532 */ 3533 Call_Back(); 3534 3535 /* 3536 ...................... Refresh display if needed ...................... 3537 */ 3538 if (display) { 3539 Hide_Mouse(); 3540 /* 3541 .................. Redraw backgound & dialog box ................... 3542 */ 3543 if (display >= REDRAW_BACKGROUND) { 3544 Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); 3545 3546 // init font variables 3547 3548 Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, 3549 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 3550 3551 /*............................................................... 3552 Dialog & Field labels 3553 ...............................................................*/ 3554 #ifdef FORCE_WINSOCK 3555 if (Winsock.Get_Connected()){ 3556 Draw_Caption (TXT_HOST_INTERNET_GAME, d_dialog_x, d_dialog_y, d_dialog_w); 3557 }else{ 3558 Draw_Caption (TXT_HOST_SERIAL_GAME, d_dialog_x, d_dialog_y, d_dialog_w); 3559 } 3560 #else 3561 Draw_Caption (TXT_HOST_SERIAL_GAME, d_dialog_x, d_dialog_y, d_dialog_w); 3562 #endif //FORCE_WINSOCK 3563 3564 Fancy_Text_Print(TXT_YOUR_NAME, 3565 d_name_x - 5*factor, d_name_y + 1*factor, 3566 CC_GREEN, TBLACK, 3567 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 3568 3569 Fancy_Text_Print(TXT_SIDE_COLON, 3570 d_gdi_x - 5*factor, d_gdi_y + 1*factor, 3571 CC_GREEN, TBLACK, 3572 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 3573 3574 Fancy_Text_Print (TXT_START_CREDITS_COLON, d_credits_x - 5*factor, d_credits_y + 1*factor, 3575 CC_GREEN, TBLACK, 3576 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 3577 3578 Fancy_Text_Print(TXT_COLOR_COLON, 3579 cbox_x[0] - 5*factor, d_color_y + 1*factor, 3580 CC_GREEN, TBLACK, 3581 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 3582 3583 Fancy_Text_Print(TXT_SCENARIOS, 3584 d_scenariolist_x + (d_scenariolist_w / 2), 3585 d_scenariolist_y - d_txt6_h, 3586 CC_GREEN, TBLACK, 3587 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 3588 3589 Fancy_Text_Print (TXT_COUNT, d_count_x - 3*factor, d_count_y, CC_GREEN, TBLACK, 3590 TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_RIGHT); 3591 3592 Fancy_Text_Print (TXT_LEVEL, d_level_x - 3*factor, d_level_y, CC_GREEN, TBLACK, 3593 TPF_NOSHADOW | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_RIGHT); 3594 } 3595 3596 /*.................................................................. 3597 Draw the color boxes 3598 ..................................................................*/ 3599 if (display >= REDRAW_COLORS) { 3600 for (i = 0; i < MAX_MPLAYER_COLORS; i++) { 3601 LogicPage->Fill_Rect (cbox_x[i] + 1*factor, d_color_y + 1*factor, 3602 cbox_x[i] + 1*factor + d_color_w - 2*factor, d_color_y + 1*factor + d_color_h - 2*factor, 3603 MPlayerGColors[i]); 3604 3605 if (i == MPlayerColorIdx) { 3606 Draw_Box(cbox_x[i], d_color_y, d_color_w, d_color_h, 3607 BOXSTYLE_GREEN_DOWN, false); 3608 } else { 3609 Draw_Box(cbox_x[i], d_color_y, d_color_w, d_color_h, 3610 BOXSTYLE_GREEN_RAISED, false); 3611 } 3612 } 3613 } 3614 3615 /*.................................................................. 3616 Draw the message: 3617 - Erase an old message first 3618 ..................................................................*/ 3619 if (display >= REDRAW_MESSAGE) { 3620 Draw_Box(d_message_x, d_message_y, d_message_w, d_message_h, 3621 BOXSTYLE_GREEN_BORDER, true); 3622 Messages.Draw(); 3623 3624 LogicPage->Fill_Rect (d_dialog_x + 2*factor, 3625 d_opponent_y, 3626 d_dialog_x + d_dialog_w - 4*factor, 3627 d_opponent_y + d_txt6_h, 3628 BLACK); 3629 3630 if (parms_received) { 3631 if (oppscorescreen) { 3632 sprintf(txt,"%s",Text_String(TXT_WAITING_FOR_OPPONENT)); 3633 3634 int txtwidth = String_Pixel_Width( txt ); 3635 3636 Fancy_Text_Print (txt, d_dialog_cx - (txtwidth / 2), 3637 d_opponent_y, CC_GREEN, TBLACK, 3638 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 3639 } else { 3640 Fancy_Text_Print (TXT_OPPONENT_COLON, d_opponent_x - 3*factor, 3641 d_opponent_y, CC_GREEN, TBLACK, 3642 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 3643 3644 if (TheirHouse == HOUSE_GOOD) { 3645 sprintf(txt,"%s %s",TheirName,Text_String(TXT_G_D_I)); 3646 } else { 3647 sprintf(txt,"%s %s",TheirName,Text_String(TXT_N_O_D)); 3648 } 3649 3650 Fancy_Text_Print (txt, d_opponent_x, 3651 d_opponent_y, MPlayerTColors[TheirColor], TBLACK, 3652 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 3653 } 3654 } 3655 3656 sprintf( txt, "%d ", MPlayerUnitCount ); 3657 Fancy_Text_Print (txt, d_count_x + d_count_w + 3*factor, 3658 d_count_y, CC_GREEN, BLACK, 3659 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 3660 3661 if (BuildLevel <= MPLAYER_BUILD_LEVEL_MAX) { 3662 sprintf(txt, "%d ", BuildLevel); 3663 } else { 3664 sprintf(txt, "**"); 3665 } 3666 Fancy_Text_Print (txt, d_level_x + d_level_w + 3*factor, 3667 d_level_y, CC_GREEN, BLACK, 3668 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 3669 } 3670 3671 /* 3672 .......................... Redraw buttons .......................... 3673 */ 3674 if (display >= REDRAW_BUTTONS) { 3675 commands->Flag_List_To_Redraw(); 3676 } 3677 3678 Show_Mouse(); 3679 display = REDRAW_NONE; 3680 } 3681 3682 /* 3683 ........................... Get user input ............................ 3684 */ 3685 input = commands->Input(); 3686 3687 /* 3688 ---------------------------- Process input ---------------------------- 3689 */ 3690 switch (input) { 3691 /*------------------------------------------------------------------ 3692 User clicks on a color button 3693 ------------------------------------------------------------------*/ 3694 case KN_LMOUSE: 3695 if (_Kbd->MouseQX > cbox_x[0] && 3696 _Kbd->MouseQX < (cbox_x[MAX_MPLAYER_COLORS - 1] + d_color_w) && 3697 _Kbd->MouseQY > d_color_y && 3698 _Kbd->MouseQY < (d_color_y + d_color_h)) { 3699 if (!ready_to_go){ 3700 MPlayerPrefColor = (_Kbd->MouseQX - cbox_x[0]) / d_color_w; 3701 MPlayerColorIdx = MPlayerPrefColor; 3702 display = REDRAW_COLORS; 3703 3704 name_edt.Set_Color (MPlayerTColors[MPlayerColorIdx]); 3705 name_edt.Flag_To_Redraw(); 3706 MPlayerCredits = atoi(credbuf); 3707 strcpy (MPlayerName, namebuf); 3708 transmit = 1; 3709 changed = 1; 3710 } 3711 } 3712 break; 3713 3714 /*------------------------------------------------------------------ 3715 User edits the name field; retransmit new game options 3716 ------------------------------------------------------------------*/ 3717 case (BUTTON_NAME | KN_BUTTON): 3718 if (!ready_to_go){ 3719 credit_edt.Clear_Focus(); 3720 credit_edt.Flag_To_Redraw(); 3721 MPlayerCredits = atoi(credbuf); 3722 strcpy (MPlayerName, namebuf); 3723 transmit = 1; 3724 changed = 1; 3725 } 3726 break; 3727 3728 /*------------------------------------------------------------------ 3729 House Buttons: set the player's desired House 3730 ------------------------------------------------------------------*/ 3731 case (BUTTON_GDI | KN_BUTTON): 3732 if (!ready_to_go){ 3733 MPlayerHouse = HOUSE_GOOD; 3734 gdibtn.Turn_On(); 3735 nodbtn.Turn_Off(); 3736 MPlayerCredits = atoi(credbuf); 3737 strcpy (MPlayerName, namebuf); 3738 transmit = 1; 3739 } 3740 break; 3741 3742 case (BUTTON_NOD | KN_BUTTON): 3743 if (!ready_to_go){ 3744 MPlayerHouse = HOUSE_BAD; 3745 gdibtn.Turn_Off(); 3746 nodbtn.Turn_On(); 3747 MPlayerCredits = atoi(credbuf); 3748 strcpy (MPlayerName, namebuf); 3749 transmit = 1; 3750 } 3751 break; 3752 3753 /*------------------------------------------------------------------ 3754 User edits the credits value; retransmit new game options 3755 ------------------------------------------------------------------*/ 3756 case (BUTTON_CREDITS | KN_BUTTON): 3757 if (!ready_to_go){ 3758 name_edt.Clear_Focus(); 3759 name_edt.Flag_To_Redraw(); 3760 MPlayerCredits = atoi(credbuf); 3761 strcpy (MPlayerName, namebuf); 3762 transmit = 1; 3763 } 3764 break; 3765 3766 /*------------------------------------------------------------------ 3767 New Scenario selected. 3768 ------------------------------------------------------------------*/ 3769 case (BUTTON_SCENARIOLIST | KN_BUTTON): 3770 if (scenariolist.Current_Index() != ScenarioIdx && !ready_to_go) { 3771 ScenarioIdx = scenariolist.Current_Index(); 3772 MPlayerCredits = atoi(credbuf); 3773 strcpy (MPlayerName, namebuf); 3774 transmit = 1; 3775 } 3776 break; 3777 3778 /*------------------------------------------------------------------ 3779 User adjusts max # units 3780 ------------------------------------------------------------------*/ 3781 case (BUTTON_COUNT | KN_BUTTON): 3782 if (!ready_to_go){ 3783 MPlayerUnitCount = countgauge.Get_Value() + MPlayerCountMin[MPlayerBases]; 3784 if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; 3785 transmit = 1; 3786 } 3787 break; 3788 3789 /*------------------------------------------------------------------ 3790 User adjusts build level 3791 ------------------------------------------------------------------*/ 3792 case (BUTTON_LEVEL | KN_BUTTON): 3793 if (!ready_to_go){ 3794 BuildLevel = levelgauge.Get_Value() + 1; 3795 if (BuildLevel > MPLAYER_BUILD_LEVEL_MAX) // if it's pegged, max it out 3796 BuildLevel = MPLAYER_BUILD_LEVEL_MAX; 3797 if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; 3798 transmit = 1; 3799 } 3800 break; 3801 3802 /*------------------------------------------------------------------ 3803 Toggle bases 3804 ------------------------------------------------------------------*/ 3805 case (BUTTON_BASES | KN_BUTTON): 3806 if (!ready_to_go){ 3807 if (MPlayerBases) { 3808 MPlayerBases = 0; 3809 basesbtn.Turn_Off(); 3810 basesbtn.Set_Text(TXT_BASES_OFF); 3811 MPlayerUnitCount = Fixed_To_Cardinal (MPlayerCountMax[0]-MPlayerCountMin[0], 3812 Cardinal_To_Fixed(MPlayerCountMax[1]-MPlayerCountMin[1], 3813 MPlayerUnitCount-MPlayerCountMin[1])) + MPlayerCountMin[0]; 3814 } else { 3815 MPlayerBases = 1; 3816 basesbtn.Turn_On(); 3817 basesbtn.Set_Text(TXT_BASES_ON); 3818 MPlayerUnitCount = Fixed_To_Cardinal (MPlayerCountMax[1]-MPlayerCountMin[1], 3819 Cardinal_To_Fixed(MPlayerCountMax[0]-MPlayerCountMin[0], 3820 MPlayerUnitCount-MPlayerCountMin[0])) + MPlayerCountMin[1]; 3821 } 3822 MPlayerCredits = atoi(credbuf); 3823 countgauge.Set_Maximum(MPlayerCountMax[MPlayerBases] - MPlayerCountMin[MPlayerBases]); 3824 countgauge.Set_Value(MPlayerUnitCount - MPlayerCountMin[MPlayerBases]); 3825 strcpy (MPlayerName, namebuf); 3826 transmit = 1; 3827 display = REDRAW_ALL; 3828 } 3829 break; 3830 3831 /*------------------------------------------------------------------ 3832 Toggle tiberium 3833 ------------------------------------------------------------------*/ 3834 case (BUTTON_TIBERIUM | KN_BUTTON): 3835 if (!ready_to_go){ 3836 if (MPlayerTiberium) { 3837 MPlayerTiberium = 0; 3838 Special.IsTGrowth = 0; 3839 Special.IsTSpread = 0; 3840 tiberiumbtn.Turn_Off(); 3841 tiberiumbtn.Set_Text(TXT_TIBERIUM_OFF); 3842 } else { 3843 MPlayerTiberium = 1; 3844 Special.IsTGrowth = 1; 3845 Special.IsTSpread = 1; 3846 tiberiumbtn.Turn_On(); 3847 tiberiumbtn.Set_Text(TXT_TIBERIUM_ON); 3848 } 3849 MPlayerCredits = atoi(credbuf); 3850 strcpy (MPlayerName, namebuf); 3851 transmit = 1; 3852 } 3853 break; 3854 3855 /*------------------------------------------------------------------ 3856 Toggle goodies 3857 ------------------------------------------------------------------*/ 3858 case (BUTTON_GOODIES | KN_BUTTON): 3859 if (!ready_to_go){ 3860 if (MPlayerGoodies) { 3861 MPlayerGoodies = 0; 3862 goodiesbtn.Turn_Off(); 3863 goodiesbtn.Set_Text(TXT_CRATES_OFF); 3864 } else { 3865 MPlayerGoodies = 1; 3866 goodiesbtn.Turn_On(); 3867 goodiesbtn.Set_Text(TXT_CRATES_ON); 3868 } 3869 MPlayerCredits = atoi(credbuf); 3870 strcpy (MPlayerName, namebuf); 3871 transmit = 1; 3872 } 3873 break; 3874 3875 /*------------------------------------------------------------------ 3876 Toggle ghosts 3877 ------------------------------------------------------------------*/ 3878 case (BUTTON_GHOSTS | KN_BUTTON): 3879 if (!ready_to_go){ 3880 if (!MPlayerGhosts && !Special.IsCaptureTheFlag) { // ghosts OFF => ghosts ON 3881 MPlayerGhosts = 1; 3882 Special.IsCaptureTheFlag = 0; 3883 ghostsbtn.Turn_On(); 3884 ghostsbtn.Set_Text(TXT_AI_PLAYERS_ON); 3885 } 3886 else if (MPlayerGhosts) { // ghosts ON => capture-flag 3887 MPlayerGhosts = 0; 3888 Special.IsCaptureTheFlag = 1; 3889 ghostsbtn.Turn_On(); 3890 ghostsbtn.Set_Text(TXT_CAPTURE_THE_FLAG); 3891 } 3892 else if (Special.IsCaptureTheFlag) { // capture-flag => AI OFF 3893 MPlayerGhosts = 0; 3894 Special.IsCaptureTheFlag = 0; 3895 ghostsbtn.Turn_Off(); 3896 ghostsbtn.Set_Text(TXT_AI_PLAYERS_OFF); 3897 } 3898 MPlayerCredits = atoi(credbuf); 3899 strcpy (MPlayerName, namebuf); 3900 transmit = 1; 3901 } 3902 break; 3903 3904 /*------------------------------------------------------------------ 3905 OK: exit loop with true status 3906 ------------------------------------------------------------------*/ 3907 case (BUTTON_OK | KN_BUTTON): 3908 if (!ready_to_go){ 3909 // 3910 // make sure we got a game options packet from the other player 3911 // 3912 if (gameoptions) { 3913 //rc = true; 3914 //process = false; 3915 3916 // force transmitting of game options packet one last time 3917 3918 3919 3920 SendPacket.Command = SERIAL_READY_TO_GO; 3921 SendPacket.ID = ModemGameToPlay; 3922 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 3923 3924 starttime = TickCount.Time(); 3925 3926 while ( ( NullModem.Num_Send() 3927 && ((TickCount.Time() - starttime) < PACKET_SENDING_TIMEOUT) )){ 3928 #if(SHOW_MONO) 3929 NullModem.Mono_Debug_Print(0); 3930 #endif 3931 3932 NullModem.Service(); 3933 Keyboard::Check(); //Make sure the message loop gets called 3934 } 3935 3936 ready_to_go = true; 3937 ready_time.Set(120, true); 3938 3939 transmit = 1; 3940 transmittime = 0; 3941 3942 } else { 3943 CCMessageBox().Process (TXT_ONLY_ONE,TXT_OOPS,NULL); 3944 display = REDRAW_ALL; 3945 } 3946 } 3947 break; 3948 3949 /*------------------------------------------------------------------ 3950 CANCEL: send a SIGN_OFF, bail out with error code 3951 ------------------------------------------------------------------*/ 3952 case (KN_ESC): 3953 if (!ready_to_go){ 3954 if (Messages.Get_Edit_Buf() != NULL) { 3955 Messages.Input(input); 3956 if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; 3957 break; 3958 } 3959 } 3960 case (BUTTON_CANCEL | KN_BUTTON): 3961 if (!ready_to_go){ 3962 process = false; 3963 rc = false; 3964 } 3965 break; 3966 3967 /*------------------------------------------------------------------ 3968 Default: manage the inter-player messages 3969 ------------------------------------------------------------------*/ 3970 default: 3971 if (ready_to_go) break; 3972 3973 /*............................................................... 3974 F4/SEND/'M' = send a message 3975 ...............................................................*/ 3976 if (Messages.Get_Edit_Buf()==NULL) { 3977 if (input == KN_M || input==(BUTTON_SEND | KN_BUTTON) || 3978 input == KN_F4) { 3979 memset (txt, 0, 80); 3980 3981 strcpy(txt,Text_String(TXT_MESSAGE)); // "Message:" 3982 3983 Messages.Add_Edit (MPlayerTColors[MPlayerColorIdx], 3984 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, txt, d_message_w-70*factor); 3985 if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; 3986 3987 credit_edt.Clear_Focus(); 3988 credit_edt.Flag_To_Redraw(); 3989 name_edt.Clear_Focus(); 3990 name_edt.Flag_To_Redraw(); 3991 3992 break; 3993 } 3994 } else { 3995 if ( input == (BUTTON_SEND | KN_BUTTON) ) { 3996 input = KN_RETURN; 3997 } 3998 } 3999 4000 /*............................................................... 4001 Manage the message system (get rid of old messages) 4002 ...............................................................*/ 4003 if (Messages.Manage()) { 4004 if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; 4005 } 4006 4007 /*............................................................... 4008 Service keyboard input for any message being edited. 4009 ...............................................................*/ 4010 i = Messages.Input(input); 4011 4012 /*............................................................... 4013 If 'Input' returned 1, it means refresh the message display. 4014 ...............................................................*/ 4015 if (i==1) { 4016 Messages.Draw(); 4017 } 4018 4019 /*............................................................... 4020 If 'Input' returned 2, it means redraw the message display. 4021 ...............................................................*/ 4022 else if (i==2) { 4023 if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; 4024 } 4025 4026 /*............................................................... 4027 If 'input' returned 3, it means send the current message. 4028 ...............................................................*/ 4029 else if (i==3) { 4030 long actual_message_size; 4031 char *the_string; 4032 4033 sent_so_far = 0; 4034 magic_number = MESSAGE_HEAD_MAGIC_NUMBER; 4035 message_length = strlen(Messages.Get_Edit_Buf()); 4036 crc = (unsigned short) 4037 (Calculate_CRC(Messages.Get_Edit_Buf(), message_length) &0xffff); 4038 4039 while (sent_so_far < message_length){ 4040 4041 SendPacket.Command = SERIAL_MESSAGE; 4042 strcpy (SendPacket.Name, MPlayerName); 4043 SendPacket.ID = Build_MPlayerID(MPlayerColorIdx, MPlayerHouse); 4044 memcpy (SendPacket.Message, Messages.Get_Edit_Buf()+sent_so_far, COMPAT_MESSAGE_LENGTH-5); 4045 4046 /* 4047 ** Steve I's stuff for splitting message on word boundries 4048 */ 4049 actual_message_size = COMPAT_MESSAGE_LENGTH - 5; 4050 4051 /* Start at the end of the message and find a space with 10 chars. */ 4052 the_string = SendPacket.Message; 4053 while ( (COMPAT_MESSAGE_LENGTH -5) -actual_message_size < 10 && 4054 the_string[actual_message_size] != ' '){ 4055 --actual_message_size; 4056 } 4057 if ( the_string[actual_message_size] == ' ' ){ 4058 4059 /* Now delete the extra characters after the space (they musnt print) */ 4060 for ( int i=0 ; i< (COMPAT_MESSAGE_LENGTH-5) - actual_message_size; i++ ){ 4061 the_string[i + actual_message_size] = 0xff; 4062 } 4063 }else{ 4064 actual_message_size = COMPAT_MESSAGE_LENGTH - 5; 4065 } 4066 4067 *(SendPacket.Message + COMPAT_MESSAGE_LENGTH-5) = 0; 4068 *((unsigned short*)(SendPacket.Message + COMPAT_MESSAGE_LENGTH-4)) = magic_number; 4069 *((unsigned short*)(SendPacket.Message + COMPAT_MESSAGE_LENGTH-2)) = crc; 4070 4071 /*.................................................................. 4072 Send the message 4073 ..................................................................*/ 4074 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 4075 NullModem.Service(); 4076 4077 /*.................................................................. 4078 Add the message to our own screen 4079 ..................................................................*/ 4080 sprintf(txt, Text_String (TXT_FROM), MPlayerName, SendPacket.Message); 4081 Messages.Add_Message (txt, MPlayerTColors[MPlayerColorIdx], 4082 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, magic_number, crc); 4083 4084 magic_number++; 4085 sent_so_far += actual_message_size; //COMPAT_MESSAGE_LENGTH-5; 4086 } 4087 4088 if (display < REDRAW_MESSAGE) display = REDRAW_MESSAGE; 4089 } /* end of send message */ 4090 4091 } /* end of input processing */ 4092 4093 /*--------------------------------------------------------------------- 4094 Detect editing of the credits buffer, transmit new values to players 4095 ---------------------------------------------------------------------*/ 4096 if (atoi(credbuf) != old_cred) { 4097 old_cred = Bound(atoi(credbuf), 0, 9999); 4098 MPlayerCredits = old_cred; 4099 transmit = 1; 4100 sprintf(credbuf, "%d", MPlayerCredits); 4101 credit_edt.Set_Text(credbuf, CREDITSBUF_MAX); 4102 } 4103 4104 /*--------------------------------------------------------------------- 4105 Detect editing of the name buffer, transmit new values to players 4106 ---------------------------------------------------------------------*/ 4107 if (strcmp (namebuf, MPlayerName)) { 4108 strcpy (MPlayerName, namebuf); 4109 transmit = 1; 4110 changed = 1; 4111 } 4112 4113 /*--------------------------------------------------------------------- 4114 If our Transmit flag is set, we need to send out a game option packet. 4115 This message requires an ACK. The first time through the loop, transmit 4116 should be set, so we send out our default options; we'll then send 4117 any changes we make to the defaults. 4118 ---------------------------------------------------------------------*/ 4119 if (transmit && (TickCount.Time() - transmittime) > PACKET_RETRANS_TIME) { 4120 SendPacket.Command = SERIAL_GAME_OPTIONS; 4121 strcpy (SendPacket.Name, MPlayerName); 4122 #ifdef PATCH 4123 if (IsV107) { 4124 SendPacket.Version = 1; 4125 } else { 4126 SendPacket.Version = 2; 4127 } 4128 #else 4129 SendPacket.Version = Version_Number(); 4130 #endif 4131 SendPacket.House = MPlayerHouse; 4132 SendPacket.Color = MPlayerColorIdx; 4133 4134 SendPacket.Scenario = MPlayerFilenum[ScenarioIdx]; 4135 4136 SendPacket.Credits = MPlayerCredits; 4137 SendPacket.IsBases = MPlayerBases; 4138 SendPacket.IsTiberium = MPlayerTiberium; 4139 SendPacket.IsGoodies = MPlayerGoodies; 4140 SendPacket.IsGhosties = MPlayerGhosts; 4141 SendPacket.BuildLevel = BuildLevel; 4142 SendPacket.UnitCount = MPlayerUnitCount; 4143 SendPacket.Seed = Seed; 4144 SendPacket.Special = Special; 4145 SendPacket.GameSpeed = Options.GameSpeed; 4146 SendPacket.ID = ModemGameToPlay; 4147 4148 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 4149 4150 transmittime = TickCount.Time(); 4151 transmit = 0; 4152 4153 starttime = TickCount.Time(); 4154 while ( ( NullModem.Num_Send() 4155 && ((TickCount.Time() - starttime) < PACKET_SENDING_TIMEOUT) )){ 4156 #if(SHOW_MONO) 4157 NullModem.Mono_Debug_Print(0); 4158 #endif 4159 4160 NullModem.Service(); 4161 Keyboard::Check(); //Make sure the message loop gets called 4162 } 4163 } 4164 4165 // 4166 // send a timing packet if enough time has gone by. 4167 // 4168 if ( (TickCount.Time() - timingtime) > PACKET_TIMING_TIMEOUT) { 4169 SendPacket.Command = SERIAL_TIMING; 4170 SendPacket.ResponseTime = NullModem.Response_Time(); 4171 SendPacket.ID = ModemGameToPlay; 4172 4173 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 0); 4174 timingtime = TickCount.Time(); 4175 } 4176 4177 /*--------------------------------------------------------------------- 4178 Check for an incoming message 4179 ---------------------------------------------------------------------*/ 4180 while (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { 4181 // Smart_Printf( "received packet of length %d\n", packetlen ); 4182 4183 lastmsgtime = TickCount.Time(); 4184 msg_timeout = 600; // reset timeout value to 10 seconds 4185 // (only the 1st time through is 20 seconds) 4186 4187 // are we getting our own packets back?? 4188 4189 if (ReceivePacket.Command >= SERIAL_CONNECT && 4190 ReceivePacket.Command < SERIAL_LAST_COMMAND && 4191 ReceivePacket.Command != SERIAL_MESSAGE && 4192 ReceivePacket.ID == ModemGameToPlay) { 4193 4194 CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); 4195 4196 // to skip the other system not responding msg 4197 lastmsgtime = TickCount.Time(); 4198 4199 process = false; 4200 rc = false; 4201 4202 // say we did receive sign off to keep from sending one 4203 recsignedoff = true; 4204 break; 4205 } 4206 4207 event = (EventClass *)&ReceivePacket; 4208 if (event->Type <= EventClass::FRAMEINFO) { 4209 if ( (TickCount.Time() - lastredrawtime) > PACKET_REDRAW_TIME) { 4210 lastredrawtime = TickCount.Time(); 4211 oppscorescreen = true; 4212 4213 if (display != REDRAW_ALL) { 4214 display = REDRAW_MESSAGE; 4215 } 4216 4217 // display = REDRAW_MESSAGE; 4218 parms_received = 1; 4219 } 4220 } else { 4221 switch ( ReceivePacket.Command ) { 4222 /*.................................................................. 4223 Sign-off: Give the other machine time to receive my ACK, display a 4224 message, and exit. 4225 ..................................................................*/ 4226 case (SERIAL_SIGN_OFF): 4227 // Smart_Printf( "received sign off\n" ); 4228 starttime = TickCount.Time(); 4229 while (TickCount.Time() - starttime < 60) 4230 NullModem.Service(); 4231 CCMessageBox().Process(TXT_USER_SIGNED_OFF); 4232 4233 // to skip the other system not responding msg 4234 lastmsgtime = TickCount.Time(); 4235 4236 process = false; 4237 rc = false; 4238 recsignedoff = true; 4239 break; 4240 4241 /*.................................................................. 4242 Game Options: Store the other machine's name, color & house; 4243 If they've picked the same color as myself, re-transmit my settings 4244 to force him to choose a different color. (Com_Show_Scenario_Dialog 4245 is responsible for ensuring the colors are different.) 4246 ..................................................................*/ 4247 case (SERIAL_GAME_OPTIONS): 4248 // Smart_Printf( "received game options\n" ); 4249 oppscorescreen = false; 4250 gameoptions = true; 4251 strcpy (TheirName, ReceivePacket.Name); 4252 TheirColor = ReceivePacket.Color; 4253 TheirHouse = ReceivePacket.House; 4254 transmit = 1; 4255 4256 parms_received = 1; 4257 if (display != REDRAW_ALL) { 4258 display = REDRAW_MESSAGE; 4259 } 4260 // display = REDRAW_MESSAGE; 4261 4262 /*............................................................... 4263 Check the version number of the other system. 4264 ...............................................................*/ 4265 #ifdef PATCH 4266 if (IsV107) { 4267 version = 1; 4268 } else { 4269 version = 2; 4270 } 4271 #else 4272 version = Version_Number(); 4273 #endif 4274 if (ReceivePacket.Version > version) { 4275 CCMessageBox().Process (TXT_YOURGAME_OUTDATED); 4276 4277 // to skip the other system not responding msg 4278 lastmsgtime = TickCount.Time(); 4279 4280 process = false; 4281 rc = false; 4282 } else { 4283 if (ReceivePacket.Version < version) { 4284 CCMessageBox().Process (TXT_DESTGAME_OUTDATED); 4285 4286 // to skip the other system not responding msg 4287 lastmsgtime = TickCount.Time(); 4288 4289 process = false; 4290 rc = false; 4291 } 4292 } 4293 break; 4294 4295 /*.................................................................. 4296 Incoming message: add to our list 4297 ..................................................................*/ 4298 case (SERIAL_MESSAGE): 4299 // Smart_Printf( "received serial message\n" ); 4300 oppscorescreen = false; 4301 sprintf(txt, Text_String (TXT_FROM), ReceivePacket.Name, 4302 ReceivePacket.Message); 4303 magic_number = *((unsigned short*)(ReceivePacket.Message + COMPAT_MESSAGE_LENGTH-4)); 4304 crc = *((unsigned short*)(ReceivePacket.Message + COMPAT_MESSAGE_LENGTH-2)); 4305 Messages.Add_Message (txt, 4306 MPlayerTColors[MPlayerID_To_ColorIndex(ReceivePacket.ID)], 4307 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, magic_number, crc); 4308 if (display != REDRAW_ALL) { 4309 display = REDRAW_MESSAGE; 4310 } 4311 // display = REDRAW_MESSAGE; 4312 break; 4313 4314 // 4315 // get their response time 4316 // 4317 case (SERIAL_TIMING): 4318 // Smart_Printf( "received timing\n" ); 4319 oppscorescreen = false; 4320 theirresponsetime = ReceivePacket.ResponseTime; 4321 4322 if ( !gameoptions ) { 4323 4324 // retransmit of game options packet again 4325 transmit = 1; 4326 } 4327 break; 4328 4329 // 4330 // print msg waiting for opponent 4331 // 4332 case (SERIAL_SCORE_SCREEN): 4333 // Smart_Printf( "received score screen\n" ); 4334 oppscorescreen = true; 4335 if (display != REDRAW_ALL) { 4336 display = REDRAW_MESSAGE; 4337 } 4338 // display = REDRAW_MESSAGE; 4339 parms_received = 1; 4340 break; 4341 4342 default: 4343 // Smart_Printf( "received unknown command %X\n", ReceivePacket.Command ); 4344 break; 4345 } 4346 } 4347 } 4348 4349 // if we haven't received a msg for 10 seconds exit 4350 4351 if ( (TickCount.Time() - lastmsgtime) > msg_timeout) { 4352 CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); 4353 process = false; 4354 rc = false; 4355 4356 // say we did receive sign off to keep from sending one 4357 recsignedoff = true; 4358 } 4359 4360 /*--------------------------------------------------------------------- 4361 Service the connection 4362 ---------------------------------------------------------------------*/ 4363 NullModem.Service(); 4364 4365 /* 4366 ** If user has clicked 'GO' and the timeout has elapsed then quit the loop 4367 */ 4368 if ( ready_to_go && ready_time.Time() == 0 ){ 4369 rc = 1; 4370 process = false; 4371 } 4372 4373 } /* end of while */ 4374 4375 /*------------------------------------------------------------------------ 4376 Sort player ID's, so we can execute commands in the same order on both 4377 machines. 4378 ------------------------------------------------------------------------*/ 4379 if (rc) { 4380 /*..................................................................... 4381 Set the number of players in this game, and my ID 4382 .....................................................................*/ 4383 MPlayerCount = 2; 4384 MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); 4385 4386 TheirID = Build_MPlayerID (TheirColor,TheirHouse); 4387 4388 /*..................................................................... 4389 Store every player's ID in the MPlayerID[] array. This array will 4390 determine the order of event execution, so the ID's must be stored 4391 in the same order on all systems. 4392 .....................................................................*/ 4393 if (TheirID < MPlayerLocalID) { 4394 MPlayerID[0] = TheirID; 4395 MPlayerID[1] = MPlayerLocalID; 4396 strcpy (MPlayerNames[0], TheirName); 4397 strcpy (MPlayerNames[1], MPlayerName); 4398 } else { 4399 MPlayerID[0] = MPlayerLocalID; 4400 MPlayerID[1] = TheirID; 4401 strcpy (MPlayerNames[0], MPlayerName); 4402 strcpy (MPlayerNames[1], TheirName); 4403 } 4404 4405 /*..................................................................... 4406 Get the scenario filename 4407 .....................................................................*/ 4408 Scenario = MPlayerFilenum[ScenarioIdx]; 4409 4410 /*..................................................................... 4411 Send all players the GO packet. 4412 .....................................................................*/ 4413 SendPacket.Command = SERIAL_GO; 4414 SendPacket.ResponseTime = NullModem.Response_Time(); 4415 if ( theirresponsetime == 10000 ) { 4416 // Mono_Clear_Screen(); 4417 // Smart_Printf( "Did not receive their response time!!!!!!!\n" ); 4418 // Get_Key(); 4419 } else { 4420 if (SendPacket.ResponseTime < theirresponsetime) { 4421 SendPacket.ResponseTime = theirresponsetime; 4422 } 4423 } 4424 4425 // 4426 // calculated one way delay for a packet and overall delay to execute 4427 // a packet 4428 // 4429 MPlayerMaxAhead = MAX( (SendPacket.ResponseTime / 8), 2); 4430 char flip[128]; 4431 sprintf (flip, "C&C95 - MaxAhead set to %d frames\n", MPlayerMaxAhead); 4432 CCDebugString (flip); 4433 4434 SendPacket.ID = ModemGameToPlay; 4435 4436 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 4437 4438 starttime = TickCount.Time(); 4439 while ( ( NullModem.Num_Send() 4440 && ((TickCount.Time() - starttime) < PACKET_SENDING_TIMEOUT) )){ 4441 #if(SHOW_MONO) 4442 NullModem.Mono_Debug_Print(0); 4443 #endif 4444 4445 NullModem.Service(); 4446 Keyboard::Check(); //Make sure the message loop gets called 4447 } 4448 4449 // clear queue to keep from doing any resends 4450 NullModem.Init_Send_Queue(); 4451 4452 } else { 4453 if ( !recsignedoff ) { 4454 /*..................................................................... 4455 Broadcast my sign-off over my network 4456 .....................................................................*/ 4457 SendPacket.Command = SERIAL_SIGN_OFF; 4458 SendPacket.Color = MPlayerLocalID; // use Color for ID 4459 SendPacket.ID = ModemGameToPlay; 4460 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 4461 4462 starttime = TickCount.Time(); 4463 while ( (NullModem.Num_Send() 4464 && ((TickCount.Time() - starttime) < PACKET_CANCEL_TIMEOUT) )){ 4465 #if(SHOW_MONO) 4466 NullModem.Mono_Debug_Print(0); 4467 #endif 4468 4469 if ( NullModem.Get_Message( &ReceivePacket, &packetlen ) > 0) { 4470 4471 // are we getting our own packets back?? 4472 4473 if (ReceivePacket.Command == SERIAL_SIGN_OFF 4474 && ReceivePacket.ID == ModemGameToPlay) { 4475 4476 // exit while 4477 break; 4478 } 4479 } 4480 4481 NullModem.Service(); 4482 } 4483 } 4484 4485 Shutdown_Modem(); 4486 } 4487 4488 /*------------------------------------------------------------------------ 4489 Clear all lists 4490 ------------------------------------------------------------------------*/ 4491 while (scenariolist.Count()) { 4492 scenariolist.Remove_Item(scenariolist.Get_Item(0)); 4493 } 4494 4495 /*------------------------------------------------------------------------ 4496 Restore screen 4497 ------------------------------------------------------------------------*/ 4498 Hide_Mouse(); 4499 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 4500 Blit_Hid_Page_To_Seen_Buff(); 4501 Show_Mouse(); 4502 4503 /*------------------------------------------------------------------------ 4504 Save any changes made to our options 4505 ------------------------------------------------------------------------*/ 4506 if (changed) { 4507 Write_MultiPlayer_Settings (); 4508 } 4509 4510 return(rc); 4511 4512 } /* end of Com_Scenario_Dialog */ 4513 4514 4515 /*********************************************************************************************** 4516 * Com_Show_Scenario_Dialog -- Serial game scenario selection dialog * 4517 * * 4518 * * 4519 * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * 4520 * ³ Serial Game ³ * 4521 * ³ ³ * 4522 * ³ Your Name: __________ ³ * 4523 * ³ House: [GDI] [NOD] ³ * 4524 * ³ Desired Color: [ ][ ][ ][ ] ³ * 4525 * ³ ³ * 4526 * ³ Opponent: Name ³ * 4527 * ³ Scenario: Description ³ * 4528 * ³ Credits: xxxx ³ * 4529 * ³ Bases: ON ³ * 4530 * ³ Crates: ON ³ * 4531 * ³ Tiberium: ON ³ * 4532 * ³ Ghosts: ON ³ * 4533 * ³ ³ * 4534 * ³ [Cancel] ³ * 4535 * ³ ³ * 4536 * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ * 4537 * ³ ³ ³ ³ * 4538 * ³ ³ ³ ³ * 4539 * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * 4540 * ³ [Send Message] ³ * 4541 * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * 4542 * * 4543 * INPUT: * 4544 * none. * 4545 * * 4546 * OUTPUT: * 4547 * true = success, false = cancel * 4548 * * 4549 * WARNINGS: * 4550 * MPlayerName & MPlayerGameName must contain this player's name. * 4551 * * 4552 * HISTORY: * 4553 * 02/14/1995 BR : Created. * 4554 *=============================================================================================*/ 4555 int Com_Show_Scenario_Dialog(void) 4556 { 4557 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 4558 /*........................................................................ 4559 Dialog & button dimensions 4560 ........................................................................*/ 4561 int d_dialog_w = 306*factor; // dialog width 4562 int d_dialog_h = 187*factor; // dialog height 4563 int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord 4564 int d_dialog_y = ((200*factor - d_dialog_h) / 2); // dialog y-coord 4565 int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord 4566 4567 int d_txt6_h = 6*factor+1; // ht of 6-pt text 4568 int d_margin1 = 5*factor; // margin width/height 4569 int d_margin2 = 2*factor; // margin width/height 4570 4571 int d_name_w = 70*factor; 4572 int d_name_h = 9*factor; 4573 int d_name_x = d_dialog_cx; 4574 int d_name_y = d_dialog_y + d_margin1 + d_txt6_h + d_txt6_h; 4575 4576 int d_gdi_w = 30*factor; 4577 int d_gdi_h = 9*factor; 4578 int d_gdi_x = d_dialog_cx; 4579 int d_gdi_y = d_name_y + d_name_h + d_margin2; 4580 4581 int d_nod_w = 30*factor; 4582 int d_nod_h = 9*factor; 4583 int d_nod_x = d_gdi_x + d_gdi_w + d_margin2; 4584 int d_nod_y = d_gdi_y; 4585 4586 int d_color_w = 10*factor; 4587 int d_color_h = 9*factor; 4588 int d_color_y = d_gdi_y + d_gdi_h + d_margin2; 4589 4590 int d_opponent_y = d_color_y + d_color_h + d_margin1; 4591 int d_scenario_y = d_opponent_y + d_txt6_h; 4592 int d_credits_y = d_scenario_y + d_txt6_h; 4593 int d_count_y = d_credits_y + d_txt6_h; 4594 int d_level_y = d_count_y + d_txt6_h; 4595 int d_bases_y = d_level_y + d_txt6_h; 4596 int d_goodies_y = d_bases_y + d_txt6_h; 4597 int d_tiberium_y = d_goodies_y + d_txt6_h; 4598 int d_ghosts_y = d_tiberium_y + d_txt6_h; 4599 4600 int d_cancel_w = 45*factor; 4601 int d_cancel_h = 9*factor; 4602 int d_cancel_x = d_dialog_cx - (d_cancel_w / 2); 4603 int d_cancel_y = d_ghosts_y + d_txt6_h + d_margin1; 4604 4605 int d_message_w = d_dialog_w - (d_margin1 * 2); 4606 int d_message_h = 34*factor; 4607 int d_message_x = d_dialog_x + d_margin1; 4608 int d_message_y = d_cancel_y + d_cancel_h + d_margin1; 4609 4610 int d_send_w = 80*factor; 4611 int d_send_h = 9*factor; 4612 int d_send_x = d_dialog_cx - (d_send_w / 2); 4613 int d_send_y = d_message_y + d_message_h + d_margin2; 4614 4615 /*........................................................................ 4616 Button Enumerations 4617 ........................................................................*/ 4618 enum { 4619 BUTTON_NAME = 100, 4620 BUTTON_GDI, 4621 BUTTON_NOD, 4622 BUTTON_CANCEL, 4623 BUTTON_SEND, 4624 }; 4625 4626 /*........................................................................ 4627 Redraw values: in order from "top" to "bottom" layer of the dialog 4628 ........................................................................*/ 4629 typedef enum { 4630 REDRAW_NONE = 0, 4631 REDRAW_MESSAGE, 4632 REDRAW_COLORS, 4633 REDRAW_BUTTONS, 4634 REDRAW_BACKGROUND, 4635 REDRAW_ALL = REDRAW_BACKGROUND 4636 } RedrawType; 4637 4638 /*........................................................................ 4639 Dialog variables 4640 ........................................................................*/ 4641 RedrawType display = REDRAW_ALL; // redraw level 4642 BOOL process = true; // process while true 4643 KeyNumType input; 4644 4645 char namebuf[MPLAYER_NAME_MAX] = {0}; // buffer for player's name 4646 int transmit; // 1 = re-transmit new game options 4647 int first; // 1 = no packets received yet 4648 int cbox_x[] = { d_dialog_cx, 4649 d_dialog_cx + d_color_w, 4650 d_dialog_cx + (d_color_w * 2), 4651 d_dialog_cx + (d_color_w * 3), 4652 d_dialog_cx + (d_color_w * 4), 4653 d_dialog_cx + (d_color_w * 5)}; 4654 int parms_received = 0; // 1 = game options received 4655 int changed = 0; // 1 = user has changed an option 4656 4657 int rc; 4658 int recsignedoff = 0; 4659 int i; 4660 int version; 4661 char txt[80]; 4662 unsigned long starttime; 4663 unsigned long timingtime; 4664 unsigned long lastmsgtime; 4665 unsigned long lastredrawtime; 4666 unsigned long transmittime = 0; 4667 int packetlen; 4668 bool oppscorescreen = false; 4669 bool gameoptions = false; 4670 EventClass *event; // event ptr 4671 unsigned long msg_timeout = 1200; // init to 20 seconds 4672 4673 int message_length; 4674 int sent_so_far; 4675 unsigned short magic_number; 4676 unsigned short crc; 4677 bool ready_to_go = false; 4678 4679 /*........................................................................ 4680 Buttons 4681 ........................................................................*/ 4682 GadgetClass *commands; // button list 4683 4684 EditClass name_edt (BUTTON_NAME, 4685 namebuf, MPLAYER_NAME_MAX, 4686 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 4687 d_name_x, d_name_y, d_name_w, d_name_h, EditClass::ALPHANUMERIC); 4688 4689 TextButtonClass gdibtn(BUTTON_GDI, TXT_G_D_I, 4690 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 4691 d_gdi_x, d_gdi_y, d_gdi_w, d_gdi_h); 4692 4693 TextButtonClass nodbtn(BUTTON_NOD, TXT_N_O_D, 4694 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 4695 d_nod_x, d_nod_y, d_nod_w, d_nod_h); 4696 4697 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, 4698 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 4699 //#if (GERMAN | FRENCH) 4700 // d_cancel_x, d_cancel_y); 4701 //#else 4702 d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); 4703 //#endif 4704 4705 TextButtonClass sendbtn(BUTTON_SEND, TXT_SEND_MESSAGE, 4706 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 4707 //#if (GERMAN | FRENCH) 4708 // d_send_x, d_send_y); 4709 //#else 4710 d_send_x, d_send_y, d_send_w, d_send_h); 4711 //#endif 4712 4713 /* 4714 ------------------------- Build the button list -------------------------- 4715 */ 4716 commands = &name_edt; 4717 gdibtn.Add_Tail(*commands); 4718 nodbtn.Add_Tail(*commands); 4719 cancelbtn.Add_Tail(*commands); 4720 sendbtn.Add_Tail(*commands); 4721 4722 /* 4723 ----------------------------- Various Inits ------------------------------ 4724 */ 4725 /*........................................................................ 4726 Init player name & house 4727 ........................................................................*/ 4728 MPlayerColorIdx = MPlayerPrefColor; // init my preferred color 4729 strcpy (namebuf, MPlayerName); // set my name 4730 name_edt.Set_Text(namebuf,MPLAYER_NAME_MAX); 4731 name_edt.Set_Color(MPlayerTColors[MPlayerColorIdx]); 4732 4733 if (MPlayerHouse==HOUSE_GOOD) { 4734 gdibtn.Turn_On(); 4735 } else { 4736 nodbtn.Turn_On(); 4737 } 4738 4739 Fancy_Text_Print("", 0, 0, CC_GREEN, TBLACK, 4740 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4741 4742 transmit = 1; 4743 first = 1; 4744 4745 /*........................................................................ 4746 Init the message display system 4747 ........................................................................*/ 4748 Messages.Init (d_message_x + 2*factor, d_message_y + 2*factor, 4, MAX_MESSAGE_LENGTH, d_txt6_h); 4749 4750 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 4751 Blit_Hid_Page_To_Seen_Buff(); 4752 Set_Palette(Palette); 4753 4754 extern char ModemRXString[]; 4755 4756 if (strlen(ModemRXString) > 36) 4757 ModemRXString[36] = 0; 4758 4759 if (strlen(ModemRXString) > 0) 4760 Messages.Add_Message (ModemRXString, CC_TAN, 4761 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, 0, 0); 4762 4763 ModemRXString[0] = '\0'; 4764 4765 /* 4766 ---------------------------- Init Mono Output ---------------------------- 4767 */ 4768 #if(SHOW_MONO) 4769 NullModem.Configure_Debug(sizeof (CommHeaderType),sizeof (SerialCommandType), 4770 SerialPacketNames, 106); 4771 NullModem.Mono_Debug_Print(1); 4772 #endif 4773 4774 /* 4775 ---------------------------- Processing loop ----------------------------- 4776 */ 4777 NullModem.Reset_Response_Time(); // clear response time 4778 timingtime = lastmsgtime = lastredrawtime = TickCount.Time(); 4779 while (Get_Mouse_State() > 0) Show_Mouse(); 4780 4781 while (process) { 4782 4783 /* 4784 ** If we have just received input focus again after running in the background then 4785 ** we need to redraw. 4786 */ 4787 if (AllSurfaces.SurfacesRestored){ 4788 AllSurfaces.SurfacesRestored=FALSE; 4789 display=REDRAW_ALL; 4790 } 4791 4792 #if(SHOW_MONO) 4793 NullModem.Mono_Debug_Print(0); 4794 #endif 4795 4796 /* 4797 ........................ Invoke game callback ......................... 4798 */ 4799 Call_Back(); 4800 4801 /* 4802 ...................... Refresh display if needed ...................... 4803 */ 4804 if (display) { 4805 Hide_Mouse(); 4806 /* 4807 .................. Redraw backgound & dialog box ................... 4808 */ 4809 if (display >= REDRAW_BACKGROUND) { 4810 Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); 4811 4812 /*............................................................... 4813 Dialog & Field labels 4814 ...............................................................*/ 4815 #ifdef FORCE_WINSOCK 4816 if (Winsock.Get_Connected()){ 4817 Draw_Caption (TXT_JOIN_INTERNET_GAME, d_dialog_x, d_dialog_y, d_dialog_w); 4818 }else{ 4819 Draw_Caption (TXT_JOIN_SERIAL_GAME, d_dialog_x, d_dialog_y, d_dialog_w); 4820 } 4821 #else 4822 Draw_Caption (TXT_JOIN_SERIAL_GAME, d_dialog_x, d_dialog_y, d_dialog_w); 4823 #endif //FORCE_WINSOCK 4824 4825 Fancy_Text_Print(TXT_YOUR_NAME, 4826 d_name_x - 5*factor, d_name_y + 1*factor, 4827 CC_GREEN, TBLACK, 4828 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4829 4830 Fancy_Text_Print(TXT_SIDE_COLON, 4831 d_gdi_x - 5*factor, d_gdi_y + 1*factor, 4832 CC_GREEN, TBLACK, 4833 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4834 4835 Fancy_Text_Print(TXT_COLOR_COLON, 4836 cbox_x[0] - 5*factor, d_color_y + 1*factor, 4837 CC_GREEN, TBLACK, 4838 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4839 4840 } 4841 4842 /*.................................................................. 4843 Draw the color boxes 4844 ..................................................................*/ 4845 if (display >= REDRAW_COLORS) { 4846 for (i = 0; i < MAX_MPLAYER_COLORS; i++) { 4847 LogicPage->Fill_Rect (cbox_x[i] + 1*factor, d_color_y + 1*factor, 4848 cbox_x[i] + 1*factor + d_color_w - 2*factor, d_color_y + 1*factor + d_color_h - 2*factor, 4849 MPlayerGColors[i]); 4850 4851 if (i == MPlayerColorIdx) { 4852 Draw_Box(cbox_x[i], d_color_y, d_color_w, d_color_h, 4853 BOXSTYLE_GREEN_DOWN, false); 4854 } else { 4855 Draw_Box(cbox_x[i], d_color_y, d_color_w, d_color_h, 4856 BOXSTYLE_GREEN_RAISED, false); 4857 } 4858 } 4859 } 4860 4861 /*.................................................................. 4862 Draw the message: 4863 - Erase an old message first 4864 ..................................................................*/ 4865 if (display >= REDRAW_MESSAGE) { 4866 Draw_Box(d_message_x, d_message_y, d_message_w, d_message_h, 4867 BOXSTYLE_GREEN_BORDER, true); 4868 Messages.Draw(); 4869 4870 LogicPage->Fill_Rect( d_dialog_x + 2*factor, 4871 d_opponent_y, 4872 d_dialog_x + d_dialog_w - 4*factor, 4873 d_ghosts_y + d_txt6_h, 4874 BLACK); 4875 4876 if (parms_received) { 4877 if (oppscorescreen) { 4878 sprintf(txt,"%s",Text_String(TXT_WAITING_FOR_OPPONENT)); 4879 4880 int txtwidth = String_Pixel_Width( txt ); 4881 4882 Fancy_Text_Print (txt, d_dialog_cx - (txtwidth / 2), 4883 d_opponent_y, CC_GREEN, TBLACK, 4884 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4885 } else { 4886 /*............................................................ 4887 Opponent's name 4888 ............................................................*/ 4889 Fancy_Text_Print (TXT_OPPONENT_COLON, d_dialog_cx - 3*factor, 4890 d_opponent_y, CC_GREEN, TBLACK, 4891 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4892 4893 if (TheirHouse == HOUSE_GOOD) { 4894 sprintf(txt,"%s %s",TheirName,Text_String(TXT_G_D_I)); 4895 } else { 4896 sprintf(txt,"%s %s",TheirName,Text_String(TXT_N_O_D)); 4897 } 4898 4899 Fancy_Text_Print (txt, d_dialog_cx, 4900 d_opponent_y, MPlayerTColors[TheirColor], TBLACK, 4901 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4902 4903 /*............................................................ 4904 Scenario description 4905 ............................................................*/ 4906 Fancy_Text_Print (TXT_SCENARIO_COLON, d_dialog_cx - 3*factor, 4907 d_scenario_y, CC_GREEN, TBLACK, 4908 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4909 4910 if (ScenarioIdx != -1) { 4911 sprintf(txt,"%s", MPlayerScenarios[ScenarioIdx]); 4912 4913 Fancy_Text_Print (txt, d_dialog_cx, 4914 d_scenario_y, CC_GREEN, TBLACK, 4915 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4916 } else { 4917 strcpy(txt,Text_String(TXT_NOT_FOUND)); 4918 4919 Fancy_Text_Print (txt, d_dialog_cx, 4920 d_scenario_y, RED, TBLACK, 4921 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4922 } 4923 4924 /*............................................................ 4925 Credits 4926 ............................................................*/ 4927 Fancy_Text_Print (TXT_START_CREDITS_COLON, d_dialog_cx - 3*factor, 4928 d_credits_y, CC_GREEN, TBLACK, 4929 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4930 4931 sprintf(txt,"%d",MPlayerCredits); 4932 Fancy_Text_Print (txt, d_dialog_cx, 4933 d_credits_y, CC_GREEN, TBLACK, 4934 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4935 4936 /*............................................................ 4937 Count 4938 ............................................................*/ 4939 4940 Fancy_Text_Print (TXT_COUNT, d_dialog_cx - 3*factor, 4941 d_count_y, CC_GREEN, TBLACK, 4942 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4943 4944 sprintf( txt, "%d ", MPlayerUnitCount ); 4945 Fancy_Text_Print (txt, d_dialog_cx, 4946 d_count_y, CC_GREEN, TBLACK, 4947 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4948 4949 /*............................................................ 4950 Level 4951 ............................................................*/ 4952 4953 Fancy_Text_Print (TXT_LEVEL, d_dialog_cx - 3*factor, 4954 d_level_y, CC_GREEN, TBLACK, 4955 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4956 4957 if (BuildLevel <= MPLAYER_BUILD_LEVEL_MAX) { 4958 sprintf(txt, "%d ", BuildLevel); 4959 } else { 4960 sprintf(txt, "**"); 4961 } 4962 Fancy_Text_Print (txt, d_dialog_cx, 4963 d_level_y, CC_GREEN, TBLACK, 4964 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4965 4966 /*............................................................ 4967 Bases status 4968 ............................................................*/ 4969 Fancy_Text_Print (TXT_BASES_COLON, d_dialog_cx - 3*factor, 4970 d_bases_y, CC_GREEN, TBLACK, 4971 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4972 4973 if (MPlayerBases) { 4974 strcpy(txt,Text_String(TXT_ON)); 4975 } else { 4976 strcpy(txt,Text_String(TXT_OFF)); 4977 } 4978 Fancy_Text_Print (txt, d_dialog_cx, 4979 d_bases_y, CC_GREEN, TBLACK, 4980 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4981 4982 /*............................................................ 4983 Tiberium status 4984 ............................................................*/ 4985 Fancy_Text_Print (TXT_TIBERIUM_COLON, d_dialog_cx - 3*factor, 4986 d_tiberium_y, CC_GREEN, TBLACK, 4987 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4988 4989 if (MPlayerTiberium) { 4990 strcpy(txt,Text_String(TXT_ON)); 4991 } else { 4992 strcpy(txt,Text_String(TXT_OFF)); 4993 } 4994 Fancy_Text_Print (txt, d_dialog_cx, 4995 d_tiberium_y, CC_GREEN, TBLACK, 4996 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 4997 4998 /*............................................................ 4999 Goodies status 5000 ............................................................*/ 5001 Fancy_Text_Print (TXT_CRATES_COLON, d_dialog_cx - 3*factor, 5002 d_goodies_y, CC_GREEN, TBLACK, 5003 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 5004 5005 if (MPlayerGoodies) { 5006 strcpy(txt,Text_String(TXT_ON)); 5007 } else { 5008 strcpy(txt,Text_String(TXT_OFF)); 5009 } 5010 Fancy_Text_Print (txt, d_dialog_cx, 5011 d_goodies_y, CC_GREEN, TBLACK, 5012 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 5013 5014 /*............................................................ 5015 Capture the flag or AI player ON/OFF 5016 ............................................................*/ 5017 if ( Special.IsCaptureTheFlag ) { 5018 strcpy( txt, Text_String( TXT_CAPTURE_THE_FLAG ) ); 5019 strcat( txt, ":" ); 5020 Fancy_Text_Print (txt, d_dialog_cx - 3*factor, 5021 d_ghosts_y, CC_GREEN, TBLACK, 5022 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 5023 5024 strcpy(txt,Text_String(TXT_ON)); 5025 Fancy_Text_Print (txt, d_dialog_cx, 5026 d_ghosts_y, CC_GREEN, TBLACK, 5027 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 5028 } else { 5029 /*............................................................ 5030 Ghost player status 5031 ............................................................*/ 5032 Fancy_Text_Print (TXT_AI_PLAYERS_COLON, d_dialog_cx - 3*factor, 5033 d_ghosts_y, CC_GREEN, TBLACK, 5034 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 5035 5036 if (MPlayerGhosts) { 5037 strcpy(txt,Text_String(TXT_ON)); 5038 } else { 5039 strcpy(txt,Text_String(TXT_OFF)); 5040 } 5041 Fancy_Text_Print (txt, d_dialog_cx, 5042 d_ghosts_y, CC_GREEN, TBLACK, 5043 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 5044 } 5045 } 5046 } 5047 } 5048 5049 /* 5050 .......................... Redraw buttons .......................... 5051 */ 5052 if (display >= REDRAW_BUTTONS) { 5053 commands->Flag_List_To_Redraw(); 5054 } 5055 Show_Mouse(); 5056 display = REDRAW_NONE; 5057 } 5058 5059 /* 5060 ........................... Get user input ............................ 5061 */ 5062 input = commands->Input(); 5063 5064 /* 5065 ---------------------------- Process input ---------------------------- 5066 */ 5067 switch (input) { 5068 /*------------------------------------------------------------------ 5069 User clicks on a color button 5070 ------------------------------------------------------------------*/ 5071 case KN_LMOUSE: 5072 if (_Kbd->MouseQX > cbox_x[0] && 5073 _Kbd->MouseQX < (cbox_x[MAX_MPLAYER_COLORS - 1] + d_color_w) && 5074 _Kbd->MouseQY > d_color_y && 5075 _Kbd->MouseQY < (d_color_y + d_color_h)) { 5076 if (!ready_to_go){ 5077 /*......................................................... 5078 Compute my preferred color as the one I clicked on. 5079 .........................................................*/ 5080 MPlayerPrefColor = (_Kbd->MouseQX - cbox_x[0]) / d_color_w; 5081 changed = 1; 5082 /*......................................................... 5083 If 'TheirColor' is set to the other player's color, make 5084 sure we can't pick that color. 5085 .........................................................*/ 5086 if (parms_received) { 5087 if (MPlayerPrefColor == TheirColor) 5088 break; 5089 } 5090 MPlayerColorIdx = MPlayerPrefColor; 5091 5092 name_edt.Set_Color(MPlayerTColors[MPlayerColorIdx]); 5093 name_edt.Flag_To_Redraw(); 5094 display = REDRAW_COLORS; 5095 strcpy (MPlayerName, namebuf); 5096 transmit = 1; 5097 } 5098 } 5099 break; 5100 5101 /*------------------------------------------------------------------ 5102 House Buttons: set the player's desired House 5103 ------------------------------------------------------------------*/ 5104 case (BUTTON_GDI | KN_BUTTON): 5105 if (!ready_to_go){ 5106 MPlayerHouse = HOUSE_GOOD; 5107 gdibtn.Turn_On(); 5108 nodbtn.Turn_Off(); 5109 strcpy (MPlayerName, namebuf); 5110 transmit = 1; 5111 } 5112 break; 5113 5114 case (BUTTON_NOD | KN_BUTTON): 5115 if (!ready_to_go){ 5116 MPlayerHouse = HOUSE_BAD; 5117 gdibtn.Turn_Off(); 5118 nodbtn.Turn_On(); 5119 strcpy (MPlayerName, namebuf); 5120 transmit = 1; 5121 } 5122 break; 5123 5124 /*------------------------------------------------------------------ 5125 User edits the name value; retransmit 5126 ------------------------------------------------------------------*/ 5127 case (BUTTON_NAME | KN_BUTTON): 5128 if (!ready_to_go){ 5129 strcpy (MPlayerName, namebuf); 5130 transmit = 1; 5131 changed = 1; 5132 } 5133 break; 5134 5135 /*------------------------------------------------------------------ 5136 CANCEL: send a SIGN_OFF, bail out with error code 5137 ------------------------------------------------------------------*/ 5138 case (KN_ESC): 5139 if (!ready_to_go){ 5140 if (Messages.Get_Edit_Buf() != NULL) { 5141 Messages.Input(input); 5142 display = REDRAW_MESSAGE; 5143 break; 5144 } 5145 } 5146 case (BUTTON_CANCEL | KN_BUTTON): 5147 if (!ready_to_go){ 5148 process = false; 5149 rc = false; 5150 } 5151 break; 5152 5153 /*------------------------------------------------------------------ 5154 Default: manage the inter-player messages 5155 ------------------------------------------------------------------*/ 5156 default: 5157 if (!ready_to_go){ 5158 5159 /*............................................................... 5160 F4/SEND/'M' = send a message 5161 ...............................................................*/ 5162 if (Messages.Get_Edit_Buf()==NULL) { 5163 if (input == KN_M || input==(BUTTON_SEND | KN_BUTTON) || 5164 input == KN_F4) { 5165 memset (txt, 0, 80); 5166 5167 strcpy(txt,Text_String(TXT_MESSAGE)); // "Message:" 5168 5169 Messages.Add_Edit (MPlayerTColors[MPlayerColorIdx], 5170 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, txt, d_message_w-70*factor); 5171 display = REDRAW_MESSAGE; 5172 5173 name_edt.Clear_Focus(); 5174 name_edt.Flag_To_Redraw(); 5175 5176 break; 5177 } 5178 } else { 5179 if ( input == (BUTTON_SEND | KN_BUTTON) ) { 5180 input = KN_RETURN; 5181 } 5182 } 5183 5184 /*............................................................... 5185 Manage the message system (get rid of old messages) 5186 ...............................................................*/ 5187 if (Messages.Manage()) { 5188 display = REDRAW_MESSAGE; 5189 } 5190 5191 /*............................................................... 5192 Re-draw the messages & service keyboard input for any message 5193 being edited. 5194 ...............................................................*/ 5195 i = Messages.Input(input); 5196 5197 /*............................................................... 5198 If 'Input' returned 1, it means refresh the message display. 5199 ...............................................................*/ 5200 if (i==1) { 5201 Messages.Draw(); 5202 } else { 5203 5204 /*............................................................... 5205 If 'Input' returned 2, it means redraw the message display. 5206 ...............................................................*/ 5207 if (i==2) { 5208 display = REDRAW_MESSAGE; 5209 } else { 5210 5211 /*............................................................... 5212 If 'input' returned 3, it means send the current message. 5213 ...............................................................*/ 5214 if (i==3) { 5215 long actual_message_size; 5216 char *the_string; 5217 5218 sent_so_far = 0; 5219 magic_number = MESSAGE_HEAD_MAGIC_NUMBER; 5220 message_length = strlen(Messages.Get_Edit_Buf()); 5221 crc = (unsigned short) 5222 (Calculate_CRC(Messages.Get_Edit_Buf(), message_length) &0xffff); 5223 5224 while (sent_so_far < message_length){ 5225 SendPacket.Command = SERIAL_MESSAGE; 5226 strcpy (SendPacket.Name, MPlayerName); 5227 SendPacket.ID = Build_MPlayerID(MPlayerColorIdx, MPlayerHouse); 5228 memcpy (SendPacket.Message, Messages.Get_Edit_Buf()+sent_so_far, COMPAT_MESSAGE_LENGTH-5); 5229 5230 /* 5231 ** Steve I's stuff for splitting message on word boundries 5232 */ 5233 actual_message_size = COMPAT_MESSAGE_LENGTH - 5; 5234 5235 /* Start at the end of the message and find a space with 10 chars. */ 5236 the_string = GPacket.Message.Buf; 5237 while ( (COMPAT_MESSAGE_LENGTH -5) -actual_message_size < 10 && 5238 the_string[actual_message_size] != ' '){ 5239 --actual_message_size; 5240 } 5241 if ( the_string[actual_message_size] == ' ' ){ 5242 5243 /* Now delete the extra characters after the space (they musnt print) */ 5244 for ( int i=0 ; i< (COMPAT_MESSAGE_LENGTH-5) - actual_message_size; i++ ){ 5245 the_string[i + actual_message_size] = 0xff; 5246 } 5247 }else{ 5248 actual_message_size = COMPAT_MESSAGE_LENGTH - 5; 5249 } 5250 5251 *(SendPacket.Message + COMPAT_MESSAGE_LENGTH-5) = 0; 5252 *((unsigned short*)(SendPacket.Message + COMPAT_MESSAGE_LENGTH-4)) = magic_number; 5253 *((unsigned short*)(SendPacket.Message + COMPAT_MESSAGE_LENGTH-2)) = crc; 5254 5255 /*.................................................................. 5256 Send the message 5257 ..................................................................*/ 5258 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 5259 NullModem.Service(); 5260 5261 /*.................................................................. 5262 Add the message to our own screen 5263 ..................................................................*/ 5264 sprintf(txt, Text_String (TXT_FROM), MPlayerName, SendPacket.Message); 5265 Messages.Add_Message (txt, MPlayerTColors[MPlayerColorIdx], 5266 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, magic_number, crc); 5267 5268 magic_number++; 5269 sent_so_far += actual_message_size; //COMPAT_MESSAGE_LENGTH-5; 5270 } 5271 display = REDRAW_MESSAGE; 5272 } 5273 } 5274 } 5275 } 5276 break; 5277 } 5278 5279 /*--------------------------------------------------------------------- 5280 Detect editing of the name buffer, transmit new values to players 5281 ---------------------------------------------------------------------*/ 5282 if (strcmp (namebuf, MPlayerName)) { 5283 strcpy (MPlayerName, namebuf); 5284 transmit = 1; 5285 changed = 1; 5286 } 5287 5288 /*--------------------------------------------------------------------- 5289 If our Transmit flag is set, we need to send out a game option packet 5290 ---------------------------------------------------------------------*/ 5291 if (transmit && (TickCount.Time() - transmittime) > PACKET_RETRANS_TIME) { 5292 SendPacket.Command = SERIAL_GAME_OPTIONS; 5293 strcpy (SendPacket.Name, MPlayerName); 5294 #ifdef PATCH 5295 if (IsV107) { 5296 SendPacket.Version = 1; 5297 } else { 5298 SendPacket.Version = 2; 5299 } 5300 #else 5301 SendPacket.Version = Version_Number(); 5302 #endif 5303 SendPacket.House = MPlayerHouse; 5304 SendPacket.Color = MPlayerColorIdx; 5305 SendPacket.ID = ModemGameToPlay; 5306 5307 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 5308 5309 transmittime = TickCount.Time(); 5310 transmit = 0; 5311 } 5312 5313 // 5314 // send a timing packet if enough time has gone by. 5315 // 5316 if ( (TickCount.Time() - timingtime) > PACKET_TIMING_TIMEOUT) { 5317 SendPacket.Command = SERIAL_TIMING; 5318 SendPacket.ResponseTime = NullModem.Response_Time(); 5319 SendPacket.ID = ModemGameToPlay; 5320 5321 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 0); 5322 timingtime = TickCount.Time(); 5323 } 5324 5325 /*--------------------------------------------------------------------- 5326 Check for an incoming message 5327 ---------------------------------------------------------------------*/ 5328 if (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { 5329 // Smart_Printf( "received packet of length %d\n", packetlen ); 5330 5331 lastmsgtime = TickCount.Time(); 5332 5333 msg_timeout = 600; 5334 5335 // are we getting our own packets back?? 5336 5337 if (ReceivePacket.Command >= SERIAL_CONNECT && 5338 ReceivePacket.Command < SERIAL_LAST_COMMAND && 5339 ReceivePacket.Command != SERIAL_MESSAGE && 5340 ReceivePacket.ID == ModemGameToPlay) { 5341 5342 CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); 5343 5344 // to skip the other system not responding msg 5345 lastmsgtime = TickCount.Time(); 5346 5347 process = false; 5348 rc = false; 5349 5350 // say we did receive sign off to keep from sending one 5351 recsignedoff = true; 5352 break; 5353 } 5354 5355 event = (EventClass *)&ReceivePacket; 5356 if (event->Type <= EventClass::FRAMEINFO) { 5357 if ( (TickCount.Time() - lastredrawtime) > PACKET_REDRAW_TIME) { 5358 lastredrawtime = TickCount.Time(); 5359 oppscorescreen = true; 5360 display = REDRAW_MESSAGE; 5361 parms_received = 1; 5362 } 5363 } else { 5364 switch ( ReceivePacket.Command ) { 5365 5366 /* 5367 ** Once the host is ready to go, we can no longer change game options. 5368 */ 5369 case SERIAL_READY_TO_GO: 5370 ready_to_go = true; 5371 break; 5372 5373 /*.................................................................. 5374 Other system signs off: Give it time to receive my ACK, then show 5375 a message. 5376 ..................................................................*/ 5377 case (SERIAL_SIGN_OFF): 5378 starttime = TickCount.Time(); 5379 while ( (TickCount.Time() - starttime) < 60) 5380 NullModem.Service(); 5381 CCMessageBox().Process(TXT_USER_SIGNED_OFF); 5382 5383 // to skip the other system not responding msg 5384 lastmsgtime = TickCount.Time(); 5385 5386 process = false; 5387 rc = false; 5388 recsignedoff = true; 5389 break; 5390 5391 /*.................................................................. 5392 Game Options: Store all options; check my color & game version. 5393 ..................................................................*/ 5394 case (SERIAL_GAME_OPTIONS): 5395 oppscorescreen = false; 5396 gameoptions = true; 5397 display = REDRAW_MESSAGE; 5398 parms_received = 1; 5399 5400 strcpy (TheirName, ReceivePacket.Name); 5401 TheirColor = ReceivePacket.Color; 5402 TheirHouse = ReceivePacket.House; 5403 5404 /*............................................................... 5405 Make sure I don't have the same color as the other guy. 5406 ...............................................................*/ 5407 if (MPlayerColorIdx == TheirColor) { 5408 5409 // force transmitting of game options packet 5410 5411 transmit = 1; 5412 transmittime = 0; 5413 5414 MPlayerColorIdx = TheirColor + 1; 5415 if (MPlayerColorIdx >= 6) 5416 MPlayerColorIdx = 0; 5417 name_edt.Set_Color(MPlayerTColors[MPlayerColorIdx]); 5418 name_edt.Flag_To_Redraw(); 5419 display = REDRAW_COLORS; 5420 } 5421 5422 /*............................................................... 5423 Save scenario settings. 5424 ...............................................................*/ 5425 MPlayerCredits = ReceivePacket.Credits; 5426 MPlayerBases = ReceivePacket.IsBases; 5427 MPlayerTiberium = ReceivePacket.IsTiberium; 5428 MPlayerGoodies = ReceivePacket.IsGoodies; 5429 MPlayerGhosts = ReceivePacket.IsGhosties; 5430 BuildLevel = ReceivePacket.BuildLevel; 5431 MPlayerUnitCount = ReceivePacket.UnitCount; 5432 Seed = ReceivePacket.Seed; 5433 Special = ReceivePacket.Special; 5434 Options.GameSpeed = ReceivePacket.GameSpeed; 5435 5436 if (MPlayerTiberium) { 5437 Special.IsTGrowth = 1; 5438 Special.IsTSpread = 1; 5439 } else { 5440 Special.IsTGrowth = 0; 5441 Special.IsTSpread = 0; 5442 } 5443 5444 /*............................................................... 5445 Find the index of the scenario number; if it's not found, leave 5446 it at -1. 5447 ...............................................................*/ 5448 ScenarioIdx = -1; 5449 for (i = 0; i < MPlayerFilenum.Count(); i++) { 5450 if (ReceivePacket.Scenario == MPlayerFilenum[i]) 5451 ScenarioIdx = i; 5452 } 5453 5454 /*............................................................... 5455 Check our version numbers; if they're incompatible, sign off. 5456 ...............................................................*/ 5457 #ifdef PATCH 5458 if (IsV107) { 5459 version = 1; 5460 } else { 5461 version = 2; 5462 } 5463 #else 5464 version = Version_Number(); 5465 #endif 5466 if (ReceivePacket.Version > version) { 5467 CCMessageBox().Process (TXT_YOURGAME_OUTDATED); 5468 5469 // to skip the other system not responding msg 5470 lastmsgtime = TickCount.Time(); 5471 5472 process = false; 5473 rc = false; 5474 } else { 5475 if (ReceivePacket.Version < version) { 5476 CCMessageBox().Process (TXT_DESTGAME_OUTDATED); 5477 5478 // to skip the other system not responding msg 5479 lastmsgtime = TickCount.Time(); 5480 5481 process = false; 5482 rc = false; 5483 } 5484 } 5485 5486 /*............................................................... 5487 If this is the first game-options packet we've received, transmit 5488 our options to him. 5489 ...............................................................*/ 5490 if (first) { 5491 first = 0; 5492 5493 // force transmitting of game options packet 5494 5495 transmit = 1; 5496 transmittime = 0; 5497 } 5498 break; 5499 5500 /*.................................................................. 5501 GO: Exit this routine with a success code. 5502 ..................................................................*/ 5503 case (SERIAL_GO): 5504 // 5505 // calculated one way delay for a packet and overall delay 5506 // to execute a packet 5507 // 5508 MPlayerMaxAhead = MAX( (ReceivePacket.ResponseTime / 8), 2); 5509 char flip[128]; 5510 sprintf (flip, "C&C95 - MaxAhead set to %d frames\n", MPlayerMaxAhead); 5511 CCDebugString (flip); 5512 5513 process = false; 5514 rc = true; 5515 break; 5516 5517 /*.................................................................. 5518 Incoming message: add to our list 5519 ..................................................................*/ 5520 case (SERIAL_MESSAGE): 5521 oppscorescreen = false; 5522 sprintf(txt, Text_String (TXT_FROM), ReceivePacket.Name, 5523 ReceivePacket.Message); 5524 magic_number = *((unsigned short*)(ReceivePacket.Message + COMPAT_MESSAGE_LENGTH-4)); 5525 crc = *((unsigned short*)(ReceivePacket.Message + COMPAT_MESSAGE_LENGTH-2)); 5526 Messages.Add_Message (txt, MPlayerTColors[MPlayerID_To_ColorIndex(ReceivePacket.ID)], 5527 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 1200, magic_number, crc); 5528 display = REDRAW_MESSAGE; 5529 break; 5530 5531 // 5532 // throw away timing packet 5533 // 5534 case (SERIAL_TIMING): 5535 oppscorescreen = false; 5536 break; 5537 5538 // 5539 // print msg waiting for opponent 5540 // 5541 case (SERIAL_SCORE_SCREEN): 5542 // Smart_Printf( "received score screen\n" ); 5543 oppscorescreen = true; 5544 display = REDRAW_MESSAGE; 5545 parms_received = 1; 5546 break; 5547 5548 default: 5549 break; 5550 } 5551 } 5552 } 5553 5554 // if we haven't received a msg for 10 seconds exit 5555 5556 //if ( ((TickCount.Time() - lastmsgtime) > msg_timeout) || 5557 //(Winsock.Get_Connected() && Winsock.Get_Connection_Status == TcpipManagerClass::CONNECTION_LOST)) { 5558 5559 if ( (TickCount.Time() - lastmsgtime) > msg_timeout) { 5560 CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); 5561 process = false; 5562 rc = false; 5563 5564 // say we did receive sign off to keep from sending one 5565 recsignedoff = true; 5566 } 5567 5568 5569 5570 5571 /*--------------------------------------------------------------------- 5572 Service the connection 5573 ---------------------------------------------------------------------*/ 5574 NullModem.Service(); 5575 5576 } /* end of while */ 5577 5578 /*------------------------------------------------------------------------ 5579 Sort player ID's, so we can execute commands in the same order on both 5580 machines. 5581 ------------------------------------------------------------------------*/ 5582 if (rc) { 5583 /*..................................................................... 5584 Set the number of players in this game, and my ID 5585 .....................................................................*/ 5586 MPlayerCount = 2; 5587 MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); 5588 5589 TheirID = Build_MPlayerID (TheirColor,TheirHouse); 5590 5591 /*..................................................................... 5592 Store every player's ID in the MPlayerID[] array. This array will 5593 determine the order of event execution, so the ID's must be stored 5594 in the same order on all systems. 5595 .....................................................................*/ 5596 if (TheirID < MPlayerLocalID) { 5597 MPlayerID[0] = TheirID; 5598 MPlayerID[1] = MPlayerLocalID; 5599 strcpy (MPlayerNames[0], TheirName); 5600 strcpy (MPlayerNames[1], MPlayerName); 5601 } else { 5602 MPlayerID[0] = MPlayerLocalID; 5603 MPlayerID[1] = TheirID; 5604 strcpy (MPlayerNames[0], MPlayerName); 5605 strcpy (MPlayerNames[1], TheirName); 5606 } 5607 5608 /*..................................................................... 5609 Get the scenario filename 5610 .....................................................................*/ 5611 Scenario = MPlayerFilenum[ScenarioIdx]; 5612 5613 starttime = TickCount.Time(); 5614 while ( ( NullModem.Num_Send() 5615 && ((TickCount.Time() - starttime) < PACKET_SENDING_TIMEOUT) )){ 5616 #if(SHOW_MONO) 5617 NullModem.Mono_Debug_Print(0); 5618 #endif 5619 5620 NullModem.Service(); 5621 Keyboard::Check(); //Make sure the message loop gets called 5622 } 5623 5624 // clear queue to keep from doing any resends 5625 NullModem.Init_Send_Queue(); 5626 5627 } else { 5628 if ( !recsignedoff ) { 5629 /*..................................................................... 5630 Broadcast my sign-off over my network 5631 .....................................................................*/ 5632 SendPacket.Command = SERIAL_SIGN_OFF; 5633 SendPacket.Color = MPlayerLocalID; // use Color for ID 5634 SendPacket.ID = ModemGameToPlay; 5635 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 5636 5637 starttime = TickCount.Time(); 5638 while ( (NullModem.Num_Send() 5639 && ((TickCount.Time() - starttime) < PACKET_CANCEL_TIMEOUT) )){ 5640 #if(SHOW_MONO) 5641 NullModem.Mono_Debug_Print(0); 5642 #endif 5643 5644 if ( NullModem.Get_Message( &ReceivePacket, &packetlen ) > 0) { 5645 5646 // are we getting our own packets back?? 5647 5648 if (ReceivePacket.Command == SERIAL_SIGN_OFF 5649 && ReceivePacket.ID == ModemGameToPlay) { 5650 5651 // exit while 5652 break; 5653 } 5654 } 5655 5656 NullModem.Service(); 5657 } 5658 } 5659 5660 Shutdown_Modem(); 5661 } 5662 5663 /*------------------------------------------------------------------------ 5664 Restore screen 5665 ------------------------------------------------------------------------*/ 5666 Hide_Mouse(); 5667 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 5668 Blit_Hid_Page_To_Seen_Buff(); 5669 Show_Mouse(); 5670 5671 /*------------------------------------------------------------------------ 5672 Save any changes made to our options 5673 ------------------------------------------------------------------------*/ 5674 if (changed) { 5675 Write_MultiPlayer_Settings (); 5676 } 5677 5678 return(rc); 5679 5680 } /* end of Com_Show_Scenario_Dialog */ 5681 5682 5683 5684 /*************************************************************************** 5685 * Phone_Dialog -- Lets user edit phone directory & dial * 5686 * * 5687 * INPUT: * 5688 * none. * 5689 * * 5690 * OUTPUT: * 5691 * true = dial the current phone book entry, false = cancel. * 5692 * * 5693 * WARNINGS: * 5694 * Serial options must have been read from CC.INI. * 5695 * * 5696 * HISTORY: * 5697 * 04/29/1995 BRR : Created. * 5698 *=========================================================================*/ 5699 static int Phone_Dialog (void) 5700 { 5701 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 5702 /*........................................................................ 5703 Dialog & button dimensions 5704 ........................................................................*/ 5705 int d_dialog_w = 280 *factor; // dialog width 5706 int d_dialog_h = 150 *factor; // dialog height 5707 int d_dialog_x = ((320 *factor - d_dialog_w) / 2); // dialog x-coord 5708 int d_dialog_y = ((200 *factor- d_dialog_h) / 2); // dialog y-coord 5709 int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord 5710 5711 int d_txt6_h = 11 *factor; // ht of 6-pt text 5712 int d_margin = 7 *factor; // margin width/height 5713 5714 int d_phonelist_w = 268 *factor; 5715 int d_phonelist_h = 87 *factor; 5716 int d_phonelist_x = d_dialog_cx - (d_phonelist_w / 2); 5717 int d_phonelist_y = d_dialog_y + d_margin + d_txt6_h + 11*factor; 5718 5719 int d_add_w = 45*factor; 5720 int d_add_h = 9*factor; 5721 int d_add_x = d_dialog_cx - (d_add_w / 2) - d_margin - d_add_w; 5722 int d_add_y = d_phonelist_y + d_phonelist_h + d_margin; 5723 5724 int d_edit_w = 45*factor; 5725 int d_edit_h = 9*factor; 5726 int d_edit_x = d_dialog_cx - (d_edit_w / 2); 5727 int d_edit_y = d_phonelist_y + d_phonelist_h + d_margin; 5728 5729 int d_delete_w = 45*factor; 5730 int d_delete_h = 9*factor; 5731 int d_delete_x = d_dialog_cx + (d_delete_w / 2) + d_margin; 5732 int d_delete_y = d_phonelist_y + d_phonelist_h + d_margin; 5733 5734 int d_numedit_w = ( (PhoneEntryClass::PHONE_MAX_NUM - 1) * 6*factor) + 3*factor; 5735 int d_numedit_h = 9*factor; 5736 int d_numedit_x = d_dialog_cx - (d_numedit_w / 2); 5737 int d_numedit_y = d_add_y + d_add_h + d_margin; 5738 5739 int d_dial_w = 45*factor; 5740 int d_dial_h = 9*factor; 5741 int d_dial_x = d_dialog_cx - (d_numedit_w / 2) - d_margin - d_dial_w; 5742 int d_dial_y = d_add_y + d_add_h + d_margin; 5743 5744 int d_cancel_w = 45*factor; 5745 int d_cancel_h = 9*factor; 5746 int d_cancel_x = d_dialog_cx + (d_numedit_w / 2) + d_margin; 5747 int d_cancel_y = d_add_y + d_add_h + d_margin; 5748 5749 /*........................................................................ 5750 Button Enumerations 5751 ........................................................................*/ 5752 enum { 5753 BUTTON_PHONELIST = 100, 5754 BUTTON_ADD, 5755 BUTTON_EDIT, 5756 BUTTON_DELETE, 5757 BUTTON_DIAL, 5758 BUTTON_CANCEL, 5759 BUTTON_NUMEDIT, 5760 }; 5761 5762 /*........................................................................ 5763 Redraw values: in order from "top" to "bottom" layer of the dialog 5764 ........................................................................*/ 5765 typedef enum { 5766 REDRAW_NONE = 0, 5767 REDRAW_BUTTONS, 5768 REDRAW_BACKGROUND, 5769 REDRAW_ALL = REDRAW_BACKGROUND 5770 } RedrawType; 5771 5772 /*........................................................................ 5773 Dialog variables 5774 ........................................................................*/ 5775 RedrawType display = REDRAW_ALL; // redraw level 5776 BOOL process = true; // process while true 5777 KeyNumType input; 5778 5779 char phone_num[ PhoneEntryClass::PHONE_MAX_NUM ] = { 0 }; // buffer for editing phone # 5780 int rc; 5781 int i; 5782 int tabs[] = {123*factor, 207*factor}; // tabs for list box 5783 char *item; // for removing items from list box 5784 PhoneEntryClass *p_entry; // for creating / editing phonebook entries 5785 int changed = 0; // 1 = save changes to INI file 5786 int firsttime = 0; 5787 5788 /*........................................................................ 5789 Buttons 5790 ........................................................................*/ 5791 GadgetClass *commands; // button list 5792 5793 void const *up_button; 5794 void const *down_button; 5795 5796 if (InMainLoop){ 5797 up_button = Hires_Retrieve("BTN-UP.SHP"); 5798 down_button = Hires_Retrieve("BTN-DN.SHP"); 5799 }else{ 5800 up_button = Hires_Retrieve("BTN-UP2.SHP"); 5801 down_button = Hires_Retrieve("BTN-DN2.SHP"); 5802 } 5803 5804 5805 ListClass phonelist(BUTTON_PHONELIST, 5806 d_phonelist_x, d_phonelist_y, d_phonelist_w, d_phonelist_h, 5807 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 5808 up_button, 5809 down_button); 5810 5811 TextButtonClass addbtn(BUTTON_ADD, TXT_ADD, 5812 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 5813 //#ifdef FRENCH 5814 // d_add_x-4, d_add_y); 5815 //#else 5816 d_add_x, d_add_y, d_add_w, d_add_h); 5817 //#endif 5818 5819 TextButtonClass editbtn(BUTTON_EDIT, TXT_EDIT, 5820 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 5821 d_edit_x, d_edit_y, d_edit_w, d_edit_h); 5822 5823 TextButtonClass deletebtn(BUTTON_DELETE, TXT_DELETE_BUTTON, 5824 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 5825 //#ifdef FRENCH 5826 // d_delete_x, d_delete_y); 5827 //#else 5828 d_delete_x, d_delete_y, d_delete_w, d_delete_h); 5829 //#endif 5830 5831 TextButtonClass dialbtn(BUTTON_DIAL, TXT_DIAL, 5832 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 5833 /* ###Change collision detected! C:\PROJECTS\CODE\NULLDLG.CPP... */ 5834 d_dial_x, d_dial_y, d_dial_w, d_dial_h); 5835 5836 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, 5837 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 5838 //#if (GERMAN | FRENCH) 5839 // d_cancel_x, d_cancel_y); 5840 //#else 5841 d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); 5842 //#endif 5843 5844 EditClass numedit (BUTTON_NUMEDIT, 5845 phone_num, PhoneEntryClass::PHONE_MAX_NUM, 5846 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 5847 d_numedit_x, d_numedit_y, d_numedit_w, d_numedit_h, EditClass::ALPHANUMERIC); 5848 5849 /* 5850 ------------------------- Build the button list -------------------------- 5851 */ 5852 commands = &phonelist; 5853 addbtn.Add_Tail(*commands); 5854 editbtn.Add_Tail(*commands); 5855 deletebtn.Add_Tail(*commands); 5856 dialbtn.Add_Tail(*commands); 5857 cancelbtn.Add_Tail(*commands); 5858 numedit.Add_Tail(*commands); 5859 dialbtn.Turn_On(); 5860 5861 /* 5862 ----------------------------- Various Inits ------------------------------ 5863 */ 5864 /*........................................................................ 5865 Fill in the phone directory list box 5866 ........................................................................*/ 5867 phonelist.Set_Tabs(tabs); 5868 Build_Phone_Listbox(&phonelist, &numedit, phone_num); 5869 5870 if (CurPhoneIdx == -1) { 5871 firsttime = 1; 5872 } 5873 5874 /* 5875 ---------------------------- Processing loop ----------------------------- 5876 */ 5877 while (process) { 5878 5879 /* 5880 ** If we have just received input focus again after running in the background then 5881 ** we need to redraw. 5882 */ 5883 if (AllSurfaces.SurfacesRestored){ 5884 AllSurfaces.SurfacesRestored=FALSE; 5885 display=REDRAW_ALL; 5886 } 5887 5888 /* 5889 ........................ Invoke game callback ......................... 5890 */ 5891 Call_Back(); 5892 5893 /* 5894 ...................... Refresh display if needed ...................... 5895 */ 5896 if (display) { 5897 Hide_Mouse(); 5898 /* 5899 .................. Redraw backgound & dialog box ................... 5900 */ 5901 if (display >= REDRAW_BACKGROUND) { 5902 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 5903 Blit_Hid_Page_To_Seen_Buff(); 5904 Set_Palette(Palette); 5905 5906 Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); 5907 5908 // init font variables 5909 5910 Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, 5911 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 5912 5913 /*............................................................... 5914 Dialog & Field labels 5915 ...............................................................*/ 5916 Draw_Caption (TXT_PHONE_LIST, d_dialog_x, d_dialog_y, d_dialog_w); 5917 } 5918 /* 5919 .......................... Redraw buttons .......................... 5920 */ 5921 if (display >= REDRAW_BUTTONS) { 5922 phonelist.Flag_To_Redraw(); 5923 addbtn.Flag_To_Redraw(); 5924 editbtn.Flag_To_Redraw(); 5925 deletebtn.Flag_To_Redraw(); 5926 dialbtn.Flag_To_Redraw(); 5927 cancelbtn.Flag_To_Redraw(); 5928 numedit.Flag_To_Redraw(); 5929 } 5930 Show_Mouse(); 5931 display = REDRAW_NONE; 5932 } 5933 5934 /* 5935 ........................... Get user input ............................ 5936 */ 5937 input = commands->Input(); 5938 5939 if ( firsttime ) { 5940 numedit.Set_Focus(); 5941 numedit.Flag_To_Redraw(); 5942 input = commands->Input(); 5943 firsttime = 0; 5944 } 5945 5946 /* 5947 ---------------------------- Process input ---------------------------- 5948 */ 5949 switch (input) { 5950 /*------------------------------------------------------------------ 5951 New phone listing selected. 5952 ------------------------------------------------------------------*/ 5953 case (BUTTON_PHONELIST | KN_BUTTON): 5954 /*............................................................... 5955 Detect a change in the selected item; update CurPhoneIdx, and 5956 the edit box buffer. 5957 ...............................................................*/ 5958 if (phonelist.Current_Index() != CurPhoneIdx) { 5959 CurPhoneIdx = phonelist.Current_Index(); 5960 strcpy (phone_num, PhoneBook[CurPhoneIdx]->Number); 5961 numedit.Set_Text (phone_num, PhoneEntryClass::PHONE_MAX_NUM ); 5962 changed = 1; 5963 } 5964 break; 5965 5966 /*------------------------------------------------------------------ 5967 Add a new entry 5968 ------------------------------------------------------------------*/ 5969 case (BUTTON_ADD | KN_BUTTON): 5970 5971 /*............................................................... 5972 Allocate a new phone book entry 5973 ...............................................................*/ 5974 p_entry = new PhoneEntryClass(); 5975 p_entry->Name[0] = 0; 5976 p_entry->Number[0] = 0; 5977 p_entry->Settings.Port = 0; 5978 p_entry->Settings.IRQ = -1; 5979 p_entry->Settings.Baud = -1; 5980 p_entry->Settings.DialMethod = DIAL_TOUCH_TONE; 5981 p_entry->Settings.InitStringIndex = 0; 5982 p_entry->Settings.CallWaitStringIndex = CALL_WAIT_CUSTOM; 5983 p_entry->Settings.CallWaitString[0] = 0; 5984 5985 /*............................................................... 5986 Invoke the entry editor; if user clicks Save, add the new entry 5987 to the list, and rebuild the list box. 5988 ...............................................................*/ 5989 if ( Edit_Phone_Dialog( p_entry ) ) { 5990 PhoneBook.Add (p_entry); 5991 Build_Phone_Listbox( &phonelist, &numedit, phone_num ); 5992 /*............................................................ 5993 Set the current listbox index to the newly-added item. 5994 ............................................................*/ 5995 for (i = 0; i < PhoneBook.Count(); i++) { 5996 if (p_entry == PhoneBook[i]) { 5997 CurPhoneIdx = i; 5998 strcpy (phone_num, PhoneBook[CurPhoneIdx]->Number); 5999 numedit.Set_Text (phone_num, PhoneEntryClass::PHONE_MAX_NUM ); 6000 phonelist.Set_Selected_Index( CurPhoneIdx ); 6001 } 6002 } 6003 changed = 1; 6004 } else { 6005 6006 /*............................................................... 6007 If the user clicked Cancel, delete the entry & keep looping. 6008 ...............................................................*/ 6009 delete p_entry; 6010 } 6011 display = REDRAW_ALL; 6012 break; 6013 6014 /*------------------------------------------------------------------ 6015 Edit the current entry 6016 ------------------------------------------------------------------*/ 6017 case (BUTTON_EDIT | KN_BUTTON): 6018 6019 /*............................................................... 6020 Do nothing if no entry is selected. 6021 ...............................................................*/ 6022 if (CurPhoneIdx==-1) 6023 break; 6024 6025 /*............................................................... 6026 Allocate a new entry & copy the currently-selected entry into it 6027 ...............................................................*/ 6028 p_entry = new PhoneEntryClass(); 6029 (*p_entry) = (*PhoneBook[CurPhoneIdx]); 6030 6031 /*............................................................... 6032 Pass the new entry to the entry editor; if the user selects OK, 6033 copy the data back into our phone book. Rebuild the list so 6034 the changes show up in the list box. 6035 ...............................................................*/ 6036 if ( Edit_Phone_Dialog( p_entry ) ) { 6037 (*PhoneBook[CurPhoneIdx]) = (*p_entry); 6038 Build_Phone_Listbox(&phonelist, &numedit, phone_num); 6039 /*............................................................ 6040 Set the current listbox index to the newly-added item. 6041 ............................................................*/ 6042 for (i = 0; i < PhoneBook.Count(); i++) { 6043 if (PhoneBook[CurPhoneIdx] == PhoneBook[i]) { 6044 CurPhoneIdx = i; 6045 strcpy (phone_num, PhoneBook[CurPhoneIdx]->Number); 6046 numedit.Set_Text (phone_num, PhoneEntryClass::PHONE_MAX_NUM ); 6047 phonelist.Set_Selected_Index( CurPhoneIdx ); 6048 } 6049 } 6050 changed = 1; 6051 } 6052 delete p_entry; 6053 display = REDRAW_ALL; 6054 break; 6055 6056 /*------------------------------------------------------------------ 6057 Delete the current entry 6058 ------------------------------------------------------------------*/ 6059 case (BUTTON_DELETE | KN_BUTTON): 6060 6061 /*............................................................... 6062 Do nothing if no entry is selected. 6063 ...............................................................*/ 6064 if (CurPhoneIdx == -1) 6065 break; 6066 6067 /*............................................................... 6068 Delete the current item & rebuild the phone listbox 6069 ...............................................................*/ 6070 PhoneBook.Delete (CurPhoneIdx); 6071 Build_Phone_Listbox(&phonelist, &numedit, phone_num); 6072 6073 if (CurPhoneIdx == -1) { 6074 *phone_num = 0; 6075 numedit.Set_Text (phone_num, PhoneEntryClass::PHONE_MAX_NUM ); 6076 } 6077 changed = 1; 6078 break; 6079 6080 /*------------------------------------------------------------------ 6081 Dial the current number 6082 ------------------------------------------------------------------*/ 6083 case (KN_RETURN): 6084 dialbtn.IsPressed = true; 6085 dialbtn.Draw_Me(true); 6086 // fall thru 6087 6088 case (BUTTON_DIAL | KN_BUTTON): 6089 6090 /*............................................................... 6091 If no item is selected, just dial the number in the phone # 6092 edit box: 6093 - Create a new phone entry 6094 - Copy the phone number into it 6095 - Set settings to defaults 6096 ...............................................................*/ 6097 if (CurPhoneIdx == -1 || 6098 strcmp( PhoneBook[CurPhoneIdx]->Number, phone_num) ) { 6099 6100 if ( strlen(phone_num) == 0) { // do not dial 6101 dialbtn.IsPressed = false; 6102 dialbtn.Flag_To_Redraw(); 6103 break; 6104 } 6105 6106 p_entry = new PhoneEntryClass(); 6107 strcpy( p_entry->Name, "NONAME" ); 6108 strcpy( p_entry->Number, phone_num); 6109 p_entry->Settings.Port = 0; 6110 p_entry->Settings.IRQ = -1; 6111 p_entry->Settings.Baud = -1; 6112 p_entry->Settings.DialMethod = DIAL_TOUCH_TONE; 6113 p_entry->Settings.InitStringIndex = 0; 6114 p_entry->Settings.CallWaitStringIndex = CALL_WAIT_CUSTOM; 6115 p_entry->Settings.CallWaitString[0] = 0; 6116 6117 PhoneBook.Add (p_entry); 6118 Build_Phone_Listbox(&phonelist, &numedit, phone_num); 6119 /*............................................................ 6120 Set the current listbox index to the newly-added item. 6121 ............................................................*/ 6122 for (i = 0; i < PhoneBook.Count(); i++) { 6123 if (p_entry == PhoneBook[i]) { 6124 CurPhoneIdx = i; 6125 } 6126 } 6127 changed = 1; 6128 } 6129 6130 process = false; 6131 rc = true; 6132 break; 6133 6134 /*------------------------------------------------------------------ 6135 CANCEL: bail out 6136 ------------------------------------------------------------------*/ 6137 case (KN_ESC): 6138 case (BUTTON_CANCEL | KN_BUTTON): 6139 process = false; 6140 rc = false; 6141 break; 6142 } 6143 6144 } /* end of while */ 6145 6146 /*------------------------------------------------------------------------ 6147 Save any changes we've made to the phone list or settings 6148 ------------------------------------------------------------------------*/ 6149 if (changed) { 6150 Write_MultiPlayer_Settings (); 6151 } 6152 6153 /*------------------------------------------------------------------------ 6154 Clear the list box 6155 ------------------------------------------------------------------------*/ 6156 while (phonelist.Count()) { 6157 item = (char *)phonelist.Get_Item(0); 6158 phonelist.Remove_Item(item); 6159 delete [] item; 6160 } 6161 6162 return(rc); 6163 6164 } /* end of Phone_Dialog */ 6165 6166 6167 /*************************************************************************** 6168 * Build_Phone_Listbox -- [re]builds the phone entry listbox * 6169 * * 6170 * This routine rebuilds the phone list box from scratch; it also updates * 6171 * the contents of the phone # edit field. * 6172 * * 6173 * INPUT: * 6174 * list ptr to list box * 6175 * edit ptr to edit box * 6176 * buf ptr to buffer for phone # * 6177 * * 6178 * OUTPUT: * 6179 * none. * 6180 * * 6181 * WARNINGS: * 6182 * none. * 6183 * * 6184 * HISTORY: * 6185 * 04/29/1995 BRR : Created. * 6186 *=========================================================================*/ 6187 static void Build_Phone_Listbox (ListClass *list, EditClass *edit, char *buf) 6188 { 6189 int i; 6190 char *item; 6191 char phonename[21]; 6192 char phonenum[15]; 6193 6194 /*........................................................................ 6195 Clear the list 6196 ........................................................................*/ 6197 while (list->Count()) { 6198 item = (char *)(list->Get_Item(0)); 6199 list->Remove_Item(item); 6200 delete [] item; 6201 } 6202 6203 /* 6204 ** Now sort the phone list by name then number 6205 */ 6206 qsort ((void *)(&PhoneBook[0]), PhoneBook.Count(), sizeof(class PhoneEntryClass *), Phone_Compare); 6207 6208 /*........................................................................ 6209 Build the list 6210 ........................................................................*/ 6211 for (i = 0; i < PhoneBook.Count(); i++) { 6212 item = new char[80]; 6213 if ( !(strlen( PhoneBook[i]->Name )) ) { 6214 strcpy( phonename, " " ); 6215 } else { 6216 strncpy( phonename, PhoneBook[i]->Name, 20 ); 6217 phonename[21] = 0; 6218 } 6219 6220 if ( !(strlen( PhoneBook[i]->Number )) ) { 6221 strcpy( phonenum, " " ); 6222 } else { 6223 if ( strlen( PhoneBook[i]->Number ) < 14) { 6224 strcpy( phonenum, PhoneBook[i]->Number ); 6225 } else { 6226 strncpy( phonenum, PhoneBook[i]->Number, 12 ); 6227 phonenum[12] = 0; 6228 strcat( phonenum, "..." ); 6229 } 6230 } 6231 6232 if (PhoneBook[i]->Settings.Baud != -1) { 6233 sprintf(item,"%s\t%s\t%d", phonename, phonenum, 6234 PhoneBook[i]->Settings.Baud); 6235 } else { 6236 sprintf(item,"%s\t%s\t[%s]", phonename, phonenum, 6237 Text_String(TXT_DEFAULT)); 6238 } 6239 list->Add_Item(item); 6240 } 6241 list->Flag_To_Redraw(); 6242 6243 /*........................................................................ 6244 Init the current phone book index 6245 ........................................................................*/ 6246 if (list->Count() == 0 || CurPhoneIdx < -1) { 6247 CurPhoneIdx = -1; 6248 } else { 6249 if (CurPhoneIdx >= list->Count() ) { 6250 CurPhoneIdx = 0; 6251 } 6252 } 6253 6254 /*........................................................................ 6255 Fill in phone number edit buffer 6256 ........................................................................*/ 6257 if (CurPhoneIdx > -1) { 6258 strcpy (buf, PhoneBook[CurPhoneIdx]->Number); 6259 edit->Set_Text (buf, PhoneEntryClass::PHONE_MAX_NUM ); 6260 list->Set_Selected_Index( CurPhoneIdx ); 6261 } 6262 } 6263 6264 6265 /*************************************************************************** 6266 * Phone_Compare -- for qsort * 6267 * * 6268 * INPUT: * 6269 * p1,p2 ptrs to elements to compare * 6270 * * 6271 * OUTPUT: * 6272 * 0 = same, -1 = (*p1) goes BEFORE (*p2), 1 = (*p1) goes AFTER (*p2) * 6273 * * 6274 * WARNINGS: * 6275 * none. * 6276 * * 6277 * HISTORY: * 6278 * 02/14/1995 BR : Created. * 6279 *=========================================================================*/ 6280 static int Phone_Compare (const void *p1, const void *p2) 6281 { 6282 class PhoneEntryClass *pe1,*pe2; 6283 int result; 6284 6285 pe1 = *((class PhoneEntryClass **)p1); 6286 pe2 = *((class PhoneEntryClass **)p2); 6287 6288 result = strcmp( pe1->Name, pe2->Name ); 6289 6290 // if strings are equal then check the phone number 6291 6292 if ( !result ) { 6293 result = strcmp( pe1->Number, pe2->Number ); 6294 } 6295 6296 return(result); 6297 } 6298 6299 6300 /*************************************************************************** 6301 * Edit_Phone_Dialog -- lets user edit a phone book entry * 6302 * * 6303 * INPUT: * 6304 * phone entry to edit * 6305 * * 6306 * OUTPUT: * 6307 * true = OK, false = cancel * 6308 * * 6309 * WARNINGS: * 6310 * none. * 6311 * * 6312 * HISTORY: * 6313 * 04/29/1995 BRR : Created. * 6314 *=========================================================================*/ 6315 static int Edit_Phone_Dialog (PhoneEntryClass *phone) 6316 { 6317 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 6318 /*........................................................................ 6319 Dialog & button dimensions 6320 ........................................................................*/ 6321 int d_dialog_w = 230 *factor; // dialog width 6322 int d_dialog_h = 105*factor; // dialog height 6323 int d_dialog_x = ((320*factor - d_dialog_w) / 2); // dialog x-coord 6324 // D_DIALOG_Y = ((200 - D_DIALOG_H) / 2); // dialog y-coord 6325 int d_dialog_y = ((136*factor - d_dialog_h) / 2); // dialog y-coord 6326 int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord 6327 6328 int d_txt6_h = 11 *factor; // ht of 6-pt text 6329 int d_margin = 7 *factor; // margin width/height 6330 6331 int d_name_w = ( (PhoneEntryClass::PHONE_MAX_NAME - 1) * 6) + 3 *factor; 6332 int d_name_h = 9 *factor; 6333 int d_name_x = d_dialog_x + (((d_dialog_w - d_name_w) * 3) / 4) - 5 *factor; 6334 int d_name_y = d_dialog_y + 25 *factor; 6335 6336 int d_number_w = ( (PhoneEntryClass::PHONE_MAX_NUM - 1) * 6) + 3 *factor; 6337 int d_number_h = 9 *factor; 6338 int d_number_x = d_dialog_x + (((d_dialog_w - d_number_w) * 3) / 4) - 5 *factor; 6339 int d_number_y = d_name_y + d_name_h + d_margin; 6340 6341 #if (GERMAN | FRENCH) 6342 int d_default_w = 130 *factor; 6343 #else 6344 int d_default_w = 104 *factor; 6345 #endif 6346 int d_default_h = 9 *factor; 6347 int d_default_x = d_dialog_cx - (d_default_w / 2); 6348 int d_default_y = d_number_y + d_number_h + d_margin; 6349 6350 #if (GERMAN | FRENCH) 6351 int d_custom_w = 130 *factor; 6352 #else 6353 int d_custom_w = 100 *factor; 6354 #endif 6355 int d_custom_h = 9 *factor; 6356 int d_custom_x = d_dialog_cx - (d_default_w / 2); 6357 int d_custom_y = d_default_y + d_default_h + d_margin; 6358 6359 #if (GERMAN | FRENCH) 6360 int d_save_w = 55 *factor; 6361 #else 6362 int d_save_w = 45 *factor; 6363 #endif 6364 int d_save_h = 9 *factor; 6365 int d_save_x = d_dialog_cx - d_margin - d_save_w; 6366 int d_save_y = d_dialog_y + d_dialog_h - d_margin - d_save_h; 6367 6368 #if (GERMAN | FRENCH) 6369 int d_cancel_w = 55 *factor; 6370 #else 6371 int d_cancel_w = 45 *factor; 6372 #endif 6373 int d_cancel_h = 9 *factor; 6374 int d_cancel_x = d_dialog_cx + d_margin; 6375 int d_cancel_y = d_dialog_y + d_dialog_h - d_margin - d_cancel_h; 6376 6377 /*........................................................................ 6378 Button Enumerations 6379 ........................................................................*/ 6380 enum { 6381 BUTTON_NAME = 100, 6382 BUTTON_NUMBER, 6383 BUTTON_DEFAULT, 6384 BUTTON_CUSTOM, 6385 BUTTON_SAVE, 6386 BUTTON_CANCEL, 6387 }; 6388 6389 /*........................................................................ 6390 Redraw values: in order from "top" to "bottom" layer of the dialog 6391 ........................................................................*/ 6392 typedef enum { 6393 REDRAW_NONE = 0, 6394 REDRAW_BUTTONS, 6395 REDRAW_BACKGROUND, 6396 REDRAW_ALL = REDRAW_BACKGROUND 6397 } RedrawType; 6398 6399 /*........................................................................ 6400 Dialog variables 6401 ........................................................................*/ 6402 RedrawType display = REDRAW_ALL; // redraw level 6403 BOOL process = true; // process while true 6404 KeyNumType input; 6405 6406 char namebuf[PhoneEntryClass::PHONE_MAX_NAME] = { 0 }; // buffer for editing name 6407 char numbuf[PhoneEntryClass::PHONE_MAX_NUM] = { 0 }; // buffer for editing phone # 6408 int rc; 6409 SerialSettingsType settings; 6410 int custom = 0; 6411 int firsttime = 1; 6412 6413 /*........................................................................ 6414 Buttons 6415 ........................................................................*/ 6416 GadgetClass *commands; // button list 6417 6418 EditClass nameedit (BUTTON_NAME, 6419 namebuf, PhoneEntryClass::PHONE_MAX_NAME, 6420 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 6421 d_name_x, d_name_y, d_name_w, d_name_h, EditClass::ALPHANUMERIC); 6422 6423 EditClass numedit (BUTTON_NUMBER, 6424 numbuf, PhoneEntryClass::PHONE_MAX_NUM, 6425 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 6426 d_number_x, d_number_y, d_number_w, d_number_h, EditClass::ALPHANUMERIC); 6427 6428 TextButtonClass defaultbtn(BUTTON_DEFAULT, TXT_DEFAULT_SETTINGS, 6429 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 6430 d_default_x, d_default_y, d_default_w, d_default_h); 6431 6432 TextButtonClass custombtn(BUTTON_CUSTOM, TXT_CUSTOM_SETTINGS, 6433 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 6434 d_custom_x, d_custom_y, d_custom_w, d_custom_h); 6435 6436 TextButtonClass savebtn(BUTTON_SAVE, TXT_SAVE_BUTTON, 6437 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 6438 d_save_x, d_save_y, d_save_w, d_save_h); 6439 6440 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, 6441 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 6442 d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h); 6443 6444 /* 6445 ------------------------- Build the button list -------------------------- 6446 */ 6447 commands = &nameedit; 6448 numedit.Add_Tail(*commands); 6449 defaultbtn.Add_Tail(*commands); 6450 custombtn.Add_Tail(*commands); 6451 savebtn.Add_Tail(*commands); 6452 cancelbtn.Add_Tail(*commands); 6453 6454 /* 6455 ----------------------------- Various Inits ------------------------------ 6456 */ 6457 /*........................................................................ 6458 Init the settings; if the phone entry is set to use defaults, init our 6459 settings to sensible values (in case we invoke the setting editor); 6460 otherwise, copy the entry's settings. 6461 ........................................................................*/ 6462 if (phone->Settings.Port == 0 || phone->Settings.IRQ == -1 || 6463 phone->Settings.Baud == -1) { 6464 settings = SerialDefaults; 6465 defaultbtn.Turn_On(); 6466 custom = false; 6467 } else { 6468 settings = phone->Settings; 6469 custombtn.Turn_On(); 6470 custom = true; 6471 } 6472 6473 strcpy (namebuf, phone->Name); 6474 nameedit.Set_Text (namebuf, PhoneEntryClass::PHONE_MAX_NAME); 6475 6476 strcpy (numbuf, phone->Number); 6477 numedit.Set_Text (numbuf, PhoneEntryClass::PHONE_MAX_NUM); 6478 6479 /* 6480 ---------------------------- Processing loop ----------------------------- 6481 */ 6482 while (process) { 6483 6484 /* 6485 ** If we have just received input focus again after running in the background then 6486 ** we need to redraw. 6487 */ 6488 if (AllSurfaces.SurfacesRestored){ 6489 AllSurfaces.SurfacesRestored=FALSE; 6490 display=REDRAW_ALL; 6491 } 6492 6493 /* 6494 ........................ Invoke game callback ......................... 6495 */ 6496 Call_Back(); 6497 6498 /* 6499 ...................... Refresh display if needed ...................... 6500 */ 6501 if (display) { 6502 Hide_Mouse(); 6503 /* 6504 .................. Redraw backgound & dialog box ................... 6505 */ 6506 if (display >= REDRAW_BACKGROUND) { 6507 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 6508 Blit_Hid_Page_To_Seen_Buff(); 6509 Set_Palette(Palette); 6510 6511 Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); 6512 6513 // init font variables 6514 6515 Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, 6516 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 6517 6518 /*............................................................... 6519 Dialog & Field labels 6520 ...............................................................*/ 6521 Draw_Caption (TXT_PHONE_LISTING, d_dialog_x, d_dialog_y, d_dialog_w); 6522 6523 Fancy_Text_Print (TXT_NAME_COLON, 6524 d_name_x - 5, d_name_y + 1, 6525 CC_GREEN, TBLACK, 6526 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 6527 6528 Fancy_Text_Print (TXT_NUMBER_COLON, 6529 d_number_x - 5, d_number_y + 1, 6530 CC_GREEN, TBLACK, 6531 TPF_RIGHT | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 6532 } 6533 /* 6534 .......................... Redraw buttons .......................... 6535 */ 6536 if (display >= REDRAW_BUTTONS) { 6537 commands->Flag_List_To_Redraw(); 6538 } 6539 Show_Mouse(); 6540 display = REDRAW_NONE; 6541 } 6542 6543 /* 6544 ........................... Get user input ............................ 6545 */ 6546 input = commands->Input(); 6547 6548 if ( firsttime ) { 6549 nameedit.Set_Focus(); 6550 nameedit.Flag_To_Redraw(); 6551 input = commands->Input(); 6552 firsttime = 0; 6553 } 6554 6555 /* 6556 ---------------------------- Process input ---------------------------- 6557 */ 6558 switch (input) { 6559 case (BUTTON_NAME | KN_BUTTON): 6560 numedit.Set_Focus(); 6561 numedit.Flag_To_Redraw(); 6562 break; 6563 6564 // case (BUTTON_NUMBER | KN_BUTTON): 6565 // nameedit.Clear_Focus(); 6566 // nameedit.Flag_To_Redraw(); 6567 // break; 6568 6569 /*------------------------------------------------------------------ 6570 Use Default Serial Settings 6571 ------------------------------------------------------------------*/ 6572 case (BUTTON_DEFAULT | KN_BUTTON): 6573 custombtn.Turn_Off(); 6574 defaultbtn.Turn_On(); 6575 custom = 0; 6576 break; 6577 6578 /*------------------------------------------------------------------ 6579 Use Custom Serial Settings 6580 ------------------------------------------------------------------*/ 6581 case (BUTTON_CUSTOM | KN_BUTTON): 6582 if (Com_Settings_Dialog (&settings)) { 6583 custombtn.Turn_On(); 6584 defaultbtn.Turn_Off(); 6585 } 6586 custom = 1; 6587 display = REDRAW_ALL; 6588 break; 6589 6590 /*------------------------------------------------------------------ 6591 CANCEL: bail out 6592 ------------------------------------------------------------------*/ 6593 case (KN_ESC): 6594 case (BUTTON_CANCEL | KN_BUTTON): 6595 process = false; 6596 rc = false; 6597 break; 6598 6599 /*------------------------------------------------------------------ 6600 Save: save changes 6601 ------------------------------------------------------------------*/ 6602 case (KN_RETURN): 6603 case (BUTTON_SAVE | KN_BUTTON): 6604 process = false; 6605 rc = true; 6606 break; 6607 } 6608 6609 } /* end of while */ 6610 6611 /*------------------------------------------------------------------------ 6612 If 'Save', save all current settings 6613 ------------------------------------------------------------------------*/ 6614 if (rc) { 6615 strcpy( phone->Name, strupr( namebuf ) ); 6616 6617 // if nothing was entered then make if NONAME 6618 6619 if ( !(phone->Name[0]) ) { 6620 strcpy( phone->Name, "NONAME" ); 6621 } 6622 6623 strcpy( phone->Number, strupr( numbuf ) ); 6624 6625 if (custom) { 6626 phone->Settings = settings; 6627 } else { 6628 phone->Settings.Port = 0; 6629 phone->Settings.IRQ = -1; 6630 phone->Settings.Baud = -1; 6631 phone->Settings.DialMethod = DIAL_TOUCH_TONE; 6632 phone->Settings.InitStringIndex = 0; 6633 phone->Settings.CallWaitStringIndex = CALL_WAIT_CUSTOM; 6634 phone->Settings.CallWaitString[0] = 0; 6635 } 6636 } 6637 6638 return(rc); 6639 6640 6641 } /* end of Edit_Phone_Dialog */ 6642 6643 6644 static bool Dial_Modem( SerialSettingsType *settings, bool reconnect ) 6645 { 6646 bool connected = false; 6647 DialStatusType dialstatus; 6648 int modemstatus; 6649 6650 /* 6651 ** Turn modem servicing off in the callback routine. 6652 */ 6653 ModemService = false; 6654 6655 // save for later to reconnect 6656 6657 DialSettings = settings; 6658 6659 modemstatus = NullModem.Get_Modem_Status(); 6660 if (reconnect) { 6661 if ( (modemstatus & CD_SET) ) { 6662 connected = true; 6663 ModemService = true; 6664 return( connected ); 6665 } 6666 } else { 6667 if ( (modemstatus & CD_SET) ) { 6668 NullModem.Hangup_Modem(); 6669 ModemService = false; 6670 } 6671 } 6672 6673 NullModem.Setup_Modem_Echo( Modem_Echo ); 6674 6675 modemstatus = NullModem.Detect_Modem( settings, reconnect ); 6676 if ( !modemstatus ) { 6677 NullModem.Remove_Modem_Echo(); 6678 NullModem.Print_EchoBuf(); 6679 NullModem.Reset_EchoBuf(); 6680 6681 /* 6682 ** If our first attempt to detect the modem failed, and we're at 6683 ** 14400 or 28800, bump up to the next baud rate & try again. 6684 */ 6685 switch (settings->Baud) { 6686 6687 case 14400: 6688 settings->Baud = 19200; 6689 Shutdown_Modem(); 6690 Init_Null_Modem(settings); 6691 NullModem.Setup_Modem_Echo( Modem_Echo ); 6692 modemstatus = NullModem.Detect_Modem( settings, reconnect ); 6693 if ( !modemstatus ) { 6694 NullModem.Remove_Modem_Echo(); 6695 NullModem.Print_EchoBuf(); 6696 NullModem.Reset_EchoBuf(); 6697 CCMessageBox().Process( TXT_UNABLE_FIND_MODEM ); 6698 ModemService = true; 6699 return( connected ); 6700 } 6701 break; 6702 6703 case 28800: 6704 settings->Baud = 38400; 6705 Shutdown_Modem(); 6706 Init_Null_Modem(settings); 6707 NullModem.Setup_Modem_Echo( Modem_Echo ); 6708 modemstatus = NullModem.Detect_Modem( settings, reconnect ); 6709 if ( !modemstatus ) { 6710 NullModem.Remove_Modem_Echo(); 6711 NullModem.Print_EchoBuf(); 6712 NullModem.Reset_EchoBuf(); 6713 CCMessageBox().Process( TXT_UNABLE_FIND_MODEM ); 6714 ModemService = true; 6715 return( connected ); 6716 } 6717 break; 6718 6719 default: 6720 CCMessageBox().Process( TXT_UNABLE_FIND_MODEM ); 6721 ModemService = true; 6722 return( connected ); 6723 6724 } 6725 } 6726 else if ( modemstatus == -1 ) { 6727 NullModem.Remove_Modem_Echo(); 6728 NullModem.Print_EchoBuf(); 6729 NullModem.Reset_EchoBuf(); 6730 CCMessageBox().Process( TXT_ERROR_IN_INITSTRING ); 6731 ModemService = true; 6732 return( connected ); 6733 } 6734 6735 6736 /* 6737 ** Completely disable audio. This is required for MWave devices 6738 */ 6739 ThemeType old_theme = THEME_NONE; 6740 if (SoundOn){ 6741 old_theme = Theme.What_Is_Playing(); 6742 Theme.Stop(); 6743 CountDownTimerClass wait; 6744 Call_Back(); 6745 wait.Set (60,true); 6746 while ( wait.Time() ) { 6747 Call_Back(); 6748 } 6749 Sound_End(); 6750 Call_Back(); 6751 wait.Set (60,true); 6752 while ( wait.Time() ) { 6753 Call_Back(); 6754 } 6755 SoundOn = 0; 6756 } 6757 6758 dialstatus = NullModem.Dial_Modem( DialString, settings->DialMethod, reconnect ); 6759 6760 if (reconnect) { 6761 /* 6762 --------------------------- Redraw the display --------------------------- 6763 */ 6764 HiddenPage.Clear(); 6765 Map.Flag_To_Redraw(true); 6766 Map.Render(); 6767 } 6768 6769 switch ( dialstatus ) { 6770 case DIAL_CONNECTED: 6771 connected = true; 6772 break; 6773 6774 case DIAL_NO_CARRIER: 6775 CCMessageBox().Process(TXT_NO_CARRIER); 6776 connected = false; 6777 break; 6778 6779 case DIAL_BUSY: 6780 CCMessageBox().Process(TXT_LINE_BUSY); 6781 connected = false; 6782 break; 6783 6784 case DIAL_ERROR: 6785 CCMessageBox().Process(TXT_NUMBER_INVALID); 6786 connected = false; 6787 break; 6788 6789 case DIAL_NO_DIAL_TONE: 6790 CCMessageBox().Process(TXT_NO_DIAL_TONE); 6791 connected = false; 6792 break; 6793 6794 case DIAL_CANCELED: 6795 NullModem.Hangup_Modem(); 6796 ModemService = false; 6797 CCMessageBox().Process(TXT_DIALING_CANCELED); 6798 connected = false; 6799 break; 6800 } 6801 6802 NullModem.Remove_Modem_Echo(); 6803 NullModem.Print_EchoBuf(); 6804 NullModem.Reset_EchoBuf(); 6805 6806 /* 6807 ** Restore audio capability 6808 */ 6809 SoundOn = Audio_Init ( MainWindow , 16 , false , 11025*2 , 0 ); 6810 if (SoundOn){ 6811 Theme.Play_Song (old_theme); 6812 } 6813 6814 ModemService = true; 6815 return( connected ); 6816 6817 } /* end of Dial_Modem */ 6818 6819 6820 static bool Answer_Modem( SerialSettingsType *settings, bool reconnect ) 6821 { 6822 bool connected = false; 6823 DialStatusType dialstatus; 6824 int modemstatus; 6825 6826 /* ###Change collision detected! C:\PROJECTS\CODE\NULLDLG.CPP... */ 6827 /* 6828 ** Turn modem servicing off in the callback routine. 6829 */ 6830 ModemService = false; 6831 6832 // save for later to reconnect 6833 6834 DialSettings = settings; 6835 6836 modemstatus = NullModem.Get_Modem_Status(); 6837 if (reconnect) { 6838 if ( (modemstatus & CD_SET) ) { 6839 connected = true; 6840 ModemService = true; 6841 return( connected ); 6842 } 6843 } else { 6844 if ( (modemstatus & CD_SET) ) { 6845 NullModem.Hangup_Modem(); 6846 ModemService = false; 6847 } 6848 } 6849 6850 NullModem.Setup_Modem_Echo( Modem_Echo ); 6851 6852 modemstatus = NullModem.Detect_Modem( settings, reconnect ); 6853 if ( !modemstatus ) { 6854 NullModem.Remove_Modem_Echo(); 6855 NullModem.Print_EchoBuf(); 6856 NullModem.Reset_EchoBuf(); 6857 6858 /* 6859 ** If our first attempt to detect the modem failed, and we're at 6860 ** 14400 or 28800, bump up to the next baud rate & try again. 6861 */ 6862 switch (settings->Baud) { 6863 6864 case 14400: 6865 settings->Baud = 19200; 6866 Shutdown_Modem(); 6867 Init_Null_Modem(settings); 6868 NullModem.Setup_Modem_Echo( Modem_Echo ); 6869 modemstatus = NullModem.Detect_Modem( settings, reconnect ); 6870 if ( !modemstatus ) { 6871 NullModem.Remove_Modem_Echo(); 6872 NullModem.Print_EchoBuf(); 6873 NullModem.Reset_EchoBuf(); 6874 CCMessageBox().Process( TXT_UNABLE_FIND_MODEM ); 6875 ModemService = true; 6876 return( connected ); 6877 } 6878 break; 6879 6880 case 28800: 6881 settings->Baud = 38400; 6882 Shutdown_Modem(); 6883 Init_Null_Modem(settings); 6884 NullModem.Setup_Modem_Echo( Modem_Echo ); 6885 modemstatus = NullModem.Detect_Modem( settings, reconnect ); 6886 if ( !modemstatus ) { 6887 NullModem.Remove_Modem_Echo(); 6888 NullModem.Print_EchoBuf(); 6889 NullModem.Reset_EchoBuf(); 6890 CCMessageBox().Process( TXT_UNABLE_FIND_MODEM ); 6891 ModemService = true; 6892 return( connected ); 6893 } 6894 break; 6895 6896 default: 6897 CCMessageBox().Process( TXT_UNABLE_FIND_MODEM ); 6898 ModemService = true; 6899 return( connected ); 6900 } 6901 6902 } 6903 else if ( modemstatus == -1 ) { 6904 NullModem.Remove_Modem_Echo(); 6905 NullModem.Print_EchoBuf(); 6906 NullModem.Reset_EchoBuf(); 6907 CCMessageBox().Process( TXT_ERROR_IN_INITSTRING ); 6908 ModemService = true; 6909 return( connected ); 6910 } 6911 6912 /* 6913 ** Completely disable audio. This is required for MWave devices 6914 */ 6915 ThemeType old_theme = THEME_NONE; 6916 if (SoundOn){ 6917 old_theme = Theme.What_Is_Playing(); 6918 Theme.Stop(); 6919 CountDownTimerClass wait; 6920 Call_Back(); 6921 wait.Set (60,true); 6922 while ( wait.Time() ) { 6923 Call_Back(); 6924 } 6925 Sound_End(); 6926 Call_Back(); 6927 wait.Set (60,true); 6928 while ( wait.Time() ) { 6929 Call_Back(); 6930 } 6931 SoundOn = 0; 6932 } 6933 6934 dialstatus = NullModem.Answer_Modem( reconnect ); 6935 6936 switch ( dialstatus ) { 6937 case DIAL_CONNECTED: 6938 connected = true; 6939 break; 6940 6941 case DIAL_NO_CARRIER: 6942 CCMessageBox().Process(TXT_NO_CARRIER); 6943 connected = false; 6944 break; 6945 6946 case DIAL_BUSY: 6947 CCMessageBox().Process(TXT_LINE_BUSY); 6948 connected = false; 6949 break; 6950 6951 case DIAL_ERROR: 6952 CCMessageBox().Process(TXT_NUMBER_INVALID); 6953 connected = false; 6954 break; 6955 6956 case DIAL_NO_DIAL_TONE: 6957 CCMessageBox().Process(TXT_NO_DIAL_TONE); 6958 connected = false; 6959 break; 6960 6961 case DIAL_CANCELED: 6962 CCMessageBox().Process(TXT_ANSWERING_CANCELED); 6963 connected = false; 6964 break; 6965 } 6966 6967 NullModem.Remove_Modem_Echo(); 6968 NullModem.Print_EchoBuf(); 6969 NullModem.Reset_EchoBuf(); 6970 6971 /* 6972 ** Restore audio capability 6973 */ 6974 SoundOn = Audio_Init ( MainWindow , 16 , false , 11025*2 , 0 ); 6975 if (SoundOn){ 6976 Theme.Play_Song (old_theme); 6977 } 6978 6979 ModemService = true; 6980 return( connected ); 6981 6982 } /* end of Answer_Modem */ 6983 6984 6985 static void Modem_Echo( char c ) 6986 { 6987 if (NullModem.EchoCount < (NullModem.EchoSize - 1) ) { 6988 *(NullModem.EchoBuf + NullModem.EchoCount) = c; 6989 *(NullModem.EchoBuf + NullModem.EchoCount + 1) = 0; 6990 NullModem.EchoCount++; 6991 } else { 6992 //Smart_Printf( "Echo buffer full!!!\n" ); 6993 } 6994 6995 } /* end of Modem_Echo */ 6996 6997 6998 void Smart_Printf( char *format, ... ) 6999 { 7000 va_list arglist; 7001 char buf[501]; 7002 7003 7004 va_start(arglist,format); 7005 vsprintf(buf,format,arglist); 7006 va_end(arglist); 7007 7008 if (Debug_Smart_Print) { 7009 if (Special.IsMonoEnabled) { 7010 // Mono_Set_Cursor(0,0); 7011 Mono_Printf("%s",buf); 7012 } else { 7013 // Mono_Printf("%s",buf); 7014 printf("%s",buf); 7015 } 7016 } else { 7017 if (Debug_Heap_Dump) { 7018 printf("%s",buf); 7019 } 7020 } 7021 } 7022 7023 7024 void Hex_Dump_Data( char *buffer, int length ) 7025 { 7026 int i; 7027 int offset = 0; 7028 char buff[10]; 7029 char ptr[16]; 7030 char c; 7031 7032 7033 while (length >= 16) { 7034 memcpy( ptr, (buffer + offset), 16); 7035 7036 Smart_Printf("%05lX ", offset); 7037 7038 for (i = 0; i < 16; i++) { 7039 7040 c = ptr[i]; 7041 itoh(c, buff); 7042 7043 if (!(i & 0x3) && i) { 7044 Smart_Printf("³ "); 7045 } 7046 7047 Smart_Printf("%s ", buff); 7048 } 7049 7050 Smart_Printf(" "); 7051 7052 for (i = 0; i < 16; i++) { 7053 c = ptr[i]; 7054 7055 if (c && ((c < 7) || (c > 11)) && (c != 13)) { 7056 Smart_Printf("%c", c); 7057 } else { 7058 Smart_Printf("."); 7059 } 7060 } 7061 7062 Smart_Printf("\n"); 7063 7064 offset += 16; 7065 length -= 16; 7066 } 7067 7068 if (length) { 7069 memcpy( ptr, (buffer + offset), 16); 7070 7071 Smart_Printf("%05lX ", offset); 7072 7073 for (i = 0; i < 16; i++) { 7074 if (i < length) { 7075 c = ptr[i]; 7076 itoh(c, buff); 7077 if (!(i & 0x3) && i) { 7078 Smart_Printf("³ "); 7079 } 7080 Smart_Printf("%s ", buff); 7081 } else { 7082 if (!(i & 0x3) && i) { 7083 Smart_Printf(" "); 7084 } 7085 Smart_Printf(" "); 7086 } 7087 } 7088 7089 Smart_Printf(" "); 7090 7091 for (i = 0; i < length; i++) { 7092 7093 c = ptr[i]; 7094 7095 if (c && ((c < 7) || (c > 11)) && (c != 13)) { 7096 Smart_Printf("%c", c); 7097 } else { 7098 Smart_Printf("."); 7099 } 7100 } 7101 7102 Smart_Printf("\n"); 7103 } 7104 7105 } /* end of Hex_Dump_Data */ 7106 7107 7108 void itoh( int i, char *s) 7109 { 7110 7111 int nibble, loop; 7112 7113 // *s++ = '0'; 7114 // *s++ = 'x'; 7115 7116 if (i == 0) { 7117 *s++ = '0'; 7118 *s++ = '0'; 7119 } else { 7120 for (loop = 1; loop >= 0; loop--) { 7121 nibble = (i >> (loop << 2)) & 0x000F; 7122 7123 /* decimal range */ 7124 if (nibble < 10) { 7125 *s++ = '0' + nibble; 7126 } else { 7127 *s++ = 'A' + (nibble - 10); 7128 } 7129 } 7130 } 7131 *s = 0; /* null terminate it */ 7132 } 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 #if (0) 7163 7164 int Com_Fake_Scenario_Dialog(void) 7165 { 7166 bool display = true; // redraw level 7167 bool process = true; // process while true 7168 7169 char namebuf[MPLAYER_NAME_MAX] = {0}; // buffer for player's name 7170 int transmit; // 1 = re-transmit new game options 7171 int parms_received = 1; // 1 = game options received 7172 int changed = 0; // 1 = user has changed an option 7173 7174 int rc; 7175 int recsignedoff = false; 7176 int version; 7177 unsigned long starttime; 7178 unsigned long timingtime; 7179 unsigned long lastmsgtime; 7180 unsigned long lastredrawtime; 7181 unsigned long transmittime = 0; 7182 unsigned long theirresponsetime; 7183 int packetlen; 7184 bool oppscorescreen = false; 7185 bool gameoptions = false; 7186 EventClass *event; // event ptr 7187 unsigned long msg_timeout = 60*60; // init to 60 seconds 7188 7189 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 7190 7191 /*........................................................................ 7192 Button Enumerations 7193 ........................................................................*/ 7194 enum { 7195 BUTTON_CANCEL = 100, 7196 }; 7197 7198 /*........................................................................ 7199 Dialog variables 7200 ........................................................................*/ 7201 TextButtonClass * buttons = 0; 7202 7203 KeyNumType input; 7204 7205 int x,y; 7206 int width=0; 7207 int height=0; 7208 char text_buffer[80*3]; 7209 7210 const char *current_status_string = Text_String(TXT_WINSOCK_CONNECTING); 7211 strcpy(text_buffer, current_status_string); 7212 7213 Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); 7214 7215 Format_Window_String(text_buffer, SeenBuff.Get_Height(), width, height); 7216 7217 width = MAX(width, 50*factor); 7218 width += 40*factor; 7219 height += 60*factor; 7220 7221 x = (SeenBuff.Get_Width() - width) / 2; 7222 y = (SeenBuff.Get_Height() - height) / 2; 7223 7224 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, 7225 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 7226 x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8*factor)) >> 1), 7227 y + height - (FontHeight + FontYSpacing + 2*factor) - 5*factor); 7228 7229 Set_Logic_Page(SeenBuff); 7230 buttons = &cancelbtn; 7231 7232 buttons->Flag_List_To_Redraw(); 7233 process = true; 7234 7235 /*........................................................................ 7236 Init other scenario parameters 7237 ........................................................................*/ 7238 Special.IsTGrowth = MPlayerTiberium; 7239 Special.IsTSpread = MPlayerTiberium; 7240 transmit = 1; 7241 7242 /*........................................................................ 7243 Init random-number generator, & create a seed to be used for all random 7244 numbers from here on out 7245 ........................................................................*/ 7246 randomize(); 7247 //Seed = rand(); 7248 7249 /* 7250 ---------------------------- Processing loop ----------------------------- 7251 */ 7252 NullModem.Reset_Response_Time(); // clear response time 7253 theirresponsetime = 10000; // initialize to an invalid value 7254 timingtime = lastmsgtime = lastredrawtime = TickCount.Time(); 7255 7256 7257 while (process) { 7258 7259 /* 7260 ** If we have just received input focus again after running in the background then 7261 ** we need to redraw. 7262 */ 7263 if (AllSurfaces.SurfacesRestored){ 7264 AllSurfaces.SurfacesRestored=FALSE; 7265 display=true; 7266 } 7267 7268 /* 7269 ........................ Invoke game callback ......................... 7270 */ 7271 Call_Back(); 7272 7273 /* 7274 ...................... Refresh display if needed ...................... 7275 */ 7276 if (display) { 7277 Hide_Mouse(); 7278 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 7279 Blit_Hid_Page_To_Seen_Buff(); 7280 Set_Palette(Palette); 7281 /* 7282 ..................... Draw the background ....................... 7283 */ 7284 Dialog_Box(x, y, width, height); 7285 /* 7286 ....................... Draw the labels ......................... 7287 */ 7288 Draw_Caption(TXT_NONE, x, y, width); 7289 7290 Fancy_Text_Print(text_buffer, x + 20*factor, y + 25*factor, CC_GREEN, TBLACK, 7291 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 7292 7293 buttons->Draw_All(); 7294 Show_Mouse(); 7295 display = false; 7296 } 7297 7298 /* 7299 ............................ Process input ............................ 7300 */ 7301 input = buttons->Input(); 7302 switch (input) { 7303 case (KN_ESC): 7304 case (BUTTON_CANCEL | KN_BUTTON): 7305 process = false; 7306 rc = false; 7307 break; 7308 7309 default: 7310 break; 7311 } 7312 7313 7314 /*--------------------------------------------------------------------- 7315 If our Transmit flag is set, we need to send out a game option packet. 7316 This message requires an ACK. The first time through the loop, transmit 7317 should be set, so we send out our default options; we'll then send 7318 any changes we make to the defaults. 7319 ---------------------------------------------------------------------*/ 7320 if (transmit && (TickCount.Time() - transmittime) > PACKET_RETRANS_TIME) { 7321 SendPacket.Command = SERIAL_GAME_OPTIONS; 7322 strcpy (SendPacket.Name, MPlayerName); 7323 #ifdef PATCH 7324 if (IsV107) { 7325 SendPacket.Version = 1; 7326 } else { 7327 SendPacket.Version = 2; 7328 } 7329 #else 7330 SendPacket.Version = Version_Number(); 7331 #endif 7332 SendPacket.House = MPlayerHouse; 7333 SendPacket.Color = MPlayerColorIdx; 7334 7335 SendPacket.Scenario = MPlayerFilenum[ScenarioIdx]; 7336 7337 SendPacket.Credits = MPlayerCredits; 7338 SendPacket.IsBases = MPlayerBases; 7339 SendPacket.IsTiberium = MPlayerTiberium; 7340 SendPacket.IsGoodies = MPlayerGoodies; 7341 SendPacket.IsGhosties = MPlayerGhosts; 7342 SendPacket.BuildLevel = BuildLevel; 7343 SendPacket.UnitCount = MPlayerUnitCount; 7344 SendPacket.Seed = Seed; 7345 SendPacket.Special = Special; 7346 SendPacket.GameSpeed = Options.GameSpeed; 7347 SendPacket.ID = ModemGameToPlay; 7348 7349 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 7350 7351 transmittime = TickCount.Time(); 7352 transmit = 0; 7353 } 7354 7355 // 7356 // send a timing packet if enough time has gone by. 7357 // 7358 if ( (TickCount.Time() - timingtime) > PACKET_TIMING_TIMEOUT) { 7359 SendPacket.Command = SERIAL_TIMING; 7360 SendPacket.ResponseTime = NullModem.Response_Time(); 7361 SendPacket.ID = ModemGameToPlay; 7362 7363 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 0); 7364 timingtime = TickCount.Time(); 7365 } 7366 7367 /*--------------------------------------------------------------------- 7368 Check for an incoming message 7369 ---------------------------------------------------------------------*/ 7370 if (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { 7371 7372 lastmsgtime = TickCount.Time(); 7373 msg_timeout = 600; // reset timeout value to 10 seconds 7374 // (only the 1st time through is 20 seconds) 7375 7376 7377 if (ReceivePacket.Command >= SERIAL_CONNECT && 7378 ReceivePacket.Command < SERIAL_LAST_COMMAND && 7379 ReceivePacket.Command != SERIAL_MESSAGE && 7380 ReceivePacket.ID == ModemGameToPlay) { 7381 7382 CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); 7383 7384 // to skip the other system not responding msg 7385 lastmsgtime = TickCount.Time(); 7386 7387 process = false; 7388 rc = false; 7389 7390 // say we did receive sign off to keep from sending one 7391 recsignedoff = true; 7392 break; 7393 } 7394 7395 event = (EventClass *)&ReceivePacket; 7396 if (event->Type <= EventClass::FRAMEINFO) { 7397 if ( (TickCount.Time() - lastredrawtime) > PACKET_REDRAW_TIME) { 7398 lastredrawtime = TickCount.Time(); 7399 oppscorescreen = true; 7400 parms_received = 1; 7401 } 7402 } else { 7403 switch ( ReceivePacket.Command ) { 7404 /*.................................................................. 7405 Sign-off: Give the other machine time to receive my ACK, display a 7406 message, and exit. 7407 ..................................................................*/ 7408 case (SERIAL_SIGN_OFF): 7409 starttime = TickCount.Time(); 7410 while (TickCount.Time() - starttime < 60) 7411 NullModem.Service(); 7412 CCMessageBox().Process(TXT_USER_SIGNED_OFF); 7413 7414 // to skip the other system not responding msg 7415 lastmsgtime = TickCount.Time(); 7416 7417 process = false; 7418 rc = false; 7419 recsignedoff = true; 7420 break; 7421 7422 /*.................................................................. 7423 Game Options: Store the other machine's name, color & house; 7424 If they've picked the same color as myself, re-transmit my settings 7425 to force him to choose a different color. (Com_Show_Scenario_Dialog 7426 is responsible for ensuring the colors are different.) 7427 ..................................................................*/ 7428 case (SERIAL_GAME_OPTIONS): 7429 oppscorescreen = false; 7430 gameoptions = true; 7431 strcpy (TheirName, ReceivePacket.Name); 7432 TheirColor = ReceivePacket.Color; 7433 TheirHouse = ReceivePacket.House; 7434 transmit = 1; 7435 7436 parms_received = 1; 7437 7438 /*............................................................... 7439 Check the version number of the other system. 7440 ...............................................................*/ 7441 #ifdef PATCH 7442 if (IsV107) { 7443 version = 1; 7444 } else { 7445 version = 2; 7446 } 7447 #else 7448 version = Version_Number(); 7449 #endif 7450 if (ReceivePacket.Version > version) { 7451 CCMessageBox().Process (TXT_YOURGAME_OUTDATED); 7452 7453 // to skip the other system not responding msg 7454 lastmsgtime = TickCount.Time(); 7455 7456 process = false; 7457 rc = false; 7458 } else { 7459 if (ReceivePacket.Version < version) { 7460 CCMessageBox().Process (TXT_DESTGAME_OUTDATED); 7461 7462 // to skip the other system not responding msg 7463 lastmsgtime = TickCount.Time(); 7464 7465 process = false; 7466 rc = false; 7467 } 7468 } 7469 break; 7470 7471 /*.................................................................. 7472 Incoming message: add to our list 7473 ..................................................................*/ 7474 7475 // 7476 // get their response time 7477 // 7478 case (SERIAL_TIMING): 7479 oppscorescreen = false; 7480 theirresponsetime = ReceivePacket.ResponseTime; 7481 7482 if ( !gameoptions ) { 7483 transmit = 1; 7484 }else{ 7485 process = false; 7486 rc = true; 7487 } 7488 break; 7489 7490 // 7491 // print msg waiting for opponent 7492 // 7493 case (SERIAL_SCORE_SCREEN): 7494 oppscorescreen = true; 7495 parms_received = 1; 7496 break; 7497 7498 default: 7499 break; 7500 } 7501 } 7502 } 7503 7504 // if we haven't received a msg for 10 seconds exit 7505 7506 if ( (TickCount.Time() - lastmsgtime) > msg_timeout) { 7507 CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); 7508 process = false; 7509 rc = false; 7510 7511 // say we did receive sign off to keep from sending one 7512 recsignedoff = true; 7513 } 7514 7515 /*--------------------------------------------------------------------- 7516 Service the connection 7517 ---------------------------------------------------------------------*/ 7518 NullModem.Service(); 7519 7520 } /* end of while */ 7521 7522 /*------------------------------------------------------------------------ 7523 Sort player ID's, so we can execute commands in the same order on both 7524 machines. 7525 ------------------------------------------------------------------------*/ 7526 if (rc) { 7527 /*..................................................................... 7528 Set the number of players in this game, and my ID 7529 .....................................................................*/ 7530 MPlayerCount = 2; 7531 MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); 7532 7533 TheirID = Build_MPlayerID (TheirColor,TheirHouse); 7534 7535 /*..................................................................... 7536 Store every player's ID in the MPlayerID[] array. This array will 7537 determine the order of event execution, so the ID's must be stored 7538 in the same order on all systems. 7539 .....................................................................*/ 7540 if (TheirID < MPlayerLocalID) { 7541 MPlayerID[0] = TheirID; 7542 MPlayerID[1] = MPlayerLocalID; 7543 strcpy (MPlayerNames[0], TheirName); 7544 strcpy (MPlayerNames[1], MPlayerName); 7545 } else { 7546 MPlayerID[0] = MPlayerLocalID; 7547 MPlayerID[1] = TheirID; 7548 strcpy (MPlayerNames[0], MPlayerName); 7549 strcpy (MPlayerNames[1], TheirName); 7550 } 7551 7552 /*..................................................................... 7553 Get the scenario filename 7554 .....................................................................*/ 7555 Scenario = MPlayerFilenum[ScenarioIdx]; 7556 7557 /*..................................................................... 7558 Send all players the GO packet. 7559 .....................................................................*/ 7560 SendPacket.Command = SERIAL_GO; 7561 SendPacket.ResponseTime = NullModem.Response_Time(); 7562 if ( theirresponsetime == 10000 ) { 7563 // Mono_Clear_Screen(); 7564 // Smart_Printf( "Did not receive their response time!!!!!!!\n" ); 7565 // Get_Key(); 7566 } else { 7567 if (SendPacket.ResponseTime < theirresponsetime) { 7568 SendPacket.ResponseTime = theirresponsetime; 7569 } 7570 } 7571 7572 // 7573 // calculated one way delay for a packet and overall delay to execute 7574 // a packet 7575 // 7576 ////////MPlayerMaxAhead = MAX( (SendPacket.ResponseTime / 8), 2); 7577 SendPacket.ID = ModemGameToPlay; 7578 7579 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 7580 7581 starttime = TickCount.Time(); 7582 while ( ( NullModem.Num_Send() 7583 && ((TickCount.Time() - starttime) < PACKET_SENDING_TIMEOUT) ) 7584 || ((TickCount.Time() - starttime) < 60) ) { 7585 #if(SHOW_MONO) 7586 NullModem.Mono_Debug_Print(0); 7587 #endif 7588 7589 NullModem.Service(); 7590 Keyboard::Check(); //Make sure the message loop gets called 7591 } 7592 7593 // clear queue to keep from doing any resends 7594 NullModem.Init_Send_Queue(); 7595 7596 } else { 7597 if ( !recsignedoff ) { 7598 /*..................................................................... 7599 Broadcast my sign-off over my network 7600 .....................................................................*/ 7601 SendPacket.Command = SERIAL_SIGN_OFF; 7602 SendPacket.Color = MPlayerLocalID; // use Color for ID 7603 SendPacket.ID = ModemGameToPlay; 7604 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 7605 7606 starttime = TickCount.Time(); 7607 while ( (NullModem.Num_Send() 7608 && ((TickCount.Time() - starttime) < PACKET_CANCEL_TIMEOUT) ) 7609 || ((TickCount.Time() - starttime) < 60) ) { 7610 #if(SHOW_MONO) 7611 NullModem.Mono_Debug_Print(0); 7612 #endif 7613 7614 if ( NullModem.Get_Message( &ReceivePacket, &packetlen ) > 0) { 7615 7616 // are we getting our own packets back?? 7617 7618 if (ReceivePacket.Command == SERIAL_SIGN_OFF 7619 && ReceivePacket.ID == ModemGameToPlay) { 7620 7621 // exit while 7622 break; 7623 } 7624 } 7625 7626 NullModem.Service(); 7627 } 7628 } 7629 7630 Shutdown_Modem(); 7631 } 7632 7633 /*------------------------------------------------------------------------ 7634 Restore screen 7635 ------------------------------------------------------------------------*/ 7636 Hide_Mouse(); 7637 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 7638 Blit_Hid_Page_To_Seen_Buff(); 7639 Show_Mouse(); 7640 7641 /*------------------------------------------------------------------------ 7642 Save any changes made to our options 7643 ------------------------------------------------------------------------*/ 7644 if (changed) { 7645 Write_MultiPlayer_Settings (); 7646 } 7647 7648 return(rc); 7649 7650 } /* end of Com_Scenario_Dialog */ 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 int Com_Show_Fake_Scenario_Dialog(void) 7678 { 7679 /*........................................................................ 7680 Dialog variables 7681 ........................................................................*/ 7682 bool display = true; // redraw level 7683 BOOL process = true; // process while true 7684 7685 char namebuf[MPLAYER_NAME_MAX] = {0}; // buffer for player's name 7686 int transmit; // 1 = re-transmit new game options 7687 int first; // 1 = no packets received yet 7688 int parms_received = 0; // 1 = game options received 7689 int changed = 0; // 1 = user has changed an option 7690 7691 int rc; 7692 int recsignedoff = 0; 7693 int i; 7694 int version; 7695 unsigned long starttime; 7696 unsigned long timingtime; 7697 unsigned long lastmsgtime; 7698 unsigned long lastredrawtime; 7699 unsigned long transmittime = 0; 7700 int packetlen; 7701 bool oppscorescreen = false; 7702 bool gameoptions = false; 7703 EventClass *event; // event ptr 7704 unsigned long msg_timeout = 60*60; // init to 60 seconds 7705 7706 7707 int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2; 7708 7709 /*........................................................................ 7710 Button Enumerations 7711 ........................................................................*/ 7712 enum { 7713 BUTTON_CANCEL = 100, 7714 }; 7715 7716 /*........................................................................ 7717 Dialog variables 7718 ........................................................................*/ 7719 TextButtonClass * buttons = 0; 7720 7721 KeyNumType input; 7722 7723 int x,y; 7724 int width=0; 7725 int height=0; 7726 char text_buffer[80*3]; 7727 7728 const char *current_status_string = Text_String(TXT_WINSOCK_CONNECTING); 7729 strcpy(text_buffer, current_status_string); 7730 7731 Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW); 7732 7733 Format_Window_String(text_buffer, SeenBuff.Get_Height(), width, height); 7734 7735 width = MAX(width, 50*factor); 7736 width += 40*factor; 7737 height += 60*factor; 7738 7739 x = (SeenBuff.Get_Width() - width) / 2; 7740 y = (SeenBuff.Get_Height() - height) / 2; 7741 7742 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, 7743 TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW, 7744 x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8*factor)) >> 1), 7745 y + height - (FontHeight + FontYSpacing + 2*factor) - 5*factor); 7746 7747 Set_Logic_Page(SeenBuff); 7748 buttons = &cancelbtn; 7749 7750 buttons->Flag_List_To_Redraw(); 7751 7752 7753 transmit = 1; 7754 first = 1; 7755 7756 7757 /* 7758 ---------------------------- Processing loop ----------------------------- 7759 */ 7760 NullModem.Reset_Response_Time(); // clear response time 7761 timingtime = lastmsgtime = lastredrawtime = TickCount.Time(); 7762 7763 while (process) { 7764 7765 /* 7766 ** If we have just received input focus again after running in the background then 7767 ** we need to redraw. 7768 */ 7769 if (AllSurfaces.SurfacesRestored){ 7770 AllSurfaces.SurfacesRestored=FALSE; 7771 display=true; 7772 } 7773 7774 /* 7775 ........................ Invoke game callback ......................... 7776 */ 7777 Call_Back(); 7778 7779 /* 7780 ...................... Refresh display if needed ...................... 7781 */ 7782 if (display) { 7783 Hide_Mouse(); 7784 /* 7785 .................. Redraw backgound & dialog box ................... 7786 */ 7787 Load_Title_Screen("HTITLE.PCX", &HidPage, Palette); 7788 Blit_Hid_Page_To_Seen_Buff(); 7789 Set_Palette(Palette); 7790 /* 7791 ..................... Draw the background ....................... 7792 */ 7793 Dialog_Box(x, y, width, height); 7794 /* 7795 ....................... Draw the labels ......................... 7796 */ 7797 Draw_Caption(TXT_NONE, x, y, width); 7798 7799 Fancy_Text_Print(text_buffer, x + 20*factor, y + 25*factor, CC_GREEN, TBLACK, 7800 TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW); 7801 7802 buttons->Draw_All(); 7803 Show_Mouse(); 7804 display = false; 7805 } 7806 7807 7808 /* 7809 ............................ Process input ............................ 7810 */ 7811 input = buttons->Input(); 7812 switch (input) { 7813 case (KN_ESC): 7814 case (BUTTON_CANCEL | KN_BUTTON): 7815 process = false; 7816 rc = false; 7817 break; 7818 7819 default: 7820 break; 7821 } 7822 7823 7824 7825 /*--------------------------------------------------------------------- 7826 If our Transmit flag is set, we need to send out a game option packet 7827 ---------------------------------------------------------------------*/ 7828 if (transmit && (TickCount.Time() - transmittime) > PACKET_RETRANS_TIME) { 7829 SendPacket.Command = SERIAL_GAME_OPTIONS; 7830 strcpy (SendPacket.Name, MPlayerName); 7831 #ifdef PATCH 7832 if (IsV107) { 7833 SendPacket.Version = 1; 7834 } else { 7835 SendPacket.Version = 2; 7836 } 7837 #else 7838 SendPacket.Version = Version_Number(); 7839 #endif 7840 SendPacket.House = MPlayerHouse; 7841 SendPacket.Color = MPlayerColorIdx; 7842 SendPacket.ID = ModemGameToPlay; 7843 7844 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 7845 7846 transmittime = TickCount.Time(); 7847 transmit = 0; 7848 } 7849 7850 // 7851 // send a timing packet if enough time has gone by. 7852 // 7853 if ( (TickCount.Time() - timingtime) > PACKET_TIMING_TIMEOUT) { 7854 SendPacket.Command = SERIAL_TIMING; 7855 SendPacket.ResponseTime = NullModem.Response_Time(); 7856 SendPacket.ID = ModemGameToPlay; 7857 7858 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 0); 7859 timingtime = TickCount.Time(); 7860 } 7861 7862 /*--------------------------------------------------------------------- 7863 Check for an incoming message 7864 ---------------------------------------------------------------------*/ 7865 if (NullModem.Get_Message (&ReceivePacket, &packetlen) > 0) { 7866 7867 lastmsgtime = TickCount.Time(); 7868 7869 msg_timeout = 600; 7870 7871 // are we getting our own packets back?? 7872 7873 if (ReceivePacket.Command >= SERIAL_CONNECT && 7874 ReceivePacket.Command < SERIAL_LAST_COMMAND && 7875 ReceivePacket.Command != SERIAL_MESSAGE && 7876 ReceivePacket.ID == ModemGameToPlay) { 7877 7878 CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); 7879 7880 // to skip the other system not responding msg 7881 lastmsgtime = TickCount.Time(); 7882 7883 process = false; 7884 rc = false; 7885 7886 // say we did receive sign off to keep from sending one 7887 recsignedoff = true; 7888 break; 7889 } 7890 7891 event = (EventClass *)&ReceivePacket; 7892 if (event->Type <= EventClass::FRAMEINFO) { 7893 if ( (TickCount.Time() - lastredrawtime) > PACKET_REDRAW_TIME) { 7894 lastredrawtime = TickCount.Time(); 7895 oppscorescreen = true; 7896 display = false; 7897 parms_received = 1; 7898 } 7899 } else { 7900 switch ( ReceivePacket.Command ) { 7901 /*.................................................................. 7902 Other system signs off: Give it time to receive my ACK, then show 7903 a message. 7904 ..................................................................*/ 7905 case (SERIAL_SIGN_OFF): 7906 starttime = TickCount.Time(); 7907 while ( (TickCount.Time() - starttime) < 60) 7908 NullModem.Service(); 7909 CCMessageBox().Process(TXT_USER_SIGNED_OFF); 7910 7911 // to skip the other system not responding msg 7912 lastmsgtime = TickCount.Time(); 7913 7914 process = false; 7915 rc = false; 7916 recsignedoff = true; 7917 break; 7918 7919 /*.................................................................. 7920 Game Options: Store all options; check my color & game version. 7921 ..................................................................*/ 7922 case (SERIAL_GAME_OPTIONS): 7923 oppscorescreen = false; 7924 gameoptions = true; 7925 display = false; 7926 parms_received = 1; 7927 7928 strcpy (TheirName, ReceivePacket.Name); 7929 TheirColor = ReceivePacket.Color; 7930 TheirHouse = ReceivePacket.House; 7931 7932 /*............................................................... 7933 Save scenario settings. 7934 ...............................................................*/ 7935 MPlayerCredits = ReceivePacket.Credits; 7936 MPlayerBases = ReceivePacket.IsBases; 7937 MPlayerTiberium = ReceivePacket.IsTiberium; 7938 MPlayerGoodies = ReceivePacket.IsGoodies; 7939 MPlayerGhosts = ReceivePacket.IsGhosties; 7940 BuildLevel = ReceivePacket.BuildLevel; 7941 MPlayerUnitCount = ReceivePacket.UnitCount; 7942 Seed = ReceivePacket.Seed; 7943 Special = ReceivePacket.Special; 7944 Options.GameSpeed = ReceivePacket.GameSpeed; 7945 7946 if (MPlayerTiberium) { 7947 Special.IsTGrowth = 1; 7948 Special.IsTSpread = 1; 7949 } else { 7950 Special.IsTGrowth = 0; 7951 Special.IsTSpread = 0; 7952 } 7953 7954 /*............................................................... 7955 Find the index of the scenario number; if it's not found, leave 7956 it at -1. 7957 ...............................................................*/ 7958 ScenarioIdx = -1; 7959 for (i = 0; i < MPlayerFilenum.Count(); i++) { 7960 if (ReceivePacket.Scenario == MPlayerFilenum[i]) 7961 ScenarioIdx = i; 7962 } 7963 7964 /*............................................................... 7965 Check our version numbers; if they're incompatible, sign off. 7966 ...............................................................*/ 7967 #ifdef PATCH 7968 if (IsV107) { 7969 version = 1; 7970 } else { 7971 version = 2; 7972 } 7973 #else 7974 version = Version_Number(); 7975 #endif 7976 if (ReceivePacket.Version > version) { 7977 CCMessageBox().Process (TXT_YOURGAME_OUTDATED); 7978 7979 // to skip the other system not responding msg 7980 lastmsgtime = TickCount.Time(); 7981 7982 process = false; 7983 rc = false; 7984 } else { 7985 if (ReceivePacket.Version < version) { 7986 CCMessageBox().Process (TXT_DESTGAME_OUTDATED); 7987 7988 // to skip the other system not responding msg 7989 lastmsgtime = TickCount.Time(); 7990 7991 process = false; 7992 rc = false; 7993 } 7994 } 7995 7996 /*............................................................... 7997 If this is the first game-options packet we've received, transmit 7998 our options to him. 7999 ...............................................................*/ 8000 if (first) { 8001 first = 0; 8002 8003 // force transmitting of game options packet 8004 8005 transmit = 1; 8006 transmittime = 0; 8007 } 8008 break; 8009 8010 /*.................................................................. 8011 GO: Exit this routine with a success code. 8012 ..................................................................*/ 8013 case (SERIAL_GO): 8014 8015 // 8016 // calculated one way delay for a packet and overall delay 8017 // to execute a packet 8018 // 8019 ////////MPlayerMaxAhead = MAX( (ReceivePacket.ResponseTime / 8), 2); 8020 8021 process = false; 8022 rc = true; 8023 break; 8024 8025 // 8026 // throw away timing packet 8027 // 8028 case (SERIAL_TIMING): 8029 oppscorescreen = false; 8030 break; 8031 8032 // 8033 // print msg waiting for opponent 8034 // 8035 case (SERIAL_SCORE_SCREEN): 8036 // Smart_Printf( "received score screen\n" ); 8037 oppscorescreen = true; 8038 display = false; 8039 parms_received = 1; 8040 break; 8041 8042 default: 8043 break; 8044 } 8045 } 8046 } 8047 8048 // if we haven't received a msg for 10 seconds exit 8049 8050 if ( (TickCount.Time() - lastmsgtime) > msg_timeout) { 8051 CCMessageBox().Process (TXT_SYSTEM_NOT_RESPONDING); 8052 process = false; 8053 rc = false; 8054 8055 // say we did receive sign off to keep from sending one 8056 recsignedoff = true; 8057 } 8058 8059 8060 /*--------------------------------------------------------------------- 8061 Service the connection 8062 ---------------------------------------------------------------------*/ 8063 NullModem.Service(); 8064 8065 } /* end of while */ 8066 8067 /*------------------------------------------------------------------------ 8068 Sort player ID's, so we can execute commands in the same order on both 8069 machines. 8070 ------------------------------------------------------------------------*/ 8071 if (rc) { 8072 /*..................................................................... 8073 Set the number of players in this game, and my ID 8074 .....................................................................*/ 8075 MPlayerCount = 2; 8076 MPlayerLocalID = Build_MPlayerID (MPlayerColorIdx, MPlayerHouse); 8077 8078 TheirID = Build_MPlayerID (TheirColor,TheirHouse); 8079 8080 /*..................................................................... 8081 Store every player's ID in the MPlayerID[] array. This array will 8082 determine the order of event execution, so the ID's must be stored 8083 in the same order on all systems. 8084 .....................................................................*/ 8085 if (TheirID < MPlayerLocalID) { 8086 MPlayerID[0] = TheirID; 8087 MPlayerID[1] = MPlayerLocalID; 8088 strcpy (MPlayerNames[0], TheirName); 8089 strcpy (MPlayerNames[1], MPlayerName); 8090 } else { 8091 MPlayerID[0] = MPlayerLocalID; 8092 MPlayerID[1] = TheirID; 8093 strcpy (MPlayerNames[0], MPlayerName); 8094 strcpy (MPlayerNames[1], TheirName); 8095 } 8096 8097 /*..................................................................... 8098 Get the scenario filename 8099 .....................................................................*/ 8100 Scenario = MPlayerFilenum[ScenarioIdx]; 8101 8102 starttime = TickCount.Time(); 8103 while ( ( NullModem.Num_Send() 8104 && ((TickCount.Time() - starttime) < PACKET_SENDING_TIMEOUT) ) 8105 || ((TickCount.Time() - starttime) < 60) ) { 8106 #if(SHOW_MONO) 8107 NullModem.Mono_Debug_Print(0); 8108 #endif 8109 8110 NullModem.Service(); 8111 Keyboard::Check(); //Make sure the message loop gets called 8112 } 8113 8114 // clear queue to keep from doing any resends 8115 NullModem.Init_Send_Queue(); 8116 8117 } else { 8118 if ( !recsignedoff ) { 8119 /*..................................................................... 8120 Broadcast my sign-off over my network 8121 .....................................................................*/ 8122 SendPacket.Command = SERIAL_SIGN_OFF; 8123 SendPacket.Color = MPlayerLocalID; // use Color for ID 8124 SendPacket.ID = ModemGameToPlay; 8125 NullModem.Send_Message (&SendPacket, sizeof(SendPacket), 1); 8126 8127 starttime = TickCount.Time(); 8128 while ( (NullModem.Num_Send() 8129 && ((TickCount.Time() - starttime) < PACKET_CANCEL_TIMEOUT) ) 8130 || ((TickCount.Time() - starttime) < 60) ) { 8131 #if(SHOW_MONO) 8132 NullModem.Mono_Debug_Print(0); 8133 #endif 8134 8135 if ( NullModem.Get_Message( &ReceivePacket, &packetlen ) > 0) { 8136 8137 // are we getting our own packets back?? 8138 8139 if (ReceivePacket.Command == SERIAL_SIGN_OFF 8140 && ReceivePacket.ID == ModemGameToPlay) { 8141 8142 // exit while 8143 break; 8144 } 8145 } 8146 8147 NullModem.Service(); 8148 } 8149 } 8150 8151 Shutdown_Modem(); 8152 } 8153 8154 /*------------------------------------------------------------------------ 8155 Save any changes made to our options 8156 ------------------------------------------------------------------------*/ 8157 if (changed) { 8158 Write_MultiPlayer_Settings (); 8159 } 8160 8161 return(rc); 8162 8163 } /* end of Com_Show_Scenario_Dialog */ 8164 8165 8166 #endif //(0) 8167 8168 8169 #endif //(0) 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 void Smart_Printf( char *format, ... ) 8226 { 8227 va_list arglist; 8228 char buf[501]; 8229 8230 8231 va_start(arglist,format); 8232 vsprintf(buf,format,arglist); 8233 va_end(arglist); 8234 8235 if (Debug_Smart_Print) { 8236 if (Special.IsMonoEnabled) { 8237 // Mono_Set_Cursor(0,0); 8238 Mono_Printf("%s",buf); 8239 } else { 8240 // Mono_Printf("%s",buf); 8241 printf("%s",buf); 8242 } 8243 } else { 8244 if (Debug_Heap_Dump) { 8245 printf("%s",buf); 8246 } 8247 } 8248 } 8249 8250 8251 void Hex_Dump_Data( char *buffer, int length ) 8252 { 8253 int i; 8254 int offset = 0; 8255 char buff[10]; 8256 char ptr[16]; 8257 char c; 8258 8259 8260 while (length >= 16) { 8261 memcpy( ptr, (buffer + offset), 16); 8262 8263 Smart_Printf("%05lX ", offset); 8264 8265 for (i = 0; i < 16; i++) { 8266 8267 c = ptr[i]; 8268 itoh(c, buff); 8269 8270 if (!(i & 0x3) && i) { 8271 Smart_Printf("³ "); 8272 } 8273 8274 Smart_Printf("%s ", buff); 8275 } 8276 8277 Smart_Printf(" "); 8278 8279 for (i = 0; i < 16; i++) { 8280 c = ptr[i]; 8281 8282 if (c && ((c < 7) || (c > 11)) && (c != 13)) { 8283 Smart_Printf("%c", c); 8284 } else { 8285 Smart_Printf("."); 8286 } 8287 } 8288 8289 Smart_Printf("\n"); 8290 8291 offset += 16; 8292 length -= 16; 8293 } 8294 8295 if (length) { 8296 memcpy( ptr, (buffer + offset), 16); 8297 8298 Smart_Printf("%05lX ", offset); 8299 8300 for (i = 0; i < 16; i++) { 8301 if (i < length) { 8302 c = ptr[i]; 8303 itoh(c, buff); 8304 if (!(i & 0x3) && i) { 8305 Smart_Printf("³ "); 8306 } 8307 Smart_Printf("%s ", buff); 8308 } else { 8309 if (!(i & 0x3) && i) { 8310 Smart_Printf(" "); 8311 } 8312 Smart_Printf(" "); 8313 } 8314 } 8315 8316 Smart_Printf(" "); 8317 8318 for (i = 0; i < length; i++) { 8319 8320 c = ptr[i]; 8321 8322 if (c && ((c < 7) || (c > 11)) && (c != 13)) { 8323 Smart_Printf("%c", c); 8324 } else { 8325 Smart_Printf("."); 8326 } 8327 } 8328 8329 Smart_Printf("\n"); 8330 } 8331 8332 } /* end of Hex_Dump_Data */ 8333 8334 8335 void itoh( int i, char *s) 8336 { 8337 8338 int nibble, loop; 8339 8340 // *s++ = '0'; 8341 // *s++ = 'x'; 8342 8343 if (i == 0) { 8344 *s++ = '0'; 8345 *s++ = '0'; 8346 } else { 8347 for (loop = 1; loop >= 0; loop--) { 8348 nibble = (i >> (loop << 2)) & 0x000F; 8349 8350 /* decimal range */ 8351 if (nibble < 10) { 8352 *s++ = '0' + nibble; 8353 } else { 8354 *s++ = 'A' + (nibble - 10); 8355 } 8356 } 8357 } 8358 *s = 0; /* null terminate it */ 8359 } 8360