MPLAYER.CPP 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  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/MPLAYER.CPP 3 3/13/97 2:06p 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 : MPLAYER.CPP *
  22. * *
  23. * Programmer : Bill Randolph *
  24. * *
  25. * Start Date : April 14, 1995 *
  26. * *
  27. * Last Update : November 30, 1995 [BRR] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * Select_MPlayer_Game -- prompts user for NULL-Modem, Modem, or Network game *
  32. * Clear_Listbox -- clears the given list box *
  33. * Clear_Vector -- clears the given NodeNameType vector *
  34. * Computer_Message -- "sends" a message from the computer *
  35. * Garble_Message -- "garbles" a message *
  36. * Surrender_Dialog -- Prompts user for surrendering *
  37. * Abort_Dialog -- Prompts user for confirmation on aborting the mission *
  38. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  39. #include "function.h"
  40. extern bool Is_Mission_Counterstrike (char *file_name);
  41. #ifdef WOLAPI_INTEGRATION
  42. #include "WolStrng.h"
  43. #endif
  44. /***********************************************************************************************
  45. * Select_MPlayer_Game -- prompts user for NULL-Modem, Modem, or Network game *
  46. * *
  47. * INPUT: *
  48. * none. *
  49. * *
  50. * OUTPUT: *
  51. * GAME_NORMAL, GAME_MODEM, etc. *
  52. * *
  53. * WARNINGS: *
  54. * none. *
  55. * *
  56. * HISTORY: *
  57. * 02/14/1995 BR : Created. *
  58. *=============================================================================================*/
  59. GameType Select_MPlayer_Game (void)
  60. {
  61. //------------------------------------------------------------------------
  62. // Dialog & button dimensions
  63. //------------------------------------------------------------------------
  64. int d_dialog_w = 190 *RESFACTOR;
  65. #ifdef WOLAPI_INTEGRATION
  66. int d_dialog_h = 89 * RESFACTOR; // ajw
  67. int d_dialog_y = (((255 * RESFACTOR) - d_dialog_h) / 2);
  68. #else
  69. int d_dialog_h = 78 *RESFACTOR;
  70. int d_dialog_y = 90 * RESFACTOR;
  71. #endif
  72. int d_dialog_x = (((320*RESFACTOR) - d_dialog_w) / 2);
  73. int d_dialog_cx = d_dialog_x + (d_dialog_w / 2);
  74. int d_txt6_h = 7 *RESFACTOR;
  75. int d_margin = 7 *RESFACTOR;
  76. int d_modemserial_w = 80 *RESFACTOR;
  77. int d_modemserial_h = 9 *RESFACTOR;
  78. int d_modemserial_x = d_dialog_cx - d_modemserial_w / 2;
  79. int d_modemserial_y = d_dialog_y + d_margin + d_txt6_h + d_margin;
  80. int d_skirmish_w = 80 *RESFACTOR;
  81. int d_skirmish_h = 9 *RESFACTOR;
  82. int d_skirmish_x = d_dialog_cx - d_skirmish_w / 2;
  83. int d_skirmish_y = d_modemserial_y + d_modemserial_h + 2*RESFACTOR;
  84. int d_ipx_w = 80 *RESFACTOR;
  85. int d_ipx_h = 9 *RESFACTOR;
  86. int d_ipx_x = d_dialog_cx - d_ipx_w / 2;
  87. int d_ipx_y = d_skirmish_y + d_skirmish_h + 2*RESFACTOR;
  88. #ifdef WOLAPI_INTEGRATION
  89. // ajw 7/2/98 - added button
  90. int d_wol_w = 80 * RESFACTOR;
  91. int d_wol_h = 9 * RESFACTOR;
  92. int d_wol_x = d_dialog_cx - d_wol_w / 2;
  93. int d_wol_y = d_ipx_y + d_ipx_h + 2*RESFACTOR;
  94. #endif
  95. int d_cancel_w = 60 *RESFACTOR;
  96. int d_cancel_h = 9 *RESFACTOR;
  97. int d_cancel_x = d_dialog_cx - d_cancel_w / 2;
  98. #ifdef WOLAPI_INTEGRATION
  99. int d_cancel_y = d_wol_y + d_wol_h + d_margin;
  100. #else
  101. int d_cancel_y = d_ipx_y + d_ipx_h + d_margin;
  102. #endif
  103. #ifdef WIN32
  104. GraphicBufferClass seen_buff_save(VisiblePage.Get_Width(), VisiblePage.Get_Height(), (void*)NULL);
  105. #endif
  106. //------------------------------------------------------------------------
  107. // Button enumerations:
  108. //------------------------------------------------------------------------
  109. enum {
  110. BUTTON_MODEMSERIAL = 100,
  111. BUTTON_SKIRMISH,
  112. BUTTON_IPX,
  113. #ifdef WOLAPI_INTEGRATION
  114. BUTTON_WOL, // ajw
  115. #endif
  116. BUTTON_CANCEL,
  117. #ifdef WOLAPI_INTEGRATION
  118. NUM_OF_BUTTONS = 5, // ajw
  119. #else
  120. NUM_OF_BUTTONS = 4,
  121. #endif
  122. };
  123. int num_of_buttons = NUM_OF_BUTTONS - (Ipx.Is_IPX() ? 0 : 1);
  124. //------------------------------------------------------------------------
  125. // Redraw values: in order from "top" to "bottom" layer of the dialog
  126. //------------------------------------------------------------------------
  127. typedef enum {
  128. REDRAW_NONE = 0,
  129. REDRAW_BUTTONS, // includes map interior & coord values
  130. REDRAW_BACKGROUND, // includes box, map bord, key, coord labels, btns
  131. REDRAW_ALL = REDRAW_BACKGROUND
  132. } RedrawType;
  133. //------------------------------------------------------------------------
  134. // Dialog variables:
  135. //------------------------------------------------------------------------
  136. KeyNumType input; // input from user
  137. bool process; // loop while true
  138. RedrawType display; // true = re-draw everything
  139. GameType retval; // return value
  140. int selection;
  141. bool pressed;
  142. int curbutton;
  143. TextButtonClass * buttons[NUM_OF_BUTTONS];
  144. //------------------------------------------------------------------------
  145. // Buttons
  146. //------------------------------------------------------------------------
  147. ControlClass * commands = NULL; // the button list
  148. //------------------------------------------------------------------------
  149. // If IPX not active then do only the modem serial dialog
  150. //------------------------------------------------------------------------
  151. // if ( !Ipx.Is_IPX() ) {
  152. // return( Select_Serial_Dialog() );
  153. // }
  154. TextButtonClass modemserialbtn (BUTTON_MODEMSERIAL, TXT_MODEM_SERIAL, TPF_BUTTON,
  155. d_modemserial_x, d_modemserial_y, d_modemserial_w, d_modemserial_h);
  156. TextButtonClass skirmishbtn (BUTTON_SKIRMISH, TXT_SKIRMISH, TPF_BUTTON,
  157. d_skirmish_x, d_skirmish_y, d_skirmish_w, d_skirmish_h);
  158. TextButtonClass ipxbtn (BUTTON_IPX, TXT_NETWORK, TPF_BUTTON,
  159. d_ipx_x, d_ipx_y, d_ipx_w, d_ipx_h);
  160. #ifdef WOLAPI_INTEGRATION
  161. // ajw
  162. TextButtonClass wolbtn(BUTTON_WOL, TXT_WOL_INTERNETBUTTON, TPF_BUTTON,
  163. d_wol_x, d_wol_y, d_wol_w, d_wol_h);
  164. #endif
  165. if(!Ipx.Is_IPX()) {
  166. d_cancel_y = d_ipx_y;
  167. d_dialog_h -= d_cancel_h;
  168. }
  169. TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON,
  170. d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h);
  171. //------------------------------------------------------------------------
  172. // Initialize
  173. //------------------------------------------------------------------------
  174. Set_Logic_Page(SeenBuff);
  175. #ifdef WIN32
  176. VisiblePage.Blit(seen_buff_save);
  177. #endif
  178. //------------------------------------------------------------------------
  179. // Create the list
  180. //------------------------------------------------------------------------
  181. commands = &modemserialbtn;
  182. skirmishbtn.Add_Tail(*commands);
  183. if(Ipx.Is_IPX()) {
  184. ipxbtn.Add_Tail(*commands);
  185. }
  186. #ifdef WOLAPI_INTEGRATION
  187. wolbtn.Add_Tail(*commands); // ajw
  188. #endif
  189. cancelbtn.Add_Tail(*commands);
  190. //------------------------------------------------------------------------
  191. // Fill array of button ptrs
  192. //------------------------------------------------------------------------
  193. curbutton = 0;
  194. buttons[0] = &modemserialbtn;
  195. buttons[1] = &skirmishbtn;
  196. if(Ipx.Is_IPX()) {
  197. buttons[2] = &ipxbtn;
  198. #ifdef WOLAPI_INTEGRATION
  199. buttons[3] = &wolbtn; // ajw
  200. buttons[4] = &cancelbtn;
  201. #else
  202. buttons[3] = &cancelbtn;
  203. #endif
  204. } else {
  205. #ifdef WOLAPI_INTEGRATION
  206. buttons[2] = &wolbtn; // ajw
  207. buttons[3] = &cancelbtn;
  208. #else
  209. buttons[2] = &cancelbtn;
  210. #endif
  211. }
  212. buttons[curbutton]->Turn_On();
  213. Keyboard->Clear();
  214. Fancy_Text_Print(TXT_NONE, 0, 0, GadgetClass::Get_Color_Scheme(), TBLACK,
  215. TPF_CENTER | TPF_TEXT);
  216. //------------------------------------------------------------------------
  217. // Main Processing Loop
  218. //------------------------------------------------------------------------
  219. display = REDRAW_ALL;
  220. process = true;
  221. pressed = false;
  222. while (process) {
  223. #ifdef WIN32
  224. /*
  225. ** If we have just received input focus again after running in the background then
  226. ** we need to redraw.
  227. */
  228. if (AllSurfaces.SurfacesRestored) {
  229. AllSurfaces.SurfacesRestored=FALSE;
  230. seen_buff_save.Blit(VisiblePage);
  231. display = REDRAW_ALL;
  232. }
  233. #endif
  234. //.....................................................................
  235. // Invoke game callback
  236. //.....................................................................
  237. Call_Back();
  238. //.....................................................................
  239. // Refresh display if needed
  240. //.....................................................................
  241. if (display) {
  242. Hide_Mouse();
  243. if (display >= REDRAW_BACKGROUND) {
  244. //...............................................................
  245. // Refresh the backdrop
  246. //...............................................................
  247. Load_Title_Page(true);
  248. CCPalette.Set();
  249. //...............................................................
  250. // Draw the background
  251. //...............................................................
  252. Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
  253. Draw_Caption (TXT_SELECT_MPLAYER_GAME, d_dialog_x, d_dialog_y, d_dialog_w);
  254. }
  255. //..................................................................
  256. // Redraw buttons
  257. //..................................................................
  258. if (display >= REDRAW_BUTTONS) {
  259. commands->Flag_List_To_Redraw();
  260. }
  261. Show_Mouse();
  262. display = REDRAW_NONE;
  263. }
  264. //.....................................................................
  265. // Get user input
  266. //.....................................................................
  267. input = commands->Input();
  268. //.....................................................................
  269. // Process input
  270. //.....................................................................
  271. switch (input) {
  272. case (BUTTON_MODEMSERIAL | KN_BUTTON):
  273. selection = BUTTON_MODEMSERIAL;
  274. pressed = true;
  275. break;
  276. case (BUTTON_SKIRMISH | KN_BUTTON):
  277. selection = BUTTON_SKIRMISH;
  278. pressed = true;
  279. break;
  280. case (BUTTON_IPX | KN_BUTTON):
  281. selection = BUTTON_IPX;
  282. pressed = true;
  283. break;
  284. #ifdef WOLAPI_INTEGRATION
  285. case (BUTTON_WOL | KN_BUTTON): // ajw
  286. selection = BUTTON_WOL;
  287. pressed = true;
  288. break;
  289. #endif
  290. case (KN_ESC):
  291. case (BUTTON_CANCEL | KN_BUTTON):
  292. selection = BUTTON_CANCEL;
  293. pressed = true;
  294. break;
  295. case KN_UP:
  296. buttons[curbutton]->Turn_Off();
  297. buttons[curbutton]->Flag_To_Redraw();
  298. curbutton--;
  299. if (curbutton < 0)
  300. curbutton = (num_of_buttons - 1);
  301. buttons[curbutton]->Turn_On();
  302. buttons[curbutton]->Flag_To_Redraw();
  303. break;
  304. case KN_DOWN:
  305. buttons[curbutton]->Turn_Off();
  306. buttons[curbutton]->Flag_To_Redraw();
  307. curbutton++;
  308. if (curbutton > (num_of_buttons - 1) )
  309. curbutton = 0;
  310. buttons[curbutton]->Turn_On();
  311. buttons[curbutton]->Flag_To_Redraw();
  312. break;
  313. case KN_RETURN:
  314. selection = curbutton + BUTTON_MODEMSERIAL;
  315. pressed = true;
  316. break;
  317. default:
  318. break;
  319. }
  320. if (pressed) {
  321. //..................................................................
  322. // to make sure the selection is correct in case they used the mouse
  323. //..................................................................
  324. buttons[curbutton]->Turn_Off();
  325. buttons[curbutton]->Flag_To_Redraw();
  326. curbutton = selection - BUTTON_MODEMSERIAL;
  327. if(selection == BUTTON_CANCEL && !Ipx.Is_IPX()) curbutton--;
  328. buttons[curbutton]->Turn_On();
  329. buttons[curbutton]->IsPressed = true;
  330. buttons[curbutton]->Draw_Me(true);
  331. switch (selection) {
  332. case (BUTTON_MODEMSERIAL):
  333. //............................................................
  334. // Pop up the modem/serial/com port dialog
  335. //............................................................
  336. retval = Select_Serial_Dialog();
  337. if (retval != GAME_NORMAL) {
  338. process = false;
  339. } else {
  340. buttons[curbutton]->IsPressed = false;
  341. display = REDRAW_ALL;
  342. }
  343. break;
  344. case (BUTTON_SKIRMISH):
  345. Session.Type = GAME_SKIRMISH;
  346. #if (0) //PG
  347. if (Com_Scenario_Dialog(true)) {
  348. retval = GAME_SKIRMISH;
  349. process = false;
  350. #ifdef FIXIT_VERSION_3
  351. bAftermathMultiplayer = Is_Aftermath_Installed();
  352. // ajw I'll bet this was needed before also...
  353. Session.ScenarioIsOfficial = Session.Scenarios[Session.Options.ScenarioIndex]->Get_Official();
  354. #endif
  355. } else {
  356. buttons[curbutton]->IsPressed = false;
  357. Session.Type = GAME_NORMAL;
  358. display = REDRAW_ALL;
  359. }
  360. #endif
  361. break;
  362. case (BUTTON_IPX):
  363. retval = GAME_IPX;
  364. process = false;
  365. break;
  366. #ifdef WOLAPI_INTEGRATION
  367. case (BUTTON_WOL): // ajw
  368. retval = GAME_INTERNET;
  369. process = false;
  370. break;
  371. #endif
  372. case (BUTTON_CANCEL):
  373. retval = GAME_NORMAL;
  374. process = false;
  375. break;
  376. }
  377. pressed = false;
  378. }
  379. }
  380. return(retval);
  381. } /* end of Select_MPlayer_Game */
  382. /***************************************************************************
  383. * Clear_Listbox -- clears the given list box *
  384. * *
  385. * This routine assumes the items in the given list box are character *
  386. * buffers; it deletes each item in the list, then clears the list. *
  387. * *
  388. * INPUT: *
  389. * list ptr to listbox *
  390. * *
  391. * OUTPUT: *
  392. * none. *
  393. * *
  394. * WARNINGS: *
  395. * none. *
  396. * *
  397. * HISTORY: *
  398. * 11/29/1995 BRR : Created. *
  399. *=========================================================================*/
  400. void Clear_Listbox(ListClass * list)
  401. {
  402. char * item;
  403. //------------------------------------------------------------------------
  404. // Clear the list box
  405. //------------------------------------------------------------------------
  406. while (list->Count()) {
  407. item = (char *)(list->Get_Item(0));
  408. list->Remove_Item(item);
  409. delete [] item;
  410. }
  411. list->Flag_To_Redraw();
  412. } // end of Clear_Listbox
  413. /***************************************************************************
  414. * Clear_Vector -- clears the given NodeNameType vector *
  415. * *
  416. * INPUT: *
  417. * vector ptr to vector to clear *
  418. * *
  419. * OUTPUT: *
  420. * none. *
  421. * *
  422. * WARNINGS: *
  423. * none. *
  424. * *
  425. * HISTORY: *
  426. * 11/29/1995 BRR : Created. *
  427. *=========================================================================*/
  428. void Clear_Vector(DynamicVectorClass <NodeNameType *> * vector)
  429. {
  430. int i;
  431. //------------------------------------------------------------------------
  432. // Clear the 'Players' Vector
  433. //------------------------------------------------------------------------
  434. for (i = 0; i < vector->Count(); i++) {
  435. delete (*vector)[i];
  436. }
  437. vector->Clear();
  438. } // end of Clear_Vector
  439. /***************************************************************************
  440. * Computer_Message -- "sends" a message from the computer *
  441. * *
  442. * INPUT: *
  443. * none. *
  444. * *
  445. * OUTPUT: *
  446. * none. *
  447. * *
  448. * WARNINGS: *
  449. * none. *
  450. * *
  451. * HISTORY: *
  452. * 06/06/1995 BRR : Created. *
  453. *=========================================================================*/
  454. void Computer_Message(void)
  455. {
  456. #ifdef NEVER
  457. int color;
  458. HousesType house;
  459. HouseClass * ptr;
  460. //------------------------------------------------------------------------
  461. // Find the computer house that the message will be from
  462. //------------------------------------------------------------------------
  463. for (house = HOUSE_MULTI1; house < (HOUSE_MULTI1 + Session.MaxPlayers); house++) {
  464. ptr = HouseClass::As_Pointer(house);
  465. if (!ptr || ptr->IsHuman || ptr->IsDefeated) {
  466. continue;
  467. }
  468. //.....................................................................
  469. // Decode this house's color
  470. //.....................................................................
  471. color = ptr->RemapColor;
  472. //.....................................................................
  473. // We now have a 1/4 chance of echoing one of the human players'
  474. // messages back.
  475. //.....................................................................
  476. if (Percent_Chance(25)) {
  477. //..................................................................
  478. // Now we have a 1/3 chance of garbling the human message.
  479. //..................................................................
  480. if (Percent_Chance(33)) {
  481. Garble_Message(Session.LastMessage);
  482. }
  483. //..................................................................
  484. // Only add the message if there is one to add.
  485. //..................................................................
  486. if (strlen(Session.LastMessage)) {
  487. Session.Messages.Add_Message(Text_String(TXT_COMPUTER), 0,
  488. Session.LastMessage,
  489. color, TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, Rule.MessageDelay * TICKS_PER_MINUTE);
  490. }
  491. }
  492. else {
  493. Session.Messages.Add_Message(Text_String(TXT_COMPUTER), 0,
  494. Text_String(TXT_COMP_MSG1 + Random_Pick(0, 12)),
  495. color, TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, Rule.MessageDelay * TICKS_PER_MINUTE);
  496. }
  497. return;
  498. }
  499. #endif
  500. } /* end of Computer_Message */
  501. #ifdef NEVER
  502. /***************************************************************************
  503. * Garble_Message -- "garbles" a message *
  504. * *
  505. * INPUT: *
  506. * buf buffer to garble; stores output message *
  507. * *
  508. * OUTPUT: *
  509. * none. *
  510. * *
  511. * WARNINGS: *
  512. * none. *
  513. * *
  514. * HISTORY: *
  515. * 06/06/1995 BRR : Created. *
  516. *=========================================================================*/
  517. static void Garble_Message(char * buf)
  518. {
  519. char txt[80];
  520. char punct[20]; // for punctuation
  521. char * p; // working ptr
  522. int numwords; // # words in the phrase
  523. char * words[40]; // ptrs to various words in the phrase
  524. int i,j;
  525. //------------------------------------------------------------------------
  526. // Pull off any trailing punctuation
  527. //------------------------------------------------------------------------
  528. p = buf + strlen(buf) - 1;
  529. while (1) {
  530. if (p < buf)
  531. break;
  532. if (p[0]=='!' || p[0]=='.' || p[0]=='?') {
  533. p--;
  534. }
  535. else {
  536. p++;
  537. break;
  538. }
  539. if (strlen(p) >= (sizeof(punct) - 1) ) {
  540. break;
  541. }
  542. }
  543. strcpy (punct, p);
  544. p[0] = 0;
  545. for (i = 0; i < 40; i++) {
  546. words[i] = NULL;
  547. }
  548. //------------------------------------------------------------------------
  549. // Copy the original buffer
  550. //------------------------------------------------------------------------
  551. strcpy(txt, buf);
  552. //------------------------------------------------------------------------
  553. // Split it up into words
  554. //------------------------------------------------------------------------
  555. p = strtok (txt, " ");
  556. numwords = 0;
  557. while (p) {
  558. words[numwords] = p;
  559. numwords++;
  560. p = strtok (NULL, " ");
  561. }
  562. //------------------------------------------------------------------------
  563. // Now randomly put the words back. Don't use the real random-number
  564. // generator, since different machines will have different LastMessage's,
  565. // and will go out of sync.
  566. //------------------------------------------------------------------------
  567. buf[0] = 0;
  568. for (i = 0; i < numwords; i++) {
  569. j = Sim_IRandom(0, numwords);
  570. if (words[j] == NULL) { // this word has been used already
  571. i--;
  572. continue;
  573. }
  574. strcat(buf, words[j]);
  575. words[j] = NULL;
  576. if (i < numwords-1)
  577. strcat(buf, " ");
  578. }
  579. strcat(buf, punct);
  580. } /* end of Garble_Message */
  581. #endif
  582. /***************************************************************************
  583. * Surrender_Dialog -- Prompts user for surrendering *
  584. * *
  585. * INPUT: *
  586. * none. *
  587. * *
  588. * OUTPUT: *
  589. * 0 = user cancels, 1 = user wants to surrender. *
  590. * *
  591. * WARNINGS: *
  592. * none. *
  593. * *
  594. * HISTORY: *
  595. * 07/05/1995 BRR : Created. *
  596. *=========================================================================*/
  597. #ifdef FIXIT_VERSION_3 // Stalemate games.
  598. int Surrender_Dialog(int text)
  599. {
  600. return Surrender_Dialog( Text_String( text ) );
  601. }
  602. #endif
  603. #ifdef FIXIT_VERSION_3 // Stalemate games.
  604. int Surrender_Dialog(const char* text)
  605. #else
  606. int Surrender_Dialog(int text)
  607. #endif
  608. {
  609. //------------------------------------------------------------------------
  610. // Dialog & button dimensions
  611. //------------------------------------------------------------------------
  612. enum {
  613. D_DIALOG_W = 240*RESFACTOR, // dialog width
  614. D_DIALOG_H = 63*RESFACTOR, // dialog height
  615. D_DIALOG_X = ((320*RESFACTOR - D_DIALOG_W) / 2),// centered x-coord
  616. D_DIALOG_Y = ((200*RESFACTOR - D_DIALOG_H) / 2),// centered y-coord
  617. D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), // coord of x-center
  618. D_TXT6_H = 7*RESFACTOR, // ht of 6-pt text
  619. D_MARGIN = 5*RESFACTOR, // margin width/height
  620. D_TOPMARGIN = 20*RESFACTOR, // top margin
  621. D_OK_W = 45*RESFACTOR, // OK width
  622. D_OK_H = 9*RESFACTOR, // OK height
  623. D_OK_X = D_DIALOG_CX - D_OK_W - 5*RESFACTOR, // OK x
  624. D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - D_MARGIN*2, // OK y
  625. D_CANCEL_W = 45*RESFACTOR, // Cancel width
  626. D_CANCEL_H = 9*RESFACTOR, // Cancel height
  627. D_CANCEL_X = D_DIALOG_CX + 5*RESFACTOR, // Cancel x
  628. D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN*2, // Cancel y
  629. };
  630. //------------------------------------------------------------------------
  631. // Button enumerations
  632. //------------------------------------------------------------------------
  633. enum {
  634. BUTTON_OK = 100,
  635. BUTTON_CANCEL,
  636. };
  637. //------------------------------------------------------------------------
  638. // Buttons
  639. //------------------------------------------------------------------------
  640. ControlClass * commands = NULL; // the button list
  641. TextButtonClass okbtn(BUTTON_OK, TXT_OK, TPF_BUTTON, D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
  642. TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON, D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
  643. int curbutton;
  644. TextButtonClass * buttons[2];
  645. curbutton = 0;
  646. //------------------------------------------------------------------------
  647. // Initialize
  648. //------------------------------------------------------------------------
  649. Set_Logic_Page(SeenBuff);
  650. //------------------------------------------------------------------------
  651. // Create the button list
  652. //------------------------------------------------------------------------
  653. commands = &okbtn;
  654. cancelbtn.Add_Tail(*commands);
  655. buttons[0] = &okbtn;
  656. buttons[1] = &cancelbtn;
  657. buttons[curbutton]->Turn_On();
  658. //------------------------------------------------------------------------
  659. // Main Processing Loop
  660. //------------------------------------------------------------------------
  661. int retcode = 0;
  662. bool display = true;
  663. bool process = true;
  664. while (process) {
  665. //.....................................................................
  666. // Invoke game callback
  667. //.....................................................................
  668. if (Session.Type != GAME_SKIRMISH) {
  669. if (Main_Loop()) {
  670. retcode = 0;
  671. process = false;
  672. }
  673. }
  674. //.....................................................................
  675. // Refresh display if needed
  676. //.....................................................................
  677. if (display) {
  678. display = false;
  679. //..................................................................
  680. // Display the dialog box
  681. //..................................................................
  682. Hide_Mouse();
  683. Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
  684. Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
  685. //...............................................................
  686. // Draw the captions
  687. //...............................................................
  688. #ifdef FIXIT_VERSION_3 // Stalemate games.
  689. Fancy_Text_Print(text,
  690. D_DIALOG_CX, D_DIALOG_Y + D_TOPMARGIN,
  691. GadgetClass::Get_Color_Scheme(), TBLACK,
  692. TPF_CENTER | TPF_TEXT);
  693. #else
  694. Fancy_Text_Print(Text_String(text),
  695. D_DIALOG_CX, D_DIALOG_Y + D_TOPMARGIN,
  696. GadgetClass::Get_Color_Scheme(), TBLACK,
  697. TPF_CENTER | TPF_TEXT);
  698. #endif
  699. //..................................................................
  700. // Redraw the buttons
  701. //..................................................................
  702. commands->Flag_List_To_Redraw();
  703. Show_Mouse();
  704. }
  705. //.....................................................................
  706. // Get user input
  707. //.....................................................................
  708. KeyNumType input = commands->Input();
  709. //.....................................................................
  710. // Process input
  711. //.....................................................................
  712. switch (input) {
  713. case (BUTTON_OK | KN_BUTTON):
  714. retcode = 1;
  715. process = false;
  716. break;
  717. case (BUTTON_CANCEL | KN_BUTTON):
  718. retcode = 0;
  719. process = false;
  720. break;
  721. case (KN_RETURN):
  722. if (curbutton == 0) {
  723. retcode = 1;
  724. } else {
  725. retcode = 0;
  726. }
  727. process = false;
  728. break;
  729. case (KN_ESC):
  730. retcode = 0;
  731. process = false;
  732. break;
  733. case (KN_RIGHT):
  734. buttons[curbutton]->Turn_Off();
  735. curbutton++;
  736. if (curbutton > 1) {
  737. curbutton = 0;
  738. }
  739. buttons[curbutton]->Turn_On();
  740. break;
  741. case (KN_LEFT):
  742. buttons[curbutton]->Turn_Off();
  743. curbutton--;
  744. if (curbutton < 0) {
  745. curbutton = 1;
  746. }
  747. buttons[curbutton]->Turn_On();
  748. break;
  749. default:
  750. break;
  751. }
  752. }
  753. //------------------------------------------------------------------------
  754. // Redraw the display
  755. //------------------------------------------------------------------------
  756. HidPage.Clear();
  757. Map.Flag_To_Redraw(true);
  758. Map.Render();
  759. return (retcode);
  760. }
  761. /***************************************************************************
  762. * Abort_Dialog -- Prompts user for confirmation on aborting the mission *
  763. * *
  764. * INPUT: *
  765. * none. *
  766. * *
  767. * OUTPUT: *
  768. * 1 = user confirms abort, 0 = user cancels *
  769. * *
  770. * WARNINGS: *
  771. * none. *
  772. * *
  773. * HISTORY: *
  774. * 07/05/1995 BRR : Created. *
  775. *=========================================================================*/
  776. int Abort_Dialog(void)
  777. {
  778. //------------------------------------------------------------------------
  779. // Dialog & button dimensions
  780. //------------------------------------------------------------------------
  781. enum {
  782. D_DIALOG_W = 170*RESFACTOR, // dialog width
  783. D_DIALOG_H = 63*RESFACTOR, // dialog height
  784. D_DIALOG_X = ((320*RESFACTOR - D_DIALOG_W) / 2),// centered x-coord
  785. D_DIALOG_Y = ((200*RESFACTOR - D_DIALOG_H) / 2),// centered y-coord
  786. D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), // coord of x-center
  787. D_TXT6_H = 7*RESFACTOR, // ht of 6-pt text
  788. D_MARGIN = 5*RESFACTOR, // margin width/height
  789. D_TOPMARGIN = 20*RESFACTOR, // top margin
  790. D_YES_W = 45*RESFACTOR, // YES width
  791. D_YES_H = 9*RESFACTOR, // YES height
  792. D_YES_X = D_DIALOG_CX - D_YES_W - 5*RESFACTOR, // YES x
  793. D_YES_Y = D_DIALOG_Y + D_DIALOG_H - D_YES_H - D_MARGIN*2, // YES y
  794. D_NO_W = 45*RESFACTOR, // Cancel width
  795. D_NO_H = 9*RESFACTOR, // Cancel height
  796. D_NO_X = D_DIALOG_CX + 5*RESFACTOR, // Cancel x
  797. D_NO_Y = D_DIALOG_Y + D_DIALOG_H - D_NO_H - D_MARGIN*2, // Cancel y
  798. };
  799. //------------------------------------------------------------------------
  800. // Button enumerations
  801. //------------------------------------------------------------------------
  802. enum {
  803. BUTTON_YES = 100,
  804. BUTTON_NO,
  805. };
  806. //------------------------------------------------------------------------
  807. // Buttons
  808. //------------------------------------------------------------------------
  809. ControlClass * commands = NULL; // the button list
  810. TextButtonClass yesbtn(BUTTON_YES, TXT_YES, TPF_BUTTON, D_YES_X, D_YES_Y, D_YES_W, D_YES_H);
  811. TextButtonClass nobtn(BUTTON_NO, TXT_NO, TPF_BUTTON, D_NO_X, D_NO_Y, D_NO_W, D_NO_H);
  812. int curbutton;
  813. TextButtonClass * buttons[2];
  814. curbutton = 0;
  815. //------------------------------------------------------------------------
  816. // Initialize
  817. //------------------------------------------------------------------------
  818. Set_Logic_Page(SeenBuff);
  819. //------------------------------------------------------------------------
  820. // Create the button list
  821. //------------------------------------------------------------------------
  822. commands = &yesbtn;
  823. nobtn.Add_Tail(*commands);
  824. buttons[0] = &yesbtn;
  825. buttons[1] = &nobtn;
  826. buttons[curbutton]->Turn_On();
  827. //------------------------------------------------------------------------
  828. // Main Processing Loop
  829. //------------------------------------------------------------------------
  830. int retcode = 0;
  831. bool display = true;
  832. bool process = true;
  833. while (process) {
  834. //.....................................................................
  835. // Invoke game callback
  836. //.....................................................................
  837. if (Session.Type != GAME_SKIRMISH) {
  838. if (Main_Loop()) {
  839. retcode = 0;
  840. process = false;
  841. }
  842. }
  843. //.....................................................................
  844. // Refresh display if needed
  845. //.....................................................................
  846. if (display) {
  847. display = false;
  848. //..................................................................
  849. // Display the dialog box
  850. //..................................................................
  851. Hide_Mouse();
  852. Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
  853. Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
  854. //...............................................................
  855. // Draw the captions
  856. //...............................................................
  857. Fancy_Text_Print(Text_String(TXT_CONFIRM_EXIT),
  858. D_DIALOG_CX, D_DIALOG_Y + D_TOPMARGIN,
  859. GadgetClass::Get_Color_Scheme(), TBLACK,
  860. TPF_CENTER | TPF_TEXT);
  861. //..................................................................
  862. // Redraw the buttons
  863. //..................................................................
  864. commands->Flag_List_To_Redraw();
  865. Show_Mouse();
  866. }
  867. //.....................................................................
  868. // Get user input
  869. //.....................................................................
  870. KeyNumType input = commands->Input();
  871. //.....................................................................
  872. // Process input
  873. //.....................................................................
  874. switch (input) {
  875. case (BUTTON_YES | KN_BUTTON):
  876. retcode = 1;
  877. process = false;
  878. break;
  879. case (BUTTON_NO | KN_BUTTON):
  880. retcode = 0;
  881. process = false;
  882. break;
  883. case (KN_RETURN):
  884. if (curbutton == 0) {
  885. retcode = 1;
  886. } else {
  887. retcode = 0;
  888. }
  889. process = false;
  890. break;
  891. case (KN_ESC):
  892. retcode = 0;
  893. process = false;
  894. break;
  895. case (KN_RIGHT):
  896. buttons[curbutton]->Turn_Off();
  897. curbutton++;
  898. if (curbutton > 1) {
  899. curbutton = 0;
  900. }
  901. buttons[curbutton]->Turn_On();
  902. break;
  903. case (KN_LEFT):
  904. buttons[curbutton]->Turn_Off();
  905. curbutton--;
  906. if (curbutton < 0) {
  907. curbutton = 1;
  908. }
  909. buttons[curbutton]->Turn_On();
  910. break;
  911. default:
  912. break;
  913. }
  914. }
  915. //------------------------------------------------------------------------
  916. // Redraw the display
  917. //------------------------------------------------------------------------
  918. HidPage.Clear();
  919. Map.Flag_To_Redraw(true);
  920. Map.Render();
  921. return (retcode);
  922. }
  923. #if(TEN)
  924. /***************************************************************************
  925. * Read_TEN_Game_Options -- reads multiplayer game options from disk *
  926. * *
  927. * This routine is used for multiplayer games which read the game options *
  928. * from disk, rather than through a connection dialog. *
  929. * *
  930. * INPUT: *
  931. * none. *
  932. * *
  933. * OUTPUT: *
  934. * 1 = OK, 0 = error *
  935. * *
  936. * WARNINGS: *
  937. * none. *
  938. * *
  939. * HISTORY: *
  940. * 01/11/1996 BRR : Created. *
  941. *=========================================================================*/
  942. int Read_TEN_Game_Options(void)
  943. {
  944. INIClass ini;
  945. if (!ini.Load(RawFileClass(Session.OptionsFile))) {
  946. return (0);
  947. }
  948. ini.Get_String("Options", "Handle", "Noname", Session.Handle,
  949. sizeof(Session.Handle));
  950. if (Session.TenPlayerID == -1) {
  951. return (0);
  952. }
  953. Session.ColorIdx = (PlayerColorType)Session.TenPlayerID;
  954. Session.House = (HousesType)
  955. ((int)HOUSE_USSR + ini.Get_Int("Options", "Side", 0));
  956. Session.Options.Credits = ini.Get_Int("Options", "Credits", 3000);
  957. Session.Options.Bases = ini.Get_Int("Options", "Bases", 1);
  958. Session.Options.Tiberium = ini.Get_Int("Options", "Tiberium", 1);
  959. Session.Options.Goodies = ini.Get_Int("Options", "Crates", 1);
  960. Special.IsShadowGrow = ini.Get_Int ("Options", "Shadow", 0);
  961. BuildLevel = ini.Get_Int("Options", "BuildLevel", 3);
  962. Session.Options.UnitCount = ini.Get_Int("Options", "UnitCount", 5);
  963. Seed = ini.Get_Int("Options", "Seed", 0);
  964. Special.IsCaptureTheFlag = ini.Get_Int("Options", "CapFlag", 0);
  965. Session.Options.AIPlayers = ini.Get_Int("Options", "AI", 0);
  966. Session.NumPlayers = ini.Get_Int("Options", "Players", 2);
  967. if (Session.Options.AIPlayers){
  968. Session.Options.Ghosts = 1;
  969. }
  970. if (Session.Options.Tiberium) {
  971. Special.IsTGrowth = 1;
  972. Special.IsTSpread = 1;
  973. } else {
  974. Special.IsTGrowth = 0;
  975. Special.IsTSpread = 0;
  976. }
  977. /*
  978. ** Read the scenario name from the .INI and try to match it with a scenario file in our list.
  979. */
  980. ini.Get_String("Options", "Scenario", "Black Acres",
  981. Session.Options.ScenarioDescription,
  982. sizeof (Session.Options.ScenarioDescription));
  983. Session.Options.ScenarioIndex = -1;
  984. for (int i = 0; i < Session.Scenarios.Count(); i++) {
  985. if (!strcmp (Session.Scenarios[i]->Description(),
  986. Session.Options.ScenarioDescription) ) {
  987. Session.Options.ScenarioIndex = i;
  988. strcpy(Session.ScenarioFileName, Session.Scenarios[i]->Get_Filename());
  989. strcpy(Scen.ScenarioName, Session.Scenarios[i]->Get_Filename());
  990. break;
  991. }
  992. }
  993. if (Session.Options.ScenarioIndex == -1) {
  994. WWMessageBox().Process("Scenario not found!");
  995. //Prog_End();
  996. Emergency_Exit(0);
  997. }
  998. Options.GameSpeed = 0;
  999. Session.MaxAhead = ini.Get_Int("Timing", "MaxAhead", 9);
  1000. Session.FrameSendRate = ini.Get_Int("Timing", "SendRate", 3);
  1001. Session.NetResponseTime = ini.Get_Int("Timing","Latency",600);
  1002. return (1);
  1003. }
  1004. #endif // TEN
  1005. #if(MPATH)
  1006. /***************************************************************************
  1007. * Read_MPATH_Game_Options -- reads multiplayer game options from disk *
  1008. * *
  1009. * This routine is used for multiplayer games which read the game options *
  1010. * from disk, rather than through a connection dialog. *
  1011. * *
  1012. * INPUT: *
  1013. * none. *
  1014. * *
  1015. * OUTPUT: *
  1016. * 1 = OK, 0 = error *
  1017. * *
  1018. * WARNINGS: *
  1019. * none. *
  1020. * *
  1021. * HISTORY: *
  1022. * 01/11/1996 BRR : Created. *
  1023. *=========================================================================*/
  1024. int Read_MPATH_Game_Options(void)
  1025. {
  1026. INIClass ini;
  1027. if (!ini.Load(RawFileClass(Session.OptionsFile))) {
  1028. return (0);
  1029. }
  1030. ini.Get_String("Options", "Handle", "Noname", Session.Handle,
  1031. sizeof(Session.Handle));
  1032. Session.ColorIdx = (PlayerColorType)ini.Get_Int("Options", "Color", 0);
  1033. Session.House = (HousesType)
  1034. ((int)HOUSE_USSR + ini.Get_Int("Options", "Side", 0));
  1035. Session.Options.Credits = ini.Get_Int("Options", "Credits", 3000);
  1036. Session.Options.Bases = ini.Get_Int("Options", "Bases", 1);
  1037. Session.Options.Tiberium = ini.Get_Int("Options", "Tiberium", 1);
  1038. Session.Options.Goodies = ini.Get_Int("Options", "Crates", 1);
  1039. Special.IsShadowGrow = ini.Get_Int ("Options", "Shadow", 0);
  1040. BuildLevel = ini.Get_Int("Options", "BuildLevel", 3);
  1041. Session.Options.UnitCount = ini.Get_Int("Options", "UnitCount", 5);
  1042. Seed = ini.Get_Int("Options", "Seed", 0);
  1043. Special.IsCaptureTheFlag = ini.Get_Int("Options", "CapFlag", 0);
  1044. Session.Options.AIPlayers = ini.Get_Int("Options", "AI", 0);
  1045. if (Session.Options.AIPlayers){
  1046. Session.Options.Ghosts = 1;
  1047. }
  1048. if (Session.Options.Tiberium) {
  1049. Special.IsTGrowth = 1;
  1050. Special.IsTSpread = 1;
  1051. } else {
  1052. Special.IsTGrowth = 0;
  1053. Special.IsTSpread = 0;
  1054. }
  1055. /*
  1056. ** Read the scenario name from the .INI and try to match it with a scenario file in our list.
  1057. */
  1058. ini.Get_String("Options", "Scenario", "Black Acres",
  1059. Session.Options.ScenarioDescription,
  1060. sizeof (Session.Options.ScenarioDescription));
  1061. Session.Options.ScenarioIndex = -1;
  1062. for (int i = 0; i < Session.Scenarios.Count(); i++) {
  1063. if (!strcmp (Session.Scenarios[i]->Description(),
  1064. Session.Options.ScenarioDescription) ) {
  1065. Session.Options.ScenarioIndex = i;
  1066. strcpy(Session.ScenarioFileName, Session.Scenarios[i]->Get_Filename());
  1067. strcpy(Scen.ScenarioName, Session.Scenarios[i]->Get_Filename());
  1068. break;
  1069. }
  1070. }
  1071. if (Session.Options.ScenarioIndex == -1) {
  1072. WWMessageBox().Process("Scenario not found!");
  1073. //Prog_End();
  1074. Emergency_Exit(0);
  1075. }
  1076. Options.GameSpeed = 0;
  1077. Session.MaxAhead = ini.Get_Int("Timing", "MaxAhead", 9);
  1078. Session.FrameSendRate = ini.Get_Int("Timing", "SendRate", 3);
  1079. Session.NetResponseTime = ini.Get_Int("Timing","Latency",600);
  1080. return (1);
  1081. }
  1082. #endif // MPATH
  1083. /************************** end of mplayer.cpp *****************************/