EXPAND.CPP 19 KB

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