CnC_Remastered_Collection

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

SESSION.CPP (71335B)


      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/SESSION.CPP 3     3/10/97 6:23p 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 : SESSION.CPP                                                  *
     24  *                                                                                             *
     25  *                   Programmer : Bill R. Randolph                                             *
     26  *                                                                                             *
     27  *                   Start Date : 11/30/95                                                     *
     28  *                                                                                             *
     29  *                  Last Update : September 10, 1996 [JLB]                                     *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   SessionClass::SessionClass -- Constructor                                                 *
     34  *   SessionClass::~SessionClass -- Destructor                                                 *
     35  *   SessionClass::One_Time -- one-time initializations                                        *
     36  *   SessionClass::Init -- Initializes all values                                              *
     37  *   SessionClass::Create_Connections -- forms connections to other players                    *
     38  *   SessionClass::Am_I_Master -- tells if the local system is the "master"                    *
     39  *   SessionClass::Save -- Saves this class to a file                                          *
     40  *   SessionClass::Load -- Loads this class from a file                                        *
     41  *   SessionClass::Read_MultiPlayer_Settings -- reads settings from INI                        *
     42  *   SessionClass::Write_MultiPlayer_Settings -- writes settings to INI                        *
     43  *   SessionClass::Read_Scenario_Descriptions -- reads scen. descriptions                      *
     44  *   SessionClass::Free_Scenario_Descriptions -- frees scen. descriptions                      *
     45  *   SessionClass::Trap_Object -- searches for an object, for debugging                        *
     46  *   SessionClass::Compute_Unique_ID -- computes unique local ID number                        *
     47  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     48 
     49 #include "function.h"
     50 #include <dos.h>			// for station ID computation
     51 #include <time.h>			// for station ID computation
     52 
     53 //#include "WolDebug.h"
     54 
     55 /***************************** Globals *************************************/
     56 //---------------------------------------------------------------------------
     57 //	This is the array of remap colors.  Each player in a network game is
     58 // assigned one of these colors.  The 'G' is for graphics drawing; the 'T'
     59 // is for text printing (indicates a remap table for the font to use).
     60 //---------------------------------------------------------------------------
     61 //int SessionClass::GColors[MAX_MPLAYER_COLORS] = {
     62 	//5, 			// Yellow
     63 	//127, 			// Red
     64 	//135, 			// BlueGreen
     65 	//26,			// Orange
     66 	//4,				// Green
     67 	//202			// Blue-Grey
     68 //};
     69 
     70 //int SessionClass::TColors[MAX_MPLAYER_COLORS] = {
     71 	//CC_GDI_COLOR, 			// Yellow
     72 	//CC_NOD_COLOR, 			// Red
     73 	//CC_BLUE_GREEN, 		// BlueGreen
     74 	//CC_ORANGE,				// Orange
     75 	//CC_GREEN,				// Green
     76 	//CC_BLUE_GREY,			// Blue
     77 //};
     78 
     79 /*---------------------------------------------------------------------------
     80 Min & Max unit count values; index0 = bases OFF, index1 = bases ON
     81 ---------------------------------------------------------------------------*/
     82 int SessionClass::CountMin[2] = {1,0};
     83 int SessionClass::CountMax[2] = {50,12};
     84 
     85 //---------------------------------------------------------------------------
     86 //	This is a list of all the names of the multiplayer scenarios
     87 //---------------------------------------------------------------------------
     88 char SessionClass::Descriptions[100][40];
     89 
     90 //---------------------------------------------------------------------------
     91 // These values are used purely for the Mono debug display.  They show the
     92 // names of the Global Channel packet types, and the event types.
     93 //---------------------------------------------------------------------------
     94 char * SessionClass::GlobalPacketNames[] = {
     95 	"Game?",
     96 	"Game!",
     97 	"Player?",
     98 	"Player!",
     99 	"Join?",
    100 	"Join!",
    101 	"Reject",
    102 	"GameOptions",
    103 	"Sign Off",
    104 	"GO!",
    105 	"Message",
    106 	"Ping",
    107 	"Load"
    108 };
    109 
    110 char * SessionClass::SerialPacketNames[] = {
    111 	"CONNECT",
    112 	"GAME_OPTIONS",
    113 	"SIGN_OFF",
    114 	"GO",
    115 	"MESSAGE",
    116 	"TIMING",
    117 	"SCORE_SCREEN",
    118 	"LOADGAME",
    119 	"LAST_COMMAND",
    120 };
    121 
    122 
    123 char * SessionClass::DialMethodCheck[ DIAL_METHODS ] = {
    124 	"T",
    125 	"P"
    126 };
    127 
    128 char *SessionClass::CallWaitStrings[ CALL_WAIT_STRINGS_NUM ] = {
    129 	"*70,",
    130 	"70#,",
    131 	"1170,",
    132 	"CUSTOM -                "
    133 };
    134 
    135 /***************************************************************************
    136  * SessionClass::SessionClass -- Constructor                               *
    137  *                                                                         *
    138  * INPUT:                                                                  *
    139  *		none.																						*
    140  *                                                                         *
    141  * OUTPUT:                                                                 *
    142  *		none.																						*
    143  *                                                                         *
    144  * WARNINGS:                                                               *
    145  *		none.																						*
    146  *                                                                         *
    147  * HISTORY:                                                                *
    148  *   11/30/1995 BRR : Created.                                             *
    149  *=========================================================================*/
    150 SessionClass::SessionClass(void)
    151 {
    152 	Type = GAME_NORMAL;
    153 	CommProtocol = DEFAULT_COMM_PROTOCOL;
    154 
    155 	Options.ScenarioIndex = 0;
    156 	Options.Bases = 0;
    157 	Options.Credits = 0;
    158 	Options.Tiberium = 0;
    159 	Options.Goodies = 0;
    160 	Options.Ghosts = 0;
    161 	Options.UnitCount = 0;
    162 
    163 	UniqueID = 0;
    164 
    165 	Handle[0] = 0;
    166 	PrefColor = PCOLOR_FIRST;
    167 	ColorIdx = PCOLOR_FIRST;
    168 	House = HOUSE_GOOD;
    169 	ObiWan = 0;
    170 	Solo = 0;
    171 
    172 	MaxPlayers = 8;
    173 	NumPlayers = 0;
    174 
    175 	MaxAhead = 5;
    176 	FrameSendRate = DEFAULT_FRAME_SEND_RATE;
    177 
    178 	LoadGame = 0;
    179 	EmergencySave = 0;
    180 
    181 	LastMessage[0] = 0;
    182 	WWChat = 0;
    183 
    184 	RecordFile.Set_Name("RECORD.BIN");		// always uses this name
    185 	Record= 0;										// set via command line
    186 	Play = 0;										// set via command line
    187 	Attract = 0;									// set via command line
    188 
    189 	IsBridge = 0;
    190 	NetStealth = 0;
    191 	NetProtect = 1;
    192 	NetOpen = 0;
    193 	GameName[0] = 0;
    194 	GProductID = 0;
    195 
    196 	MetaSize = MAX_IPX_PACKET_SIZE;
    197 
    198 	ModemService = true;
    199 	CurPhoneIdx = 0;										// set from INI file
    200 	SerialDefaults.Port = 0x2f8;						// set from INI file
    201 	SerialDefaults.IRQ = 3;								// set from INI file
    202 	SerialDefaults.Baud = 9600;						// set from INI file
    203 	SerialDefaults.DialMethod = DIAL_TOUCH_TONE;	// set from INI file
    204 	SerialDefaults.InitStringIndex = 0;				// set from INI file
    205 	SerialDefaults.CallWaitStringIndex = 0;		// set from INI file
    206 	strcpy(SerialDefaults.CallWaitString,"");
    207 	ModemType = MODEM_NULL_HOST;						// set from INI file
    208 
    209 	TrapFrame = 0x7fffffff;		// frame to start trapping object values at
    210 	TrapObjType = RTTI_NONE;	// type of object to trap
    211 	TrapObject.Ptr.All = NULL;	// ptr to object being trapped
    212 	TrapCoord = 0;					// COORDINATE of object to trap
    213 	TrapTarget = TARGET_NONE;	// TARGET value of object to trap
    214 	TrapCell = NULL;				// for trapping a cell
    215 	TrapCheckHeap = 0;			// start checking the Heap
    216 	TrapPrintCRC = 0;				// output CRC file
    217 
    218 #if(TEN)
    219 	TenPacket = NULL;
    220 	TenSize = 200;
    221 	TenPlayerID = -1;
    222 	OptionsFile[0] = 0;
    223 	AllowSolo = 0;
    224 	NetResponseTime = 600;
    225 #endif	// TEN
    226 
    227 #if(MPATH)
    228 	MPathPacket = NULL;
    229 	MPathSize = 200;
    230 	OptionsFile[0] = 0;
    231 	AllowSolo = 0;
    232 	NetResponseTime = 600;
    233 #endif	// MPATH
    234 
    235 }	// end of SessionClass
    236 
    237 
    238 /***************************************************************************
    239  * SessionClass::~SessionClass -- Destructor                               *
    240  *                                                                         *
    241  * INPUT:                                                                  *
    242  *		none.																						*
    243  *                                                                         *
    244  * OUTPUT:                                                                 *
    245  *		none.																						*
    246  *                                                                         *
    247  * WARNINGS:                                                               *
    248  *		none.																						*
    249  *                                                                         *
    250  * HISTORY:                                                                *
    251  *   11/30/1995 BRR : Created.                                             *
    252  *=========================================================================*/
    253 SessionClass::~SessionClass(void)
    254 {
    255 }	// end of ~SessionClass
    256 
    257 
    258 /***************************************************************************
    259  * SessionClass::One_Time -- one-time initializations                      *
    260  *                                                                         *
    261  * INPUT:                                                                  *
    262  *		none.																						*
    263  *                                                                         *
    264  * OUTPUT:                                                                 *
    265  *		none.																						*
    266  *                                                                         *
    267  * WARNINGS:                                                               *
    268  *		none.																						*
    269  *                                                                         *
    270  * HISTORY:                                                                *
    271  *   12/01/1995 BRR : Created.                                             *
    272  *=========================================================================*/
    273 void SessionClass::One_Time(void)
    274 {
    275 	Read_MultiPlayer_Settings();
    276 	Read_Scenario_Descriptions();
    277 
    278 	UniqueID = Compute_Unique_ID();
    279 
    280 }	// end of One_Time
    281 
    282 
    283 /***************************************************************************
    284  * SessionClass::Init -- Initializes all values                            *
    285  *                                                                         *
    286  * This function should be called for every new game played; it only sets	*
    287  * those variables that should be set for a new game.								*
    288  *                                                                         *
    289  * INPUT:                                                                  *
    290  *		none.																						*
    291  *                                                                         *
    292  * OUTPUT:                                                                 *
    293  *		none.																						*
    294  *                                                                         *
    295  * WARNINGS:                                                               *
    296  *		none.																						*
    297  *                                                                         *
    298  * HISTORY:                                                                *
    299  *   11/30/1995 BRR : Created.                                             *
    300  *=========================================================================*/
    301 void SessionClass::Init(void)
    302 {
    303 
    304 }	// end of Init
    305 
    306 
    307 /***************************************************************************
    308  * SessionClass::Create_Connections -- forms connections to other players  *
    309  *                                                                         *
    310  * This routine uses the contents of the Players vector, combined with		*
    311  * that of the Houses array, to create connections to each other player.	*
    312  * It is assumed that 'Players' contains all the other players to connect	*
    313  * to, and that the HouseClass's have been filled in with players' data.	*
    314  *                                                                         *
    315  * INPUT:                                                                  *
    316  *		none.																						*
    317  *                                                                         *
    318  * OUTPUT:                                                                 *
    319  *		1 = success, 0 = failure															*
    320  *                                                                         *
    321  * WARNINGS:                                                               *
    322  *		none.																						*
    323  *                                                                         *
    324  * HISTORY:                                                                *
    325  *   11/30/1995 BRR : Created.                                             *
    326  *=========================================================================*/
    327 int SessionClass::Create_Connections(void)
    328 {
    329 #if (0)//PG
    330 	int i;
    331 
    332 	if (Session.Type != GAME_IPX && Session.Type != GAME_INTERNET) {
    333 		return (0);
    334 	}
    335 
    336 	//------------------------------------------------------------------------
    337 	// Loop through all entries in 'Players'.  To avoid connecting to myself,
    338 	// skip the 1st entry.
    339 	//------------------------------------------------------------------------
    340 	for (i = 1; i < Players.Count(); i++) {
    341 		//.....................................................................
    342 		// Make sure the name matches before creating the connection
    343 		//.....................................................................
    344 		if (!stricmp (Players[i]->Name,
    345 			HouseClass::As_Pointer(Players[i]->Player.ID)->IniName)) {
    346 			Ipx.Create_Connection((int)Players[i]->Player.ID, Players[i]->Name,
    347 				&(Players[i]->Address) );
    348 		Players[i]->Player.ProcessTime = -1;
    349 		}
    350 		else {
    351 			return (0);
    352 		}
    353 	}
    354 #endif
    355 	return (1);
    356 
    357 }	// end of Create_Connections
    358 
    359 
    360 #if(TEN)
    361 /***************************************************************************
    362  * SessionClass::Create_TEN_Connections -- forms connections to TEN players*
    363  *                                                                         *
    364  * This routine uses the contents of the Players vector, combined with		*
    365  * that of the Houses array, to create connections to each other player.	*
    366  * It is assumed that 'Players' contains all the other players to connect	*
    367  * to, and that the HouseClass's have been filled in with players' data.	*
    368  *                                                                         *
    369  * INPUT:                                                                  *
    370  *		none.																						*
    371  *                                                                         *
    372  * OUTPUT:                                                                 *
    373  *		1 = success, 0 = failure															*
    374  *                                                                         *
    375  * WARNINGS:                                                               *
    376  *		none.																						*
    377  *                                                                         *
    378  * HISTORY:                                                                *
    379  *   11/30/1995 BRR : Created.                                             *
    380  *=========================================================================*/
    381 int SessionClass::Create_TEN_Connections(void)
    382 {
    383 	int i;
    384 
    385 	if (Session.Type != GAME_TEN) {
    386 		return (0);
    387 	}
    388 
    389 	//------------------------------------------------------------------------
    390 	// Loop through all entries in 'Players'.  To avoid connecting to myself,
    391 	// skip the 1st entry.
    392 	//------------------------------------------------------------------------
    393 	for (i = 1; i < Players.Count(); i++) {
    394 		//.....................................................................
    395 		// Make sure the name matches before creating the connection
    396 		//.....................................................................
    397 		if (!stricmp (Players[i]->Name,
    398 			HouseClass::As_Pointer(Players[i]->Player.ID)->IniName)) {
    399 			Ten->Create_Connection((int)Players[i]->Player.ID, Players[i]->Name,
    400 				Players[i]->TenAddress);
    401 			Players[i]->Player.ProcessTime = -1;
    402 		}
    403 		else {
    404 			return (0);
    405 		}
    406 	}
    407 
    408 	return (1);
    409 
    410 }	// end of Create_TEN_Connections
    411 
    412 #endif	// TEN
    413 
    414 
    415 #if(MPATH)
    416 /***************************************************************************
    417  * SessionClass::Create_MPATH_Connections -- forms connections to MPATH players*
    418  *                                                                         *
    419  * This routine uses the contents of the Players vector, combined with		*
    420  * that of the Houses array, to create connections to each other player.	*
    421  * It is assumed that 'Players' contains all the other players to connect	*
    422  * to, and that the HouseClass's have been filled in with players' data.	*
    423  *                                                                         *
    424  * INPUT:                                                                  *
    425  *		none.																						*
    426  *                                                                         *
    427  * OUTPUT:                                                                 *
    428  *		1 = success, 0 = failure															*
    429  *                                                                         *
    430  * WARNINGS:                                                               *
    431  *		none.																						*
    432  *                                                                         *
    433  * HISTORY:                                                                *
    434  *   11/30/1995 BRR : Created.                                             *
    435  *=========================================================================*/
    436 int SessionClass::Create_MPATH_Connections(void)
    437 {
    438 	int i;
    439 
    440 	if (Session.Type != GAME_MPATH) {
    441 		return (0);
    442 	}
    443 
    444 	//------------------------------------------------------------------------
    445 	// Loop through all entries in 'Players'.  To avoid connecting to myself,
    446 	// skip the 1st entry.
    447 	//------------------------------------------------------------------------
    448 	for (i = 1; i < Players.Count(); i++) {
    449 		//.....................................................................
    450 		// Make sure the name matches before creating the connection
    451 		//.....................................................................
    452 		if (!stricmp (Players[i]->Name,
    453 			HouseClass::As_Pointer(Players[i]->Player.ID)->IniName)) {
    454 			MPath->Create_Connection((int)Players[i]->Player.ID, Players[i]->Name,
    455 				Players[i]->MPathAddress);
    456 			Players[i]->Player.ProcessTime = -1;
    457 		}
    458 		else {
    459 			return (0);
    460 		}
    461 	}
    462 
    463 	return (1);
    464 
    465 }	// end of Create_MPATH_Connections
    466 
    467 #endif	// MPATH
    468 
    469 
    470 /***************************************************************************
    471  * SessionClass::Am_I_Master -- tells if the local system is the "master"  *
    472  *                                                                         *
    473  * INPUT:                                                                  *
    474  *		none.																						*
    475  *                                                                         *
    476  * OUTPUT:                                                                 *
    477  *		none.																						*
    478  *                                                                         *
    479  * WARNINGS:                                                               *
    480  *		none.																						*
    481  *                                                                         *
    482  * HISTORY:                                                                *
    483  *   11/29/1995 BRR : Created.                                             *
    484  *=========================================================================*/
    485 bool SessionClass::Am_I_Master(void)
    486 {
    487 	int i;
    488 	HousesType house;
    489 	HouseClass *hptr;
    490 
    491 	//------------------------------------------------------------------------
    492 	// Check every house; if PlayerPtr points to the first human house, we're
    493 	// the master.
    494 	//------------------------------------------------------------------------
    495 	for (i = 0; i < Session.MaxPlayers; i++) {
    496 		house = (HousesType)((int)HOUSE_MULTI1 + i);
    497 		hptr = HouseClass::As_Pointer(house);
    498 		if (hptr->IsHuman) {
    499 			if (PlayerPtr == hptr) {
    500 				return (true);
    501 			}
    502 			else {
    503 				return (false);
    504 			}
    505 		}
    506 	}
    507 
    508 	return (false);
    509 
    510 }	// end of Am_I_Master
    511 
    512 
    513 /***************************************************************************
    514  * SessionClass::Save -- Saves this class to a file                        *
    515  *                                                                         *
    516  * Only certain members of this class should be saved into a save-game		*
    517  * file; this routine saves only those members.										*
    518  *                                                                         *
    519  * INPUT:                                                                  *
    520  *		file		file to save to															*
    521  *                                                                         *
    522  * OUTPUT:                                                                 *
    523  *		1 = OK, 0 = error																		*
    524  *                                                                         *
    525  * WARNINGS:                                                               *
    526  *		none.																						*
    527  *                                                                         *
    528  * HISTORY:                                                                *
    529  *   12/04/1995 BRR : Created.                                             *
    530  *=========================================================================*/
    531 int SessionClass::Save(Pipe & file) const
    532 {
    533 #ifdef FIXIT_MULTI_SAVE
    534 	file.Put(&CommProtocol, sizeof(CommProtocol));
    535 	file.Put(&MaxAhead, sizeof(MaxAhead));
    536 	file.Put(&FrameSendRate, sizeof(FrameSendRate));
    537 	file.Put(&DesiredFrameRate, sizeof(DesiredFrameRate));
    538 #endif	// FIXIT_MULTI_SAVE
    539 	file.Put(&PrefColor, sizeof(PrefColor));
    540 	file.Put(&ColorIdx, sizeof(ColorIdx));
    541 	file.Put(&House, sizeof(House));
    542 	file.Put(&NumPlayers, sizeof(NumPlayers));
    543 	file.Put(&Options.Bases, sizeof(Options.Bases));
    544 	file.Put(&Options.Credits, sizeof(Options.Credits));
    545 	file.Put(&Options.Tiberium, sizeof(Options.Tiberium));
    546 	file.Put(&Options.Goodies, sizeof(Options.Goodies));
    547 	file.Put(&Options.Ghosts, sizeof(Options.Ghosts));
    548 	file.Put(&Options.UnitCount, sizeof(Options.UnitCount));
    549 	file.Put(&Options.AIPlayers, sizeof(Options.AIPlayers));
    550 	file.Put(&ObiWan, sizeof(ObiWan));
    551 	file.Put(&EmergencySave, sizeof(EmergencySave));
    552 
    553 	return (1);
    554 
    555 }	// end of Save
    556 
    557 
    558 /***************************************************************************
    559  * SessionClass::Load -- Loads this class from a file                      *
    560  *                                                                         *
    561  * INPUT:                                                                  *
    562  *		file		file to load from															*
    563  *                                                                         *
    564  * OUTPUT:                                                                 *
    565  *		1 = OK, 0 = error																		*
    566  *                                                                         *
    567  * WARNINGS:                                                               *
    568  *		none.																						*
    569  *                                                                         *
    570  * HISTORY:                                                                *
    571  *   12/04/1995 BRR : Created.                                             *
    572  *=========================================================================*/
    573 int SessionClass::Load(Straw & file)
    574 {
    575 #ifdef FIXIT_MULTI_SAVE
    576 //	if(GameVersion != 0x0100616D){
    577 	file.Get(&CommProtocol, sizeof(CommProtocol));
    578 	file.Get(&MaxAhead, sizeof(MaxAhead));
    579 	file.Get(&FrameSendRate, sizeof(FrameSendRate));
    580 	file.Get(&DesiredFrameRate, sizeof(DesiredFrameRate));
    581 //	}
    582 #endif	// FIXIT_MULTI_SAVE
    583 	file.Get(&PrefColor, sizeof(PrefColor));
    584 	file.Get(&ColorIdx, sizeof(ColorIdx));
    585 	file.Get(&House, sizeof(House));
    586 	file.Get(&NumPlayers, sizeof(NumPlayers));
    587 	file.Get(&Options.Bases, sizeof(Options.Bases));
    588 	file.Get(&Options.Credits, sizeof(Options.Credits));
    589 	file.Get(&Options.Tiberium, sizeof(Options.Tiberium));
    590 	file.Get(&Options.Goodies, sizeof(Options.Goodies));
    591 	file.Get(&Options.Ghosts, sizeof(Options.Ghosts));
    592 	file.Get(&Options.UnitCount, sizeof(Options.UnitCount));
    593 	file.Get(&Options.AIPlayers, sizeof(Options.AIPlayers));
    594 	file.Get(&ObiWan, sizeof(ObiWan));
    595 	file.Get(&EmergencySave, sizeof(EmergencySave));
    596 
    597 	return (1);
    598 
    599 }	// end of Load
    600 
    601 
    602 /***************************************************************************
    603  * SessionClass::Save -- Saves this class to a file                        *
    604  *                                                                         *
    605  * Only certain members of this class should be saved into a save-game		*
    606  * file; this routine saves only those members.										*
    607  *                                                                         *
    608  * INPUT:                                                                  *
    609  *		file		file to save to															*
    610  *                                                                         *
    611  * OUTPUT:                                                                 *
    612  *		1 = OK, 0 = error																		*
    613  *                                                                         *
    614  * WARNINGS:                                                               *
    615  *		none.																						*
    616  *                                                                         *
    617  * HISTORY:                                                                *
    618  *   12/04/1995 BRR : Created.                                             *
    619  *=========================================================================*/
    620 int SessionClass::Save(CCFileClass & file)
    621 {
    622 	int i;
    623 
    624 	file.Write(&Type, sizeof(Type));
    625 	file.Write(&CommProtocol, sizeof(CommProtocol));
    626 	file.Write(&FrameSendRate, sizeof(FrameSendRate));
    627 	file.Write(&PrefColor, sizeof(PrefColor));
    628 	file.Write(&ColorIdx, sizeof(ColorIdx));
    629 	file.Write(&House, sizeof(House));
    630 	file.Write(&NumPlayers, sizeof(NumPlayers));
    631 	file.Write(&Options.Bases, sizeof(Options.Bases));
    632 	file.Write(&Options.Credits, sizeof(Options.Credits));
    633 	file.Write(&Options.Tiberium, sizeof(Options.Tiberium));
    634 	file.Write(&Options.Goodies, sizeof(Options.Goodies));
    635 	file.Write(&Options.Ghosts, sizeof(Options.Ghosts));
    636 	file.Write(&Options.UnitCount, sizeof(Options.UnitCount));
    637 	file.Write(&Options.AIPlayers, sizeof(Options.AIPlayers));
    638 	file.Write(&ObiWan, sizeof(ObiWan));
    639 	file.Write(&EmergencySave, sizeof(EmergencySave));
    640 
    641 	i = Players.Count();
    642 	file.Write(&i, sizeof(i));
    643 	for (i = 0; i < Players.Count(); i++) {
    644 		file.Write(Players[i], sizeof(NodeNameType));
    645 	}
    646 
    647 	return (1);
    648 
    649 }	// end of Save
    650 
    651 
    652 /***************************************************************************
    653  * SessionClass::Load -- Loads this class from a file                      *
    654  *                                                                         *
    655  * INPUT:                                                                  *
    656  *		file		file to load from															*
    657  *                                                                         *
    658  * OUTPUT:                                                                 *
    659  *		1 = OK, 0 = error																		*
    660  *                                                                         *
    661  * WARNINGS:                                                               *
    662  *		none.																						*
    663  *                                                                         *
    664  * HISTORY:                                                                *
    665  *   12/04/1995 BRR : Created.                                             *
    666  *=========================================================================*/
    667 int SessionClass::Load(CCFileClass & file)
    668 {
    669 	int count;
    670 	int i;
    671 	NodeNameType *node;
    672 
    673 	file.Read(&Type, sizeof(Type));
    674 	file.Read(&CommProtocol, sizeof(CommProtocol));
    675 	file.Read(&FrameSendRate, sizeof(FrameSendRate));
    676 	file.Read(&PrefColor, sizeof(PrefColor));
    677 	file.Read(&ColorIdx, sizeof(ColorIdx));
    678 	file.Read(&House, sizeof(House));
    679 	file.Read(&NumPlayers, sizeof(NumPlayers));
    680 	file.Read(&Options.Bases, sizeof(Options.Bases));
    681 	file.Read(&Options.Credits, sizeof(Options.Credits));
    682 	file.Read(&Options.Tiberium, sizeof(Options.Tiberium));
    683 	file.Read(&Options.Goodies, sizeof(Options.Goodies));
    684 	file.Read(&Options.Ghosts, sizeof(Options.Ghosts));
    685 	file.Read(&Options.UnitCount, sizeof(Options.UnitCount));
    686 	file.Read(&Options.AIPlayers, sizeof(Options.AIPlayers));
    687 	file.Read(&ObiWan, sizeof(ObiWan));
    688 	file.Read(&EmergencySave, sizeof(EmergencySave));
    689 
    690 	file.Read(&count, sizeof(count));
    691 	for (i = 0; i < count; i++) {
    692 		node = new NodeNameType;
    693 		file.Read(node, sizeof(NodeNameType));
    694 		Players.Add(node);
    695 	}
    696 
    697 	return (1);
    698 
    699 }	// end of Load
    700 
    701 
    702 /***************************************************************************
    703  * SessionClass::Read_MultiPlayer_Settings -- reads settings INI           *
    704  *                                                                         *
    705  * INPUT:                                                                  *
    706  *      none.                                                              *
    707  *                                                                         *
    708  * OUTPUT:                                                                 *
    709  *      none.                                                              *
    710  *                                                                         *
    711  * WARNINGS:                                                               *
    712  *      none.                                                              *
    713  *                                                                         *
    714  * HISTORY:                                                                *
    715  *   02/14/1995 BR : Created.                                              *
    716  *=========================================================================*/
    717 void SessionClass::Read_MultiPlayer_Settings (void)
    718 {
    719 #if (0)//PG
    720 	char *tokenptr;						// ptr to token
    721 	PhoneEntryClass *phone;				// a phone book entry
    722 	char *entry;							// a phone book entry
    723 	char buf[128];							// buffer for parsing INI entry
    724 	int i;
    725 	CELL cell;
    726 
    727 
    728 //	CCFileClass file (CONFIG_FILE_NAME);
    729 
    730 	//------------------------------------------------------------------------
    731 	//	Clear the initstring entries
    732 	//------------------------------------------------------------------------
    733 	for (i = 0; i < InitStrings.Count(); i++) {
    734 		delete[] InitStrings[i];
    735 	}
    736 	InitStrings.Clear();
    737 
    738 	//	Clear the dialing entries
    739 	for (i = 0; i < PhoneBook.Count(); i++) {
    740 		delete[] PhoneBook[i];
    741 	}
    742 	PhoneBook.Clear();
    743 
    744 	//	Create filename and read the file.
    745 	INIClass ini;
    746 	if (ini.Load(RawFileClass(CONFIG_FILE_NAME))) {
    747 
    748 		//	Get the player's last-used Handle
    749 		ini.Get_String("MultiPlayer", "Handle", "Noname", Handle, sizeof(Handle));
    750 
    751 		//	Get the player's last-used Color
    752 		PrefColor = (PlayerColorType)ini.Get_Int("MultiPlayer", "Color", 0);
    753 #ifdef FIXIT_VERSION_3
    754 		int iSide = ini.Get_Int("MultiPlayer", "Side", HOUSE_USSR);
    755 		iSide = max( 2, min( 6, iSide ) );
    756 		House = (HousesType)iSide;
    757 #else
    758 		House = (HousesType)ini.Get_Int("MultiPlayer", "Side", HOUSE_USSR);
    759 #endif
    760 		CurPhoneIdx = ini.Get_Int("MultiPlayer", "PhoneIndex", -1);
    761 		TrapCheckHeap = ini.Get_Int("MultiPlayer", "CheckHeap", 0);
    762 
    763 		//	Read in default serial settings
    764 		ini.Get_String("SerialDefaults", "ModemName", "NoName", SerialDefaults.ModemName, MODEM_NAME_MAX);
    765 		if (!strcmp ( SerialDefaults.ModemName, "NoName")) {
    766 			SerialDefaults.ModemName[0] = 0;
    767 		}
    768 		SerialDefaults.Port = ini.Get_Int("SerialDefaults", "Port", 0);
    769 		SerialDefaults.IRQ = ini.Get_Int("SerialDefaults", "IRQ", -1);
    770 		SerialDefaults.Baud = ini.Get_Int("SerialDefaults", "Baud", -1);
    771 		SerialDefaults.Compression = ini.Get_Int ("SerialDefaults", "Compression", 0);
    772 		SerialDefaults.ErrorCorrection = ini.Get_Int ("SerialDefaults", "ErrorCorrection", 0);
    773 		SerialDefaults.HardwareFlowControl = ini.Get_Int ("SerialDefaults", "HardwareFlowControl", 1);
    774 
    775 		ini.Get_String("SerialDefaults", "DialMethod", "T", buf, 2);
    776 
    777 #ifndef WIN32
    778 		/*
    779 		** Ignore any modem name in DOS. This should only be nessasary if the user
    780 		** previously set up the modem in the windows version.
    781 		*/
    782 		if (SerialDefaults.ModemName[0] && SerialDefaults.Port == 1) {
    783 			SerialDefaults.Port = 0x3F8;
    784 			SerialDefaults.ModemName[0] = 0;
    785 		}
    786 #endif	//WIN32
    787 
    788 		// find dial method
    789 		for (i = 0; i < DIAL_METHODS; i++) {
    790 			if ( !strcmpi( buf, DialMethodCheck[ i ]) ) {
    791 				SerialDefaults.DialMethod = (DialMethodType)i;
    792 				break;
    793 			}
    794 		}
    795 
    796 		// if method not found set to touch tone
    797 		if (i == DIAL_METHODS) {
    798 			SerialDefaults.DialMethod = DIAL_TOUCH_TONE;
    799 		}
    800 
    801 		SerialDefaults.InitStringIndex = ini.Get_Int("SerialDefaults", "InitStringIndex", 0);
    802 
    803 		SerialDefaults.CallWaitStringIndex = ini.Get_Int("SerialDefaults", "CallWaitStringIndex", CALL_WAIT_CUSTOM);
    804 
    805 		ini.Get_String("SerialDefaults", "CallWaitString", "", SerialDefaults.CallWaitString, CWAITSTRBUF_MAX);
    806 
    807 		if (SerialDefaults.IRQ == 0 || SerialDefaults.Baud == 0) {
    808 			SerialDefaults.Port = 0;
    809 			SerialDefaults.IRQ = -1;
    810 			SerialDefaults.Baud = -1;
    811 		}
    812 
    813 		int initcount = ini.Entry_Count("InitStrings");
    814 		for (int index = 0; index < initcount; index++) {
    815 			entry = new char[ INITSTRBUF_MAX ];
    816 			entry[0] = 0;
    817 			ini.Get_String("InitStrings", ini.Get_Entry("InitStrings", index), NULL, entry, INITSTRBUF_MAX);
    818 			strupr( entry );
    819 			InitStrings.Add( entry );
    820 		}
    821 
    822 		//	if no entries then have at least one
    823 		if (initcount == 0) {
    824 			entry = new char[ INITSTRBUF_MAX ];
    825 			strcpy( entry, "ATZ" );
    826 			InitStrings.Add( entry );
    827 			SerialDefaults.InitStringIndex = 0;
    828 		}
    829 
    830 		//	Read the entry names in
    831 		int phonecount = ini.Entry_Count("PhoneBook");
    832 		for (int index = 0; index < phonecount; index++) {
    833 			//	Create a new phone book entry
    834 			phone = new PhoneEntryClass();
    835 
    836 			//	Read the entire entry in
    837 			ini.Get_String("PhoneBook", ini.Get_Entry("PhoneBook", index), NULL, buf, sizeof(buf));
    838 
    839 			//	Extract name, phone # & serial port settings
    840 			tokenptr = strtok( buf, "|" );
    841 			if (tokenptr) {
    842 				strcpy( phone->Name, tokenptr );
    843 				strupr( phone->Name );
    844 			} else {
    845 				phone->Name[0] = 0;
    846 			}
    847 
    848 			tokenptr = strtok( NULL, "|" );
    849 			if (tokenptr) {
    850 				strcpy( phone->Number, tokenptr );
    851 				strupr( phone->Number );
    852 			} else {
    853 				phone->Number[0] = 0;
    854 			}
    855 
    856 			tokenptr = strtok( NULL, "|" );
    857 			if (tokenptr) {
    858 				sscanf( tokenptr, "%x", &phone->Settings.Port );
    859 			} else {
    860 				phone->Settings.Port = 0;
    861 			}
    862 
    863 			tokenptr = strtok( NULL, "|" );
    864 			if (tokenptr) {
    865 				phone->Settings.IRQ = atoi( tokenptr );
    866 			} else {
    867 				phone->Settings.IRQ = -1;
    868 			}
    869 
    870 			tokenptr = strtok( NULL, "|" );
    871 			if (tokenptr) {
    872 				phone->Settings.Baud = atoi( tokenptr );
    873 			} else {
    874 				phone->Settings.Baud = -1;
    875 			}
    876 
    877 			phone->Settings.Compression = 0;
    878 			phone->Settings.ErrorCorrection = 0;
    879 			phone->Settings.HardwareFlowControl = 1;
    880 
    881 			/*
    882 			** Find out if this phonebook entry has the new settings included. If not
    883 			** then we need to skip this section.
    884 			*/
    885 			tokenptr = strtok( NULL, "|" );
    886 			if (tokenptr){
    887 				strcpy( buf, tokenptr );
    888 
    889 				// find dial method
    890 
    891 				for (i = 0; i < DIAL_METHODS; i++) {
    892 					if ( !strcmpi( buf, DialMethodCheck[ i ]) ) {
    893 						/*
    894 						** This must be an old phonebook entry
    895 						*/
    896 						break;
    897 					}
    898 				}
    899 
    900 				/*
    901 				** Method wasnt found - assume its a new phonebook entry so get the extra settings
    902 				*/
    903 				// if method not found set to touch tone
    904 
    905 				if (i == DIAL_METHODS) {
    906 
    907 					phone->Settings.Compression = atoi( tokenptr );
    908 
    909 					tokenptr = strtok( NULL, "|" );
    910 					if (tokenptr) {
    911 						phone->Settings.ErrorCorrection = atoi( tokenptr );
    912 					}
    913 
    914 					tokenptr = strtok( NULL, "|" );
    915 					if (tokenptr) {
    916 						phone->Settings.HardwareFlowControl = atoi( tokenptr );
    917 					}
    918 
    919 					tokenptr = strtok( NULL, "|" );
    920 				}
    921 			}
    922 
    923 
    924 			if (tokenptr) {
    925 				strcpy( buf, tokenptr );
    926 
    927 				//	find dial method
    928 				for (i = 0; i < DIAL_METHODS; i++) {
    929 					if ( !strcmpi( buf, DialMethodCheck[ i ]) ) {
    930 						phone->Settings.DialMethod = (DialMethodType)i;
    931 						break;
    932 					}
    933 				}
    934 
    935 				//	if method not found set to touch tone
    936 				if (i == DIAL_METHODS) {
    937 					phone->Settings.DialMethod = DIAL_TOUCH_TONE;
    938 				}
    939 			} else {
    940 				phone->Settings.DialMethod = DIAL_TOUCH_TONE;
    941 			}
    942 
    943 			tokenptr = strtok( NULL, "|" );
    944 			if (tokenptr) {
    945 				phone->Settings.InitStringIndex = atoi( tokenptr );
    946 			} else {
    947 				phone->Settings.InitStringIndex = 0;
    948 			}
    949 
    950 			tokenptr = strtok( NULL, "|" );
    951 			if (tokenptr) {
    952 				phone->Settings.CallWaitStringIndex = atoi( tokenptr );
    953 			} else {
    954 				phone->Settings.CallWaitStringIndex = CALL_WAIT_CUSTOM;
    955 			}
    956 
    957 			tokenptr = strtok( NULL, "|" );
    958 			if (tokenptr) {
    959 				strcpy (phone->Settings.CallWaitString, tokenptr);
    960 			} else {
    961 				phone->Settings.CallWaitString[0] = 0;
    962 			}
    963 
    964 			//	Add it to our list
    965 			PhoneBook.Add(phone);
    966 		}
    967 
    968 		//	Read special recording playback values, to help find sync bugs
    969 		TrapFrame = ini.Get_Int("SyncBug", "Frame", 0x7fffffff);
    970 
    971 		ini.Get_String("SyncBug", "Type", "NONE", buf, 80);
    972 
    973 		if (!stricmp(buf,"AIRCRAFT"))
    974 			TrapObjType = RTTI_AIRCRAFT;
    975 		else if (!stricmp(buf,"ANIM"))
    976 			TrapObjType = RTTI_ANIM;
    977 		else if (!stricmp(buf,"BUILDING"))
    978 			TrapObjType = RTTI_BUILDING;
    979 		else if (!stricmp(buf,"BULLET"))
    980 			TrapObjType = RTTI_BULLET;
    981 		else if (!stricmp(buf,"INFANTRY"))
    982 			TrapObjType = RTTI_INFANTRY;
    983 		else if (!stricmp(buf,"UNIT"))
    984 			TrapObjType = RTTI_UNIT;
    985 		else {
    986 			TrapObjType = RTTI_NONE;
    987 		}
    988 
    989 		ini.Get_String("SyncBug", "Coord", "0", buf, 80);
    990 		sscanf(buf,"%x",&TrapCoord);
    991 
    992 		ini.Get_String("SyncBug", "Target", "0", buf, 80);
    993 		sscanf(buf,"%x",&TrapTarget);
    994 
    995 		ini.Get_String("SyncBug", "Cell", "0", buf, 80);
    996 		cell = atoi(buf);
    997 		if (cell) {
    998 			TrapCell = &(Map[cell]);
    999 		}
   1000 
   1001 		TrapPrintCRC = ini.Get_Int("SyncBug", "PrintCRC", 0x7fffffff);
   1002 	}
   1003 #endif
   1004 }
   1005 
   1006 
   1007 /***************************************************************************
   1008  * SessionClass::Write_MultiPlayer_Settings -- writes settings INI         *
   1009  *                                                                         *
   1010  * INPUT:                                                                  *
   1011  *      none.                                                              *
   1012  *                                                                         *
   1013  * OUTPUT:                                                                 *
   1014  *      none.                                                              *
   1015  *                                                                         *
   1016  * WARNINGS:                                                               *
   1017  *      none.                                                              *
   1018  *                                                                         *
   1019  * HISTORY:                                                                *
   1020  *   02/14/1995 BR : Created.                                              *
   1021  *=========================================================================*/
   1022 void SessionClass::Write_MultiPlayer_Settings (void)
   1023 {
   1024 #ifdef NEVER
   1025 	char * buffer;					// INI staging buffer pointer.
   1026 	CCFileClass file;
   1027 	int i;
   1028 	char entrytext[4];
   1029 	char buf[128];					// buffer for parsing INI entry
   1030 
   1031 	//------------------------------------------------------------------------
   1032 	//	Get a working pointer to the INI staging buffer. Make sure that the
   1033 	// buffer starts cleared out of any data.
   1034 	//------------------------------------------------------------------------
   1035 	buffer = (char *)_ShapeBuffer;
   1036 	memset(buffer, '\0', _ShapeBufferSize);
   1037 
   1038 	file.Set_Name(CONFIG_FILE_NAME);
   1039 	if (file.Is_Available()) {
   1040 		file.Open(READ);
   1041 		file.Read(buffer, _ShapeBufferSize-1);
   1042 		file.Close();
   1043 	}
   1044 
   1045 	//------------------------------------------------------------------------
   1046 	//	Save the player's last-used Handle & Color
   1047 	//------------------------------------------------------------------------
   1048 	WWWritePrivateProfileInt("MultiPlayer", "PhoneIndex", CurPhoneIdx, buffer);
   1049 	WWWritePrivateProfileInt ("MultiPlayer", "Color", (int)PrefColor, buffer);
   1050 	WWWritePrivateProfileInt ("MultiPlayer", "Side", House, buffer);
   1051 	WWWritePrivateProfileString("MultiPlayer", "Handle", Handle, buffer);
   1052 
   1053 	//------------------------------------------------------------------------
   1054 	//	Clear all existing Settings.SerialDefault entries.
   1055 	//------------------------------------------------------------------------
   1056 	WWWritePrivateProfileString ("SerialDefaults", NULL, NULL, buffer);
   1057 
   1058 	//------------------------------------------------------------------------
   1059 	//	Save default serial settings in opposite order you want to see them
   1060 	//------------------------------------------------------------------------
   1061 	WWWritePrivateProfileString("SerialDefaults", "CallWaitString", SerialDefaults.CallWaitString, buffer);
   1062 	WWWritePrivateProfileInt ("SerialDefaults", "CallWaitStringIndex", SerialDefaults.CallWaitStringIndex, buffer);
   1063 	WWWritePrivateProfileInt ("SerialDefaults", "InitStringIndex", SerialDefaults.InitStringIndex, buffer);
   1064 	WWWritePrivateProfileString("SerialDefaults", "DialMethod", DialMethodCheck[ SerialDefaults.DialMethod ], buffer);
   1065 	WWWritePrivateProfileInt ("SerialDefaults", "Baud", SerialDefaults.Baud, buffer);
   1066 	WWWritePrivateProfileInt ("SerialDefaults", "IRQ", SerialDefaults.IRQ, buffer);
   1067 	sprintf(buf, "%x", SerialDefaults.Port);
   1068 	WWWritePrivateProfileString("SerialDefaults", "Port", buf, buffer);
   1069 	WWWritePrivateProfileInt ("SerialDefaults", "Compression", SerialDefaults.Compression , buffer);
   1070 	WWWritePrivateProfileInt ("SerialDefaults", "ErrorCorrection", SerialDefaults.ErrorCorrection, buffer);
   1071 	WWWritePrivateProfileInt ("SerialDefaults", "HardwareFlowControl", SerialDefaults.HardwareFlowControl, buffer);
   1072 
   1073 	//------------------------------------------------------------------------
   1074 	//	Clear all existing InitString entries.
   1075 	//------------------------------------------------------------------------
   1076 	WWWritePrivateProfileString ("InitStrings", NULL, NULL, buffer);
   1077 
   1078 	//------------------------------------------------------------------------
   1079 	//	Save all InitString entries.  In descending order so they come out in
   1080 	//	ascending order.
   1081 	//------------------------------------------------------------------------
   1082 	for (i = (InitStrings.Count() - 1); i >= 0; i--) {
   1083 		sprintf( buf, "%03d", i);
   1084 		WWWritePrivateProfileString ("InitStrings", buf, InitStrings[i], buffer);
   1085 	}
   1086 
   1087 	//------------------------------------------------------------------------
   1088 	//	Clear all existing Phone Book entries.
   1089 	//------------------------------------------------------------------------
   1090 	WWWritePrivateProfileString ("PhoneBook", NULL, NULL, buffer);
   1091 
   1092 	//------------------------------------------------------------------------
   1093 	//	Save all Phone Book entries.
   1094 	//	Format: Entry=Name,PhoneNum,Port,IRQ,Baud,InitString
   1095 	//------------------------------------------------------------------------
   1096 	for (i = (PhoneBook.Count() - 1); i >= 0; i--) {
   1097 		sprintf(buf,"%s|%s|%x|%d|%d|%d|%d|%d|%s|%d|%d|%s",
   1098 			PhoneBook[i]->Name,
   1099 			PhoneBook[i]->Number,
   1100 			PhoneBook[i]->Settings.Port,
   1101 			PhoneBook[i]->Settings.IRQ,
   1102 			PhoneBook[i]->Settings.Baud,
   1103 			PhoneBook[i]->Settings.Compression,
   1104 			PhoneBook[i]->Settings.ErrorCorrection,
   1105 			PhoneBook[i]->Settings.HardwareFlowControl,
   1106 			DialMethodCheck[ PhoneBook[i]->Settings.DialMethod ],
   1107 			PhoneBook[i]->Settings.InitStringIndex,
   1108 			PhoneBook[i]->Settings.CallWaitStringIndex,
   1109 			PhoneBook[i]->Settings.CallWaitString);
   1110 		sprintf( entrytext, "%03d", i );
   1111 		WWWritePrivateProfileString ("PhoneBook", entrytext, buf, buffer);
   1112 	}
   1113 
   1114 	//------------------------------------------------------------------------
   1115 	//	Write the INI data out to a file.
   1116 	//------------------------------------------------------------------------
   1117 	file.Open(WRITE);
   1118 	file.Write(buffer,strlen(buffer));
   1119 	file.Close();
   1120 #endif
   1121 
   1122 #if (0)//PG
   1123 	INIClass ini;
   1124 	RawFileClass file(CONFIG_FILE_NAME);
   1125 	if (ini.Load(file)) {
   1126 
   1127 		//	Save the player's last-used Handle & Color
   1128 		ini.Put_Int("MultiPlayer", "PhoneIndex", CurPhoneIdx);
   1129 		ini.Put_Int("MultiPlayer", "Color", (int)PrefColor);
   1130 		ini.Put_Int("MultiPlayer", "Side", House);
   1131 		ini.Put_String("MultiPlayer", "Handle", Handle);
   1132 
   1133 		//	Clear all existing Settings.SerialDefault entries.
   1134 		ini.Clear("SerialDefaults");
   1135 
   1136 		//	Save default serial settings in opposite order you want to see them
   1137 		ini.Put_String("SerialDefaults", "CallWaitString", SerialDefaults.CallWaitString);
   1138 		ini.Put_Int("SerialDefaults", "CallWaitStringIndex", SerialDefaults.CallWaitStringIndex);
   1139 		ini.Put_Int("SerialDefaults", "InitStringIndex", SerialDefaults.InitStringIndex);
   1140 		ini.Put_String("SerialDefaults", "DialMethod", DialMethodCheck[ SerialDefaults.DialMethod ]);
   1141 		ini.Put_Int("SerialDefaults", "Baud", SerialDefaults.Baud);
   1142 		ini.Put_Int("SerialDefaults", "IRQ", SerialDefaults.IRQ);
   1143 		ini.Put_Int("SerialDefaults", "Port", SerialDefaults.Port, 1);
   1144 		ini.Put_String("SerialDefaults", "ModemName", SerialDefaults.ModemName);
   1145 		ini.Put_Int ("SerialDefaults", "Compression", SerialDefaults.Compression );
   1146 		ini.Put_Int ("SerialDefaults", "ErrorCorrection", SerialDefaults.ErrorCorrection );
   1147 		ini.Put_Int ("SerialDefaults", "HardwareFlowControl", SerialDefaults.HardwareFlowControl );
   1148 
   1149 		//	Clear all existing InitString entries.
   1150 		ini.Clear("InitStrings");
   1151 
   1152 		//	Save all InitString entries.
   1153 		for (int index = 0; index < InitStrings.Count(); index++) {
   1154 			char buf[10];
   1155 			sprintf( buf, "%03d", index);
   1156 			ini.Put_String("InitStrings", buf, InitStrings[index]);
   1157 		}
   1158 
   1159 		//	Clear all existing Phone Book entries.
   1160 		ini.Clear("PhoneBook");
   1161 
   1162 		//	Save all Phone Book entries.
   1163 		//	Format: Entry=Name,PhoneNum,Port,IRQ,Baud,InitString
   1164 		for (int i = (PhoneBook.Count() - 1); i >= 0; i--) {
   1165 			char buf[128];
   1166 			char entrytext[10];
   1167 			sprintf(buf,"%s|%s|%x|%d|%d|%d|%d|%d|%s|%d|%d|%s",
   1168 				PhoneBook[i]->Name,
   1169 				PhoneBook[i]->Number,
   1170 				PhoneBook[i]->Settings.Port,
   1171 				PhoneBook[i]->Settings.IRQ,
   1172 				PhoneBook[i]->Settings.Baud,
   1173 				PhoneBook[i]->Settings.Compression,
   1174 				PhoneBook[i]->Settings.ErrorCorrection,
   1175 				PhoneBook[i]->Settings.HardwareFlowControl,
   1176 				DialMethodCheck[ PhoneBook[i]->Settings.DialMethod ],
   1177 				PhoneBook[i]->Settings.InitStringIndex,
   1178 				PhoneBook[i]->Settings.CallWaitStringIndex,
   1179 				PhoneBook[i]->Settings.CallWaitString);
   1180 			sprintf( entrytext, "%03d", i );
   1181 			ini.Put_String("PhoneBook", entrytext, buf);
   1182 		}
   1183 
   1184 		//	Write the INI data out to a file.
   1185 		ini.Save(file);
   1186 	}
   1187 #endif
   1188 }
   1189 
   1190 
   1191 // Determine if a mission is from counterstrike or aftermath, or either.
   1192 // Multiplayer maps >24, with a numerical name, are Counterstrike.
   1193 // Multiplayer maps with an alphabetical name, like SCMJGEA.INI, are Aftermath.
   1194 
   1195 bool Is_Mission_Counterstrike (char *file_name)
   1196 {
   1197 	int scenario_number = 0;
   1198 
   1199 	if ( isdigit ( file_name[5] )){
   1200 		sscanf (file_name, "SCM%03d", &scenario_number);
   1201 	} else {
   1202 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
   1203 		if (!isdigit(file_name[3]) || !isdigit(file_name[4])) {
   1204 			return(false);
   1205 		}
   1206 #endif
   1207 		sscanf (file_name, "SCM%02d", &scenario_number);
   1208 	}
   1209 	return ( scenario_number > 24 );
   1210 }
   1211 
   1212 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
   1213 bool Is_Mission_Aftermath (char *file_name)
   1214 {
   1215 	//	ajw added
   1216 	//	Must start with "scm".
   1217 	char szCopy[ _MAX_PATH + 1 ];
   1218 	strcpy( szCopy, file_name );
   1219 	_strlwr( szCopy );
   1220 	if( strstr( szCopy, "scm" ) != szCopy )
   1221 		return false;
   1222 
   1223 	if (isdigit(file_name[5])) {
   1224 		return(false);
   1225 	}
   1226 
   1227 	if ( !isdigit(file_name[3]) || !isdigit(file_name[4]) ) {
   1228 		return (true);
   1229 	}
   1230 	return (false);
   1231 }
   1232 
   1233 /*
   1234 ** Certain missions are 126x126 size, and those can't be downloaded to a
   1235 ** non-Aftermath player, so this function checks to see if the map in
   1236 ** question is one of those.  We'll know that by the file name: if it's
   1237 ** K0 -> M9, it's 126x126.
   1238 */
   1239 bool Is_Mission_126x126 (char *file_name)		//	This is no longer used. ajw
   1240 {
   1241 	if (isdigit(file_name[5])) {
   1242 		return(false);
   1243 	}
   1244 
   1245 	if ( (file_name[3] >= 'k' && file_name[3] <= 'm') ||
   1246 			(file_name[3] >= 'K' && file_name[3] <= 'M') ) {
   1247 		return (true);
   1248 	}
   1249 	return (false);
   1250 }
   1251 
   1252 #endif
   1253 
   1254 
   1255 
   1256 
   1257 
   1258 /***************************************************************************
   1259  * SessionClass::Read_Scenario_Descriptions -- reads scen. descriptions    *
   1260  *                                                                         *
   1261  * INPUT:                                                                  *
   1262  *      none.                                                              *
   1263  *                                                                         *
   1264  * OUTPUT:                                                                 *
   1265  *      none.                                                              *
   1266  *                                                                         *
   1267  * WARNINGS:                                                               *
   1268  *      none.                                                              *
   1269  *                                                                         *
   1270  * HISTORY:                                                                *
   1271  *   02/14/1995 BR : Created.                                              *
   1272  *   09/10/1996 JLB : Searches using different method.                     *
   1273  *=========================================================================*/
   1274 void SessionClass::Read_Scenario_Descriptions (void)
   1275 {
   1276 
   1277 	//	Clear the scenario description lists
   1278 	Scenarios.Clear();
   1279 
   1280 	/*
   1281 	**	Fetch the main multiplayer scenario packet data.
   1282 	*/
   1283 	CCFileClass file("MISSIONS.PKT");
   1284 	if (file.Is_Available()) {
   1285 		INIClass ini;
   1286 		ini.Load(file);
   1287 		int count = ini.Entry_Count("Missions");
   1288 //debugprint( "Found %i missions in Missions.pkt\n", count );
   1289 		for (int index = 0; index < count; index++) {
   1290 			char const * fname = ini.Get_Entry("Missions", index);
   1291 			char buffer[128];
   1292 			ini.Get_String("Missions", fname, "", buffer, sizeof(buffer));
   1293 #ifdef FIXIT_VERSION_3
   1294 			Scenarios.Add(new MultiMission(fname, buffer, NULL, true,
   1295 									Is_Mission_Counterstrike ((char*)fname)));
   1296 #else	//	FIXIT_VERSION_3
   1297 #ifdef FIXIT_CSII	//	checked - ajw
   1298 			bool official = Is_Mission_126x126( (char *)fname);
   1299 			if (!official) {
   1300 				official = !Is_Mission_Aftermath((char *)fname);
   1301 			}
   1302 
   1303 			Scenarios.Add(new MultiMission(fname, buffer, NULL, official,
   1304 									Is_Mission_Counterstrike ((char*)fname)));
   1305 #else
   1306 			Scenarios.Add(new MultiMission(fname, buffer, NULL, true,
   1307 									Is_Mission_Counterstrike ((char*)fname)));
   1308 #endif
   1309 #endif	//	FIXIT_VERSION_3
   1310 		}
   1311 /*		//	ajw Copy file for viewing.
   1312 		CCFileClass fileCopy( "msns_pkt.txt" );
   1313 		file.Seek( 0, SEEK_SET );
   1314 		long lSize = file.Size();
   1315 		char* pData = new char[ lSize + 1 ];
   1316 		file.Read( pData, lSize );
   1317 		fileCopy.Write( pData, lSize );
   1318 		fileCopy.Close();
   1319 */	}
   1320 
   1321 	/*
   1322 	**	Fetch any scenario packet lists and apply them first.
   1323 	*/
   1324 #ifdef WIN32
   1325 	WIN32_FIND_DATA block;
   1326 	HANDLE handle = FindFirstFile("*.PKT", &block);
   1327 	while (handle != INVALID_HANDLE_VALUE) {
   1328 		if ((block.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY)) == 0) {
   1329 			char const * name = &block.cAlternateFileName[0];
   1330 			if (*name == '\0') name = &block.cFileName[0];
   1331 //Mono_Printf("Found file '%s'.\n", block.cAlternateFileName);
   1332 //Mono_Printf("Found file '%s'.\n", block.cFileName);
   1333 //debugprint("Found file '%s'.\n", block.cAlternateFileName);
   1334 //debugprint("Found file '%s'.\n", block.cFileName);
   1335 //debugprint( "Found alternate PKT file.\n" );
   1336 			CCFileClass file(name);
   1337 			INIClass ini;
   1338 			ini.Load(file);
   1339 
   1340 			int count = ini.Entry_Count("Missions");
   1341 			for (int index = 0; index < count; index++) {
   1342 				char const * fname = ini.Get_Entry("Missions", index);
   1343 				char buffer[128];
   1344 				ini.Get_String("Missions", fname, "", buffer, sizeof(buffer));
   1345 
   1346 #ifdef FIXIT_VERSION_3
   1347 			Scenarios.Add(new MultiMission(fname, buffer, NULL, true,
   1348 									Is_Mission_Counterstrike ((char*)fname)));
   1349 #else	//	FIXIT_VERSION_3
   1350 #ifdef FIXIT_CSII	//	checked - ajw
   1351 				bool official = Is_Mission_126x126( (char *)fname);
   1352 				if (!official) {
   1353 					official = !Is_Mission_Aftermath((char *)fname);
   1354 				}
   1355 				Scenarios.Add(new MultiMission(fname, buffer, NULL, official,
   1356 									Is_Mission_Counterstrike ((char*)fname)));
   1357 #else
   1358 				Scenarios.Add(new MultiMission(fname, buffer, NULL, true,
   1359 									Is_Mission_Counterstrike ((char*)fname)));
   1360 #endif
   1361 #endif	//	FIXIT_VERSION_3
   1362 			}
   1363 		}
   1364 
   1365 		if (FindNextFile(handle, &block) == 0) break;
   1366 	}
   1367 
   1368 
   1369   #ifdef FIXIT_CSII		//	checked - ajw
   1370 	/*
   1371 	**	Fetch the Counterstrike multiplayer scenario packet data.
   1372 	** Load the scenarios regardless of whether counterstrike's installed,
   1373 	** and at the point of hosting a network game, enable the counterstrike
   1374 	** maps only if they have CS installed.  If they don't, then the maps
   1375 	** are available as a guest, but not as a host, which fixes a multitude
   1376 	** of problems without obviously giving the maps away to non-CS owners.
   1377 	*/
   1378 #ifdef FIXIT_VERSION_3
   1379 	if( Is_Counterstrike_Installed() )
   1380 	{
   1381 #endif
   1382 		CCFileClass file2("CSTRIKE.PKT");
   1383 		if (file2.Is_Available()) {
   1384 			INIClass ini;
   1385 			ini.Load(file2);
   1386 			int count = ini.Entry_Count("Missions");
   1387 //debugprint( "Found %i missions in cstrike.pkt\n", count );
   1388 			for (int index = 0; index < count; index++) {
   1389 				char const * fname = ini.Get_Entry("Missions", index);
   1390 				char buffer[128];
   1391 				ini.Get_String("Missions", fname, "", buffer, sizeof(buffer));
   1392 #ifdef FIXIT_VERSION_3
   1393 				Scenarios.Add(new MultiMission(fname, buffer, NULL, true,
   1394 										Is_Mission_Counterstrike ((char*)fname)));
   1395 #else
   1396 				bool official = Is_Mission_126x126( (char *)fname);
   1397 				if (!official) {
   1398 					official = !Is_Mission_Aftermath((char *)fname);
   1399 				}
   1400 				Scenarios.Add(new MultiMission(fname, buffer, NULL, official,
   1401 										Is_Mission_Counterstrike ((char*)fname)));
   1402 #endif
   1403 			}
   1404 /*			//	ajw Copy file for viewing.
   1405 			CCFileClass fileCopy( "cs_pkt.txt" );
   1406 			file2.Seek( 0, SEEK_SET );
   1407 			long lSize = file2.Size();
   1408 			char* pData = new char[ lSize + 1 ];
   1409 			file2.Read( pData, lSize );
   1410 			fileCopy.Write( pData, lSize );
   1411 			fileCopy.Close();
   1412 */		}
   1413 #ifdef FIXIT_VERSION_3
   1414 	}
   1415 #endif
   1416   #endif
   1417 
   1418 #ifdef FIXIT_VERSION_3		//	Aftermath scenarios are now in their own pkt file.
   1419 	if( Is_Aftermath_Installed() )
   1420 	{
   1421 		CCFileClass file2("AFTMATH.PKT");
   1422 		if (file2.Is_Available()) {
   1423 			INIClass ini;
   1424 			ini.Load(file2);
   1425 			int count = ini.Entry_Count("Missions");
   1426 //debugprint( "Found %i missions in aftmath.pkt\n", count );
   1427 			for (int index = 0; index < count; index++) {
   1428 				char const * fname = ini.Get_Entry("Missions", index);
   1429 				char buffer[128];
   1430 				ini.Get_String("Missions", fname, "", buffer, sizeof(buffer));
   1431 				Scenarios.Add(new MultiMission(fname, buffer, NULL, true,
   1432 										Is_Mission_Counterstrike ((char*)fname)));
   1433 			}
   1434 		}
   1435 	}
   1436 #endif
   1437 
   1438 	/*
   1439 	** Scan the current directory for any loose .MPR files and build the appropriate entries
   1440 	**  into the scenario list list
   1441 	*/
   1442 	char const * file_name;
   1443 	char name_buffer[128];
   1444 	char digest_buffer[32];
   1445 
   1446 	handle = FindFirstFile ( "*.MPR" , &block );
   1447 	while (handle != INVALID_HANDLE_VALUE) {
   1448 		if ((block.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY)) == 0) {
   1449 			file_name = &block.cAlternateFileName[0];
   1450 			if (*file_name == '\0') file_name = &block.cFileName[0];
   1451 //debugprint( "Found MPR '%s'\n", file_name );
   1452 			CCFileClass file(file_name);
   1453 			INIClass ini;
   1454 			ini.Load(file);
   1455 
   1456 			ini.Get_String ("Basic", "Name", "No Name", name_buffer, sizeof (name_buffer) );
   1457 			ini.Get_String ("Digest", "1", "No Digest", digest_buffer, sizeof (digest_buffer) );
   1458 			Scenarios.Add (new MultiMission (file_name, name_buffer, digest_buffer,ini.Get_Bool("Basic", "Official", false), false ));
   1459 		}
   1460 
   1461 		if (FindNextFile(handle, &block) == 0) break;
   1462 	}
   1463 
   1464 #else	//WIN32
   1465 
   1466 #error	What? You think you can still build the DOS version after all this time?
   1467 
   1468 	char name_buffer[128];
   1469 	char digest_buffer[32];
   1470 
   1471 	struct find_t block;
   1472 	if (_dos_findfirst("*.PKT", _A_NORMAL, &block) == 0) {
   1473 		do {
   1474 			CCFileClass file(block.name);
   1475 			INIClass ini;
   1476 			ini.Load(file);
   1477 			int count = ini.Entry_Count("Missions");
   1478 			for (int index = 0; index < count; index++) {
   1479 				char const * fname = ini.Get_Entry("Missions", index);
   1480 				char buffer[128];
   1481 				ini.Get_String("Missions", fname, "", buffer, sizeof(buffer));
   1482 #ifdef FIXIT_CSII
   1483 				bool official = Is_Mission_126x126( (char *)fname);
   1484 				if (!official) {
   1485 					official = !Is_Mission_Aftermath((char *)fname);
   1486 				}
   1487 				Scenarios.Add(new MultiMission(fname, buffer, NULL, official,
   1488 										Is_Mission_Counterstrike ((char*)fname)));
   1489 #else
   1490 				Scenarios.Add(new MultiMission(fname, buffer, NULL, true,
   1491 									Is_Mission_Counterstrike ((char*)fname)));
   1492 #endif
   1493 			}
   1494 
   1495 		} while(_dos_findnext(&block) == 0);
   1496 	}
   1497 
   1498 
   1499 	/*
   1500 	** Scan the current directory for any loose .MPR files and build the appropriate entries
   1501 	**  into the scenario list list
   1502 	*/
   1503 	if (_dos_findfirst("*.MPR", _A_NORMAL, &block) == 0) {
   1504 		do {
   1505 			CCFileClass file(block.name);
   1506 			INIClass ini;
   1507 			ini.Load(file);
   1508 			ini.Get_String ("Basic", "Name", "No Name", name_buffer, sizeof (name_buffer) );
   1509 			ini.Get_String ("Digest", "1", "No Digest", digest_buffer, sizeof (digest_buffer) );
   1510 			bool official = ini.Get_Bool("Basic", "Official", false);
   1511 			Scenarios.Add (new MultiMission (block.name, name_buffer, digest_buffer, official, false ));
   1512 		} while(_dos_findnext(&block) == 0);
   1513 	}
   1514 
   1515   #ifdef FIXIT_CSII
   1516 	/*
   1517 	**	Fetch the Counterstrike multiplayer scenario packet data.
   1518 	** Load the scenarios regardless of whether counterstrike's installed,
   1519 	** and at the point of hosting a network game, enable the counterstrike
   1520 	** maps only if they have CS installed.  If they don't, then the maps
   1521 	** are available as a guest, but not as a host, which fixes a multitude
   1522 	** of problems without obviously giving the maps away to non-CS owners.
   1523 	*/
   1524 //	if (Is_Counterstrike_Installed()) {
   1525 		CCFileClass file2("CSTRIKE.PKT");
   1526 		if (file2.Is_Available()) {
   1527 			INIClass ini;
   1528 			ini.Load(file2);
   1529 			int count = ini.Entry_Count("Missions");
   1530 			for (int index = 0; index < count; index++) {
   1531 				char const * fname = ini.Get_Entry("Missions", index);
   1532 				char buffer[128];
   1533 				ini.Get_String("Missions", fname, "", buffer, sizeof(buffer));
   1534 				bool official = Is_Mission_126x126( (char *)fname);
   1535 				if (!official) {
   1536 					official = !Is_Mission_Aftermath((char *)fname);
   1537 				}
   1538 
   1539 				Scenarios.Add(new MultiMission(fname, buffer, NULL, official,
   1540 										Is_Mission_Counterstrike ((char*)fname)));
   1541 			}
   1542 		}
   1543 //	}
   1544   #endif
   1545 
   1546 #endif	//WIN32
   1547 }
   1548 
   1549 
   1550 /***************************************************************************
   1551  * SessionClass::Free_Scenario_Descriptions -- frees scen. descriptions    *
   1552  *                                                                         *
   1553  * INPUT:                                                                  *
   1554  *      none.                                                              *
   1555  *                                                                         *
   1556  * OUTPUT:                                                                 *
   1557  *      none.                                                              *
   1558  *                                                                         *
   1559  * WARNINGS:                                                               *
   1560  *      none.                                                              *
   1561  *                                                                         *
   1562  * HISTORY:                                                                *
   1563  *   06/05/1995 BRR : Created.                                             *
   1564  *=========================================================================*/
   1565 void SessionClass::Free_Scenario_Descriptions(void)
   1566 {
   1567 	int i;
   1568 
   1569 	//------------------------------------------------------------------------
   1570 	//	Clear the scenario descriptions & filenames
   1571 	//------------------------------------------------------------------------
   1572 	for (int index = 0; index < Scenarios.Count(); index++) {
   1573 		delete Scenarios[index];
   1574 	}
   1575 	Scenarios.Clear();
   1576 //	Filenum.Clear();
   1577 
   1578 	//------------------------------------------------------------------------
   1579 	//	Clear the initstring entries
   1580 	//------------------------------------------------------------------------
   1581 	for (i = 0; i < InitStrings.Count(); i++) {
   1582 		delete InitStrings[i];
   1583 	}
   1584 	InitStrings.Clear();
   1585 #if (0)//PG
   1586 	//------------------------------------------------------------------------
   1587 	//	Clear the dialing entries
   1588 	//------------------------------------------------------------------------
   1589 	for (i = 0; i < PhoneBook.Count(); i++) {
   1590 		delete PhoneBook[i];
   1591 	}
   1592 	PhoneBook.Clear();
   1593 #endif
   1594 }	/* end of Free_Scenario_Descriptions */
   1595 
   1596 
   1597 /***************************************************************************
   1598  * SessionClass::Trap_Object -- searches for an object, for debugging		*
   1599  *                                                                         *
   1600  * INPUT:                                                                  *
   1601  *		none.																						*
   1602  *                                                                         *
   1603  * OUTPUT:                                                                 *
   1604  *		none.																						*
   1605  *                                                                         *
   1606  * WARNINGS:                                                               *
   1607  *		none.																						*
   1608  *                                                                         *
   1609  * HISTORY:                                                                *
   1610  *   06/02/1995 BRR : Created.                                             *
   1611  *=========================================================================*/
   1612 void SessionClass::Trap_Object(void)
   1613 {
   1614 	int i;
   1615 
   1616 	//------------------------------------------------------------------------
   1617 	// Initialize
   1618 	//------------------------------------------------------------------------
   1619 	TrapObject.Ptr.All = NULL;
   1620 
   1621 	//------------------------------------------------------------------------
   1622 	// Search for the object based upon its type, then its coordinate or
   1623 	// 'this' pointer value.
   1624 	//------------------------------------------------------------------------
   1625 	switch (TrapObjType) {
   1626 		case RTTI_AIRCRAFT:
   1627 			for (i = 0; i < Aircraft.Count(); i++) {
   1628 				if (Aircraft.Ptr(i)->Coord == TrapCoord ||
   1629 					Aircraft.Ptr(i)->As_Target()==TrapTarget) {
   1630 					TrapObject.Ptr.Aircraft = Aircraft.Ptr(i);
   1631 					break;
   1632 				}
   1633 			}
   1634 			break;
   1635 
   1636 		case RTTI_ANIM:
   1637 			for (i = 0; i < Anims.Count(); i++) {
   1638 				if (Anims.Ptr(i)->Coord == TrapCoord ||
   1639 					Anims.Ptr(i)->As_Target()==TrapTarget) {
   1640 					TrapObject.Ptr.Anim = Anims.Ptr(i);
   1641 					break;
   1642 				}
   1643 			}
   1644 			break;
   1645 
   1646 		case RTTI_BUILDING:
   1647 			for (i = 0; i < Buildings.Count(); i++) {
   1648 				if (Buildings.Ptr(i)->Coord == TrapCoord ||
   1649 					Buildings.Ptr(i)->As_Target()==TrapTarget) {
   1650 					TrapObject.Ptr.Building = Buildings.Ptr(i);
   1651 					break;
   1652 				}
   1653 			}
   1654 			break;
   1655 
   1656 		case RTTI_BULLET:
   1657 			for (i = 0; i < Bullets.Count(); i++) {
   1658 				if (Bullets.Ptr(i)->Coord == TrapCoord ||
   1659 					Bullets.Ptr(i)->As_Target()==TrapTarget) {
   1660 					TrapObject.Ptr.Bullet = Bullets.Ptr(i);
   1661 					break;
   1662 				}
   1663 			}
   1664 			break;
   1665 
   1666 		case RTTI_INFANTRY:
   1667 			for (i = 0; i < Infantry.Count(); i++) {
   1668 				if (Infantry.Ptr(i)->Coord == TrapCoord ||
   1669 					Infantry.Ptr(i)->As_Target()==TrapTarget) {
   1670 					TrapObject.Ptr.Infantry = Infantry.Ptr(i);
   1671 					break;
   1672 				}
   1673 			}
   1674 			break;
   1675 
   1676 		case RTTI_UNIT:
   1677 			for (i = 0; i < Units.Count(); i++) {
   1678 				if (Units.Ptr(i)->Coord == TrapCoord ||
   1679 					Units.Ptr(i)->As_Target()==TrapTarget) {
   1680 					TrapObject.Ptr.Unit = Units.Ptr(i);
   1681 					break;
   1682 				}
   1683 			}
   1684 			break;
   1685 
   1686 		//.....................................................................
   1687 		// Last-ditch find-the-object-right-now-darnit loop
   1688 		//.....................................................................
   1689 		case RTTI_NONE:
   1690 			for (i = 0; i < Aircraft.Count(); i++) {
   1691 				if (Aircraft.Raw_Ptr(i)->Coord == TrapCoord ||
   1692 					Aircraft.Raw_Ptr(i)->As_Target()==TrapTarget) {
   1693 					TrapObject.Ptr.Aircraft = Aircraft.Raw_Ptr(i);
   1694 					TrapObjType = RTTI_AIRCRAFT;
   1695 					return;
   1696 				}
   1697 			}
   1698 			for (i = 0; i < Anims.Count(); i++) {
   1699 				if (Anims.Raw_Ptr(i)->Coord == TrapCoord ||
   1700 					Anims.Raw_Ptr(i)->As_Target()==TrapTarget) {
   1701 					TrapObject.Ptr.Anim = Anims.Raw_Ptr(i);
   1702 					TrapObjType = RTTI_ANIM;
   1703 					return;
   1704 				}
   1705 			}
   1706 			for (i = 0; i < Buildings.Count(); i++) {
   1707 				if (Buildings.Raw_Ptr(i)->Coord == TrapCoord ||
   1708 					Buildings.Raw_Ptr(i)->As_Target()==TrapTarget) {
   1709 					TrapObject.Ptr.Building = Buildings.Raw_Ptr(i);
   1710 					TrapObjType = RTTI_BUILDING;
   1711 					return;
   1712 				}
   1713 			}
   1714 			for (i = 0; i < Bullets.Count(); i++) {
   1715 				if (Bullets.Raw_Ptr(i)->Coord == TrapCoord ||
   1716 					Bullets.Raw_Ptr(i)->As_Target()==TrapTarget) {
   1717 					TrapObject.Ptr.Bullet = Bullets.Raw_Ptr(i);
   1718 					TrapObjType = RTTI_BULLET;
   1719 					return;
   1720 				}
   1721 			}
   1722 			for (i = 0; i < Infantry.Count(); i++) {
   1723 				if (Infantry.Raw_Ptr(i)->Coord == TrapCoord ||
   1724 					Infantry.Raw_Ptr(i)->As_Target()==TrapTarget) {
   1725 					TrapObject.Ptr.Infantry = Infantry.Raw_Ptr(i);
   1726 					TrapObjType = RTTI_INFANTRY;
   1727 					return;
   1728 				}
   1729 			}
   1730 			for (i = 0; i < Units.Count(); i++) {
   1731 				if (Units.Raw_Ptr(i)->Coord == TrapCoord ||
   1732 					Units.Raw_Ptr(i)->As_Target()==TrapTarget) {
   1733 					TrapObject.Ptr.Unit = Units.Raw_Ptr(i);
   1734 					TrapObjType = RTTI_UNIT;
   1735 					return;
   1736 				}
   1737 			}
   1738 
   1739 		default:
   1740 			break;
   1741 	}
   1742 }
   1743 
   1744 
   1745 /***************************************************************************
   1746  * SessionClass::Compute_Unique_ID -- computes unique local ID number      *
   1747  *                                                                         *
   1748  * INPUT:                                                                  *
   1749  *		none.																						*
   1750  *                                                                         *
   1751  * OUTPUT:                                                                 *
   1752  *		none.																						*
   1753  *                                                                         *
   1754  * WARNINGS:                                                               *
   1755  *		none.																						*
   1756  *                                                                         *
   1757  * HISTORY:                                                                *
   1758  *   12/07/1995 BRR : Created.                                             *
   1759  *=========================================================================*/
   1760 unsigned long SessionClass::Compute_Unique_ID(void)
   1761 {
   1762 	return 1;//PG
   1763 #if (0) //PG
   1764 	time_t tm;
   1765 	unsigned long id;
   1766 	struct diskfree_t dtable;
   1767 	char *path;
   1768 	int i;
   1769 
   1770 	//------------------------------------------------------------------------
   1771 	// Start with the seconds since Jan 1, 1970 (system local time)
   1772 	//------------------------------------------------------------------------
   1773 	time(&tm);
   1774 	id = (unsigned long)tm;
   1775 
   1776 	//------------------------------------------------------------------------
   1777 	// Now add in the free space on the hard drive
   1778 	//------------------------------------------------------------------------
   1779 	if (_dos_getdiskfree(3, &dtable) == 0) {
   1780 		Add_CRC(&id, (unsigned long)dtable.avail_clusters);
   1781 		Add_CRC(&id, (unsigned long)dtable.total_clusters);
   1782 		Add_CRC(&id, (unsigned long)dtable.bytes_per_sector);
   1783 		Add_CRC(&id, (unsigned long)dtable.sectors_per_cluster);
   1784 	}
   1785 
   1786 	//------------------------------------------------------------------------
   1787 	// Add in every byte in the user's path environment variable
   1788 	//------------------------------------------------------------------------
   1789 	path = getenv("PATH");
   1790 	if (path) {
   1791 		for (i = 0; i < strlen(path); i++) {
   1792 			Add_CRC(&id, (unsigned long)path[i]);
   1793 		}
   1794 	}
   1795 
   1796 	return (id);
   1797 #endif
   1798 }	// end of Compute_Unique_ID
   1799 
   1800 
   1801 
   1802 
   1803 MultiMission::MultiMission(char const * filename, char const * description, char const * digest, bool official, bool expansion)
   1804 {
   1805 	Set_Filename(filename);
   1806 	Set_Description(description);
   1807 	Set_Digest(digest);
   1808 	Set_Official(official);
   1809 	Set_Expansion(expansion);
   1810 }
   1811 
   1812 
   1813 void MultiMission::Draw_It(int , int x, int y, int width, int height, bool selected, TextPrintType flags) const
   1814 {
   1815 	RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
   1816 	static int _tabs[] = {35, 60, 80, 100};
   1817 	if ((flags & 0x0F) == TPF_6PT_GRAD || (flags & 0x0F) == TPF_EFNT) {
   1818 
   1819 		if (selected) {
   1820 			flags = flags | TPF_BRIGHT_COLOR;
   1821 			LogicPage->Fill_Rect(x, y, x + width - 1, y + height - 1, scheme->Shadow);
   1822 		} else {
   1823 			if (!(flags & TPF_USE_GRAD_PAL)) {
   1824 				flags = flags | TPF_MEDIUM_COLOR;
   1825 			}
   1826 		}
   1827 
   1828 		Conquer_Clip_Text_Print(ScenarioDescription, x, y, scheme, TBLACK, flags, width, _tabs);
   1829 	} else {
   1830 		Conquer_Clip_Text_Print(ScenarioDescription, x, y, (selected ? &ColorRemaps[PCOLOR_DIALOG_BLUE] : &ColorRemaps[PCOLOR_GREY]), TBLACK, flags, width, _tabs);
   1831 	}
   1832 }
   1833 
   1834 
   1835 void MultiMission::Set_Description(char const * description)
   1836 {
   1837 	if (description != NULL) {
   1838 		strncpy(ScenarioDescription, description, ARRAY_SIZE(ScenarioDescription));
   1839 		ScenarioDescription[ARRAY_SIZE(ScenarioDescription)-1] = '\0';
   1840 	}
   1841 }
   1842 
   1843 
   1844 void MultiMission::Set_Filename(char const * filename)
   1845 {
   1846 	if (filename != NULL) {
   1847 		strncpy(Filename, filename, ARRAY_SIZE(Filename));
   1848 		Filename[ARRAY_SIZE(Filename)-1] = '\0';
   1849 	}
   1850 }
   1851 
   1852 void MultiMission::Set_Digest(char const * digest)
   1853 {
   1854 	if (digest != NULL) {
   1855 		strncpy(Digest, digest, ARRAY_SIZE(Digest));
   1856 		Digest[ARRAY_SIZE(Digest)-1] = '\0';
   1857 	}
   1858 	else
   1859 	{
   1860 		strcpy( Digest, "NODIGEST" );
   1861 	}
   1862 }
   1863 
   1864 void MultiMission::Set_Official (bool official)
   1865 {
   1866 	IsOfficial = official;
   1867 }
   1868 
   1869 void MultiMission::Set_Expansion (bool expansion)
   1870 {
   1871 	IsExpansion = expansion;
   1872 }
   1873 
   1874 
   1875 /************************** end of session.cpp *****************************/