MPLAYER.CPP 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408
  1. /*
  2. ** Command & Conquer(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: F:\projects\c&c\vcs\code\mplayer.cpv 1.9 16 Oct 1995 16:51:08 JOE_BOSTIC $ */
  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 : MPLAYER.CPP *
  26. * *
  27. * Programmer : Bill Randolph *
  28. * *
  29. * Start Date : April 14, 1995 *
  30. * *
  31. * Last Update : July 5, 1995 [BRR] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * Select_MPlayer_Game -- prompts user for NULL-Modem, Modem, or Network game *
  36. * Read_MultiPlayer_Settings -- reads multi-player settings from conquer.ini *
  37. * Write_MultiPlayer_Settings -- writes multi-player settings to conquer.ini *
  38. * Read_Scenario_Descriptions -- reads multi-player scenario #'s # descriptions *
  39. * Free_Scenario_Descriptions -- frees memory for the scenario descriptions *
  40. * Computer_Message -- "sends" a message from the computer *
  41. * Garble_Message -- "garbles" a message *
  42. * Surrender_Dialog -- Prompts user for surrendering *
  43. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  44. #include "function.h"
  45. #include "tcpip.h"
  46. static void Garble_Message(char *buf);
  47. int Choose_Internet_Game(void);
  48. int Get_Internet_Host_Or_Join(void);
  49. int Get_IP_Address(void);
  50. void Show_Internet_Connection_Progress(void);
  51. /***********************************************************************************************
  52. * Select_MPlayer_Game -- prompts user for NULL-Modem, Modem, or Network game *
  53. * *
  54. * INPUT: *
  55. * none. *
  56. * *
  57. * OUTPUT: *
  58. * GAME_NORMAL, GAME_MODEM, etc. *
  59. * *
  60. * WARNINGS: *
  61. * none. *
  62. * *
  63. * HISTORY: *
  64. * 02/14/1995 BR : Created. *
  65. *=============================================================================================*/
  66. GameType Select_MPlayer_Game (void)
  67. {
  68. int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2;
  69. bool ipx_avail = FALSE;
  70. int number_of_buttons;
  71. /*........................................................................
  72. Dialog & button dimensions
  73. ........................................................................*/
  74. int d_dialog_w = 190*factor;
  75. int d_dialog_h = 26*4*factor;
  76. int d_dialog_x = ((320*factor - d_dialog_w) / 2);
  77. // d_dialog_y = ((200 - d_dialog_h) / 2),
  78. int d_dialog_y = ((136*factor - d_dialog_h) / 2);
  79. int d_dialog_cx = d_dialog_x + (d_dialog_w / 2);
  80. int d_txt6_h = 11 * factor;
  81. int d_margin = 7 *factor;
  82. int d_modemserial_w = 80*factor;
  83. int d_modemserial_h = 9*factor;
  84. int d_modemserial_x = d_dialog_cx - d_modemserial_w / 2;
  85. int d_modemserial_y = d_dialog_y + d_margin + d_txt6_h + d_margin;
  86. #if (0)
  87. int d_internet_w = 80*factor;
  88. int d_internet_h = 9*factor;
  89. int d_internet_x = d_dialog_cx - d_internet_w / 2;
  90. int d_internet_y = d_modemserial_y + d_modemserial_h + 2*factor;
  91. #endif //(0)
  92. int d_ipx_w = 80*factor;
  93. int d_ipx_h = 9*factor;
  94. int d_ipx_x = d_dialog_cx - d_ipx_w / 2;
  95. int d_ipx_y = d_modemserial_y + d_modemserial_h + 2*factor;
  96. // int d_ipx_y = d_internet_y + d_internet_h + 2*factor;
  97. int d_cancel_w = 60*factor;
  98. int d_cancel_h = 9*factor;
  99. int d_cancel_x = d_dialog_cx - d_cancel_w / 2;
  100. int d_cancel_y = d_ipx_y + d_ipx_h + d_margin;
  101. CountDownTimerClass delay;
  102. /*........................................................................
  103. Button enumerations:
  104. ........................................................................*/
  105. enum {
  106. BUTTON_MODEMSERIAL = 100,
  107. #if (0)
  108. BUTTON_INTERNET,
  109. #endif //(0)
  110. BUTTON_IPX,
  111. BUTTON_CANCEL,
  112. NUM_OF_BUTTONS = 3,
  113. };
  114. number_of_buttons = NUM_OF_BUTTONS;
  115. /*........................................................................
  116. Redraw values: in order from "top" to "bottom" layer of the dialog
  117. ........................................................................*/
  118. typedef enum {
  119. REDRAW_NONE = 0,
  120. REDRAW_BUTTONS, // includes map interior & coord values
  121. REDRAW_BACKGROUND, // includes box, map bord, key, coord labels, btns
  122. REDRAW_ALL = REDRAW_BACKGROUND
  123. } RedrawType;
  124. /*........................................................................
  125. Dialog variables:
  126. ........................................................................*/
  127. KeyNumType input; // input from user
  128. bool process; // loop while true
  129. RedrawType display; // true = re-draw everything
  130. GameType retval; // return value
  131. int selection;
  132. bool pressed;
  133. int curbutton;
  134. TextButtonClass *buttons[NUM_OF_BUTTONS];
  135. /*........................................................................
  136. Buttons
  137. ........................................................................*/
  138. ControlClass *commands = NULL; // the button list
  139. //
  140. // If neither IPX or winsock are active then do only the modem serial dialog
  141. //
  142. if (Ipx.Is_IPX){
  143. ipx_avail = TRUE;
  144. }
  145. TextButtonClass modemserialbtn (BUTTON_MODEMSERIAL, TXT_MODEM_SERIAL,
  146. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
  147. d_modemserial_x, d_modemserial_y, d_modemserial_w, d_modemserial_h);
  148. #if (0)
  149. TextButtonClass internetbtn (BUTTON_INTERNET, TXT_INTERNET,
  150. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
  151. d_internet_x, d_internet_y, d_internet_w, d_internet_h);
  152. #endif //(0)
  153. TextButtonClass ipxbtn (BUTTON_IPX, TXT_NETWORK,
  154. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
  155. d_ipx_x, d_ipx_y, d_ipx_w, d_ipx_h);
  156. TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL,
  157. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
  158. d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h);
  159. /*
  160. ------------------------------- Initialize -------------------------------
  161. */
  162. Set_Logic_Page(SeenBuff);
  163. /*
  164. ............................ Create the list .............................
  165. */
  166. commands = &modemserialbtn;
  167. #if (0)
  168. internetbtn.Add_Tail(*commands);
  169. #endif //(0)
  170. if (ipx_avail){
  171. ipxbtn.Add_Tail(*commands);
  172. }
  173. cancelbtn.Add_Tail(*commands);
  174. /*
  175. ......................... Fill array of button ptrs ......................
  176. */
  177. curbutton = 0;
  178. buttons[0] = &modemserialbtn;
  179. #if (0)
  180. buttons[1] = &internetbtn;
  181. #endif //(0)
  182. if (ipx_avail){
  183. buttons[1] = &ipxbtn;
  184. buttons[2] = &cancelbtn;
  185. }else{
  186. buttons[1] = &cancelbtn;
  187. number_of_buttons--;
  188. }
  189. buttons[curbutton]->Turn_On();
  190. Keyboard::Clear();
  191. Fancy_Text_Print(TXT_NONE, 0, 0, CC_GREEN, TBLACK,
  192. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
  193. /*
  194. -------------------------- Main Processing Loop --------------------------
  195. */
  196. display = REDRAW_ALL;
  197. process = true;
  198. pressed = false;
  199. while (process) {
  200. /*
  201. ** If we have just received input focus again after running in the background then
  202. ** we need to redraw.
  203. */
  204. if (AllSurfaces.SurfacesRestored){
  205. AllSurfaces.SurfacesRestored=FALSE;
  206. display=REDRAW_ALL;
  207. }
  208. /*
  209. ........................ Invoke game callback .........................
  210. */
  211. Call_Back();
  212. /*
  213. ...................... Refresh display if needed ......................
  214. */
  215. if (display) {
  216. Hide_Mouse();
  217. if (display >= REDRAW_BACKGROUND) {
  218. /*
  219. ..................... Refresh the backdrop ......................
  220. */
  221. Load_Title_Screen("HTITLE.PCX", &HidPage, Palette);
  222. HidPage.Blit(SeenBuff);
  223. /*
  224. ..................... Draw the background .......................
  225. */
  226. Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
  227. Draw_Caption (TXT_SELECT_MPLAYER_GAME, d_dialog_x, d_dialog_y, d_dialog_w);
  228. }
  229. /*
  230. .......................... Redraw buttons ..........................
  231. */
  232. if (display >= REDRAW_BUTTONS) {
  233. commands->Flag_List_To_Redraw();
  234. }
  235. Show_Mouse();
  236. display = REDRAW_NONE;
  237. }
  238. /*
  239. ........................... Get user input ............................
  240. */
  241. input = commands->Input();
  242. /*
  243. ............................ Process input ............................
  244. */
  245. switch (input) {
  246. case (BUTTON_MODEMSERIAL | KN_BUTTON):
  247. selection = BUTTON_MODEMSERIAL;
  248. pressed = true;
  249. break;
  250. #if (0)
  251. case (BUTTON_INTERNET | KN_BUTTON):
  252. selection = BUTTON_INTERNET;
  253. pressed = true;
  254. break;
  255. #endif //(0)
  256. case (BUTTON_IPX | KN_BUTTON):
  257. selection = BUTTON_IPX;
  258. pressed = true;
  259. break;
  260. case (KN_ESC):
  261. case (BUTTON_CANCEL | KN_BUTTON):
  262. selection = BUTTON_CANCEL;
  263. pressed = true;
  264. break;
  265. case KN_UP:
  266. buttons[curbutton]->Turn_Off();
  267. buttons[curbutton]->Flag_To_Redraw();
  268. curbutton--;
  269. if (curbutton < 0)
  270. curbutton = (number_of_buttons - 1);
  271. buttons[curbutton]->Turn_On();
  272. buttons[curbutton]->Flag_To_Redraw();
  273. break;
  274. case KN_DOWN:
  275. buttons[curbutton]->Turn_Off();
  276. buttons[curbutton]->Flag_To_Redraw();
  277. curbutton++;
  278. if (curbutton > (number_of_buttons - 1) )
  279. curbutton = 0;
  280. buttons[curbutton]->Turn_On();
  281. buttons[curbutton]->Flag_To_Redraw();
  282. break;
  283. case KN_RETURN:
  284. selection = curbutton + BUTTON_MODEMSERIAL;
  285. if (!ipx_avail) selection--;
  286. pressed = true;
  287. break;
  288. default:
  289. break;
  290. }
  291. if (pressed) {
  292. //
  293. // to make sure the selection is correct in case they used the mouse
  294. //
  295. buttons[curbutton]->Turn_Off();
  296. buttons[curbutton]->Flag_To_Redraw();
  297. curbutton = selection - BUTTON_MODEMSERIAL;
  298. buttons[curbutton]->Turn_On();
  299. // buttons[curbutton]->Flag_To_Redraw();
  300. buttons[curbutton]->IsPressed = true;
  301. buttons[curbutton]->Draw_Me(true);
  302. switch (selection) {
  303. case (BUTTON_MODEMSERIAL):
  304. //
  305. // Pop up the modem/serial/com port dialog
  306. //
  307. retval = Select_Serial_Dialog();
  308. if (retval != GAME_NORMAL) {
  309. process = false;
  310. } else {
  311. buttons[curbutton]->IsPressed = false;
  312. display = REDRAW_ALL;
  313. }
  314. break;
  315. #if (0)
  316. case (BUTTON_INTERNET):
  317. //#define ONLY_FOR_E3
  318. #ifdef ONLY_FOR_E3
  319. Call_Back();
  320. Show_Internet_Connection_Progress(); //changed to do nothing
  321. Hide_Mouse();
  322. Load_Title_Screen("HTITLE.PCX", &HidPage, Palette);
  323. HidPage.Blit(SeenBuff);
  324. Show_Mouse();
  325. Call_Back();
  326. CCMessageBox().Process("Error! - Unable to ping KANE.WESTWOOD.COM");
  327. buttons[curbutton]->IsPressed = false;
  328. display = REDRAW_ALL;
  329. #endif //ONLY_FOR_E3
  330. #ifdef FORCE_WINSOCK
  331. if (Winsock.Init()){
  332. Read_MultiPlayer_Settings ();
  333. int result = Choose_Internet_Game();
  334. if (!result){
  335. Winsock.Close();
  336. buttons[curbutton]->IsPressed = false;
  337. display = REDRAW_ALL;
  338. break;
  339. }
  340. result = Get_Internet_Host_Or_Join();
  341. if (result == 1){
  342. Winsock.Close();
  343. buttons[curbutton]->IsPressed = false;
  344. display = REDRAW_ALL;
  345. break;
  346. }
  347. Server = !result;
  348. if (Server){
  349. #if (0)
  350. ModemGameToPlay = INTERNET_HOST;
  351. Winsock.Start_Server();
  352. #else
  353. result = Get_IP_Address();
  354. if (!result){
  355. Winsock.Close();
  356. buttons[curbutton]->IsPressed = false;
  357. display = REDRAW_ALL;
  358. break;
  359. }
  360. Winsock.Set_Host_Address(PlanetWestwoodIPAddress);
  361. Winsock.Start_Server();
  362. #endif
  363. }else{
  364. ModemGameToPlay = INTERNET_JOIN;
  365. result = Get_IP_Address();
  366. if (!result){
  367. Winsock.Close();
  368. buttons[curbutton]->IsPressed = false;
  369. display = REDRAW_ALL;
  370. break;
  371. }
  372. Winsock.Set_Host_Address(PlanetWestwoodIPAddress);
  373. Winsock.Start_Client();
  374. }
  375. //CountDownTimerClass connect_timeout;
  376. //connect_timeout.Set(15*60);
  377. ////Show_Internet_Connection_Progress();
  378. if (!Winsock.Get_Connected()){
  379. Winsock.Close();
  380. return(GAME_NORMAL);
  381. }
  382. SerialSettingsType *settings;
  383. settings = &SerialDefaults;
  384. Init_Null_Modem(settings);
  385. if (Server){
  386. if (Com_Scenario_Dialog()){
  387. return (GAME_INTERNET);
  388. }else{
  389. Winsock.Close();
  390. return (GAME_NORMAL);
  391. }
  392. }else{
  393. if (Com_Show_Scenario_Dialog()){
  394. return (GAME_INTERNET);
  395. }else{
  396. Winsock.Close();
  397. return (GAME_NORMAL);
  398. }
  399. }
  400. }
  401. #endif //FORCE_WINSOCK
  402. break;
  403. #endif //(0)
  404. case (BUTTON_IPX):
  405. retval = GAME_IPX;
  406. process = false;
  407. break;
  408. case (BUTTON_CANCEL):
  409. retval = GAME_NORMAL;
  410. process = false;
  411. break;
  412. }
  413. pressed = false;
  414. }
  415. }
  416. return(retval);
  417. }
  418. /***********************************************************************************************
  419. * Read_MultiPlayer_Settings -- reads multi-player settings from conquer.ini *
  420. * *
  421. * INPUT: *
  422. * none. *
  423. * *
  424. * OUTPUT: *
  425. * none. *
  426. * *
  427. * WARNINGS: *
  428. * none. *
  429. * *
  430. * HISTORY: *
  431. * 02/14/1995 BR : Created. *
  432. *=============================================================================================*/
  433. void Read_MultiPlayer_Settings (void)
  434. {
  435. char *buffer; // INI staging buffer pointer.
  436. char *tbuffer; // Accumulation buffer of trigger IDs.
  437. int len; // Length of data in buffer.
  438. char *tokenptr; // ptr to token
  439. PhoneEntryClass *phone; // a phone book entry
  440. char *entry; // a phone book entry
  441. char buf[128]; // buffer for parsing INI entry
  442. int i;
  443. CELL cell;
  444. /*------------------------------------------------------------------------
  445. Fetch working pointer to the INI staging buffer. Make sure that the buffer
  446. is cleared out before proceeding. (Don't use the HidPage for this, since
  447. the HidPage may be needed for various uncompressions during the INI
  448. parsing.)
  449. ------------------------------------------------------------------------*/
  450. buffer = (char *)_ShapeBuffer;
  451. memset(buffer, '\0', _ShapeBufferSize);
  452. /*------------------------------------------------------------------------
  453. Clear the initstring entries
  454. ------------------------------------------------------------------------*/
  455. for (i = 0; i < InitStrings.Count(); i++) {
  456. delete[] InitStrings[i];
  457. }
  458. InitStrings.Clear();
  459. /*------------------------------------------------------------------------
  460. Clear the dialing entries
  461. ------------------------------------------------------------------------*/
  462. for (i = 0; i < PhoneBook.Count(); i++) {
  463. delete PhoneBook[i];
  464. }
  465. PhoneBook.Clear();
  466. /*------------------------------------------------------------------------
  467. Create filename and read the file.
  468. ------------------------------------------------------------------------*/
  469. CCFileClass file ("CONQUER.INI");
  470. if (!file.Is_Available()) {
  471. return;
  472. } else {
  473. file.Read(buffer, _ShapeBufferSize-1);
  474. }
  475. file.Close();
  476. if (!Special.IsFromWChat){
  477. /*------------------------------------------------------------------------
  478. Get the player's last-used Handle
  479. ------------------------------------------------------------------------*/
  480. WWGetPrivateProfileString("MultiPlayer", "Handle", "Noname", MPlayerName,
  481. sizeof(MPlayerName), buffer);
  482. /*------------------------------------------------------------------------
  483. Get the player's last-used Color
  484. ------------------------------------------------------------------------*/
  485. MPlayerPrefColor = WWGetPrivateProfileInt("MultiPlayer", "Color", 0, buffer);
  486. MPlayerHouse = (HousesType)WWGetPrivateProfileInt("MultiPlayer", "Side",
  487. HOUSE_GOOD, buffer);
  488. CurPhoneIdx = WWGetPrivateProfileInt("MultiPlayer", "PhoneIndex", -1, buffer);
  489. }else{
  490. CurPhoneIdx = -1;
  491. }
  492. #if 1
  493. TrapCheckHeap = WWGetPrivateProfileInt( "MultiPlayer", "CheckHeap", 0, buffer);
  494. #endif
  495. /*------------------------------------------------------------------------
  496. Read in default serial settings
  497. ------------------------------------------------------------------------*/
  498. WWGetPrivateProfileString ("SerialDefaults", "ModemName", "NoName", SerialDefaults.ModemName, MODEM_NAME_MAX, buffer);
  499. if (!strcmp ( SerialDefaults.ModemName, "NoName")) {
  500. SerialDefaults.ModemName[0] = 0;
  501. }
  502. WWGetPrivateProfileString ("SerialDefaults", "Port", "0", buf, 5, buffer);
  503. sscanf (buf, "%x", &SerialDefaults.Port);
  504. SerialDefaults.IRQ = WWGetPrivateProfileInt("SerialDefaults", "IRQ", -1, buffer);
  505. SerialDefaults.Baud = WWGetPrivateProfileInt("SerialDefaults", "Baud", -1, buffer);
  506. SerialDefaults.Init = WWGetPrivateProfileInt("SerialDefaults", "Init", 0, buffer);
  507. SerialDefaults.Compression = WWGetPrivateProfileInt ("SerialDefaults", "Compression", 0, buffer);
  508. SerialDefaults.ErrorCorrection = WWGetPrivateProfileInt ("SerialDefaults", "ErrorCorrection", 0, buffer);
  509. SerialDefaults.HardwareFlowControl = WWGetPrivateProfileInt ("SerialDefaults", "HardwareFlowControl", 1, buffer);
  510. WWGetPrivateProfileString ("SerialDefaults", "DialMethod", "T",
  511. buf, 2, buffer);
  512. // find dial method
  513. for (i = 0; i < DIAL_METHODS; i++) {
  514. if ( !strcmpi( buf, DialMethodCheck[ i ]) ) {
  515. SerialDefaults.DialMethod = (DialMethodType)i;
  516. break;
  517. }
  518. }
  519. // if method not found set to touch tone
  520. if (i == DIAL_METHODS) {
  521. SerialDefaults.DialMethod = DIAL_TOUCH_TONE;
  522. }
  523. SerialDefaults.InitStringIndex =
  524. WWGetPrivateProfileInt("SerialDefaults",
  525. "InitStringIndex", 0, buffer);
  526. SerialDefaults.CallWaitStringIndex =
  527. WWGetPrivateProfileInt("SerialDefaults",
  528. "CallWaitStringIndex", CALL_WAIT_CUSTOM,
  529. buffer);
  530. WWGetPrivateProfileString ("SerialDefaults", "CallWaitString", "",
  531. SerialDefaults.CallWaitString, CWAITSTRBUF_MAX, buffer);
  532. if (SerialDefaults.IRQ == 0 ||
  533. SerialDefaults.Baud == 0) {
  534. SerialDefaults.Port = 0;
  535. SerialDefaults.IRQ = -1;
  536. SerialDefaults.Baud = -1;
  537. }
  538. /*------------------------------------------------------------------------
  539. Set 'tbuffer' to point past the actual INI data
  540. ------------------------------------------------------------------------*/
  541. len = strlen(buffer) + 2;
  542. tbuffer = buffer + len;
  543. /*------------------------------------------------------------------------
  544. Read all Base-Scenario names into 'tbuffer'
  545. ------------------------------------------------------------------------*/
  546. WWGetPrivateProfileString("InitStrings", NULL, NULL, tbuffer,
  547. ShapeBufferSize-len, buffer);
  548. /*------------------------------------------------------------------------
  549. Read in & store each entry
  550. ------------------------------------------------------------------------*/
  551. while (*tbuffer != '\0') {
  552. entry = new char[ INITSTRBUF_MAX ];
  553. entry[0] = 0;
  554. WWGetPrivateProfileString("InitStrings", tbuffer, NULL, entry,
  555. INITSTRBUF_MAX, buffer);
  556. strupr( entry );
  557. InitStrings.Add( entry );
  558. tbuffer += strlen(tbuffer) + 1;
  559. }
  560. // if no entries then have at least one
  561. if ( tbuffer == (buffer + len) ) {
  562. entry = new char[ INITSTRBUF_MAX ];
  563. strcpy( entry, "ATZ" );
  564. InitStrings.Add( entry );
  565. SerialDefaults.InitStringIndex = 0;
  566. } else {
  567. len = strlen(buffer) + 2;
  568. }
  569. /*------------------------------------------------------------------------
  570. Repeat the process for the phonebook
  571. ------------------------------------------------------------------------*/
  572. tbuffer = buffer + len;
  573. /*------------------------------------------------------------------------
  574. Read in all phone book listings.
  575. Format: Name=PhoneNum,Port,IRQ,Baud,InitString
  576. ------------------------------------------------------------------------*/
  577. /*........................................................................
  578. Read the entry names in
  579. ........................................................................*/
  580. WWGetPrivateProfileString("PhoneBook", NULL, NULL, tbuffer,
  581. ShapeBufferSize-len, buffer);
  582. while (*tbuffer != '\0') {
  583. /*.....................................................................
  584. Create a new phone book entry
  585. .....................................................................*/
  586. phone = new PhoneEntryClass();
  587. /*.....................................................................
  588. Read the entire entry in
  589. .....................................................................*/
  590. WWGetPrivateProfileString("PhoneBook", tbuffer, NULL, buf, 128, buffer);
  591. /*.....................................................................
  592. Extract name, phone # & serial port settings
  593. .....................................................................*/
  594. tokenptr = strtok( buf, "|" );
  595. if (tokenptr) {
  596. strcpy( phone->Name, tokenptr );
  597. strupr( phone->Name );
  598. } else {
  599. phone->Name[0] = 0;
  600. }
  601. tokenptr = strtok( NULL, "|" );
  602. if (tokenptr) {
  603. strcpy( phone->Number, tokenptr );
  604. strupr( phone->Number );
  605. } else {
  606. phone->Number[0] = 0;
  607. }
  608. tokenptr = strtok( NULL, "|" );
  609. if (tokenptr) {
  610. sscanf( tokenptr, "%x", &phone->Settings.Port );
  611. } else {
  612. phone->Settings.Port = 0;
  613. }
  614. tokenptr = strtok( NULL, "|" );
  615. if (tokenptr) {
  616. phone->Settings.IRQ = atoi( tokenptr );
  617. } else {
  618. phone->Settings.IRQ = -1;
  619. }
  620. tokenptr = strtok( NULL, "|" );
  621. if (tokenptr) {
  622. phone->Settings.Baud = atoi( tokenptr );
  623. } else {
  624. phone->Settings.Baud = -1;
  625. }
  626. tokenptr = strtok( NULL, "|" );
  627. if (tokenptr) {
  628. phone->Settings.Compression = atoi( tokenptr );
  629. } else {
  630. phone->Settings.Compression = 0;
  631. }
  632. tokenptr = strtok( NULL, "|" );
  633. if (tokenptr) {
  634. phone->Settings.ErrorCorrection = atoi( tokenptr );
  635. } else {
  636. phone->Settings.ErrorCorrection = 0;
  637. }
  638. tokenptr = strtok( NULL, "|" );
  639. if (tokenptr) {
  640. phone->Settings.HardwareFlowControl = atoi( tokenptr );
  641. } else {
  642. phone->Settings.HardwareFlowControl = 1;
  643. }
  644. tokenptr = strtok( NULL, "|" );
  645. if (tokenptr) {
  646. strcpy( buf, tokenptr );
  647. // find dial method
  648. for (i = 0; i < DIAL_METHODS; i++) {
  649. if ( !strcmpi( buf, DialMethodCheck[ i ]) ) {
  650. phone->Settings.DialMethod = (DialMethodType)i;
  651. break;
  652. }
  653. }
  654. // if method not found set to touch tone
  655. if (i == DIAL_METHODS) {
  656. phone->Settings.DialMethod = DIAL_TOUCH_TONE;
  657. }
  658. } else {
  659. phone->Settings.DialMethod = DIAL_TOUCH_TONE;
  660. }
  661. tokenptr = strtok( NULL, "|" );
  662. if (tokenptr) {
  663. phone->Settings.InitStringIndex = atoi( tokenptr );
  664. } else {
  665. phone->Settings.InitStringIndex = 0;
  666. }
  667. tokenptr = strtok( NULL, "|" );
  668. if (tokenptr) {
  669. phone->Settings.CallWaitStringIndex = atoi( tokenptr );
  670. } else {
  671. phone->Settings.CallWaitStringIndex = CALL_WAIT_CUSTOM;
  672. }
  673. tokenptr = strtok( NULL, "|" );
  674. if (tokenptr) {
  675. strcpy (phone->Settings.CallWaitString, tokenptr);
  676. } else {
  677. phone->Settings.CallWaitString[0] = 0;
  678. }
  679. /*.....................................................................
  680. Add it to our list
  681. .....................................................................*/
  682. PhoneBook.Add(phone);
  683. tbuffer += strlen(tbuffer) + 1;
  684. }
  685. /*------------------------------------------------------------------------
  686. Read special recording playback values, to help find sync bugs
  687. ------------------------------------------------------------------------*/
  688. if (PlaybackGame) {
  689. TrapFrame = WWGetPrivateProfileInt ("SyncBug","Frame",0x7fffffff, buffer);
  690. TrapObjType = (RTTIType)WWGetPrivateProfileInt ("SyncBug","Type",RTTI_NONE, buffer);
  691. WWGetPrivateProfileString ("SyncBug","Type","NONE",buf,80,buffer);
  692. if (!stricmp(buf,"AIRCRAFT"))
  693. TrapObjType = RTTI_AIRCRAFT;
  694. else if (!stricmp(buf,"ANIM"))
  695. TrapObjType = RTTI_ANIM;
  696. else if (!stricmp(buf,"BUILDING"))
  697. TrapObjType = RTTI_BUILDING;
  698. else if (!stricmp(buf,"BULLET"))
  699. TrapObjType = RTTI_BULLET;
  700. else if (!stricmp(buf,"INFANTRY"))
  701. TrapObjType = RTTI_INFANTRY;
  702. else if (!stricmp(buf,"UNIT"))
  703. TrapObjType = RTTI_UNIT;
  704. else {
  705. TrapObjType = RTTI_NONE;
  706. }
  707. WWGetPrivateProfileString ("SyncBug","Coord","0",buf,80,buffer);
  708. sscanf(buf,"%x",&TrapCoord);
  709. WWGetPrivateProfileString ("SyncBug","this","0",buf,80,buffer);
  710. sscanf(buf,"%x",&TrapThis);
  711. WWGetPrivateProfileString ("SyncBug","Cell","0",buf,80,buffer);
  712. cell = atoi(buf);
  713. if (cell) {
  714. TrapCell = &(Map[cell]);
  715. }
  716. }
  717. }
  718. /***********************************************************************************************
  719. * Write_MultiPlayer_Settings -- writes multi-player settings to conquer.ini *
  720. * *
  721. * INPUT: *
  722. * none. *
  723. * *
  724. * OUTPUT: *
  725. * none. *
  726. * *
  727. * WARNINGS: *
  728. * none. *
  729. * *
  730. * HISTORY: *
  731. * 02/14/1995 BR : Created. *
  732. *=============================================================================================*/
  733. void Write_MultiPlayer_Settings (void)
  734. {
  735. char * buffer; // INI staging buffer pointer.
  736. CCFileClass file;
  737. int i;
  738. char entrytext[4];
  739. char buf[128]; // buffer for parsing INI entry
  740. /*------------------------------------------------------------------------
  741. Get a working pointer to the INI staging buffer. Make sure that the buffer
  742. starts cleared out of any data.
  743. ------------------------------------------------------------------------*/
  744. buffer = (char *)_ShapeBuffer;
  745. memset(buffer, '\0', _ShapeBufferSize);
  746. file.Set_Name("CONQUER.INI");
  747. if (file.Is_Available()) {
  748. file.Open(READ);
  749. file.Read(buffer, _ShapeBufferSize-1);
  750. file.Close();
  751. }
  752. /*------------------------------------------------------------------------
  753. Save the player's last-used Handle & Color
  754. ------------------------------------------------------------------------*/
  755. WWWritePrivateProfileInt("MultiPlayer", "PhoneIndex", CurPhoneIdx, buffer);
  756. WWWritePrivateProfileInt ("MultiPlayer", "Color", MPlayerPrefColor, buffer);
  757. WWWritePrivateProfileInt ("MultiPlayer", "Side", MPlayerHouse, buffer);
  758. WWWritePrivateProfileString("MultiPlayer", "Handle", MPlayerName, buffer);
  759. /*------------------------------------------------------------------------
  760. Clear all existing SerialDefault entries.
  761. ------------------------------------------------------------------------*/
  762. WWWritePrivateProfileString ("SerialDefaults", NULL, NULL, buffer);
  763. /*------------------------------------------------------------------------
  764. Save default serial settings in opposite order you want to see them
  765. ------------------------------------------------------------------------*/
  766. WWWritePrivateProfileString("SerialDefaults", "CallWaitString",
  767. SerialDefaults.CallWaitString, buffer);
  768. WWWritePrivateProfileInt ("SerialDefaults", "CallWaitStringIndex", SerialDefaults.CallWaitStringIndex, buffer);
  769. WWWritePrivateProfileInt ("SerialDefaults", "InitStringIndex", SerialDefaults.InitStringIndex, buffer);
  770. WWWritePrivateProfileInt ("SerialDefaults", "Init", SerialDefaults.Init, buffer);
  771. WWWritePrivateProfileString("SerialDefaults", "DialMethod",
  772. DialMethodCheck[ SerialDefaults.DialMethod ], buffer);
  773. WWWritePrivateProfileInt ("SerialDefaults", "Baud", SerialDefaults.Baud, buffer);
  774. WWWritePrivateProfileInt ("SerialDefaults", "IRQ", SerialDefaults.IRQ, buffer);
  775. sprintf(buf, "%x", SerialDefaults.Port);
  776. WWWritePrivateProfileString("SerialDefaults", "Port", buf, buffer);
  777. WWWritePrivateProfileString("SerialDefaults", "ModemName", SerialDefaults.ModemName, buffer);
  778. WWWritePrivateProfileInt ("SerialDefaults", "Compression", SerialDefaults.Compression , buffer);
  779. WWWritePrivateProfileInt ("SerialDefaults", "ErrorCorrection", SerialDefaults.ErrorCorrection, buffer);
  780. WWWritePrivateProfileInt ("SerialDefaults", "HardwareFlowControl", SerialDefaults.HardwareFlowControl, buffer);
  781. /*------------------------------------------------------------------------
  782. Clear all existing InitString entries.
  783. ------------------------------------------------------------------------*/
  784. WWWritePrivateProfileString ("InitStrings", NULL, NULL, buffer);
  785. /*------------------------------------------------------------------------
  786. Save all InitString entries. In descending order so they come out in
  787. ascending order.
  788. ------------------------------------------------------------------------*/
  789. for (i = (InitStrings.Count() - 1); i >= 0; i--) {
  790. sprintf( buf, "%03d", i);
  791. WWWritePrivateProfileString ("InitStrings", buf, InitStrings[i], buffer);
  792. }
  793. /*------------------------------------------------------------------------
  794. Clear all existing Phone Book entries.
  795. ------------------------------------------------------------------------*/
  796. WWWritePrivateProfileString ("PhoneBook", NULL, NULL, buffer);
  797. /*------------------------------------------------------------------------
  798. Save all Phone Book entries.
  799. Format: Entry=Name,PhoneNum,Port,IRQ,Baud,InitString
  800. ------------------------------------------------------------------------*/
  801. for (i = (PhoneBook.Count() - 1); i >= 0; i--) {
  802. sprintf(buf,"%s|%s|%x|%d|%d|%d|%d|%d|%s|%d|%d|%s",
  803. PhoneBook[i]->Name,
  804. PhoneBook[i]->Number,
  805. PhoneBook[i]->Settings.Port,
  806. PhoneBook[i]->Settings.IRQ,
  807. PhoneBook[i]->Settings.Baud,
  808. PhoneBook[i]->Settings.Compression,
  809. PhoneBook[i]->Settings.ErrorCorrection,
  810. PhoneBook[i]->Settings.HardwareFlowControl,
  811. DialMethodCheck[ PhoneBook[i]->Settings.DialMethod ],
  812. PhoneBook[i]->Settings.InitStringIndex,
  813. PhoneBook[i]->Settings.CallWaitStringIndex,
  814. PhoneBook[i]->Settings.CallWaitString);
  815. sprintf( entrytext, "%03d", i );
  816. WWWritePrivateProfileString ("PhoneBook", entrytext, buf, buffer);
  817. }
  818. /*------------------------------------------------------------------------
  819. Write the INI data out to a file.
  820. ------------------------------------------------------------------------*/
  821. file.Open(WRITE);
  822. file.Write(buffer,strlen(buffer));
  823. file.Close();
  824. }
  825. /***********************************************************************************************
  826. * Read_Scenario_Descriptions -- reads multi-player scenario #'s # descriptions *
  827. * *
  828. * INPUT: *
  829. * none. *
  830. * *
  831. * OUTPUT: *
  832. * none. *
  833. * *
  834. * WARNINGS: *
  835. * none. *
  836. * *
  837. * HISTORY: *
  838. * 02/14/1995 BR : Created. *
  839. *=============================================================================================*/
  840. void Read_Scenario_Descriptions (void)
  841. {
  842. char *buffer; // INI staging buffer pointer.
  843. CCFileClass file;
  844. int i;
  845. char fname[20];
  846. /*------------------------------------------------------------------------
  847. Clear the scenario description lists
  848. ------------------------------------------------------------------------*/
  849. MPlayerScenarios.Clear();
  850. MPlayerFilenum.Clear();
  851. /*------------------------------------------------------------------------
  852. Loop through all possible scenario numbers; if a file is available, add
  853. its number to the FileNum list.
  854. ------------------------------------------------------------------------*/
  855. for (i = 0; i < 100; i++) {
  856. Set_Scenario_Name(ScenarioName, i, SCEN_PLAYER_MPLAYER,
  857. SCEN_DIR_EAST, SCEN_VAR_A);
  858. sprintf(fname,"%s.INI",ScenarioName);
  859. file.Set_Name (fname);
  860. if (file.Is_Available()) {
  861. MPlayerFilenum.Add(i);
  862. }
  863. }
  864. /*------------------------------------------------------------------------
  865. Now, for every file in the FileNum list, read in the INI file, and extract
  866. its description.
  867. ------------------------------------------------------------------------*/
  868. for (i = 0; i < MPlayerFilenum.Count(); i++) {
  869. /*.....................................................................
  870. Fetch working pointer to the INI staging buffer. Make sure that the
  871. buffer is cleared out before proceeding.
  872. .....................................................................*/
  873. buffer = (char *)_ShapeBuffer;
  874. memset(buffer, '\0', _ShapeBufferSize);
  875. /*.....................................................................
  876. Create filename and read the file.
  877. .....................................................................*/
  878. Set_Scenario_Name(ScenarioName, MPlayerFilenum[i], SCEN_PLAYER_MPLAYER,
  879. SCEN_DIR_EAST, SCEN_VAR_A);
  880. sprintf(fname,"%s.INI",ScenarioName);
  881. file.Set_Name (fname);
  882. file.Read(buffer, _ShapeBufferSize-1);
  883. file.Close();
  884. /*.....................................................................
  885. Extract description & add it to the list.
  886. .....................................................................*/
  887. WWGetPrivateProfileString("Basic", "Name", "Nulls-Ville",
  888. MPlayerDescriptions[i], 40, buffer);
  889. MPlayerScenarios.Add(MPlayerDescriptions[i]);
  890. }
  891. }
  892. /***********************************************************************************************
  893. * Free_Scenario_Descriptions -- frees memory for the scenario descriptions *
  894. * *
  895. * INPUT: *
  896. * none. *
  897. * *
  898. * OUTPUT: *
  899. * none. *
  900. * *
  901. * WARNINGS: *
  902. * none. *
  903. * *
  904. * HISTORY: *
  905. * 06/05/1995 BRR : Created. *
  906. *=============================================================================================*/
  907. void Free_Scenario_Descriptions(void)
  908. {
  909. int i;
  910. /*------------------------------------------------------------------------
  911. Clear the scenario descriptions & filenames
  912. ------------------------------------------------------------------------*/
  913. MPlayerScenarios.Clear();
  914. MPlayerFilenum.Clear();
  915. /*------------------------------------------------------------------------
  916. Clear the initstring entries
  917. ------------------------------------------------------------------------*/
  918. for (i = 0; i < InitStrings.Count(); i++) {
  919. delete InitStrings[i];
  920. }
  921. InitStrings.Clear();
  922. /*------------------------------------------------------------------------
  923. Clear the dialing entries
  924. ------------------------------------------------------------------------*/
  925. for (i = 0; i < PhoneBook.Count(); i++) {
  926. delete PhoneBook[i];
  927. }
  928. PhoneBook.Clear();
  929. }
  930. /***************************************************************************
  931. * Computer_Message -- "sends" a message from the computer *
  932. * *
  933. * INPUT: *
  934. * none. *
  935. * *
  936. * OUTPUT: *
  937. * none. *
  938. * *
  939. * WARNINGS: *
  940. * none. *
  941. * *
  942. * HISTORY: *
  943. * 06/06/1995 BRR : Created. *
  944. *=========================================================================*/
  945. void Computer_Message(void)
  946. {
  947. int color;
  948. char txt[160];
  949. HousesType house;
  950. HouseClass *ptr;
  951. /*------------------------------------------------------------------------
  952. Find the computer house that the message will be from
  953. ------------------------------------------------------------------------*/
  954. for (house = HOUSE_MULTI1; house < (HOUSE_MULTI1 + MPlayerMax); house++) {
  955. ptr = HouseClass::As_Pointer(house);
  956. if (!ptr || ptr->IsHuman || ptr->IsDefeated) {
  957. continue;
  958. }
  959. /*.....................................................................
  960. Decode this house's color
  961. .....................................................................*/
  962. color = MPlayerTColors[ptr->RemapColor];
  963. /*.....................................................................
  964. We now have a 1/4 chance of echoing one of the human players' messages
  965. back.
  966. .....................................................................*/
  967. if (IRandom(0,3) == 2) {
  968. /*..................................................................
  969. Now we have a 1/3 chance of garbling the human message.
  970. ..................................................................*/
  971. if (IRandom(0,2) == 1) {
  972. Garble_Message(LastMessage);
  973. }
  974. /*..................................................................
  975. Only add the message if there is one to add.
  976. ..................................................................*/
  977. if (strlen(LastMessage)) {
  978. sprintf(txt,"%s %s",Text_String(TXT_FROM_COMPUTER),LastMessage);
  979. Messages.Add_Message(txt, color,
  980. TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0);
  981. }
  982. } else {
  983. sprintf(txt,"%s %s",Text_String(TXT_FROM_COMPUTER),
  984. Text_String(TXT_COMP_MSG1 + IRandom(0,12)));
  985. Messages.Add_Message(txt, color,
  986. TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, 600, 0, 0);
  987. }
  988. return;
  989. }
  990. }
  991. /***************************************************************************
  992. * Garble_Message -- "garbles" a message *
  993. * *
  994. * INPUT: *
  995. * buf buffer to garble; stores output message *
  996. * *
  997. * OUTPUT: *
  998. * none. *
  999. * *
  1000. * WARNINGS: *
  1001. * none. *
  1002. * *
  1003. * HISTORY: *
  1004. * 06/06/1995 BRR : Created. *
  1005. *=========================================================================*/
  1006. static void Garble_Message(char *buf)
  1007. {
  1008. char txt[80];
  1009. char punct[20]; // for punctuation
  1010. char *p; // working ptr
  1011. int numwords; // # words in the phrase
  1012. char *words[40]; // ptrs to various words in the phrase
  1013. int i,j;
  1014. /*------------------------------------------------------------------------
  1015. Pull off any trailing punctuation
  1016. ------------------------------------------------------------------------*/
  1017. p = buf + strlen(buf) - 1;
  1018. while (1) {
  1019. if (p < buf)
  1020. break;
  1021. if (p[0]=='!' || p[0]=='.' || p[0]=='?') {
  1022. p--;
  1023. } else {
  1024. p++;
  1025. break;
  1026. }
  1027. if (strlen(p) >= (sizeof(punct) - 1) ) {
  1028. break;
  1029. }
  1030. }
  1031. strcpy (punct, p);
  1032. p[0] = 0;
  1033. for (i = 0; i < 40; i++) {
  1034. words[i] = NULL;
  1035. }
  1036. /*------------------------------------------------------------------------
  1037. Copy the original buffer
  1038. ------------------------------------------------------------------------*/
  1039. strcpy(txt,buf);
  1040. /*------------------------------------------------------------------------
  1041. Split it up into words
  1042. ------------------------------------------------------------------------*/
  1043. p = strtok (txt, " ");
  1044. numwords = 0;
  1045. while (p) {
  1046. words[numwords] = p;
  1047. numwords++;
  1048. p = strtok (NULL, " ");
  1049. }
  1050. /*------------------------------------------------------------------------
  1051. Now randomly put the words back. Don't use the real random-number
  1052. generator, since different machines will have different LastMessage's,
  1053. and will go out of sync.
  1054. ------------------------------------------------------------------------*/
  1055. buf[0] = 0;
  1056. for (i = 0; i < numwords; i++) {
  1057. j = Sim_IRandom(0,numwords);
  1058. if (words[j] == NULL) { // this word has been used already
  1059. i--;
  1060. continue;
  1061. }
  1062. strcat(buf,words[j]);
  1063. words[j] = NULL;
  1064. if (i < numwords-1)
  1065. strcat(buf," ");
  1066. }
  1067. strcat(buf,punct);
  1068. }
  1069. /***************************************************************************
  1070. * Surrender_Dialog -- Prompts user for surrendering *
  1071. * *
  1072. * INPUT: *
  1073. * none. *
  1074. * *
  1075. * OUTPUT: *
  1076. * 0 = user cancels, 1 = user wants to surrender. *
  1077. * *
  1078. * WARNINGS: *
  1079. * none. *
  1080. * *
  1081. * HISTORY: *
  1082. * 07/05/1995 BRR : Created. *
  1083. *=========================================================================*/
  1084. int Surrender_Dialog(void)
  1085. {
  1086. int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2;
  1087. /*........................................................................
  1088. Dialog & button dimensions
  1089. ........................................................................*/
  1090. int d_dialog_w = 170*factor; // dialog width
  1091. int d_dialog_h = 53*factor; // dialog height
  1092. int d_dialog_x = ((320*factor - d_dialog_w) / 2); // centered x-coord
  1093. int d_dialog_y = ((200*factor - d_dialog_h) / 2); // centered y-coord
  1094. int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // coord of x-center
  1095. int d_txt6_h = 6*factor+1; // ht of 6-pt text
  1096. int d_margin = 5*factor; // margin width/height
  1097. int d_topmargin = 20*factor; // top margin
  1098. int d_ok_w = 45*factor; // ok width
  1099. int d_ok_h = 9*factor; // ok height
  1100. int d_ok_x = d_dialog_cx - d_ok_w - 5*factor; // ok x
  1101. int d_ok_y = d_dialog_y + d_dialog_h - d_ok_h - d_margin; // ok y
  1102. int d_cancel_w = 45*factor; // cancel width
  1103. int d_cancel_h = 9*factor; // cancel height
  1104. int d_cancel_x = d_dialog_cx + 5*factor; // cancel x
  1105. int d_cancel_y = d_dialog_y + d_dialog_h - d_cancel_h - d_margin; // cancel y
  1106. /*........................................................................
  1107. Button enumerations
  1108. ........................................................................*/
  1109. enum {
  1110. BUTTON_OK = 100,
  1111. BUTTON_CANCEL,
  1112. };
  1113. /*........................................................................
  1114. Redraw values: in order from "top" to "bottom" layer of the dialog
  1115. ........................................................................*/
  1116. typedef enum {
  1117. REDRAW_NONE = 0,
  1118. REDRAW_BUTTONS,
  1119. REDRAW_BACKGROUND,
  1120. REDRAW_ALL = REDRAW_BACKGROUND
  1121. } RedrawType;
  1122. /*........................................................................
  1123. Dialog variables
  1124. ........................................................................*/
  1125. RedrawType display; // requested redraw level
  1126. bool process; // loop while true
  1127. KeyNumType input;
  1128. int retcode;
  1129. /*........................................................................
  1130. Buttons
  1131. ........................................................................*/
  1132. ControlClass *commands = NULL; // the button list
  1133. TextButtonClass okbtn (BUTTON_OK, TXT_OK,
  1134. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
  1135. d_ok_x, d_ok_y, d_ok_w, d_ok_h);
  1136. TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL,
  1137. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
  1138. d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h);
  1139. /*
  1140. ------------------------------- Initialize -------------------------------
  1141. */
  1142. Set_Logic_Page(SeenBuff);
  1143. /*
  1144. ......................... Create the button list .........................
  1145. */
  1146. commands = &okbtn;
  1147. cancelbtn.Add_Tail(*commands);
  1148. /*
  1149. -------------------------- Main Processing Loop --------------------------
  1150. */
  1151. display = REDRAW_ALL;
  1152. process = true;
  1153. while (process) {
  1154. /*
  1155. ** If we have just received input focus again after running in the background then
  1156. ** we need to redraw.
  1157. */
  1158. if (AllSurfaces.SurfacesRestored){
  1159. AllSurfaces.SurfacesRestored=FALSE;
  1160. display=REDRAW_ALL;
  1161. }
  1162. /*
  1163. ........................ Invoke game callback .........................
  1164. */
  1165. if (Main_Loop()) {
  1166. retcode = 0;
  1167. process = false;
  1168. }
  1169. /*
  1170. ...................... Refresh display if needed ......................
  1171. */
  1172. if (display) {
  1173. /*
  1174. ...................... Display the dialog box ......................
  1175. */
  1176. Hide_Mouse();
  1177. if (display >= REDRAW_BACKGROUND) {
  1178. Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
  1179. Draw_Caption(TXT_NONE, d_dialog_x, d_dialog_y, d_dialog_w);
  1180. /*
  1181. ....................... Draw the captions .......................
  1182. */
  1183. Fancy_Text_Print(Text_String(TXT_SURRENDER),
  1184. d_dialog_cx, d_dialog_y + d_topmargin,
  1185. CC_GREEN, TBLACK,
  1186. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
  1187. }
  1188. /*
  1189. ........................ Redraw the buttons ........................
  1190. */
  1191. if (display >= REDRAW_BUTTONS) {
  1192. commands->Flag_List_To_Redraw();
  1193. }
  1194. Show_Mouse();
  1195. display = REDRAW_NONE;
  1196. }
  1197. /*
  1198. ........................... Get user input ............................
  1199. */
  1200. input = commands->Input();
  1201. /*
  1202. ............................ Process input ............................
  1203. */
  1204. switch (input) {
  1205. case (KN_RETURN):
  1206. case (BUTTON_OK | KN_BUTTON):
  1207. retcode = 1;
  1208. process = false;
  1209. break;
  1210. case (KN_ESC):
  1211. case (BUTTON_CANCEL | KN_BUTTON):
  1212. retcode = 0;
  1213. process = false;
  1214. break;
  1215. default:
  1216. break;
  1217. }
  1218. }
  1219. /*
  1220. --------------------------- Redraw the display ---------------------------
  1221. */
  1222. HiddenPage.Clear();
  1223. Map.Flag_To_Redraw(true);
  1224. Map.Render();
  1225. return (retcode);
  1226. }