CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

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