CnC_Remastered_Collection

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

NULLDLG.CPP (259007B)


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