// // Copyright 2020 Electronic Arts Inc. // // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free // software: you can redistribute it and/or modify it under the terms of // the GNU General Public License as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed // in the hope that it will be useful, but with permitted additional restrictions // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT // distributed with this program. You should have received a copy of the // GNU General Public License along with permitted additional restrictions // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection /* $Header: /counterstrike/SESSION.CPP 3 3/10/97 6:23p Steve_tall $ */ /*********************************************************************************************** *** 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 *** *********************************************************************************************** * * * Project Name : Command & Conquer * * * * File Name : SESSION.CPP * * * * Programmer : Bill R. Randolph * * * * Start Date : 11/30/95 * * * * Last Update : September 10, 1996 [JLB] * * * *---------------------------------------------------------------------------------------------* * Functions: * * SessionClass::SessionClass -- Constructor * * SessionClass::~SessionClass -- Destructor * * SessionClass::One_Time -- one-time initializations * * SessionClass::Init -- Initializes all values * * SessionClass::Create_Connections -- forms connections to other players * * SessionClass::Am_I_Master -- tells if the local system is the "master" * * SessionClass::Save -- Saves this class to a file * * SessionClass::Load -- Loads this class from a file * * SessionClass::Read_MultiPlayer_Settings -- reads settings from INI * * SessionClass::Write_MultiPlayer_Settings -- writes settings to INI * * SessionClass::Read_Scenario_Descriptions -- reads scen. descriptions * * SessionClass::Free_Scenario_Descriptions -- frees scen. descriptions * * SessionClass::Trap_Object -- searches for an object, for debugging * * SessionClass::Compute_Unique_ID -- computes unique local ID number * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "function.h" #include // for station ID computation #include // for station ID computation //#include "WolDebug.h" /***************************** Globals *************************************/ //--------------------------------------------------------------------------- // This is the array of remap colors. Each player in a network game is // assigned one of these colors. The 'G' is for graphics drawing; the 'T' // is for text printing (indicates a remap table for the font to use). //--------------------------------------------------------------------------- //int SessionClass::GColors[MAX_MPLAYER_COLORS] = { //5, // Yellow //127, // Red //135, // BlueGreen //26, // Orange //4, // Green //202 // Blue-Grey //}; //int SessionClass::TColors[MAX_MPLAYER_COLORS] = { //CC_GDI_COLOR, // Yellow //CC_NOD_COLOR, // Red //CC_BLUE_GREEN, // BlueGreen //CC_ORANGE, // Orange //CC_GREEN, // Green //CC_BLUE_GREY, // Blue //}; /*--------------------------------------------------------------------------- Min & Max unit count values; index0 = bases OFF, index1 = bases ON ---------------------------------------------------------------------------*/ int SessionClass::CountMin[2] = {1,0}; int SessionClass::CountMax[2] = {50,12}; //--------------------------------------------------------------------------- // This is a list of all the names of the multiplayer scenarios //--------------------------------------------------------------------------- char SessionClass::Descriptions[100][40]; //--------------------------------------------------------------------------- // These values are used purely for the Mono debug display. They show the // names of the Global Channel packet types, and the event types. //--------------------------------------------------------------------------- char * SessionClass::GlobalPacketNames[] = { "Game?", "Game!", "Player?", "Player!", "Join?", "Join!", "Reject", "GameOptions", "Sign Off", "GO!", "Message", "Ping", "Load" }; char * SessionClass::SerialPacketNames[] = { "CONNECT", "GAME_OPTIONS", "SIGN_OFF", "GO", "MESSAGE", "TIMING", "SCORE_SCREEN", "LOADGAME", "LAST_COMMAND", }; char * SessionClass::DialMethodCheck[ DIAL_METHODS ] = { "T", "P" }; char *SessionClass::CallWaitStrings[ CALL_WAIT_STRINGS_NUM ] = { "*70,", "70#,", "1170,", "CUSTOM - " }; /*************************************************************************** * SessionClass::SessionClass -- Constructor * * * * INPUT: * * none. * * * * OUTPUT: * * none. * * * * WARNINGS: * * none. * * * * HISTORY: * * 11/30/1995 BRR : Created. * *=========================================================================*/ SessionClass::SessionClass(void) { Type = GAME_NORMAL; CommProtocol = DEFAULT_COMM_PROTOCOL; Options.ScenarioIndex = 0; Options.Bases = 0; Options.Credits = 0; Options.Tiberium = 0; Options.Goodies = 0; Options.Ghosts = 0; Options.UnitCount = 0; UniqueID = 0; Handle[0] = 0; PrefColor = PCOLOR_FIRST; ColorIdx = PCOLOR_FIRST; House = HOUSE_GOOD; ObiWan = 0; Solo = 0; MaxPlayers = 8; NumPlayers = 0; MaxAhead = 5; FrameSendRate = DEFAULT_FRAME_SEND_RATE; LoadGame = 0; EmergencySave = 0; LastMessage[0] = 0; WWChat = 0; RecordFile.Set_Name("RECORD.BIN"); // always uses this name Record= 0; // set via command line Play = 0; // set via command line Attract = 0; // set via command line IsBridge = 0; NetStealth = 0; NetProtect = 1; NetOpen = 0; GameName[0] = 0; GProductID = 0; MetaSize = MAX_IPX_PACKET_SIZE; ModemService = true; CurPhoneIdx = 0; // set from INI file SerialDefaults.Port = 0x2f8; // set from INI file SerialDefaults.IRQ = 3; // set from INI file SerialDefaults.Baud = 9600; // set from INI file SerialDefaults.DialMethod = DIAL_TOUCH_TONE; // set from INI file SerialDefaults.InitStringIndex = 0; // set from INI file SerialDefaults.CallWaitStringIndex = 0; // set from INI file strcpy(SerialDefaults.CallWaitString,""); ModemType = MODEM_NULL_HOST; // set from INI file TrapFrame = 0x7fffffff; // frame to start trapping object values at TrapObjType = RTTI_NONE; // type of object to trap TrapObject.Ptr.All = NULL; // ptr to object being trapped TrapCoord = 0; // COORDINATE of object to trap TrapTarget = TARGET_NONE; // TARGET value of object to trap TrapCell = NULL; // for trapping a cell TrapCheckHeap = 0; // start checking the Heap TrapPrintCRC = 0; // output CRC file #if(TEN) TenPacket = NULL; TenSize = 200; TenPlayerID = -1; OptionsFile[0] = 0; AllowSolo = 0; NetResponseTime = 600; #endif // TEN #if(MPATH) MPathPacket = NULL; MPathSize = 200; OptionsFile[0] = 0; AllowSolo = 0; NetResponseTime = 600; #endif // MPATH } // end of SessionClass /*************************************************************************** * SessionClass::~SessionClass -- Destructor * * * * INPUT: * * none. * * * * OUTPUT: * * none. * * * * WARNINGS: * * none. * * * * HISTORY: * * 11/30/1995 BRR : Created. * *=========================================================================*/ SessionClass::~SessionClass(void) { } // end of ~SessionClass /*************************************************************************** * SessionClass::One_Time -- one-time initializations * * * * INPUT: * * none. * * * * OUTPUT: * * none. * * * * WARNINGS: * * none. * * * * HISTORY: * * 12/01/1995 BRR : Created. * *=========================================================================*/ void SessionClass::One_Time(void) { Read_MultiPlayer_Settings(); Read_Scenario_Descriptions(); UniqueID = Compute_Unique_ID(); } // end of One_Time /*************************************************************************** * SessionClass::Init -- Initializes all values * * * * This function should be called for every new game played; it only sets * * those variables that should be set for a new game. * * * * INPUT: * * none. * * * * OUTPUT: * * none. * * * * WARNINGS: * * none. * * * * HISTORY: * * 11/30/1995 BRR : Created. * *=========================================================================*/ void SessionClass::Init(void) { } // end of Init /*************************************************************************** * SessionClass::Create_Connections -- forms connections to other players * * * * This routine uses the contents of the Players vector, combined with * * that of the Houses array, to create connections to each other player. * * It is assumed that 'Players' contains all the other players to connect * * to, and that the HouseClass's have been filled in with players' data. * * * * INPUT: * * none. * * * * OUTPUT: * * 1 = success, 0 = failure * * * * WARNINGS: * * none. * * * * HISTORY: * * 11/30/1995 BRR : Created. * *=========================================================================*/ int SessionClass::Create_Connections(void) { #if (0)//PG int i; if (Session.Type != GAME_IPX && Session.Type != GAME_INTERNET) { return (0); } //------------------------------------------------------------------------ // Loop through all entries in 'Players'. To avoid connecting to myself, // skip the 1st entry. //------------------------------------------------------------------------ for (i = 1; i < Players.Count(); i++) { //..................................................................... // Make sure the name matches before creating the connection //..................................................................... if (!stricmp (Players[i]->Name, HouseClass::As_Pointer(Players[i]->Player.ID)->IniName)) { Ipx.Create_Connection((int)Players[i]->Player.ID, Players[i]->Name, &(Players[i]->Address) ); Players[i]->Player.ProcessTime = -1; } else { return (0); } } #endif return (1); } // end of Create_Connections #if(TEN) /*************************************************************************** * SessionClass::Create_TEN_Connections -- forms connections to TEN players* * * * This routine uses the contents of the Players vector, combined with * * that of the Houses array, to create connections to each other player. * * It is assumed that 'Players' contains all the other players to connect * * to, and that the HouseClass's have been filled in with players' data. * * * * INPUT: * * none. * * * * OUTPUT: * * 1 = success, 0 = failure * * * * WARNINGS: * * none. * * * * HISTORY: * * 11/30/1995 BRR : Created. * *=========================================================================*/ int SessionClass::Create_TEN_Connections(void) { int i; if (Session.Type != GAME_TEN) { return (0); } //------------------------------------------------------------------------ // Loop through all entries in 'Players'. To avoid connecting to myself, // skip the 1st entry. //------------------------------------------------------------------------ for (i = 1; i < Players.Count(); i++) { //..................................................................... // Make sure the name matches before creating the connection //..................................................................... if (!stricmp (Players[i]->Name, HouseClass::As_Pointer(Players[i]->Player.ID)->IniName)) { Ten->Create_Connection((int)Players[i]->Player.ID, Players[i]->Name, Players[i]->TenAddress); Players[i]->Player.ProcessTime = -1; } else { return (0); } } return (1); } // end of Create_TEN_Connections #endif // TEN #if(MPATH) /*************************************************************************** * SessionClass::Create_MPATH_Connections -- forms connections to MPATH players* * * * This routine uses the contents of the Players vector, combined with * * that of the Houses array, to create connections to each other player. * * It is assumed that 'Players' contains all the other players to connect * * to, and that the HouseClass's have been filled in with players' data. * * * * INPUT: * * none. * * * * OUTPUT: * * 1 = success, 0 = failure * * * * WARNINGS: * * none. * * * * HISTORY: * * 11/30/1995 BRR : Created. * *=========================================================================*/ int SessionClass::Create_MPATH_Connections(void) { int i; if (Session.Type != GAME_MPATH) { return (0); } //------------------------------------------------------------------------ // Loop through all entries in 'Players'. To avoid connecting to myself, // skip the 1st entry. //------------------------------------------------------------------------ for (i = 1; i < Players.Count(); i++) { //..................................................................... // Make sure the name matches before creating the connection //..................................................................... if (!stricmp (Players[i]->Name, HouseClass::As_Pointer(Players[i]->Player.ID)->IniName)) { MPath->Create_Connection((int)Players[i]->Player.ID, Players[i]->Name, Players[i]->MPathAddress); Players[i]->Player.ProcessTime = -1; } else { return (0); } } return (1); } // end of Create_MPATH_Connections #endif // MPATH /*************************************************************************** * SessionClass::Am_I_Master -- tells if the local system is the "master" * * * * INPUT: * * none. * * * * OUTPUT: * * none. * * * * WARNINGS: * * none. * * * * HISTORY: * * 11/29/1995 BRR : Created. * *=========================================================================*/ bool SessionClass::Am_I_Master(void) { int i; HousesType house; HouseClass *hptr; //------------------------------------------------------------------------ // Check every house; if PlayerPtr points to the first human house, we're // the master. //------------------------------------------------------------------------ for (i = 0; i < Session.MaxPlayers; i++) { house = (HousesType)((int)HOUSE_MULTI1 + i); hptr = HouseClass::As_Pointer(house); if (hptr->IsHuman) { if (PlayerPtr == hptr) { return (true); } else { return (false); } } } return (false); } // end of Am_I_Master /*************************************************************************** * SessionClass::Save -- Saves this class to a file * * * * Only certain members of this class should be saved into a save-game * * file; this routine saves only those members. * * * * INPUT: * * file file to save to * * * * OUTPUT: * * 1 = OK, 0 = error * * * * WARNINGS: * * none. * * * * HISTORY: * * 12/04/1995 BRR : Created. * *=========================================================================*/ int SessionClass::Save(Pipe & file) const { #ifdef FIXIT_MULTI_SAVE file.Put(&CommProtocol, sizeof(CommProtocol)); file.Put(&MaxAhead, sizeof(MaxAhead)); file.Put(&FrameSendRate, sizeof(FrameSendRate)); file.Put(&DesiredFrameRate, sizeof(DesiredFrameRate)); #endif // FIXIT_MULTI_SAVE file.Put(&PrefColor, sizeof(PrefColor)); file.Put(&ColorIdx, sizeof(ColorIdx)); file.Put(&House, sizeof(House)); file.Put(&NumPlayers, sizeof(NumPlayers)); file.Put(&Options.Bases, sizeof(Options.Bases)); file.Put(&Options.Credits, sizeof(Options.Credits)); file.Put(&Options.Tiberium, sizeof(Options.Tiberium)); file.Put(&Options.Goodies, sizeof(Options.Goodies)); file.Put(&Options.Ghosts, sizeof(Options.Ghosts)); file.Put(&Options.UnitCount, sizeof(Options.UnitCount)); file.Put(&Options.AIPlayers, sizeof(Options.AIPlayers)); file.Put(&ObiWan, sizeof(ObiWan)); file.Put(&EmergencySave, sizeof(EmergencySave)); return (1); } // end of Save /*************************************************************************** * SessionClass::Load -- Loads this class from a file * * * * INPUT: * * file file to load from * * * * OUTPUT: * * 1 = OK, 0 = error * * * * WARNINGS: * * none. * * * * HISTORY: * * 12/04/1995 BRR : Created. * *=========================================================================*/ int SessionClass::Load(Straw & file) { #ifdef FIXIT_MULTI_SAVE // if(GameVersion != 0x0100616D){ file.Get(&CommProtocol, sizeof(CommProtocol)); file.Get(&MaxAhead, sizeof(MaxAhead)); file.Get(&FrameSendRate, sizeof(FrameSendRate)); file.Get(&DesiredFrameRate, sizeof(DesiredFrameRate)); // } #endif // FIXIT_MULTI_SAVE file.Get(&PrefColor, sizeof(PrefColor)); file.Get(&ColorIdx, sizeof(ColorIdx)); file.Get(&House, sizeof(House)); file.Get(&NumPlayers, sizeof(NumPlayers)); file.Get(&Options.Bases, sizeof(Options.Bases)); file.Get(&Options.Credits, sizeof(Options.Credits)); file.Get(&Options.Tiberium, sizeof(Options.Tiberium)); file.Get(&Options.Goodies, sizeof(Options.Goodies)); file.Get(&Options.Ghosts, sizeof(Options.Ghosts)); file.Get(&Options.UnitCount, sizeof(Options.UnitCount)); file.Get(&Options.AIPlayers, sizeof(Options.AIPlayers)); file.Get(&ObiWan, sizeof(ObiWan)); file.Get(&EmergencySave, sizeof(EmergencySave)); return (1); } // end of Load /*************************************************************************** * SessionClass::Save -- Saves this class to a file * * * * Only certain members of this class should be saved into a save-game * * file; this routine saves only those members. * * * * INPUT: * * file file to save to * * * * OUTPUT: * * 1 = OK, 0 = error * * * * WARNINGS: * * none. * * * * HISTORY: * * 12/04/1995 BRR : Created. * *=========================================================================*/ int SessionClass::Save(CCFileClass & file) { int i; file.Write(&Type, sizeof(Type)); file.Write(&CommProtocol, sizeof(CommProtocol)); file.Write(&FrameSendRate, sizeof(FrameSendRate)); file.Write(&PrefColor, sizeof(PrefColor)); file.Write(&ColorIdx, sizeof(ColorIdx)); file.Write(&House, sizeof(House)); file.Write(&NumPlayers, sizeof(NumPlayers)); file.Write(&Options.Bases, sizeof(Options.Bases)); file.Write(&Options.Credits, sizeof(Options.Credits)); file.Write(&Options.Tiberium, sizeof(Options.Tiberium)); file.Write(&Options.Goodies, sizeof(Options.Goodies)); file.Write(&Options.Ghosts, sizeof(Options.Ghosts)); file.Write(&Options.UnitCount, sizeof(Options.UnitCount)); file.Write(&Options.AIPlayers, sizeof(Options.AIPlayers)); file.Write(&ObiWan, sizeof(ObiWan)); file.Write(&EmergencySave, sizeof(EmergencySave)); i = Players.Count(); file.Write(&i, sizeof(i)); for (i = 0; i < Players.Count(); i++) { file.Write(Players[i], sizeof(NodeNameType)); } return (1); } // end of Save /*************************************************************************** * SessionClass::Load -- Loads this class from a file * * * * INPUT: * * file file to load from * * * * OUTPUT: * * 1 = OK, 0 = error * * * * WARNINGS: * * none. * * * * HISTORY: * * 12/04/1995 BRR : Created. * *=========================================================================*/ int SessionClass::Load(CCFileClass & file) { int count; int i; NodeNameType *node; file.Read(&Type, sizeof(Type)); file.Read(&CommProtocol, sizeof(CommProtocol)); file.Read(&FrameSendRate, sizeof(FrameSendRate)); file.Read(&PrefColor, sizeof(PrefColor)); file.Read(&ColorIdx, sizeof(ColorIdx)); file.Read(&House, sizeof(House)); file.Read(&NumPlayers, sizeof(NumPlayers)); file.Read(&Options.Bases, sizeof(Options.Bases)); file.Read(&Options.Credits, sizeof(Options.Credits)); file.Read(&Options.Tiberium, sizeof(Options.Tiberium)); file.Read(&Options.Goodies, sizeof(Options.Goodies)); file.Read(&Options.Ghosts, sizeof(Options.Ghosts)); file.Read(&Options.UnitCount, sizeof(Options.UnitCount)); file.Read(&Options.AIPlayers, sizeof(Options.AIPlayers)); file.Read(&ObiWan, sizeof(ObiWan)); file.Read(&EmergencySave, sizeof(EmergencySave)); file.Read(&count, sizeof(count)); for (i = 0; i < count; i++) { node = new NodeNameType; file.Read(node, sizeof(NodeNameType)); Players.Add(node); } return (1); } // end of Load /*************************************************************************** * SessionClass::Read_MultiPlayer_Settings -- reads settings INI * * * * INPUT: * * none. * * * * OUTPUT: * * none. * * * * WARNINGS: * * none. * * * * HISTORY: * * 02/14/1995 BR : Created. * *=========================================================================*/ void SessionClass::Read_MultiPlayer_Settings (void) { #if (0)//PG char *tokenptr; // ptr to token PhoneEntryClass *phone; // a phone book entry char *entry; // a phone book entry char buf[128]; // buffer for parsing INI entry int i; CELL cell; // CCFileClass file (CONFIG_FILE_NAME); //------------------------------------------------------------------------ // Clear the initstring entries //------------------------------------------------------------------------ for (i = 0; i < InitStrings.Count(); i++) { delete[] InitStrings[i]; } InitStrings.Clear(); // Clear the dialing entries for (i = 0; i < PhoneBook.Count(); i++) { delete[] PhoneBook[i]; } PhoneBook.Clear(); // Create filename and read the file. INIClass ini; if (ini.Load(RawFileClass(CONFIG_FILE_NAME))) { // Get the player's last-used Handle ini.Get_String("MultiPlayer", "Handle", "Noname", Handle, sizeof(Handle)); // Get the player's last-used Color PrefColor = (PlayerColorType)ini.Get_Int("MultiPlayer", "Color", 0); #ifdef FIXIT_VERSION_3 int iSide = ini.Get_Int("MultiPlayer", "Side", HOUSE_USSR); iSide = max( 2, min( 6, iSide ) ); House = (HousesType)iSide; #else House = (HousesType)ini.Get_Int("MultiPlayer", "Side", HOUSE_USSR); #endif CurPhoneIdx = ini.Get_Int("MultiPlayer", "PhoneIndex", -1); TrapCheckHeap = ini.Get_Int("MultiPlayer", "CheckHeap", 0); // Read in default serial settings ini.Get_String("SerialDefaults", "ModemName", "NoName", SerialDefaults.ModemName, MODEM_NAME_MAX); if (!strcmp ( SerialDefaults.ModemName, "NoName")) { SerialDefaults.ModemName[0] = 0; } SerialDefaults.Port = ini.Get_Int("SerialDefaults", "Port", 0); SerialDefaults.IRQ = ini.Get_Int("SerialDefaults", "IRQ", -1); SerialDefaults.Baud = ini.Get_Int("SerialDefaults", "Baud", -1); SerialDefaults.Compression = ini.Get_Int ("SerialDefaults", "Compression", 0); SerialDefaults.ErrorCorrection = ini.Get_Int ("SerialDefaults", "ErrorCorrection", 0); SerialDefaults.HardwareFlowControl = ini.Get_Int ("SerialDefaults", "HardwareFlowControl", 1); ini.Get_String("SerialDefaults", "DialMethod", "T", buf, 2); #ifndef WIN32 /* ** Ignore any modem name in DOS. This should only be nessasary if the user ** previously set up the modem in the windows version. */ if (SerialDefaults.ModemName[0] && SerialDefaults.Port == 1) { SerialDefaults.Port = 0x3F8; SerialDefaults.ModemName[0] = 0; } #endif //WIN32 // find dial method for (i = 0; i < DIAL_METHODS; i++) { if ( !strcmpi( buf, DialMethodCheck[ i ]) ) { SerialDefaults.DialMethod = (DialMethodType)i; break; } } // if method not found set to touch tone if (i == DIAL_METHODS) { SerialDefaults.DialMethod = DIAL_TOUCH_TONE; } SerialDefaults.InitStringIndex = ini.Get_Int("SerialDefaults", "InitStringIndex", 0); SerialDefaults.CallWaitStringIndex = ini.Get_Int("SerialDefaults", "CallWaitStringIndex", CALL_WAIT_CUSTOM); ini.Get_String("SerialDefaults", "CallWaitString", "", SerialDefaults.CallWaitString, CWAITSTRBUF_MAX); if (SerialDefaults.IRQ == 0 || SerialDefaults.Baud == 0) { SerialDefaults.Port = 0; SerialDefaults.IRQ = -1; SerialDefaults.Baud = -1; } int initcount = ini.Entry_Count("InitStrings"); for (int index = 0; index < initcount; index++) { entry = new char[ INITSTRBUF_MAX ]; entry[0] = 0; ini.Get_String("InitStrings", ini.Get_Entry("InitStrings", index), NULL, entry, INITSTRBUF_MAX); strupr( entry ); InitStrings.Add( entry ); } // if no entries then have at least one if (initcount == 0) { entry = new char[ INITSTRBUF_MAX ]; strcpy( entry, "ATZ" ); InitStrings.Add( entry ); SerialDefaults.InitStringIndex = 0; } // Read the entry names in int phonecount = ini.Entry_Count("PhoneBook"); for (int index = 0; index < phonecount; index++) { // Create a new phone book entry phone = new PhoneEntryClass(); // Read the entire entry in ini.Get_String("PhoneBook", ini.Get_Entry("PhoneBook", index), NULL, buf, sizeof(buf)); // Extract name, phone # & serial port settings tokenptr = strtok( buf, "|" ); if (tokenptr) { strcpy( phone->Name, tokenptr ); strupr( phone->Name ); } else { phone->Name[0] = 0; } tokenptr = strtok( NULL, "|" ); if (tokenptr) { strcpy( phone->Number, tokenptr ); strupr( phone->Number ); } else { phone->Number[0] = 0; } tokenptr = strtok( NULL, "|" ); if (tokenptr) { sscanf( tokenptr, "%x", &phone->Settings.Port ); } else { phone->Settings.Port = 0; } tokenptr = strtok( NULL, "|" ); if (tokenptr) { phone->Settings.IRQ = atoi( tokenptr ); } else { phone->Settings.IRQ = -1; } tokenptr = strtok( NULL, "|" ); if (tokenptr) { phone->Settings.Baud = atoi( tokenptr ); } else { phone->Settings.Baud = -1; } phone->Settings.Compression = 0; phone->Settings.ErrorCorrection = 0; phone->Settings.HardwareFlowControl = 1; /* ** Find out if this phonebook entry has the new settings included. If not ** then we need to skip this section. */ tokenptr = strtok( NULL, "|" ); if (tokenptr){ strcpy( buf, tokenptr ); // find dial method for (i = 0; i < DIAL_METHODS; i++) { if ( !strcmpi( buf, DialMethodCheck[ i ]) ) { /* ** This must be an old phonebook entry */ break; } } /* ** Method wasnt found - assume its a new phonebook entry so get the extra settings */ // if method not found set to touch tone if (i == DIAL_METHODS) { phone->Settings.Compression = atoi( tokenptr ); tokenptr = strtok( NULL, "|" ); if (tokenptr) { phone->Settings.ErrorCorrection = atoi( tokenptr ); } tokenptr = strtok( NULL, "|" ); if (tokenptr) { phone->Settings.HardwareFlowControl = atoi( tokenptr ); } tokenptr = strtok( NULL, "|" ); } } if (tokenptr) { strcpy( buf, tokenptr ); // find dial method for (i = 0; i < DIAL_METHODS; i++) { if ( !strcmpi( buf, DialMethodCheck[ i ]) ) { phone->Settings.DialMethod = (DialMethodType)i; break; } } // if method not found set to touch tone if (i == DIAL_METHODS) { phone->Settings.DialMethod = DIAL_TOUCH_TONE; } } else { phone->Settings.DialMethod = DIAL_TOUCH_TONE; } tokenptr = strtok( NULL, "|" ); if (tokenptr) { phone->Settings.InitStringIndex = atoi( tokenptr ); } else { phone->Settings.InitStringIndex = 0; } tokenptr = strtok( NULL, "|" ); if (tokenptr) { phone->Settings.CallWaitStringIndex = atoi( tokenptr ); } else { phone->Settings.CallWaitStringIndex = CALL_WAIT_CUSTOM; } tokenptr = strtok( NULL, "|" ); if (tokenptr) { strcpy (phone->Settings.CallWaitString, tokenptr); } else { phone->Settings.CallWaitString[0] = 0; } // Add it to our list PhoneBook.Add(phone); } // Read special recording playback values, to help find sync bugs TrapFrame = ini.Get_Int("SyncBug", "Frame", 0x7fffffff); ini.Get_String("SyncBug", "Type", "NONE", buf, 80); if (!stricmp(buf,"AIRCRAFT")) TrapObjType = RTTI_AIRCRAFT; else if (!stricmp(buf,"ANIM")) TrapObjType = RTTI_ANIM; else if (!stricmp(buf,"BUILDING")) TrapObjType = RTTI_BUILDING; else if (!stricmp(buf,"BULLET")) TrapObjType = RTTI_BULLET; else if (!stricmp(buf,"INFANTRY")) TrapObjType = RTTI_INFANTRY; else if (!stricmp(buf,"UNIT")) TrapObjType = RTTI_UNIT; else { TrapObjType = RTTI_NONE; } ini.Get_String("SyncBug", "Coord", "0", buf, 80); sscanf(buf,"%x",&TrapCoord); ini.Get_String("SyncBug", "Target", "0", buf, 80); sscanf(buf,"%x",&TrapTarget); ini.Get_String("SyncBug", "Cell", "0", buf, 80); cell = atoi(buf); if (cell) { TrapCell = &(Map[cell]); } TrapPrintCRC = ini.Get_Int("SyncBug", "PrintCRC", 0x7fffffff); } #endif } /*************************************************************************** * SessionClass::Write_MultiPlayer_Settings -- writes settings INI * * * * INPUT: * * none. * * * * OUTPUT: * * none. * * * * WARNINGS: * * none. * * * * HISTORY: * * 02/14/1995 BR : Created. * *=========================================================================*/ void SessionClass::Write_MultiPlayer_Settings (void) { #ifdef NEVER char * buffer; // INI staging buffer pointer. CCFileClass file; int i; char entrytext[4]; char buf[128]; // buffer for parsing INI entry //------------------------------------------------------------------------ // Get a working pointer to the INI staging buffer. Make sure that the // buffer starts cleared out of any data. //------------------------------------------------------------------------ buffer = (char *)_ShapeBuffer; memset(buffer, '\0', _ShapeBufferSize); file.Set_Name(CONFIG_FILE_NAME); if (file.Is_Available()) { file.Open(READ); file.Read(buffer, _ShapeBufferSize-1); file.Close(); } //------------------------------------------------------------------------ // Save the player's last-used Handle & Color //------------------------------------------------------------------------ WWWritePrivateProfileInt("MultiPlayer", "PhoneIndex", CurPhoneIdx, buffer); WWWritePrivateProfileInt ("MultiPlayer", "Color", (int)PrefColor, buffer); WWWritePrivateProfileInt ("MultiPlayer", "Side", House, buffer); WWWritePrivateProfileString("MultiPlayer", "Handle", Handle, buffer); //------------------------------------------------------------------------ // Clear all existing Settings.SerialDefault entries. //------------------------------------------------------------------------ WWWritePrivateProfileString ("SerialDefaults", NULL, NULL, buffer); //------------------------------------------------------------------------ // Save default serial settings in opposite order you want to see them //------------------------------------------------------------------------ WWWritePrivateProfileString("SerialDefaults", "CallWaitString", SerialDefaults.CallWaitString, buffer); WWWritePrivateProfileInt ("SerialDefaults", "CallWaitStringIndex", SerialDefaults.CallWaitStringIndex, buffer); WWWritePrivateProfileInt ("SerialDefaults", "InitStringIndex", SerialDefaults.InitStringIndex, buffer); WWWritePrivateProfileString("SerialDefaults", "DialMethod", DialMethodCheck[ SerialDefaults.DialMethod ], buffer); WWWritePrivateProfileInt ("SerialDefaults", "Baud", SerialDefaults.Baud, buffer); WWWritePrivateProfileInt ("SerialDefaults", "IRQ", SerialDefaults.IRQ, buffer); sprintf(buf, "%x", SerialDefaults.Port); WWWritePrivateProfileString("SerialDefaults", "Port", buf, buffer); WWWritePrivateProfileInt ("SerialDefaults", "Compression", SerialDefaults.Compression , buffer); WWWritePrivateProfileInt ("SerialDefaults", "ErrorCorrection", SerialDefaults.ErrorCorrection, buffer); WWWritePrivateProfileInt ("SerialDefaults", "HardwareFlowControl", SerialDefaults.HardwareFlowControl, buffer); //------------------------------------------------------------------------ // Clear all existing InitString entries. //------------------------------------------------------------------------ WWWritePrivateProfileString ("InitStrings", NULL, NULL, buffer); //------------------------------------------------------------------------ // Save all InitString entries. In descending order so they come out in // ascending order. //------------------------------------------------------------------------ for (i = (InitStrings.Count() - 1); i >= 0; i--) { sprintf( buf, "%03d", i); WWWritePrivateProfileString ("InitStrings", buf, InitStrings[i], buffer); } //------------------------------------------------------------------------ // Clear all existing Phone Book entries. //------------------------------------------------------------------------ WWWritePrivateProfileString ("PhoneBook", NULL, NULL, buffer); //------------------------------------------------------------------------ // Save all Phone Book entries. // Format: Entry=Name,PhoneNum,Port,IRQ,Baud,InitString //------------------------------------------------------------------------ for (i = (PhoneBook.Count() - 1); i >= 0; i--) { sprintf(buf,"%s|%s|%x|%d|%d|%d|%d|%d|%s|%d|%d|%s", PhoneBook[i]->Name, PhoneBook[i]->Number, PhoneBook[i]->Settings.Port, PhoneBook[i]->Settings.IRQ, PhoneBook[i]->Settings.Baud, PhoneBook[i]->Settings.Compression, PhoneBook[i]->Settings.ErrorCorrection, PhoneBook[i]->Settings.HardwareFlowControl, DialMethodCheck[ PhoneBook[i]->Settings.DialMethod ], PhoneBook[i]->Settings.InitStringIndex, PhoneBook[i]->Settings.CallWaitStringIndex, PhoneBook[i]->Settings.CallWaitString); sprintf( entrytext, "%03d", i ); WWWritePrivateProfileString ("PhoneBook", entrytext, buf, buffer); } //------------------------------------------------------------------------ // Write the INI data out to a file. //------------------------------------------------------------------------ file.Open(WRITE); file.Write(buffer,strlen(buffer)); file.Close(); #endif #if (0)//PG INIClass ini; RawFileClass file(CONFIG_FILE_NAME); if (ini.Load(file)) { // Save the player's last-used Handle & Color ini.Put_Int("MultiPlayer", "PhoneIndex", CurPhoneIdx); ini.Put_Int("MultiPlayer", "Color", (int)PrefColor); ini.Put_Int("MultiPlayer", "Side", House); ini.Put_String("MultiPlayer", "Handle", Handle); // Clear all existing Settings.SerialDefault entries. ini.Clear("SerialDefaults"); // Save default serial settings in opposite order you want to see them ini.Put_String("SerialDefaults", "CallWaitString", SerialDefaults.CallWaitString); ini.Put_Int("SerialDefaults", "CallWaitStringIndex", SerialDefaults.CallWaitStringIndex); ini.Put_Int("SerialDefaults", "InitStringIndex", SerialDefaults.InitStringIndex); ini.Put_String("SerialDefaults", "DialMethod", DialMethodCheck[ SerialDefaults.DialMethod ]); ini.Put_Int("SerialDefaults", "Baud", SerialDefaults.Baud); ini.Put_Int("SerialDefaults", "IRQ", SerialDefaults.IRQ); ini.Put_Int("SerialDefaults", "Port", SerialDefaults.Port, 1); ini.Put_String("SerialDefaults", "ModemName", SerialDefaults.ModemName); ini.Put_Int ("SerialDefaults", "Compression", SerialDefaults.Compression ); ini.Put_Int ("SerialDefaults", "ErrorCorrection", SerialDefaults.ErrorCorrection ); ini.Put_Int ("SerialDefaults", "HardwareFlowControl", SerialDefaults.HardwareFlowControl ); // Clear all existing InitString entries. ini.Clear("InitStrings"); // Save all InitString entries. for (int index = 0; index < InitStrings.Count(); index++) { char buf[10]; sprintf( buf, "%03d", index); ini.Put_String("InitStrings", buf, InitStrings[index]); } // Clear all existing Phone Book entries. ini.Clear("PhoneBook"); // Save all Phone Book entries. // Format: Entry=Name,PhoneNum,Port,IRQ,Baud,InitString for (int i = (PhoneBook.Count() - 1); i >= 0; i--) { char buf[128]; char entrytext[10]; sprintf(buf,"%s|%s|%x|%d|%d|%d|%d|%d|%s|%d|%d|%s", PhoneBook[i]->Name, PhoneBook[i]->Number, PhoneBook[i]->Settings.Port, PhoneBook[i]->Settings.IRQ, PhoneBook[i]->Settings.Baud, PhoneBook[i]->Settings.Compression, PhoneBook[i]->Settings.ErrorCorrection, PhoneBook[i]->Settings.HardwareFlowControl, DialMethodCheck[ PhoneBook[i]->Settings.DialMethod ], PhoneBook[i]->Settings.InitStringIndex, PhoneBook[i]->Settings.CallWaitStringIndex, PhoneBook[i]->Settings.CallWaitString); sprintf( entrytext, "%03d", i ); ini.Put_String("PhoneBook", entrytext, buf); } // Write the INI data out to a file. ini.Save(file); } #endif } // Determine if a mission is from counterstrike or aftermath, or either. // Multiplayer maps >24, with a numerical name, are Counterstrike. // Multiplayer maps with an alphabetical name, like SCMJGEA.INI, are Aftermath. bool Is_Mission_Counterstrike (char *file_name) { int scenario_number = 0; if ( isdigit ( file_name[5] )){ sscanf (file_name, "SCM%03d", &scenario_number); } else { #ifdef FIXIT_CSII // checked - ajw 9/28/98 if (!isdigit(file_name[3]) || !isdigit(file_name[4])) { return(false); } #endif sscanf (file_name, "SCM%02d", &scenario_number); } return ( scenario_number > 24 ); } #ifdef FIXIT_CSII // checked - ajw 9/28/98 bool Is_Mission_Aftermath (char *file_name) { // ajw added // Must start with "scm". char szCopy[ _MAX_PATH + 1 ]; strcpy( szCopy, file_name ); _strlwr( szCopy ); if( strstr( szCopy, "scm" ) != szCopy ) return false; if (isdigit(file_name[5])) { return(false); } if ( !isdigit(file_name[3]) || !isdigit(file_name[4]) ) { return (true); } return (false); } /* ** Certain missions are 126x126 size, and those can't be downloaded to a ** non-Aftermath player, so this function checks to see if the map in ** question is one of those. We'll know that by the file name: if it's ** K0 -> M9, it's 126x126. */ bool Is_Mission_126x126 (char *file_name) // This is no longer used. ajw { if (isdigit(file_name[5])) { return(false); } if ( (file_name[3] >= 'k' && file_name[3] <= 'm') || (file_name[3] >= 'K' && file_name[3] <= 'M') ) { return (true); } return (false); } #endif /*************************************************************************** * SessionClass::Read_Scenario_Descriptions -- reads scen. descriptions * * * * INPUT: * * none. * * * * OUTPUT: * * none. * * * * WARNINGS: * * none. * * * * HISTORY: * * 02/14/1995 BR : Created. * * 09/10/1996 JLB : Searches using different method. * *=========================================================================*/ void SessionClass::Read_Scenario_Descriptions (void) { // Clear the scenario description lists Scenarios.Clear(); /* ** Fetch the main multiplayer scenario packet data. */ CCFileClass file("MISSIONS.PKT"); if (file.Is_Available()) { INIClass ini; ini.Load(file); int count = ini.Entry_Count("Missions"); //debugprint( "Found %i missions in Missions.pkt\n", count ); for (int index = 0; index < count; index++) { char const * fname = ini.Get_Entry("Missions", index); char buffer[128]; ini.Get_String("Missions", fname, "", buffer, sizeof(buffer)); #ifdef FIXIT_VERSION_3 Scenarios.Add(new MultiMission(fname, buffer, NULL, true, Is_Mission_Counterstrike ((char*)fname))); #else // FIXIT_VERSION_3 #ifdef FIXIT_CSII // checked - ajw bool official = Is_Mission_126x126( (char *)fname); if (!official) { official = !Is_Mission_Aftermath((char *)fname); } Scenarios.Add(new MultiMission(fname, buffer, NULL, official, Is_Mission_Counterstrike ((char*)fname))); #else Scenarios.Add(new MultiMission(fname, buffer, NULL, true, Is_Mission_Counterstrike ((char*)fname))); #endif #endif // FIXIT_VERSION_3 } /* // ajw Copy file for viewing. CCFileClass fileCopy( "msns_pkt.txt" ); file.Seek( 0, SEEK_SET ); long lSize = file.Size(); char* pData = new char[ lSize + 1 ]; file.Read( pData, lSize ); fileCopy.Write( pData, lSize ); fileCopy.Close(); */ } /* ** Fetch any scenario packet lists and apply them first. */ #ifdef WIN32 WIN32_FIND_DATA block; HANDLE handle = FindFirstFile("*.PKT", &block); while (handle != INVALID_HANDLE_VALUE) { if ((block.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY)) == 0) { char const * name = &block.cAlternateFileName[0]; if (*name == '\0') name = &block.cFileName[0]; //Mono_Printf("Found file '%s'.\n", block.cAlternateFileName); //Mono_Printf("Found file '%s'.\n", block.cFileName); //debugprint("Found file '%s'.\n", block.cAlternateFileName); //debugprint("Found file '%s'.\n", block.cFileName); //debugprint( "Found alternate PKT file.\n" ); CCFileClass file(name); INIClass ini; ini.Load(file); int count = ini.Entry_Count("Missions"); for (int index = 0; index < count; index++) { char const * fname = ini.Get_Entry("Missions", index); char buffer[128]; ini.Get_String("Missions", fname, "", buffer, sizeof(buffer)); #ifdef FIXIT_VERSION_3 Scenarios.Add(new MultiMission(fname, buffer, NULL, true, Is_Mission_Counterstrike ((char*)fname))); #else // FIXIT_VERSION_3 #ifdef FIXIT_CSII // checked - ajw bool official = Is_Mission_126x126( (char *)fname); if (!official) { official = !Is_Mission_Aftermath((char *)fname); } Scenarios.Add(new MultiMission(fname, buffer, NULL, official, Is_Mission_Counterstrike ((char*)fname))); #else Scenarios.Add(new MultiMission(fname, buffer, NULL, true, Is_Mission_Counterstrike ((char*)fname))); #endif #endif // FIXIT_VERSION_3 } } if (FindNextFile(handle, &block) == 0) break; } #ifdef FIXIT_CSII // checked - ajw /* ** Fetch the Counterstrike multiplayer scenario packet data. ** Load the scenarios regardless of whether counterstrike's installed, ** and at the point of hosting a network game, enable the counterstrike ** maps only if they have CS installed. If they don't, then the maps ** are available as a guest, but not as a host, which fixes a multitude ** of problems without obviously giving the maps away to non-CS owners. */ #ifdef FIXIT_VERSION_3 if( Is_Counterstrike_Installed() ) { #endif CCFileClass file2("CSTRIKE.PKT"); if (file2.Is_Available()) { INIClass ini; ini.Load(file2); int count = ini.Entry_Count("Missions"); //debugprint( "Found %i missions in cstrike.pkt\n", count ); for (int index = 0; index < count; index++) { char const * fname = ini.Get_Entry("Missions", index); char buffer[128]; ini.Get_String("Missions", fname, "", buffer, sizeof(buffer)); #ifdef FIXIT_VERSION_3 Scenarios.Add(new MultiMission(fname, buffer, NULL, true, Is_Mission_Counterstrike ((char*)fname))); #else bool official = Is_Mission_126x126( (char *)fname); if (!official) { official = !Is_Mission_Aftermath((char *)fname); } Scenarios.Add(new MultiMission(fname, buffer, NULL, official, Is_Mission_Counterstrike ((char*)fname))); #endif } /* // ajw Copy file for viewing. CCFileClass fileCopy( "cs_pkt.txt" ); file2.Seek( 0, SEEK_SET ); long lSize = file2.Size(); char* pData = new char[ lSize + 1 ]; file2.Read( pData, lSize ); fileCopy.Write( pData, lSize ); fileCopy.Close(); */ } #ifdef FIXIT_VERSION_3 } #endif #endif #ifdef FIXIT_VERSION_3 // Aftermath scenarios are now in their own pkt file. if( Is_Aftermath_Installed() ) { CCFileClass file2("AFTMATH.PKT"); if (file2.Is_Available()) { INIClass ini; ini.Load(file2); int count = ini.Entry_Count("Missions"); //debugprint( "Found %i missions in aftmath.pkt\n", count ); for (int index = 0; index < count; index++) { char const * fname = ini.Get_Entry("Missions", index); char buffer[128]; ini.Get_String("Missions", fname, "", buffer, sizeof(buffer)); Scenarios.Add(new MultiMission(fname, buffer, NULL, true, Is_Mission_Counterstrike ((char*)fname))); } } } #endif /* ** Scan the current directory for any loose .MPR files and build the appropriate entries ** into the scenario list list */ char const * file_name; char name_buffer[128]; char digest_buffer[32]; handle = FindFirstFile ( "*.MPR" , &block ); while (handle != INVALID_HANDLE_VALUE) { if ((block.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY)) == 0) { file_name = &block.cAlternateFileName[0]; if (*file_name == '\0') file_name = &block.cFileName[0]; //debugprint( "Found MPR '%s'\n", file_name ); CCFileClass file(file_name); INIClass ini; ini.Load(file); ini.Get_String ("Basic", "Name", "No Name", name_buffer, sizeof (name_buffer) ); ini.Get_String ("Digest", "1", "No Digest", digest_buffer, sizeof (digest_buffer) ); Scenarios.Add (new MultiMission (file_name, name_buffer, digest_buffer,ini.Get_Bool("Basic", "Official", false), false )); } if (FindNextFile(handle, &block) == 0) break; } #else //WIN32 #error What? You think you can still build the DOS version after all this time? char name_buffer[128]; char digest_buffer[32]; struct find_t block; if (_dos_findfirst("*.PKT", _A_NORMAL, &block) == 0) { do { CCFileClass file(block.name); INIClass ini; ini.Load(file); int count = ini.Entry_Count("Missions"); for (int index = 0; index < count; index++) { char const * fname = ini.Get_Entry("Missions", index); char buffer[128]; ini.Get_String("Missions", fname, "", buffer, sizeof(buffer)); #ifdef FIXIT_CSII bool official = Is_Mission_126x126( (char *)fname); if (!official) { official = !Is_Mission_Aftermath((char *)fname); } Scenarios.Add(new MultiMission(fname, buffer, NULL, official, Is_Mission_Counterstrike ((char*)fname))); #else Scenarios.Add(new MultiMission(fname, buffer, NULL, true, Is_Mission_Counterstrike ((char*)fname))); #endif } } while(_dos_findnext(&block) == 0); } /* ** Scan the current directory for any loose .MPR files and build the appropriate entries ** into the scenario list list */ if (_dos_findfirst("*.MPR", _A_NORMAL, &block) == 0) { do { CCFileClass file(block.name); INIClass ini; ini.Load(file); ini.Get_String ("Basic", "Name", "No Name", name_buffer, sizeof (name_buffer) ); ini.Get_String ("Digest", "1", "No Digest", digest_buffer, sizeof (digest_buffer) ); bool official = ini.Get_Bool("Basic", "Official", false); Scenarios.Add (new MultiMission (block.name, name_buffer, digest_buffer, official, false )); } while(_dos_findnext(&block) == 0); } #ifdef FIXIT_CSII /* ** Fetch the Counterstrike multiplayer scenario packet data. ** Load the scenarios regardless of whether counterstrike's installed, ** and at the point of hosting a network game, enable the counterstrike ** maps only if they have CS installed. If they don't, then the maps ** are available as a guest, but not as a host, which fixes a multitude ** of problems without obviously giving the maps away to non-CS owners. */ // if (Is_Counterstrike_Installed()) { CCFileClass file2("CSTRIKE.PKT"); if (file2.Is_Available()) { INIClass ini; ini.Load(file2); int count = ini.Entry_Count("Missions"); for (int index = 0; index < count; index++) { char const * fname = ini.Get_Entry("Missions", index); char buffer[128]; ini.Get_String("Missions", fname, "", buffer, sizeof(buffer)); bool official = Is_Mission_126x126( (char *)fname); if (!official) { official = !Is_Mission_Aftermath((char *)fname); } Scenarios.Add(new MultiMission(fname, buffer, NULL, official, Is_Mission_Counterstrike ((char*)fname))); } } // } #endif #endif //WIN32 } /*************************************************************************** * SessionClass::Free_Scenario_Descriptions -- frees scen. descriptions * * * * INPUT: * * none. * * * * OUTPUT: * * none. * * * * WARNINGS: * * none. * * * * HISTORY: * * 06/05/1995 BRR : Created. * *=========================================================================*/ void SessionClass::Free_Scenario_Descriptions(void) { int i; //------------------------------------------------------------------------ // Clear the scenario descriptions & filenames //------------------------------------------------------------------------ for (int index = 0; index < Scenarios.Count(); index++) { delete Scenarios[index]; } Scenarios.Clear(); // Filenum.Clear(); //------------------------------------------------------------------------ // Clear the initstring entries //------------------------------------------------------------------------ for (i = 0; i < InitStrings.Count(); i++) { delete InitStrings[i]; } InitStrings.Clear(); #if (0)//PG //------------------------------------------------------------------------ // Clear the dialing entries //------------------------------------------------------------------------ for (i = 0; i < PhoneBook.Count(); i++) { delete PhoneBook[i]; } PhoneBook.Clear(); #endif } /* end of Free_Scenario_Descriptions */ /*************************************************************************** * SessionClass::Trap_Object -- searches for an object, for debugging * * * * INPUT: * * none. * * * * OUTPUT: * * none. * * * * WARNINGS: * * none. * * * * HISTORY: * * 06/02/1995 BRR : Created. * *=========================================================================*/ void SessionClass::Trap_Object(void) { int i; //------------------------------------------------------------------------ // Initialize //------------------------------------------------------------------------ TrapObject.Ptr.All = NULL; //------------------------------------------------------------------------ // Search for the object based upon its type, then its coordinate or // 'this' pointer value. //------------------------------------------------------------------------ switch (TrapObjType) { case RTTI_AIRCRAFT: for (i = 0; i < Aircraft.Count(); i++) { if (Aircraft.Ptr(i)->Coord == TrapCoord || Aircraft.Ptr(i)->As_Target()==TrapTarget) { TrapObject.Ptr.Aircraft = Aircraft.Ptr(i); break; } } break; case RTTI_ANIM: for (i = 0; i < Anims.Count(); i++) { if (Anims.Ptr(i)->Coord == TrapCoord || Anims.Ptr(i)->As_Target()==TrapTarget) { TrapObject.Ptr.Anim = Anims.Ptr(i); break; } } break; case RTTI_BUILDING: for (i = 0; i < Buildings.Count(); i++) { if (Buildings.Ptr(i)->Coord == TrapCoord || Buildings.Ptr(i)->As_Target()==TrapTarget) { TrapObject.Ptr.Building = Buildings.Ptr(i); break; } } break; case RTTI_BULLET: for (i = 0; i < Bullets.Count(); i++) { if (Bullets.Ptr(i)->Coord == TrapCoord || Bullets.Ptr(i)->As_Target()==TrapTarget) { TrapObject.Ptr.Bullet = Bullets.Ptr(i); break; } } break; case RTTI_INFANTRY: for (i = 0; i < Infantry.Count(); i++) { if (Infantry.Ptr(i)->Coord == TrapCoord || Infantry.Ptr(i)->As_Target()==TrapTarget) { TrapObject.Ptr.Infantry = Infantry.Ptr(i); break; } } break; case RTTI_UNIT: for (i = 0; i < Units.Count(); i++) { if (Units.Ptr(i)->Coord == TrapCoord || Units.Ptr(i)->As_Target()==TrapTarget) { TrapObject.Ptr.Unit = Units.Ptr(i); break; } } break; //..................................................................... // Last-ditch find-the-object-right-now-darnit loop //..................................................................... case RTTI_NONE: for (i = 0; i < Aircraft.Count(); i++) { if (Aircraft.Raw_Ptr(i)->Coord == TrapCoord || Aircraft.Raw_Ptr(i)->As_Target()==TrapTarget) { TrapObject.Ptr.Aircraft = Aircraft.Raw_Ptr(i); TrapObjType = RTTI_AIRCRAFT; return; } } for (i = 0; i < Anims.Count(); i++) { if (Anims.Raw_Ptr(i)->Coord == TrapCoord || Anims.Raw_Ptr(i)->As_Target()==TrapTarget) { TrapObject.Ptr.Anim = Anims.Raw_Ptr(i); TrapObjType = RTTI_ANIM; return; } } for (i = 0; i < Buildings.Count(); i++) { if (Buildings.Raw_Ptr(i)->Coord == TrapCoord || Buildings.Raw_Ptr(i)->As_Target()==TrapTarget) { TrapObject.Ptr.Building = Buildings.Raw_Ptr(i); TrapObjType = RTTI_BUILDING; return; } } for (i = 0; i < Bullets.Count(); i++) { if (Bullets.Raw_Ptr(i)->Coord == TrapCoord || Bullets.Raw_Ptr(i)->As_Target()==TrapTarget) { TrapObject.Ptr.Bullet = Bullets.Raw_Ptr(i); TrapObjType = RTTI_BULLET; return; } } for (i = 0; i < Infantry.Count(); i++) { if (Infantry.Raw_Ptr(i)->Coord == TrapCoord || Infantry.Raw_Ptr(i)->As_Target()==TrapTarget) { TrapObject.Ptr.Infantry = Infantry.Raw_Ptr(i); TrapObjType = RTTI_INFANTRY; return; } } for (i = 0; i < Units.Count(); i++) { if (Units.Raw_Ptr(i)->Coord == TrapCoord || Units.Raw_Ptr(i)->As_Target()==TrapTarget) { TrapObject.Ptr.Unit = Units.Raw_Ptr(i); TrapObjType = RTTI_UNIT; return; } } default: break; } } /*************************************************************************** * SessionClass::Compute_Unique_ID -- computes unique local ID number * * * * INPUT: * * none. * * * * OUTPUT: * * none. * * * * WARNINGS: * * none. * * * * HISTORY: * * 12/07/1995 BRR : Created. * *=========================================================================*/ unsigned long SessionClass::Compute_Unique_ID(void) { return 1;//PG #if (0) //PG time_t tm; unsigned long id; struct diskfree_t dtable; char *path; int i; //------------------------------------------------------------------------ // Start with the seconds since Jan 1, 1970 (system local time) //------------------------------------------------------------------------ time(&tm); id = (unsigned long)tm; //------------------------------------------------------------------------ // Now add in the free space on the hard drive //------------------------------------------------------------------------ if (_dos_getdiskfree(3, &dtable) == 0) { Add_CRC(&id, (unsigned long)dtable.avail_clusters); Add_CRC(&id, (unsigned long)dtable.total_clusters); Add_CRC(&id, (unsigned long)dtable.bytes_per_sector); Add_CRC(&id, (unsigned long)dtable.sectors_per_cluster); } //------------------------------------------------------------------------ // Add in every byte in the user's path environment variable //------------------------------------------------------------------------ path = getenv("PATH"); if (path) { for (i = 0; i < strlen(path); i++) { Add_CRC(&id, (unsigned long)path[i]); } } return (id); #endif } // end of Compute_Unique_ID MultiMission::MultiMission(char const * filename, char const * description, char const * digest, bool official, bool expansion) { Set_Filename(filename); Set_Description(description); Set_Digest(digest); Set_Official(official); Set_Expansion(expansion); } void MultiMission::Draw_It(int , int x, int y, int width, int height, bool selected, TextPrintType flags) const { RemapControlType * scheme = GadgetClass::Get_Color_Scheme(); static int _tabs[] = {35, 60, 80, 100}; if ((flags & 0x0F) == TPF_6PT_GRAD || (flags & 0x0F) == TPF_EFNT) { if (selected) { flags = flags | TPF_BRIGHT_COLOR; LogicPage->Fill_Rect(x, y, x + width - 1, y + height - 1, scheme->Shadow); } else { if (!(flags & TPF_USE_GRAD_PAL)) { flags = flags | TPF_MEDIUM_COLOR; } } Conquer_Clip_Text_Print(ScenarioDescription, x, y, scheme, TBLACK, flags, width, _tabs); } else { Conquer_Clip_Text_Print(ScenarioDescription, x, y, (selected ? &ColorRemaps[PCOLOR_DIALOG_BLUE] : &ColorRemaps[PCOLOR_GREY]), TBLACK, flags, width, _tabs); } } void MultiMission::Set_Description(char const * description) { if (description != NULL) { strncpy(ScenarioDescription, description, ARRAY_SIZE(ScenarioDescription)); ScenarioDescription[ARRAY_SIZE(ScenarioDescription)-1] = '\0'; } } void MultiMission::Set_Filename(char const * filename) { if (filename != NULL) { strncpy(Filename, filename, ARRAY_SIZE(Filename)); Filename[ARRAY_SIZE(Filename)-1] = '\0'; } } void MultiMission::Set_Digest(char const * digest) { if (digest != NULL) { strncpy(Digest, digest, ARRAY_SIZE(Digest)); Digest[ARRAY_SIZE(Digest)-1] = '\0'; } else { strcpy( Digest, "NODIGEST" ); } } void MultiMission::Set_Official (bool official) { IsOfficial = official; } void MultiMission::Set_Expansion (bool expansion) { IsExpansion = expansion; } /************************** end of session.cpp *****************************/