SESSION.CPP 69 KB

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