EXPAND.CPP 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  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. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: /CounterStrike/EXPAND.CPP 7 3/17/97 1:05a Steve_tall $ */
  15. /***********************************************************************************************
  16. *** 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 ***
  17. ***********************************************************************************************
  18. * *
  19. * Project Name : Command & Conquer *
  20. * *
  21. * File Name : EXPAND.CPP *
  22. * *
  23. * Programmer : Joe L. Bostic *
  24. * *
  25. * Start Date : 11/03/95 *
  26. * *
  27. * Last Update : Mar 01, 1997 [V.Grippi] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * EListClass::Draw_Entry -- Draws entry for expansion scenario. *
  32. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  33. #include "function.h"
  34. #ifdef FIXIT_VERSION_3
  35. #include "WolStrng.h"
  36. #endif
  37. //#define CS_DEBUG
  38. #define ARRAYOFFSET 20
  39. /***********************************************************************************************
  40. * Expansion_CS_Present -- Is the Counterstrike expansion available? *
  41. * *
  42. * *
  43. * *
  44. * INPUT: Nothing *
  45. * *
  46. * OUTPUT: true if counterstrike installed *
  47. * *
  48. * WARNINGS: None *
  49. * *
  50. * HISTORY: *
  51. * 3/5/97 1:59PM ST : Fixed to check for EXPAND.MIX *
  52. *=============================================================================================*/
  53. bool Expansion_CS_Present(void)
  54. {
  55. // ajw 9/29/98
  56. return Is_Counterstrike_Installed();
  57. // RawFileClass file("EXPAND.MIX");
  58. // return(file.Is_Available());
  59. }
  60. #ifdef FIXIT_CSII // checked - ajw 9/28/98
  61. /***********************************************************************************************
  62. * Expansion_AM_Present -- Is the Aftermath expansion available? *
  63. * *
  64. * *
  65. * *
  66. * INPUT: Nothing *
  67. * *
  68. * OUTPUT: true if AfterMath is installed *
  69. * *
  70. * WARNINGS: None *
  71. * *
  72. * HISTORY: *
  73. * 7/9/97 1:59PM BG : Fixed to check for EXPAND2.MIX *
  74. *=============================================================================================*/
  75. bool Expansion_AM_Present(void)
  76. {
  77. // ajw 9/29/98
  78. return Is_Aftermath_Installed();
  79. // RawFileClass file("EXPAND2.MIX");
  80. // return(file.Is_Available());
  81. }
  82. #endif
  83. const char* ExpandNames[] = {
  84. "SCG20EA",
  85. "SCG21EA",
  86. "SCG22EA",
  87. "SCG23EA",
  88. "SCG24EA",
  89. "SCG26EA",
  90. "SCG27EA",
  91. "SCG28EA",
  92. "SCU31EA",
  93. "SCU32EA",
  94. "SCU33EA",
  95. "SCU34EA",
  96. "SCU35EA",
  97. "SCU36EA",
  98. "SCU37EA",
  99. "SCU38EA",
  100. #ifdef FIXIT_CSII // checked - ajw 9/28/98
  101. "SCG43EA", // Harbor Reclamation
  102. "SCG41EA", // In the nick of time
  103. "SCG40EA", // Caught in the act
  104. "SCG42EA", // Production Disruption
  105. "SCG47EA", // Negotiations
  106. "SCG45EA", // Monster Tank Madness
  107. "SCG44EA", // Time Flies
  108. "SCG48EA", // Absolut MADness
  109. "SCG46EA", // Pawn
  110. "SCU43EA", // Testing Grounds
  111. "SCU40EA", // Shock Therapy
  112. "SCU42EA", // Let's Make a Steal
  113. "SCU41EA", // Test Drive
  114. "SCU45EA", // Don't Drink The Water
  115. "SCU44EA", // Situation Critical
  116. "SCU46EA", // Brothers in Arms
  117. "SCU47EA", // Deus Ex Machina
  118. "SCU48EA", // Grunyev Revolution
  119. #endif
  120. NULL
  121. };
  122. const char* TestNames2[] = {
  123. "SCG01EA",
  124. "SCG02EA",
  125. "SCG03EA",
  126. "SCG04EA",
  127. "SCG05EA",
  128. "SCG06EA",
  129. "SCG07EA",
  130. "SCG08EA",
  131. "SCU01EA",
  132. "SCU02EA",
  133. "SCU03EA",
  134. "SCU04EA",
  135. "SCU05EA",
  136. "SCU06EA",
  137. "SCU07EA",
  138. "SCU08EA",
  139. "SCU09EA",
  140. NULL
  141. };
  142. #ifdef GERMAN
  143. const char* XlatNames[] = {
  144. "Zusammenstoss",
  145. "Unter Tage",
  146. "Kontrollierte Verbrennung",
  147. "Griechenland 1 - Stavros",
  148. "Griechenland 2 - Evakuierung",
  149. "Sibirien 1 - Frische Spuren",
  150. "Sibirien 2 - In der Falle",
  151. "Sibirien 3 - Wildnis",
  152. "Das Feld der Ehre",
  153. "Belagerung",
  154. "Mausefalle",
  155. "Teslas Erbe",
  156. "Soldat Volkov",
  157. "Die Spitze der Welt",
  158. "Paradoxe Gleichung",
  159. "Nukleare Eskalation",
  160. #ifdef FIXIT_CSII // checked - ajw 9/28/98
  161. "Ein sicherer Hafen", // "SCG43EA", // Harbor Reclamation
  162. "Zeitkritische Routine", // "SCG41EA", // In the nick of time
  163. "Auf frischer Tat ertappt", // "SCG40EA", // Caught in the act
  164. "Drastischer Baustopp", // "SCG42EA", // Production Disruption
  165. "Harte Verhandlungen", // "SCG47EA", // Negotiations
  166. "Ferngelenktes Kriegsspielzeug",// "SCG45EA", // Monster Tank Madness
  167. "Licht aus", // "SCG44EA", // Time Flies
  168. "Molekulare Kriegsf�hrung", // "SCG48EA", // Absolut MADness
  169. "Bauernopfer", // "SCG46EA", // Pawn
  170. "Testgel„nde", // "SCU43EA", // Testing Grounds
  171. "Schocktherapie", // "SCU40EA", // Shock Therapy
  172. "Der Letzte seiner Art", // "SCU42EA", // Let's Make a Steal
  173. "Probefahrt", // "SCU41EA", // Test Drive
  174. "Schlaftrunk", // "SCU45EA", // Don't Drink The Water
  175. "Der j�ngste Tag", // "SCU44EA", // Situation Critical
  176. "Waffenbr�der", // "SCU46EA", // Brothers in Arms
  177. "Deus Ex Machina", // "SCU47EA", // Deus Ex Machina
  178. "Die Replikanten von Grunyev", // "SCU48EA", // Grunyev Revolution
  179. #endif
  180. NULL
  181. };
  182. #endif
  183. #ifdef FRENCH
  184. const char* XlatNames[] = {
  185. "Gaz Sarin 1: Ravitaillement Fatal",
  186. "Gaz Sarin 2: En Sous-sol",
  187. "Gaz Sarin 3: Attaque Chirurgicale",
  188. "GrŠce Occup‚e 1: Guerre Priv‚e",
  189. "GrŠce Occup‚e 2: Evacuation",
  190. "Conflit Sib‚rien 1: Traces FraŒches",
  191. "Conflit Sib‚rien 2: Pris au PiŠge",
  192. "Conflit Sib‚rien 3: Terres de Glace",
  193. "Mise … l'Epreuve",
  194. "Assi‚g‚s",
  195. "La SouriciŠre",
  196. "L'H‚ritage de Tesla",
  197. "Tandem de Choc",
  198. "Jusqu'au Sommet du Monde",
  199. "Effets Secondaires",
  200. "Intensification nucl‚aire",
  201. #ifdef FIXIT_CSII // checked - ajw 9/28/98
  202. "Le vieux port", // "SCG43EA", // Harbor Reclamation
  203. "Juste … temps", // "SCG41EA", // In the nick of time
  204. "La main dans le sac", // "SCG40EA", // Caught in the act
  205. "Production interrompue", // "SCG42EA", // Production Disruption
  206. "N‚gociations", // "SCG47EA", // Negotiations
  207. "Tanks en folie!", // "SCG45EA", // Monster Tank Madness
  208. "Le temps passe", // "SCG44EA", // Time Flies
  209. "D‚mence absolue", // "SCG48EA", // Absolut MADness
  210. "Le pion", // "SCG46EA", // Pawn
  211. "Terrains d'essais", // "SCU43EA", // Testing Grounds
  212. "Th‚rapie de choc", // "SCU40EA", // Shock Therapy
  213. "Au voleur!", // "SCU42EA", // Let's Make a Steal
  214. "Essai de conduite", // "SCU41EA", // Test Drive
  215. "Ne buvez pas la tasse", // "SCU45EA", // Don't Drink The Water
  216. "Situation critique", // "SCU44EA", // Situation Critical
  217. "FrŠres d'armes", // "SCU46EA", // Brothers in Arms
  218. "Deus Ex Machina", // "SCU47EA", // Deus Ex Machina
  219. "La R‚volution de Grunyev",// "SCU48EA", // Grunyev Revolution
  220. #endif
  221. NULL,
  222. };
  223. #endif
  224. #ifndef WIN32 //VG
  225. #define OPTION_WIDTH 236
  226. #ifdef FIXIT_CSII // checked - ajw 9/28/98
  227. #error Can never again build without WIN32 defined.
  228. #define OPTION_HEIGHT 162
  229. #else
  230. #define OPTION_HEIGHT 162
  231. #endif
  232. #define OPTION_X ((320 - OPTION_WIDTH) / 2)
  233. #define OPTION_Y (200 - OPTION_HEIGHT) / 2
  234. #else
  235. #define OPTION_WIDTH 560
  236. #ifdef FIXIT_CSII // checked - ajw 9/28/98
  237. #define OPTION_HEIGHT 332
  238. #else
  239. #define OPTION_HEIGHT 300
  240. #endif
  241. #define OPTION_X ((640 - OPTION_WIDTH) / 2)
  242. #define OPTION_Y (400 - OPTION_HEIGHT) / 2
  243. #endif
  244. struct EObjectClass
  245. {
  246. HousesType House;
  247. int Scenario;
  248. char Name[128];
  249. char FullName[128];
  250. };
  251. /*
  252. ** Derived from list class to handle expansion scenario listings. The listings
  253. ** are recorded as EObjectClass objects. The data contained specifies the scenario
  254. ** number, side, and text description.
  255. */
  256. class EListClass : public ListClass
  257. {
  258. public:
  259. EListClass(int id, int x, int y, int w, int h, TextPrintType flags, void const * up, void const * down) :
  260. ListClass(id, x, y, w, h, flags, up, down) {};
  261. virtual int Add_Object(EObjectClass * obj) {
  262. return(ListClass::Add_Item((char const *)obj));
  263. }
  264. virtual EObjectClass * Get_Object(int index) const {
  265. return((EObjectClass *)ListClass::Get_Item(index));
  266. }
  267. virtual EObjectClass * Current_Object(void) {
  268. return((EObjectClass *)ListClass::Current_Item());
  269. }
  270. protected:
  271. virtual void Draw_Entry(int index, int x, int y, int width, int selected);
  272. private:
  273. virtual int Add_Item(char const * text) {return(ListClass::Add_Item(text));};
  274. virtual int Add_Item(int text) {return(ListClass::Add_Item(text));};
  275. virtual char const * Current_Item(void) const {return(ListClass::Current_Item());};
  276. virtual char const * Get_Item(int index) const {return(ListClass::Get_Item(index));};
  277. };
  278. /***********************************************************************************************
  279. * EListClass::Draw_Entry -- Draws entry for expansion scenario. *
  280. * *
  281. * This overrides the normal list class draw action so that the scenario name will be *
  282. * displayed along with the house name. *
  283. * *
  284. * INPUT: index -- The index of the entry that should be drawn. *
  285. * *
  286. * x,y -- Coordinate of upper left region to draw the entry into. *
  287. * *
  288. * width -- Width of region (pixels) to draw the entry. *
  289. * *
  290. * selected -- Is this entry considered selected? *
  291. * *
  292. * OUTPUT: none *
  293. * *
  294. * WARNINGS: none *
  295. * *
  296. * HISTORY: *
  297. * 11/17/1995 JLB : Created. *
  298. *=============================================================================================*/
  299. void EListClass::Draw_Entry(int index, int x, int y, int width, int selected)
  300. {
  301. char buffer[128];
  302. RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
  303. int text = TXT_NONE;
  304. if (Get_Object(index)->House == HOUSE_GOOD) {
  305. text = TXT_ALLIES;
  306. } else {
  307. text = TXT_SOVIET;
  308. }
  309. sprintf(buffer, "%s: %s", Text_String(text), Get_Object(index)->Name);
  310. TextPrintType flags = TextFlags;
  311. if (selected) {
  312. flags = flags | TPF_BRIGHT_COLOR;
  313. LogicPage->Fill_Rect (x, y, x + width - 1, y + LineHeight - 1, 1);
  314. } else {
  315. if (!(flags & TPF_USE_GRAD_PAL)) {
  316. flags = flags | TPF_MEDIUM_COLOR;
  317. }
  318. }
  319. #ifndef WIN32
  320. Conquer_Clip_Text_Print(buffer, x, y, scheme, TBLACK, flags & ~(TPF_CENTER), width, Tabs);
  321. #else
  322. Conquer_Clip_Text_Print(buffer, x + 100, y, scheme, TBLACK, flags & ~(TPF_CENTER), width, Tabs);
  323. #endif
  324. }
  325. #ifdef FIXIT_VERSION_3
  326. bool Expansion_Dialog( bool bCounterstrike ) // If not bCounterstrike, then this was called for Aftermath.
  327. #else
  328. bool Expansion_Dialog(void)
  329. #endif
  330. {
  331. GadgetClass * buttons = NULL;
  332. #ifndef WIN32
  333. TextButtonClass ok(200, TXT_OK, TPF_BUTTON, OPTION_X+40, OPTION_Y+OPTION_HEIGHT-15);
  334. TextButtonClass cancel(201, TXT_CANCEL, TPF_BUTTON, OPTION_X+OPTION_WIDTH-85, OPTION_Y+OPTION_HEIGHT-15);
  335. #else
  336. TextButtonClass ok(200, TXT_OK, TPF_BUTTON, OPTION_X+40, OPTION_Y + OPTION_HEIGHT - 50 );
  337. TextButtonClass cancel(201, TXT_CANCEL, TPF_BUTTON, OPTION_X+OPTION_WIDTH-85, OPTION_Y + OPTION_HEIGHT - 50 );
  338. #endif
  339. #ifndef WIN32
  340. EListClass list(202, OPTION_X + 20, OPTION_Y+20, OPTION_WIDTH-40, OPTION_HEIGHT-40, TPF_BUTTON, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP"));
  341. #else
  342. EListClass list(202, OPTION_X+35, OPTION_Y + 30, OPTION_WIDTH-70, OPTION_HEIGHT - 85, TPF_BUTTON, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP"));
  343. #endif
  344. buttons = &ok;
  345. cancel.Add(*buttons);
  346. list.Add(*buttons);
  347. /*
  348. ** Add in all the expansion scenarios.
  349. */
  350. CCFileClass file;
  351. char buffer[128], buffer2[128];
  352. char * sbuffer = (char*)_ShapeBuffer;
  353. #ifdef FIXIT_CSII // checked - ajw 9/28/98 - Though disgusted.
  354. for (int index = 20; index < (36+18); index++) {
  355. #else
  356. for (int index = 20; index < 36; index++) {
  357. #endif
  358. #ifndef CS_DEBUG
  359. strcpy(buffer,ExpandNames[index - 20]);
  360. strcpy(buffer2, ExpandNames[index - 20]);
  361. #else
  362. strcpy(buffer, TestNames2[index]);
  363. strcpy(buffer2, TestNames2[index]);
  364. #endif
  365. if(buffer[0] == NULL)
  366. break;
  367. strcat(buffer, ".INI");
  368. strcat(buffer2, ".INI");
  369. Scen.Set_Scenario_Name(buffer);
  370. Scen.Scenario = index;
  371. file.Set_Name(buffer);
  372. #ifdef FIXIT_VERSION_3
  373. bool bOk;
  374. if( index < 36 )
  375. bOk = bCounterstrike;
  376. else
  377. bOk = !bCounterstrike;
  378. if( bOk && file.Is_Available() )
  379. {
  380. #else // FIXIT_VERSION_3
  381. if (file.Is_Available()) {
  382. #endif // FIXIT_VERSION_3
  383. EObjectClass * obj = new EObjectClass;
  384. switch(buffer[2]){
  385. case 'G':
  386. case 'g':
  387. file.Read(sbuffer, 2000);
  388. sbuffer[2000] = '\r';
  389. sbuffer[2000+1] = '\n';
  390. sbuffer[2000+2] = '\0';
  391. WWGetPrivateProfileString("Basic", "Name", "x", buffer, sizeof(buffer), sbuffer);
  392. #if defined(GERMAN) || defined(FRENCH)
  393. strcpy(obj->Name, XlatNames[index - ARRAYOFFSET]);
  394. #else
  395. strcpy(obj->Name, buffer);
  396. #endif
  397. // strcpy(obj->Name, buffer);
  398. strcpy(obj->FullName, buffer2);
  399. obj->House = HOUSE_GOOD;
  400. obj->Scenario = index;
  401. list.Add_Object(obj);
  402. break;
  403. case 'U':
  404. case 'u':
  405. file.Read(sbuffer, 2000);
  406. sbuffer[2000] = '\r';
  407. sbuffer[2000+1] = '\n';
  408. sbuffer[2000+2] = '\0';
  409. WWGetPrivateProfileString("Basic", "Name", "x", buffer, sizeof(buffer), sbuffer);
  410. #if defined(GERMAN) || defined(FRENCH)
  411. strcpy(obj->Name, XlatNames[index - ARRAYOFFSET]);
  412. #else
  413. strcpy(obj->Name, buffer);
  414. #endif
  415. // strcpy(obj->Name, buffer);
  416. strcpy(obj->FullName, buffer2);
  417. obj->House = HOUSE_BAD;
  418. obj->Scenario = index;
  419. list.Add_Object(obj);
  420. break;
  421. default:
  422. break;
  423. }
  424. }
  425. }
  426. Set_Logic_Page(SeenBuff);
  427. bool recalc = true;
  428. bool display = true;
  429. bool process = true;
  430. bool okval = true;
  431. while (process) {
  432. #ifdef WIN32
  433. /*
  434. ** If we have just received input focus again after running in the background then
  435. ** we need to redraw.
  436. */
  437. if (AllSurfaces.SurfacesRestored) {
  438. AllSurfaces.SurfacesRestored=FALSE;
  439. display = true;
  440. }
  441. #endif
  442. Call_Back();
  443. if (display) {
  444. display = false;
  445. Hide_Mouse();
  446. /*
  447. ** Load the background picture.
  448. */
  449. Load_Title_Page();
  450. CCPalette.Set();
  451. Dialog_Box(OPTION_X, OPTION_Y, OPTION_WIDTH, OPTION_HEIGHT);
  452. #ifdef FIXIT_VERSION_3
  453. if (bCounterstrike)
  454. {
  455. //PG Draw_Caption( TXT_WOL_CS_MISSIONS, OPTION_X, OPTION_Y, OPTION_WIDTH);
  456. }
  457. else
  458. {
  459. //PG Draw_Caption( TXT_WOL_AM_MISSIONS, OPTION_X, OPTION_Y, OPTION_WIDTH);
  460. }
  461. #else
  462. Draw_Caption(TXT_NEW_MISSIONS, OPTION_X, OPTION_Y, OPTION_WIDTH);
  463. #endif
  464. buttons->Draw_All();
  465. Show_Mouse();
  466. }
  467. KeyNumType input = buttons->Input();
  468. switch (input) {
  469. case 200|KN_BUTTON:
  470. Whom = list.Current_Object()->House;
  471. Scen.Scenario = list.Current_Object()->Scenario;
  472. strcpy(Scen.ScenarioName, list.Current_Object()->FullName);
  473. process = false;
  474. okval = true;
  475. break;
  476. case KN_ESC:
  477. case 201|KN_BUTTON:
  478. process = false;
  479. okval = false;
  480. break;
  481. case (KN_RETURN):
  482. Whom = list.Current_Object()->House;
  483. Scen.Scenario = list.Current_Object()->Scenario;
  484. strcpy(Scen.ScenarioName, list.Current_Object()->FullName);
  485. process = false;
  486. okval = true;
  487. break;
  488. default:
  489. break;
  490. }
  491. }
  492. /*
  493. ** Free up the allocations for the text lines in the list box.
  494. */
  495. for (int index = 0; index < list.Count(); index++) {
  496. delete list.Get_Object(index);
  497. }
  498. return(okval);
  499. }