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 *****************************/