SCORE.CPP 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935
  1. /*
  2. ** Command & Conquer Red Alert(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* $Header: /counterstrike/SCORE.CPP 3 3/14/97 12:02a Steve_tall $ */
  19. /***********************************************************************************************
  20. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Command & Conquer *
  24. * *
  25. * File Name : SCORE.CPP *
  26. * *
  27. * Programmer : Joe L. Bostic *
  28. * *
  29. * Start Date : April 19, 1994 *
  30. * *
  31. * Last Update : May 3, 1995 [BWG] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * Call_Back_Delay -- Combines Call_Back() and Delay() functions *
  36. * Draw_Bar_Graphs -- Draw "Casualties" bar graphs *
  37. * Draw_InfantryMan -- Draw one guy in score screen, update animation *
  38. * Draw_Infantrymen -- Draw all the guys on the score screen *
  39. * New_Infantry_Anim -- Start up a new animation for one of the infantrymen *
  40. * ScoreClass::Count_Up_Print -- Prints a number (up to its max) into a string, cleanly *
  41. * ScoreClass::DO_GDI_GRAPH -- Show # of people or buildings killed on GDI score screen *
  42. * ScoreClass::Delay -- Pauses waiting for keypress. *
  43. * ScoreClass::Presentation -- Main routine to display score screen. *
  44. * ScoreClass::Print_Graph_Title -- Prints title on score screen. *
  45. * ScoreClass::Print_Minutes -- Print out hours/minutes up to max *
  46. * ScoreClass::Pulse_Bar_Graph -- Pulses the bargraph color. *
  47. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  48. #ifndef WIN32
  49. extern short StreamLowImpact;
  50. #endif
  51. #include "function.h"
  52. #define SCORETEXT_X 184
  53. #define SCORETEXT_Y 8
  54. #define CASUALTY_Y 88
  55. #define BUILDING_X 256
  56. #define BUILDING_Y 128
  57. #define BARGRAPH_X 266
  58. #define MAX_BAR_X 318 // max possible is 319 because of bar's right shadow
  59. #define SIZEGBAR 118
  60. #define HALLFAME_X 11
  61. #define HALLFAME_Y 120
  62. #define MULTISCOREX 30
  63. #define TEDIT_FAME 1
  64. #define NUMINFANTRYMEN 10
  65. #define NUMFAMENAMES 7
  66. #define MAX_FAMENAME_LENGTH 11
  67. #ifndef WIN32
  68. extern short StreamLowImpact;
  69. #endif //WIN32
  70. GraphicBufferClass *PseudoSeenBuff;
  71. struct InfantryAnim {
  72. int xpos;
  73. int ypos;
  74. void const *shapefile;
  75. void const *remap;
  76. int anim;
  77. int stage;
  78. char delay;
  79. InfantryTypeClass const *Class;
  80. } InfantryMan[NUMINFANTRYMEN];
  81. void Draw_InfantryMen(void);
  82. void Draw_InfantryMan(int index);
  83. void New_Infantry_Anim(int index, int anim);
  84. void Draw_Bar_Graphs(int i, int gkilled, int nkilled);
  85. void Animate_Cursor(int pos, int ypos);
  86. void Animate_Score_Objs(void);
  87. void Cycle_Wait_Click(bool cycle=true);
  88. #ifdef FIXIT_SCORE_CRASH
  89. void Disable_Uncompressed_Shapes (void);
  90. void Enable_Uncompressed_Shapes (void);
  91. #endif //FIXIT
  92. void const * Beepy6;
  93. int ControlQ; // cheat key to skip past score/mapsel screens
  94. bool StillUpdating;
  95. #ifdef WIN32
  96. char *ScreenNames[2]={"ALIBACKH.PCX", "SOVBACKH.PCX"};
  97. #else
  98. char *ScreenNames[2]={"ALI-TRAN.WSA", "SOV-TRAN.WSA"};
  99. #endif
  100. //#ifdef WIN32
  101. //TextBlitClass BlitList;
  102. //#endif
  103. struct Fame {
  104. char name[MAX_FAMENAME_LENGTH];
  105. int score;
  106. int level;
  107. int side;
  108. };
  109. ScoreAnimClass *ScoreObjs[MAXSCOREOBJS];
  110. ScoreAnimClass::ScoreAnimClass(int x, int y, void const * data)
  111. {
  112. XPos = x * RESFACTOR;
  113. YPos = y * RESFACTOR;
  114. Timer = 0;
  115. DataPtr = data;
  116. }
  117. ScoreTimeClass::ScoreTimeClass(int xpos, int ypos, void const * data, int maxval, int xtimer) :
  118. ScoreAnimClass(xpos, ypos, data)
  119. {
  120. Stage = 0;
  121. MaxStage = maxval;
  122. TimerReset = xtimer;
  123. }
  124. void ScoreTimeClass::Update(void)
  125. {
  126. #ifdef WIN32
  127. GraphicViewPortClass *oldpage;
  128. #else
  129. GraphicBufferClass *oldpage;
  130. #endif
  131. if (!Timer) {
  132. Timer = TimerReset;
  133. if (++Stage >= MaxStage) Stage = 0;
  134. oldpage = LogicPage;
  135. Set_Logic_Page(SeenBuff);
  136. CC_Draw_Shape(DataPtr, Stage, XPos, YPos, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  137. #ifdef WIN32
  138. Set_Logic_Page(*PseudoSeenBuff);
  139. CC_Draw_Shape(DataPtr, Stage, XPos, YPos, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  140. #endif
  141. Set_Logic_Page(oldpage);
  142. }
  143. }
  144. ScoreCredsClass::ScoreCredsClass(int xpos, int ypos, void const * data, int maxval, int xtimer) :
  145. ScoreAnimClass(xpos, ypos, data)
  146. {
  147. Stage = 0;
  148. MaxStage = maxval;
  149. TimerReset = xtimer;
  150. Clock1 = MFCD::Retrieve("CLOCK1.AUD");
  151. CashTurn = MFCD::Retrieve("CASHTURN.AUD");
  152. }
  153. void ScoreCredsClass::Update(void)
  154. {
  155. #ifdef WIN32
  156. GraphicViewPortClass *oldpage;
  157. #else
  158. GraphicBufferClass *oldpage;
  159. #endif
  160. if (!Timer) {
  161. Timer = TimerReset;
  162. if (++Stage >= MaxStage) Stage = 0;
  163. oldpage = LogicPage;
  164. Set_Logic_Page(SeenBuff);
  165. #ifdef WIN32
  166. Play_Sample(Clock1, 255, Options.Normalize_Volume(130));
  167. #else
  168. Play_Sample(Clock1, 255, Options.Normalize_Volume(50));
  169. #endif
  170. CC_Draw_Shape(DataPtr, Stage, XPos, YPos, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  171. #ifdef WIN32
  172. Set_Logic_Page(*PseudoSeenBuff);
  173. CC_Draw_Shape(DataPtr, Stage, XPos, YPos, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  174. #endif
  175. Set_Logic_Page(oldpage);
  176. }
  177. }
  178. ScorePrintClass::ScorePrintClass(int string, int xpos, int ypos, void const * palette, int background) :
  179. ScoreAnimClass(xpos, ypos, Text_String(string))
  180. {
  181. Background = background;
  182. PrimaryPalette = palette;
  183. Stage = 0;
  184. }
  185. ScorePrintClass::ScorePrintClass(void const * string, int xpos, int ypos, void const * palette, int background) :
  186. ScoreAnimClass(xpos, ypos, string)
  187. {
  188. Background = background;
  189. PrimaryPalette = palette;
  190. Stage = 0;
  191. }
  192. void ScorePrintClass::Update(void)
  193. {
  194. static char localstr[2]={0,0};
  195. static char _whitepal[]={0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F};
  196. if (Stage && (((char *)DataPtr)[Stage-1]==0) ) {
  197. for (int i = 0; i < MAXSCOREOBJS; i++) {
  198. if (ScoreObjs[i] == this) {
  199. ScoreObjs[i] = 0;
  200. }
  201. }
  202. delete this;
  203. return;
  204. }
  205. #ifdef WIN32
  206. StillUpdating = true;
  207. #endif
  208. if (!Timer) {
  209. Timer = 1;
  210. int pos = XPos+(Stage*(6*RESFACTOR));
  211. // print the letter properly
  212. if (Stage) {
  213. Set_Font_Palette(PrimaryPalette);
  214. localstr[0]=((char *)DataPtr)[Stage-1];
  215. HidPage.Print(localstr, pos-6*RESFACTOR, YPos, TBLACK, TBLACK);
  216. HidPage.Blit(SeenPage, pos-6*RESFACTOR, YPos-1*RESFACTOR, pos-6*RESFACTOR, YPos-1*RESFACTOR, 7*RESFACTOR, 8*RESFACTOR);
  217. #ifdef WIN32
  218. HidPage.Blit(*PseudoSeenBuff, pos-6*RESFACTOR, YPos-1*RESFACTOR, pos-6*RESFACTOR, YPos-1*RESFACTOR, 7*RESFACTOR, 8*RESFACTOR);
  219. PseudoSeenBuff->Print(localstr, pos-6*RESFACTOR, YPos, TBLACK, TBLACK);
  220. #endif
  221. }
  222. if (((char *)DataPtr)[Stage]) {
  223. localstr[0]=((char *)DataPtr)[Stage];
  224. Set_Font_Palette(_whitepal);
  225. SeenPage.Print(localstr, pos, YPos-1, TBLACK, TBLACK);
  226. SeenPage.Print(localstr, pos, YPos+1, TBLACK, TBLACK);
  227. SeenPage.Print(localstr, pos+1, YPos , TBLACK, TBLACK);
  228. #ifdef WIN32
  229. PseudoSeenBuff->Print(localstr, pos, YPos-1, TBLACK, TBLACK);
  230. PseudoSeenBuff->Print(localstr, pos, YPos+1, TBLACK, TBLACK);
  231. PseudoSeenBuff->Print(localstr, pos+1, YPos , TBLACK, TBLACK);
  232. #endif
  233. }
  234. Stage++;
  235. }
  236. }
  237. ScoreScaleClass::ScoreScaleClass(void const * string, int xpos, int ypos, char const palette[]) :
  238. ScoreAnimClass(xpos, ypos, string)
  239. {
  240. Palette = &palette[0];
  241. #ifdef WIN32
  242. Stage = 0;
  243. #else
  244. Stage = 5;
  245. #endif
  246. }
  247. void ScoreScaleClass::Update(void)
  248. {
  249. static int _destx[]={0,80,107,134,180,228};
  250. static int _destw[]={6,20, 30, 40, 60, 80};
  251. /*
  252. ** Restore the background for the scaled-up letter
  253. */
  254. if (!Timer) {
  255. Timer = 1;
  256. #ifndef WIN32
  257. if (Stage != 5) {
  258. int destx = _destx[Stage+1]*RESFACTOR;
  259. int destw = _destw[Stage+1]*RESFACTOR;
  260. HidPage.Blit(SeenPage, destx, YPos, destx, YPos, (destx + destw) <= 320 * RESFACTOR ? destw : (320 * RESFACTOR) - destx, (YPos + destw) <= 200 * RESFACTOR ? destw : (200 * RESFACTOR) - YPos);
  261. }
  262. #endif
  263. if (Stage) {
  264. Set_Font_Palette(Palette);
  265. HidPage.Fill_Rect(0, 0, 7*RESFACTOR, 7*RESFACTOR, TBLACK);
  266. HidPage.Print((char *)DataPtr, 0, 0, TBLACK, TBLACK);
  267. HidPage.Scale(SeenPage, 0, 0, _destx[Stage]*RESFACTOR, YPos, 5*RESFACTOR, 6*RESFACTOR, _destw[Stage]*RESFACTOR, _destw[Stage]*RESFACTOR, true);
  268. Stage--;
  269. } else {
  270. Set_Font_Palette(Palette);
  271. for (int i = 0; i < MAXSCOREOBJS; i++) {
  272. if (ScoreObjs[i]==this) ScoreObjs[i] = 0;
  273. }
  274. HidPage.Print((char *)DataPtr, XPos, YPos, TBLACK, TBLACK);
  275. HidPage.Blit(SeenPage, XPos, YPos, XPos, YPos, 6*RESFACTOR, 6*RESFACTOR);
  276. #ifdef WIN32
  277. HidPage.Blit(*PseudoSeenBuff, XPos, YPos, XPos, YPos, 6*RESFACTOR, 6*RESFACTOR);
  278. #endif
  279. delete this;
  280. return;
  281. }
  282. }
  283. }
  284. int Alloc_Object(ScoreAnimClass *obj)
  285. {
  286. int i,ret;
  287. for (i = ret = 0; i < MAXSCOREOBJS; i++) {
  288. if (!ScoreObjs[i]) {
  289. ScoreObjs[i] = obj;
  290. ret = i;
  291. break;
  292. }
  293. }
  294. return(ret);
  295. }
  296. /***********************************************************************************************
  297. * ScoreClass::Presentation -- Main routine to display score screen. *
  298. * *
  299. * This is the main routine that displays the score screen graphics. *
  300. * It gets called at the end of each scenario and is used to present *
  301. * the results and a rating of the player's battle. *
  302. * *
  303. * INPUT: none *
  304. * *
  305. * OUTPUT: none *
  306. * *
  307. * WARNINGS: none *
  308. * *
  309. * HISTORY: *
  310. * 05/02/1994 : Created. *
  311. *=============================================================================================*/
  312. static char const _bluepal[]={0xC0,0xC1,0xC1,0xC3,0xC2,0xC5,0xC3,0xC7,0xC4,0xC9,0xCA,0xCB,0xCC,0xCD,0xC0,0xCF};
  313. static char const _greenpal[]={0x70,0x71,0x7C,0x73,0x7D,0x75,0x7E,0x77,0x7F,0x79,0x7A,0x7B,0x7C,0x7D,0x7C,0x7F};
  314. static char const _redpal[]={0xD0,0xD1,0xD7,0xD3,0xD9,0xD5,0xDA,0xD7,0xDB,0xD9,0xDA,0xDB,0xDC,0xDD,0xD6,0xDF};
  315. static char const _yellowpal[]={0x0,0x0,0xEC,0x0,0xEB,0x0,0xEA,0x0,0xE9,0x0,0x0,0x0,0x0,0x0,0xED,0x0};
  316. void ScoreClass::Presentation(void)
  317. {
  318. #ifdef WIN32
  319. // if (Keyboard != NULL) return;
  320. #endif
  321. static int const _casuax[2]={144,150};
  322. static int const _casuay[2]={ 78, 78};
  323. static int const _gditxy[2]={ 90, 90};
  324. #if defined(FRENCH) || defined(GERMAN)
  325. static int const _gditxx[2]={130,150};
  326. static int const _nodtxx[2]={130,150};
  327. #else
  328. static int const _gditxx[2]={135,150};
  329. static int const _nodtxx[2]={135,150};
  330. #endif
  331. static int const _nodtxy[2]={102,102};
  332. static int const _bldggy[2]={138,138};
  333. static int const _bldgny[2]={150,150};
  334. #ifdef WIN32
  335. #ifdef FIXIT_SCORE_CRASH
  336. /*
  337. ** Fix for the score screen crash due to uncompressed shape buffer overflow.
  338. */
  339. Disable_Uncompressed_Shapes();
  340. #endif //FIXIT
  341. PseudoSeenBuff = new GraphicBufferClass(SeenBuff.Get_Width(),SeenBuff.Get_Height(),(void*)NULL);
  342. #endif
  343. int i;
  344. void const * yellowptr;
  345. void const * redptr;
  346. CCFileClass file(FAME_FILE_NAME);
  347. struct Fame hallfame[NUMFAMENAMES];
  348. void *oldfont;
  349. int oldfontxspacing = FontXSpacing;
  350. int house = (PlayerPtr->Class->House == HOUSE_USSR || PlayerPtr->Class->House == HOUSE_UKRAINE); // 0 or 1
  351. #ifdef WIN32
  352. char inter_pal[15];
  353. sprintf(inter_pal, "SCORPAL1.PAL");
  354. #endif
  355. ControlQ = 0;
  356. FontXSpacing = 0;
  357. Map.Override_Mouse_Shape(MOUSE_NORMAL);
  358. Theme.Queue_Song(THEME_SCORE);
  359. #ifdef WIN32
  360. VisiblePage.Clear();
  361. SysMemPage.Clear();
  362. WWMouse->Erase_Mouse(&HidPage, TRUE);
  363. HiddenPage.Clear();
  364. Set_Logic_Page(SysMemPage);
  365. #else
  366. SeenPage.Clear();
  367. HidPage.Clear();
  368. Set_Logic_Page(HidPage);
  369. #endif
  370. BlackPalette.Set();
  371. void const * country4 = MFCD::Retrieve("COUNTRY4.AUD");
  372. void const * sfx4 = MFCD::Retrieve("SFX4.AUD");
  373. Beepy6 = MFCD::Retrieve("BEEPY6.AUD");
  374. /*
  375. ** Load the background for the score screen
  376. */
  377. #ifndef WIN32
  378. void *anim = Open_Animation(ScreenNames[house], NULL, 0L, (WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE), ScorePalette);
  379. #endif
  380. unsigned minutes = (unsigned)((ElapsedTime / (long)TIMER_MINUTE))+1;
  381. // Load up the shapes for the Nod score screen
  382. #ifdef WIN32
  383. yellowptr = MFCD::Retrieve("BAR3BHR.SHP");
  384. redptr = MFCD::Retrieve("BAR3RHR.SHP");
  385. #else
  386. if (!house) {
  387. yellowptr = MFCD::Retrieve("BAR3BLU.SHP");
  388. redptr = MFCD::Retrieve("BAR3RED.SHP");
  389. }
  390. #endif
  391. /* Change to the six-point font for Text_Print */
  392. oldfont = Set_Font(ScoreFontPtr);
  393. Call_Back();
  394. /* --- Now display the background animation --- */
  395. Hide_Mouse();
  396. #ifdef WIN32
  397. Load_Title_Screen(ScreenNames[house], &HidPage, ScorePalette);
  398. Increase_Palette_Luminance (ScorePalette , 30, 30, 30, 63);
  399. HidPage.Blit(SeenPage);
  400. HidPage.Blit(*PseudoSeenBuff);
  401. #else
  402. Animate_Frame(anim, HidPage, 1);
  403. HidPage.Blit(SeenPage);
  404. #endif
  405. ScorePalette.Set(FADE_PALETTE_FAST, Call_Back);
  406. #ifdef WIN32
  407. Play_Sample(country4, 255, Options.Normalize_Volume(150));
  408. #else
  409. Play_Sample(country4, 255, Options.Normalize_Volume(60));
  410. #endif
  411. #ifndef WIN32
  412. int frame = 1;
  413. StreamLowImpact = true;
  414. while (frame < Get_Animation_Frame_Count(anim)) {
  415. Animate_Frame(anim, SeenPage, frame++);
  416. Call_Back_Delay(2);
  417. }
  418. StreamLowImpact = false;
  419. Call_Back();
  420. Close_Animation(anim);
  421. #endif
  422. /*
  423. ** Background's up, so now load various shapes and animations
  424. */
  425. #ifdef WIN32
  426. void const * timeshape = MFCD::Retrieve("TIMEHR.SHP");
  427. void const * hiscore1shape = MFCD::Retrieve("HISC1-HR.SHP");
  428. void const * hiscore2shape = MFCD::Retrieve("HISC2-HR.SHP");
  429. #else
  430. void const * timeshape = MFCD::Retrieve("TIME.SHP");
  431. void const * hiscore1shape = MFCD::Retrieve("HISCORE1.SHP");
  432. void const * hiscore2shape = MFCD::Retrieve("HISCORE2.SHP");
  433. #endif
  434. ScoreObjs[0] = new ScoreTimeClass(238, 2, timeshape, 30, 4);
  435. ScoreObjs[1] = new ScoreTimeClass(4, 89, hiscore1shape, 10, 4);
  436. ScoreObjs[2] = new ScoreTimeClass(4, 180, hiscore2shape, 10, 4);
  437. /* Now display the stuff */
  438. #ifdef WIN32
  439. #else
  440. SeenPage.Blit(HidPage);
  441. #endif
  442. Set_Logic_Page(SeenBuff);
  443. #ifdef FRENCH
  444. Alloc_Object(new ScorePrintClass(TXT_SCORE_TIME, 198, 9, _greenpal));
  445. #else
  446. Alloc_Object(new ScorePrintClass(TXT_SCORE_TIME, 204, 9, _greenpal));
  447. #endif
  448. Alloc_Object(new ScorePrintClass(TXT_SCORE_LEAD, 164, 26, _greenpal));
  449. Alloc_Object(new ScorePrintClass(TXT_SCORE_EFFI, 164, 38, _greenpal));
  450. Alloc_Object(new ScorePrintClass(TXT_SCORE_TOTA, 164, 50, _greenpal));
  451. #ifdef WIN32
  452. Play_Sample(sfx4, 255, Options.Normalize_Volume(150));
  453. #else
  454. Play_Sample(sfx4, 255, Options.Normalize_Volume(60));
  455. #endif
  456. Call_Back_Delay(13);
  457. int scorecounter = 0;
  458. Keyboard->Clear();
  459. /*
  460. ** Determine leadership rating.
  461. */
  462. int leadership = 0;
  463. for (int index = 0; index < Logic.Count(); index++) {
  464. ObjectClass * object = Logic[index];
  465. HousesType owner = object->Owner();
  466. if ( (house) && (owner == HOUSE_USSR || owner == HOUSE_BAD || owner == HOUSE_UKRAINE) ) {
  467. leadership++;
  468. } else {
  469. if ( (!house) && (object->Owner() == HOUSE_GREECE) ) {
  470. leadership++;
  471. }
  472. }
  473. }
  474. int uspoints = 0;
  475. for (HousesType hous = HOUSE_SPAIN; hous <= HOUSE_BAD; hous++) {
  476. HouseClass *hows = HouseClass::As_Pointer(hous);
  477. if (hous == HOUSE_USSR || hous == HOUSE_BAD || hous == HOUSE_UKRAINE) {
  478. NKilled += hows->UnitsLost;
  479. NBKilled += hows->BuildingsLost;
  480. } else {
  481. GKilled += hows->UnitsLost;
  482. GBKilled += hows->BuildingsLost;
  483. }
  484. if (PlayerPtr->Is_Ally(hous) ) {
  485. uspoints += hows->PointTotal;
  486. }
  487. }
  488. // if(uspoints < 0) uspoints = 0;
  489. // uspoints += 1000; //BG 1000 bonus points for winning mission
  490. /*
  491. ** Bias the base score upward according to the difficulty level.
  492. */
  493. switch (PlayerPtr->Difficulty) {
  494. case DIFF_EASY:
  495. uspoints += 500;
  496. break;
  497. case DIFF_NORMAL:
  498. uspoints += 1500;
  499. break;
  500. case DIFF_HARD:
  501. uspoints += 3500;
  502. break;
  503. }
  504. if (!leadership) leadership++;
  505. leadership = 100*fixed(leadership, (house ? NKilled+NBKilled+leadership : GKilled+GBKilled+leadership));
  506. leadership = min(150,leadership);
  507. /*
  508. ** Determine economy rating.
  509. */
  510. int init = PlayerPtr->Control.InitialCredits;
  511. int cred = PlayerPtr->Available_Money();
  512. int economy = 100*fixed((unsigned)PlayerPtr->Available_Money()+1+PlayerPtr->StolenBuildingsCredits, PlayerPtr->HarvestedCredits + (unsigned)PlayerPtr->Control.InitialCredits+1);
  513. economy=min(economy,150);
  514. int total = ((uspoints * leadership) / 100) + ((uspoints * economy) / 100);
  515. if (total < -9999) total = -9999;
  516. total = min(total, 99999);
  517. Keyboard->Clear();
  518. for (i = 0; i <= 130; i++) {
  519. Set_Font_Palette(_greenpal);
  520. int lead = (leadership * i) / 100;
  521. Count_Up_Print("%3d%%", lead, leadership, 244, 26);
  522. if (i>=30) {
  523. int econo = (economy * (i-30)) / 100;
  524. Count_Up_Print("%3d%%", econo, economy, 244, 38);
  525. }
  526. Print_Minutes(minutes);
  527. Call_Back_Delay(1);
  528. #ifdef WIN32
  529. Play_Sample(Beepy6, 255, Options.Normalize_Volume(100));
  530. #else
  531. Play_Sample(Beepy6, 255, Options.Normalize_Volume(40));
  532. #endif
  533. if ( (i >= 30) && (i >= leadership) && ((i-30) >= economy) ) break;
  534. //BG if (Keyboard->Check()) break;
  535. }
  536. Count_Up_Print("%3d%%", leadership, leadership, 244, 26);
  537. Count_Up_Print("%3d%%", economy, economy, 244, 38);
  538. char buffer[16];
  539. sprintf(buffer, "x %5d",uspoints);
  540. Alloc_Object(new ScorePrintClass(buffer, 274, 26, _greenpal));
  541. Alloc_Object(new ScorePrintClass(buffer, 274, 38, _greenpal));
  542. Call_Back_Delay(8);
  543. SeenBuff.Draw_Line(274*RESFACTOR, 48*RESFACTOR, 313*RESFACTOR, 48*RESFACTOR, WHITE);
  544. Call_Back_Delay(1);
  545. SeenBuff.Draw_Line(274*RESFACTOR, 48*RESFACTOR, 313*RESFACTOR, 48*RESFACTOR, GREEN);
  546. sprintf(buffer,"%5d", total);
  547. Alloc_Object(new ScorePrintClass(buffer, 286, 50, _greenpal));
  548. //BG if (!Keyboard->Check()) {
  549. Call_Back_Delay(60);
  550. //BG }
  551. if (house) Show_Credits(house, _greenpal);
  552. /*BG if (!Keyboard->Check()) */ Call_Back_Delay(60);
  553. /*
  554. ** Show stats on # of units killed
  555. */
  556. Set_Logic_Page(SeenBuff);
  557. #ifdef WIN32
  558. Play_Sample(sfx4, 255, Options.Normalize_Volume(150));
  559. #else
  560. Play_Sample(sfx4, 255, Options.Normalize_Volume(60));
  561. #endif
  562. int indx = house;
  563. #ifdef WIN32
  564. indx = 0;
  565. #endif
  566. Alloc_Object(new ScorePrintClass(TXT_SCORE_CASU, _casuax[indx], _casuay[indx], _greenpal));
  567. Call_Back_Delay(9);
  568. if (house) {
  569. Alloc_Object(new ScorePrintClass(TXT_SOVIET, _nodtxx[indx], _gditxy[indx], _redpal));
  570. Alloc_Object(new ScorePrintClass(TXT_ALLIES, _gditxx[indx], _nodtxy[indx], _bluepal));
  571. } else {
  572. Alloc_Object(new ScorePrintClass(TXT_ALLIES, _gditxx[indx], _gditxy[indx], _bluepal));
  573. Alloc_Object(new ScorePrintClass(TXT_SOVIET, _nodtxx[indx], _nodtxy[indx], _redpal));
  574. }
  575. Call_Back_Delay(6);
  576. Set_Font_Palette(_redpal);
  577. #ifdef WIN32
  578. Do_GDI_Graph(yellowptr, redptr, GKilled + CKilled, NKilled, 89);
  579. #else
  580. if (house) {
  581. Do_Nod_Casualties_Graph();
  582. } else {
  583. Do_GDI_Graph(yellowptr, redptr, GKilled + CKilled, NKilled, 89);
  584. }
  585. #endif
  586. Set_Logic_Page(SeenBuff);
  587. /*
  588. ** Print out stats on buildings destroyed
  589. */
  590. #ifdef WIN32
  591. Play_Sample(sfx4, 255, Options.Normalize_Volume(150));
  592. #else
  593. Play_Sample(sfx4, 255, Options.Normalize_Volume(60));
  594. #endif
  595. #ifdef WIN32
  596. Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL, 144, 126, _greenpal));
  597. Call_Back_Delay(9);
  598. #else
  599. if (!house) {
  600. Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL, 144, 126, _greenpal));
  601. Call_Back_Delay(9);
  602. } else {
  603. Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL1, 150, 118, _greenpal));
  604. Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL2, 150, 126, _greenpal));
  605. Call_Back_Delay(13);
  606. }
  607. #endif
  608. if(house) {
  609. Alloc_Object(new ScorePrintClass(TXT_SOVIET, _gditxx[indx], _bldggy[indx], _redpal));
  610. Alloc_Object(new ScorePrintClass(TXT_ALLIES, _gditxx[indx], _bldgny[indx], _bluepal));
  611. } else {
  612. Alloc_Object(new ScorePrintClass(TXT_ALLIES, _gditxx[indx], _bldggy[indx], _bluepal));
  613. Alloc_Object(new ScorePrintClass(TXT_SOVIET, _gditxx[indx], _bldgny[indx], _redpal));
  614. }
  615. Call_Back_Delay(7);
  616. #ifdef WIN32
  617. Do_GDI_Graph(yellowptr, redptr, GBKilled + CBKilled, NBKilled, 137);
  618. #else
  619. if (house) {
  620. Call_Back_Delay(6);
  621. Set_Font_Palette(_greenpal);
  622. Do_Nod_Buildings_Graph();
  623. } else {
  624. Do_GDI_Graph(yellowptr, redptr, GBKilled + CBKilled, NBKilled, 137);
  625. }
  626. #endif
  627. #ifdef WIN32
  628. // Wait for text printing to complete
  629. while (StillUpdating) {
  630. Call_Back_Delay(1);
  631. }
  632. #endif
  633. Keyboard->Clear();
  634. if (!house) Show_Credits(house, _greenpal);
  635. /*
  636. ** Hall of fame display and processing
  637. */
  638. #ifdef WIN32
  639. Play_Sample(sfx4, 255, Options.Normalize_Volume(150));
  640. #else
  641. Play_Sample(sfx4, 255, Options.Normalize_Volume(60));
  642. #endif
  643. Alloc_Object(new ScorePrintClass(TXT_SCORE_TOP, 28, 110, _greenpal));
  644. Call_Back_Delay(9);
  645. /*
  646. ** First check for the existence of the file, and if there isn't one,
  647. ** make a new one filled with blanks.
  648. */
  649. if (!file.Is_Available()) {
  650. // hall of fame doesn't exist, so blank it out & write it
  651. file.Open(WRITE);
  652. for (i = 0; i < NUMFAMENAMES; i++) {
  653. hallfame[i].name[0] =
  654. hallfame[i].score =
  655. hallfame[i].level = 0;
  656. hallfame[i].side = 0;
  657. file.Write(&hallfame[i], sizeof(struct Fame));
  658. }
  659. file.Close();
  660. }
  661. file.Open(READ);
  662. for (i = 0; i < NUMFAMENAMES; i++) {
  663. file.Read(&hallfame[i], sizeof(struct Fame));
  664. }
  665. file.Close();
  666. /*
  667. ** If the player's score is good enough to bump someone off the list,
  668. ** remove their data, move everyone down a notch, and set index = where
  669. ** their info goes
  670. */
  671. if (hallfame[NUMFAMENAMES-1].score >= total)
  672. hallfame[NUMFAMENAMES-1].score = 0;
  673. for (index = 0; index < NUMFAMENAMES; index++) {
  674. if (total > hallfame[index].score) {
  675. if (index < (NUMFAMENAMES-1)) for (i = (NUMFAMENAMES-1); i > index; i--) hallfame[i] = hallfame[i-1];
  676. hallfame[index].score = total;
  677. hallfame[index].level = Scen.Scenario;
  678. hallfame[index].name[0] = 0; // blank out the name
  679. hallfame[index].side = house;
  680. break;
  681. }
  682. }
  683. /*
  684. ** Now display the hall of fame
  685. */
  686. Set_Logic_Page(SeenBuff);
  687. #ifdef WIN32
  688. char maststr[NUMFAMENAMES*32];
  689. #endif
  690. char const *pal;
  691. for (i = 0; i < NUMFAMENAMES; i++) {
  692. pal = hallfame[i].side ? _redpal : _bluepal;
  693. Alloc_Object(new ScorePrintClass(hallfame[i].name, HALLFAME_X, HALLFAME_Y + (i*8), pal));
  694. if (hallfame[i].score) {
  695. #ifdef WIN32
  696. char *str = maststr + i*32;
  697. #else
  698. char *str = (char *)(HidPage.Get_Buffer()) + i*32;
  699. #endif
  700. sprintf(str, "%d", hallfame[i].score);
  701. Alloc_Object(new ScorePrintClass(str, HALLFAME_X+(6*14), HALLFAME_Y + (i*8), pal, BLACK));
  702. if (hallfame[i].level < 20) {
  703. sprintf(str+16, "%d", hallfame[i].level);
  704. } else {
  705. strcpy(str+16, "**");
  706. }
  707. Alloc_Object(new ScorePrintClass(str+16, HALLFAME_X+(6*11), HALLFAME_Y + (i*8), pal, BLACK));
  708. Call_Back_Delay(13);
  709. }
  710. }
  711. #ifdef WIN32
  712. // Wait for text printing to complete
  713. while (StillUpdating) {
  714. Call_Back_Delay(1);
  715. }
  716. #endif
  717. /*
  718. ** If the player's on the hall of fame, have him enter his name now
  719. */
  720. Keyboard->Clear();
  721. if (index < NUMFAMENAMES) {
  722. pal = hallfame[index].side ? _redpal : _bluepal;
  723. Input_Name(hallfame[index].name, HALLFAME_X, HALLFAME_Y + (index*8), pal);
  724. file.Open(WRITE);
  725. for (i = 0; i < NUMFAMENAMES; i++) {
  726. file.Write(&hallfame[i], sizeof(struct Fame));
  727. }
  728. file.Close();
  729. } else {
  730. Alloc_Object(new ScorePrintClass(TXT_CLICK_CONTINUE, 149, 190, _yellowpal));
  731. ControlQ = false;
  732. Cycle_Wait_Click();
  733. }
  734. Keyboard->Clear();
  735. /* get rid of all the animating objects */
  736. for (i = 0; i < MAXSCOREOBJS; i++) if (ScoreObjs[i]) {
  737. delete ScoreObjs[i];
  738. ScoreObjs[i] = 0;
  739. }
  740. BlackPalette.Set(FADE_PALETTE_FAST, NULL);
  741. #ifdef WIN32
  742. VisiblePage.Clear();
  743. #else
  744. SeenPage.Clear();
  745. #endif
  746. Show_Mouse();
  747. // Map_Selection();
  748. // Scen.ScenVar = SCEN_VAR_A;
  749. // Scen.ScenDir = SCEN_DIR_EAST;
  750. Theme.Queue_Song(THEME_NONE);
  751. BlackPalette.Set(FADE_PALETTE_FAST, NULL);
  752. #ifdef WIN32
  753. VisiblePage.Clear();
  754. #else
  755. SeenPage.Clear();
  756. #endif
  757. GamePalette.Set();
  758. Set_Font(oldfont);
  759. FontXSpacing = oldfontxspacing;
  760. ControlQ = 0;
  761. #ifdef WIN32
  762. delete PseudoSeenBuff;
  763. #ifdef FIXIT_SCORE_CRASH
  764. /*
  765. ** Fix for the score screen crash due to uncompressed shape buffer overflow.
  766. */
  767. Enable_Uncompressed_Shapes();
  768. #endif //FIXIT
  769. #endif
  770. }
  771. void Cycle_Wait_Click(bool cycle)
  772. {
  773. int counter = 0;
  774. int minclicks = 20;
  775. unsigned long timingtime = TickCount;
  776. SerialPacketType sendpacket;
  777. SerialPacketType receivepacket;
  778. int packetlen;
  779. Keyboard->Clear();
  780. while (minclicks || (!Keyboard->Check() && !ControlQ) ) {
  781. if (Session.Type == GAME_NULL_MODEM ||
  782. Session.Type == GAME_MODEM) {
  783. //
  784. // send a timing packet if enough time has gone by.
  785. //
  786. if ( (TickCount - timingtime) > PACKET_TIMING_TIMEOUT) {
  787. memset (&sendpacket, 0, sizeof(SerialPacketType));
  788. sendpacket.Command = SERIAL_SCORE_SCREEN;
  789. sendpacket.ScenarioInfo.ResponseTime = NullModem.Response_Time();
  790. sendpacket.ID = Session.ModemType;
  791. NullModem.Send_Message (&sendpacket, sizeof(sendpacket), 0);
  792. timingtime = TickCount;
  793. }
  794. if (NullModem.Get_Message (&receivepacket, &packetlen) > 0) {
  795. // throw packet away
  796. packetlen = packetlen;
  797. }
  798. NullModem.Service();
  799. }
  800. Call_Back_Delay(1);
  801. if (minclicks) {
  802. minclicks--;
  803. Keyboard->Clear();
  804. }
  805. if(cycle) {
  806. counter = ((++counter) & 7);
  807. if (counter == 0 && Options.IsPaletteScroll) {
  808. RGBClass rgb = ScorePalette[233];
  809. for (int i = 233; i < 237; i++) {
  810. ScorePalette[i] = ScorePalette[i+1];
  811. }
  812. ScorePalette[237] = rgb;
  813. ScorePalette.Set();
  814. }
  815. }
  816. }
  817. Keyboard->Clear();
  818. }
  819. void ScoreClass::Do_Nod_Buildings_Graph(void)
  820. {
  821. int shapenum;
  822. InfantryTypeClass const *ramboclass;
  823. void const * factptr = MFCD::Retrieve("POWR.SHP");
  824. void const * rmboptr = MFCD::Retrieve("E7.SHP");
  825. void const * fball1ptr = MFCD::Retrieve("FBALL1.SHP");
  826. ramboclass = &InfantryTypeClass::As_Reference(INFANTRY_TANYA);
  827. /*
  828. ** Print the # of buildings on the hidpage so we only need to do it once
  829. */
  830. SeenPage.Blit(HidPage);
  831. Set_Logic_Page(HidPage);
  832. Call_Back_Delay(30);
  833. Set_Font_Palette(_redpal);
  834. HidPage.Print( 0, BUILDING_X + 16, BUILDING_Y + 10, TBLACK, TBLACK);
  835. Set_Font_Palette(_bluepal);
  836. HidPage.Print( 0, BUILDING_X + 16, BUILDING_Y + 22, TBLACK, TBLACK);
  837. /*
  838. ** Here's the animation/draw loop for blowing up the factory
  839. */
  840. for (int i=0; i<98; i++) {
  841. HidPage.Blit(HidPage, BUILDING_X, BUILDING_Y, 0, 0, 320-BUILDING_X, 48);
  842. shapenum = 0; // no damage
  843. if (i >= 60) {
  844. shapenum = Extract_Shape_Count(factptr) - 2; // some damage
  845. if (i == 60) {
  846. Shake_The_Screen(6);
  847. Sound_Effect(VOC_CRUMBLE);
  848. }
  849. if (i > 65) {
  850. shapenum = Extract_Shape_Count(factptr) - 1; // mega damage
  851. }
  852. }
  853. /*
  854. ** Draw the building before Rambo
  855. */
  856. if (i < 68) {
  857. CC_Draw_Shape(factptr, shapenum, 0, 0, WINDOW_MAIN,
  858. SHAPE_GHOST|SHAPE_FADING|SHAPE_WIN_REL, ColorRemaps[PCOLOR_GOLD].RemapTable, DisplayClass::UnitShadow);
  859. }
  860. /*
  861. ** Now draw some fires, if appropriate
  862. */
  863. if (i >= 61) {
  864. int firecount = Extract_Shape_Count(fball1ptr);
  865. int shapeindex = (i-61) / 2;
  866. if (shapeindex < firecount) {
  867. CC_Draw_Shape(fball1ptr, shapeindex, 10, 10, WINDOW_MAIN,
  868. SHAPE_CENTER|SHAPE_WIN_REL);
  869. }
  870. if (i > 64) {
  871. shapeindex = (i-64) / 2;
  872. if (shapeindex < firecount) {
  873. CC_Draw_Shape(fball1ptr, shapeindex, 50, 30, WINDOW_MAIN,
  874. SHAPE_CENTER|SHAPE_WIN_REL);
  875. }
  876. }
  877. }
  878. /*
  879. ** Draw the Tanya character running away from the building
  880. */
  881. CC_Draw_Shape(rmboptr, (ramboclass->DoControls[DO_WALK].Frame + ramboclass->DoControls[DO_WALK].Jump*6) + ((unsigned(i)>>1)%ramboclass->DoControls[DO_WALK].Count),
  882. i+32, 40, WINDOW_MAIN,
  883. SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_GHOST,
  884. ColorRemaps[PCOLOR_RED].RemapTable, DisplayClass::UnitShadow);
  885. HidPage.Blit(SeenPage, 0, 0, BUILDING_X, BUILDING_Y, 320-BUILDING_X, 48);
  886. /*BG if (!Keyboard->Check()) */ Call_Back_Delay(1);
  887. }
  888. i = max(GBKilled, NBKilled);
  889. for (int q = 0; q <= i; q++) {
  890. Set_Font_Palette(_redpal);
  891. Count_Up_Print( "%d", q, NBKilled, BUILDING_X + 16, BUILDING_Y + 10);
  892. Set_Font_Palette(_bluepal);
  893. Count_Up_Print( "%d", q, GBKilled, BUILDING_X + 16, BUILDING_Y + 22);
  894. //BG if (!Keyboard->Check()) {
  895. #ifdef WIN32
  896. Play_Sample(Beepy6, 255, Options.Normalize_Volume(150));
  897. #else
  898. Play_Sample(Beepy6, 255, Options.Normalize_Volume(60));
  899. #endif
  900. Call_Back_Delay(1);
  901. //BG }
  902. }
  903. Set_Font_Palette(_redpal);
  904. Count_Up_Print( "%d", NBKilled, NBKilled, BUILDING_X + 16, BUILDING_Y + 10);
  905. Set_Font_Palette(_bluepal);
  906. Count_Up_Print( "%d", GBKilled, GBKilled, BUILDING_X + 16, BUILDING_Y + 22);
  907. }
  908. /***************************************************************************
  909. * DO_GDI_GRAPH -- Show # of people or buildings killed on GDI score screen*
  910. * *
  911. * *
  912. * *
  913. * INPUT: yellowptr, redptr = pointers to shape file for graphs *
  914. * *
  915. * OUTPUT: *
  916. * *
  917. * WARNINGS: *
  918. * *
  919. * HISTORY: *
  920. * 05/03/1995 BWG : Created. *
  921. *=========================================================================*/
  922. void ScoreClass::Do_GDI_Graph(void const * yellowptr, void const * redptr, int gkilled, int nkilled, int ypos)
  923. {
  924. int i, maxval;
  925. #ifdef WIN32
  926. int xpos = 174;
  927. int house = (PlayerPtr->Class->House == HOUSE_USSR || PlayerPtr->Class->House == HOUSE_UKRAINE); // 0 or 1
  928. if(house) {
  929. int temp = gkilled;
  930. gkilled = nkilled;
  931. nkilled = temp;
  932. void const *tempptr = yellowptr;
  933. yellowptr = redptr;
  934. redptr = tempptr;
  935. }
  936. #else
  937. int xpos = 173;
  938. #endif
  939. int gdikilled = gkilled, nodkilled=nkilled;
  940. maxval = max(gdikilled, nodkilled);
  941. if (!maxval) maxval=1;
  942. gdikilled = (gdikilled * SIZEGBAR) / maxval;
  943. nodkilled = (nodkilled * SIZEGBAR) / maxval;
  944. if (maxval < 20) {
  945. gdikilled = gkilled * 5;
  946. nodkilled = nkilled * 5;
  947. }
  948. maxval = max(gdikilled, nodkilled);
  949. if (!maxval) maxval=1;
  950. // Draw the white-flash shape on the hidpage
  951. Set_Logic_Page(HidPage);
  952. HidPage.Fill_Rect(0, 0, 124*RESFACTOR, 9*RESFACTOR, TBLACK);
  953. CC_Draw_Shape(redptr, 119, 0, 0, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  954. Set_Logic_Page(SeenBuff);
  955. #ifdef WIN32
  956. Set_Font_Palette(house ? _redpal : _bluepal);
  957. #else
  958. Set_Font_Palette(_bluepal);
  959. #endif
  960. for (i = 1; i <= gdikilled; i++) {
  961. if (i != gdikilled) {
  962. #ifdef WIN32
  963. Set_Logic_Page(*PseudoSeenBuff);
  964. CC_Draw_Shape(yellowptr, i, xpos*RESFACTOR, ypos*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  965. Set_Logic_Page(SeenBuff);
  966. #endif
  967. CC_Draw_Shape(yellowptr, i, xpos*RESFACTOR, ypos*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  968. } else {
  969. HidPage.Blit(SeenPage, 0, 0, xpos*RESFACTOR, ypos*RESFACTOR, (3+gdikilled)*RESFACTOR, 8*RESFACTOR);
  970. #ifdef WIN32
  971. HidPage.Blit(*PseudoSeenBuff, 0, 0, xpos*RESFACTOR, ypos*RESFACTOR, (3+gdikilled)*RESFACTOR, 8*RESFACTOR);
  972. #endif
  973. }
  974. Count_Up_Print("%d", (i*gkilled) / maxval, gkilled, 297, ypos+2);
  975. //BG if (!Keyboard->Check()) {
  976. #ifdef WIN32
  977. Play_Sample(Beepy6, 255, Options.Normalize_Volume(150));
  978. #else
  979. Play_Sample(Beepy6, 255, Options.Normalize_Volume(60));
  980. #endif
  981. Call_Back_Delay(2);
  982. //BG }
  983. }
  984. CC_Draw_Shape(yellowptr, gdikilled, xpos*RESFACTOR, ypos*RESFACTOR , WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  985. #ifdef WIN32
  986. Set_Logic_Page(*PseudoSeenBuff);
  987. CC_Draw_Shape(yellowptr, gdikilled, xpos*RESFACTOR, ypos*RESFACTOR , WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  988. Set_Logic_Page(SeenBuff);
  989. #endif
  990. Count_Up_Print("%d", gkilled, gkilled, 297, ypos+ 2);
  991. /*BG if (!Keyboard->Check()) */ Call_Back_Delay(40);
  992. #ifdef WIN32
  993. Set_Font_Palette(house ? _bluepal : _redpal);
  994. #else
  995. Set_Font_Palette(_redpal);
  996. #endif
  997. for (i = 1; i <= nodkilled; i++) {
  998. if (i != nodkilled) {
  999. #ifdef WIN32
  1000. Set_Logic_Page(*PseudoSeenBuff);
  1001. CC_Draw_Shape(redptr, i, xpos*RESFACTOR, (ypos+12)*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  1002. Set_Logic_Page(SeenBuff);
  1003. #endif
  1004. CC_Draw_Shape(redptr, i, xpos*RESFACTOR, (ypos+12)*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  1005. } else {
  1006. HidPage.Blit(SeenPage, 0, 0, xpos*RESFACTOR, (ypos+12)*RESFACTOR, (3+nodkilled)*RESFACTOR, 8*RESFACTOR);
  1007. #ifdef WIN32
  1008. HidPage.Blit(*PseudoSeenBuff, 0, 0, xpos*RESFACTOR, (ypos+12)*RESFACTOR, (3+nodkilled)*RESFACTOR, 8*RESFACTOR);
  1009. #endif
  1010. }
  1011. Count_Up_Print("%d", (i*nkilled) / maxval, nkilled, 297, ypos+14);
  1012. //BG if (!Keyboard->Check()) {
  1013. #ifdef WIN32
  1014. Play_Sample(Beepy6, 255, Options.Normalize_Volume(150));
  1015. #else
  1016. Play_Sample(Beepy6, 255, Options.Normalize_Volume(60));
  1017. #endif
  1018. Call_Back_Delay(2);
  1019. //BG }
  1020. }
  1021. // if (Keyboard::Check()) Keyboard::Clear();
  1022. /*
  1023. ** Make sure accurate count is printed at end
  1024. */
  1025. #ifdef WIN32
  1026. Set_Logic_Page(*PseudoSeenBuff);
  1027. CC_Draw_Shape( redptr, nodkilled, xpos*RESFACTOR, (ypos+12)*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  1028. Set_Logic_Page(SeenBuff);
  1029. #endif
  1030. CC_Draw_Shape( redptr, nodkilled, xpos*RESFACTOR, (ypos+12)*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
  1031. Count_Up_Print("%d", nkilled, nkilled, 297, ypos+14);
  1032. /*BG if (!Keyboard->Check()) */ Call_Back_Delay(40);
  1033. }
  1034. void ScoreClass::Do_Nod_Casualties_Graph(void)
  1035. {
  1036. int i, gdikilled, nodkilled, maxval;
  1037. void const * e1ptr = MFCD::Retrieve("E1.SHP");
  1038. gdikilled = GKilled;
  1039. nodkilled = NKilled;
  1040. maxval = max(gdikilled, nodkilled);
  1041. if (!maxval) maxval=1;
  1042. if ((gdikilled > (MAX_BAR_X - BARGRAPH_X)) || (nodkilled > (MAX_BAR_X - BARGRAPH_X)) ) {
  1043. gdikilled = (gdikilled * (MAX_BAR_X - BARGRAPH_X)) / maxval;
  1044. nodkilled = (nodkilled * (MAX_BAR_X - BARGRAPH_X)) / maxval;
  1045. }
  1046. maxval = max(gdikilled, nodkilled);
  1047. if (!maxval) maxval=1;
  1048. /*
  1049. ** Initialize a bunch of objects for the infantrymen who pose for the bar
  1050. ** graphs of casualties.
  1051. */
  1052. int r = NUMINFANTRYMEN/2;
  1053. for (i = 0; i < NUMINFANTRYMEN/2; i++) {
  1054. InfantryMan[i+0].xpos =
  1055. InfantryMan[i+r].xpos = (i*10) + 7;
  1056. InfantryMan[i+0].ypos = 11;
  1057. InfantryMan[i+r].ypos = 21;
  1058. InfantryMan[i+0].shapefile =
  1059. InfantryMan[i+r].shapefile = e1ptr;
  1060. InfantryMan[i+0].remap = ColorRemaps[PCOLOR_RED].RemapTable;
  1061. InfantryMan[i+r].remap = ColorRemaps[PCOLOR_BLUE].RemapTable;
  1062. InfantryMan[i+0].anim =
  1063. InfantryMan[i+r].anim = 0;
  1064. InfantryMan[i+0].stage =
  1065. InfantryMan[i+r].stage = 0;
  1066. InfantryMan[i+0].delay =
  1067. InfantryMan[i+r].delay = NonCriticalRandomNumber & 0x1F;
  1068. InfantryMan[i+0].Class =
  1069. InfantryMan[i+r].Class = &InfantryTypeClass::As_Reference(INFANTRY_E1);
  1070. }
  1071. /*
  1072. ** Draw the infantrymen and pause briefly before running the graph
  1073. */
  1074. Draw_InfantryMen();
  1075. HidPage.Blit(SeenPage, 0, 0, BARGRAPH_X, CASUALTY_Y, 320-BARGRAPH_X, 34);
  1076. Call_Back_Delay(40);
  1077. for (i = 1; i <= maxval; i++) {
  1078. // Draw & update infantrymen 3 times for every tick on the graph (i)
  1079. for (int index = 0; index < 3; index++) {
  1080. Draw_InfantryMen();
  1081. Draw_Bar_Graphs(i, nodkilled, gdikilled);
  1082. HidPage.Blit(SeenPage, 0, 0, BARGRAPH_X, CASUALTY_Y, 320-BARGRAPH_X, 34);
  1083. Set_Font_Palette(_redpal);
  1084. Count_Up_Print("%d", (i*NKilled) / maxval, NKilled, SCORETEXT_X+64, CASUALTY_Y + 2);
  1085. Set_Font_Palette(_bluepal);
  1086. Count_Up_Print("%d", (i*GKilled) / maxval, GKilled, SCORETEXT_X+64, CASUALTY_Y + 14);
  1087. /*BG if (!Keyboard->Check()) */ Call_Back_Delay(3);
  1088. }
  1089. #ifdef WIN32
  1090. Play_Sample(Beepy6, 255, Options.Normalize_Volume(150));
  1091. #else
  1092. Play_Sample(Beepy6, 255, Options.Normalize_Volume(60));
  1093. #endif
  1094. }
  1095. //BG if (Keyboard->Check()) Keyboard->Clear();
  1096. /*
  1097. ** Make sure accurate count is printed at end
  1098. */
  1099. Set_Font_Palette(_redpal);
  1100. Count_Up_Print("%d", NKilled, NKilled, SCORETEXT_X+64, CASUALTY_Y + 2);
  1101. Set_Font_Palette(_bluepal);
  1102. Count_Up_Print("%d", GKilled, GKilled, SCORETEXT_X+64, CASUALTY_Y + 14);
  1103. /*
  1104. ** Finish up death animations, if there are any active
  1105. */
  1106. int k = 1;
  1107. while (k) {
  1108. for (i=k=0; i<NUMINFANTRYMEN; i++) {
  1109. if (InfantryMan[i].anim >= DO_GUN_DEATH) {
  1110. k=1;
  1111. }
  1112. }
  1113. if (k) {
  1114. Draw_InfantryMen();
  1115. }
  1116. Draw_Bar_Graphs(maxval, nodkilled, gdikilled);
  1117. HidPage.Blit(SeenPage, 0, 0, BARGRAPH_X, CASUALTY_Y, 320-BARGRAPH_X, 34);
  1118. Call_Back_Delay(1);
  1119. }
  1120. }
  1121. void ScoreClass::Show_Credits(int house, char const pal[])
  1122. {
  1123. static int _credsx[2]={276,276};
  1124. static int _credsy[2]={173,58};
  1125. static int _credpx[2]={228,236};
  1126. #ifdef GERMAN
  1127. static int _credpy[2]={181, 74};
  1128. static int _credtx[2]={162,162};
  1129. static int _credty[2]={173, 62};
  1130. #else
  1131. static int _credpy[2]={189-12, 74};
  1132. static int _credtx[2]={182,182};
  1133. static int _credty[2]={179-12, 62};
  1134. #endif
  1135. int credobj,i;
  1136. int minval,add;
  1137. #ifdef WIN32
  1138. void const * credshape = MFCD::Retrieve(house ? "CREDSUHR.SHP" : "CREDSAHR.SHP");
  1139. #else
  1140. void const * credshape = MFCD::Retrieve(house ? "CREDSU.SHP" : "CREDSA.SHP");
  1141. #endif
  1142. Alloc_Object(new ScorePrintClass(TXT_SCORE_ENDCRED, _credtx[house], _credty[house], pal));
  1143. Call_Back_Delay(15);
  1144. credobj = Alloc_Object(new ScoreCredsClass(_credsx[house], _credsy[house], credshape, 32, 2));
  1145. minval = PlayerPtr->Available_Money() / 100;
  1146. /*
  1147. ** Print out total credits left at end of scenario
  1148. */
  1149. i = -50;
  1150. do {
  1151. add = 5;
  1152. if ((PlayerPtr->Available_Money() - i) > 100 ) add += 15;
  1153. if ((PlayerPtr->Available_Money() - i) > 500 ) add += 30;
  1154. if ((PlayerPtr->Available_Money() - i) > 1000) add += PlayerPtr->Available_Money() / 40;
  1155. if (add < minval) add = minval;
  1156. i += add;
  1157. if (i < 0) i=0;
  1158. Set_Font_Palette(pal);
  1159. Count_Up_Print("%d", i, PlayerPtr->Available_Money(), _credpx[house], _credpy[house]);
  1160. Call_Back_Delay(2);
  1161. /*BG if (Keyboard->Check()) {
  1162. Count_Up_Print("%d", PlayerPtr->Available_Money(), PlayerPtr->Available_Money(), _credpx[house], _credpy[house]);
  1163. Keyboard->Clear();
  1164. break;
  1165. }*/
  1166. } while (i < PlayerPtr->Available_Money()) ;
  1167. delete ScoreObjs[credobj];
  1168. ScoreObjs[credobj] = 0;
  1169. }
  1170. /***************************************************************************
  1171. * SCORECLASS::PRINT_MINUTES -- Print out hours/minutes up to max *
  1172. * *
  1173. * Same as count-up-print, but for the time *
  1174. * *
  1175. * INPUT: current minute count and maximum *
  1176. * *
  1177. * OUTPUT: *
  1178. * *
  1179. * WARNINGS: *
  1180. * *
  1181. * HISTORY: *
  1182. * 04/13/1995 BWG : Created. *
  1183. *=========================================================================*/
  1184. void ScoreClass::Print_Minutes(int minutes)
  1185. {
  1186. char str[20];
  1187. if (minutes >= 60) {
  1188. if ((minutes/60) > 9) minutes = (9*60 + 59);
  1189. sprintf(str, Text_String(TXT_SCORE_TIMEFORMAT1), (minutes / 60), (minutes % 60));
  1190. } else {
  1191. sprintf(str, Text_String(TXT_SCORE_TIMEFORMAT2), minutes);
  1192. }
  1193. SeenPage.Print(str, 275*RESFACTOR, 9*RESFACTOR, TBLACK, TBLACK);
  1194. #ifdef WIN32
  1195. PseudoSeenBuff->Print(str, 275*RESFACTOR, 9*RESFACTOR, TBLACK, TBLACK);
  1196. #endif
  1197. }
  1198. /***********************************************************************************************
  1199. * ScoreClass::Count_Up_Print -- Prints a number (up to its max) into a string, cleanly. *
  1200. * *
  1201. * This routine prints out a number (like 70) or its maximum number, into a string, onto *
  1202. * the screen, on a clean section of the screen, and blits it forward to the seenpage so you*
  1203. * can print without flashing and can print over something (to count up %'s). *
  1204. * *
  1205. * INPUT: str = string to print into *
  1206. * percent = # to print *
  1207. * max = # to print if percent > max *
  1208. * xpos = x pixel coord *
  1209. * ypos = y pixel coord *
  1210. * *
  1211. * OUTPUT: none *
  1212. * *
  1213. * WARNINGS: none *
  1214. * *
  1215. * HISTORY: *
  1216. * 04/07/1995 BWG : Created. *
  1217. *=============================================================================================*/
  1218. void ScoreClass::Count_Up_Print(char *str, int percent, int maxval, int xpos, int ypos)
  1219. {
  1220. char destbuf[64];
  1221. sprintf(destbuf, str, percent <= maxval ? percent : maxval);
  1222. SeenPage.Print( destbuf, xpos * RESFACTOR, ypos * RESFACTOR, TBLACK, BLACK);
  1223. #ifdef WIN32
  1224. PseudoSeenBuff->Print( destbuf, xpos * RESFACTOR, ypos * RESFACTOR, TBLACK, BLACK);
  1225. #endif
  1226. }
  1227. /***********************************************************************************************
  1228. * ScoreClass::Input_Name -- Gets the name from the keyboard *
  1229. * *
  1230. * This routine handles keyboard input, and does a nifty zooming letter effect too. *
  1231. * *
  1232. * INPUT: str = string to put user's typing into *
  1233. * xpos = x pixel coord *
  1234. * ypos = y pixel coord *
  1235. * pal = text remapping palette to print using *
  1236. * *
  1237. * OUTPUT: none *
  1238. * *
  1239. * WARNINGS: none *
  1240. * *
  1241. * HISTORY: *
  1242. * 05/15/1995 BWG : Created. *
  1243. *=============================================================================================*/
  1244. void ScoreClass::Input_Name(char str[], int xpos, int ypos, char const pal[])
  1245. {
  1246. int key = 0;
  1247. int ascii, index=0;
  1248. void const * keystrok = MFCD::Retrieve("KEYSTROK.AUD");
  1249. /*
  1250. ** Ready the hidpage so it can restore background under zoomed letters
  1251. */
  1252. SeenPage.Blit(HidPage);
  1253. /*
  1254. ** Put a copy of the high score area on a spare area of the hidpage, so
  1255. ** we can use it to restore the letter's background instead of filling
  1256. ** with black.
  1257. */
  1258. HidPage.Blit(HidPage, 0, 100*RESFACTOR, 0, 0, 100*RESFACTOR, 100*RESFACTOR);
  1259. do {
  1260. Call_Back();
  1261. Animate_Score_Objs();
  1262. Animate_Cursor(index, ypos);
  1263. if (Keyboard->Check()) {
  1264. key = Keyboard->To_ASCII(Keyboard->Get()) & 0xFF;
  1265. Call_Back();
  1266. if (index == MAX_FAMENAME_LENGTH-2) {
  1267. while (Keyboard->Check()) {
  1268. Keyboard->Get();
  1269. }
  1270. }
  1271. /*
  1272. ** If they hit 'backspace' when they're on the last letter,
  1273. ** turn it into a space instead.
  1274. */
  1275. if ((key == KA_BACKSPACE) && (index == MAX_FAMENAME_LENGTH-2) ) {
  1276. if (str[index] && str[index]!=32) key = 32;
  1277. }
  1278. if (key == KA_BACKSPACE) { //if (key == KN_BACKSPACE) {
  1279. if (index) {
  1280. str[--index] = 0;
  1281. int xposindex6 = (xpos+(index*6))*RESFACTOR;
  1282. HidPage.Blit(SeenPage, xposindex6, (ypos-100)*RESFACTOR, xposindex6, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR);
  1283. #ifdef WIN32
  1284. HidPage.Blit(*PseudoSeenBuff, xposindex6, (ypos-100)*RESFACTOR, xposindex6, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR);
  1285. #endif
  1286. HidPage.Blit(HidPage, xposindex6, (ypos-100)*RESFACTOR, xposindex6, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR);
  1287. }
  1288. } else if (key != KA_RETURN) { //else if (key != KN_RETURN && key!=KN_KEYPAD_RETURN) {
  1289. ascii = key; //ascii = KN_To_KA(key);
  1290. if (ascii >= 'a' && ascii <= 'z') ascii -= ('a' - 'A');
  1291. if ( (ascii >= '!' && ascii <= KA_TILDA) || ascii == ' ') {
  1292. HidPage.Blit(SeenPage, (xpos + (index*6))*RESFACTOR, (ypos-100)*RESFACTOR, (xpos + (index*6))*RESFACTOR, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR);
  1293. #ifdef WIN32
  1294. HidPage.Blit(*PseudoSeenBuff, (xpos + (index*6))*RESFACTOR, (ypos-100)*RESFACTOR, (xpos + (index*6))*RESFACTOR, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR);
  1295. #endif
  1296. HidPage.Blit(HidPage, (xpos + (index*6))*RESFACTOR, (ypos-100)*RESFACTOR, (xpos + (index*6))*RESFACTOR, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR);
  1297. str[index] = ascii;
  1298. str[index+1] = 0;
  1299. int objindex;
  1300. #ifdef WIN32
  1301. Play_Sample(keystrok, 255, Options.Normalize_Volume(150));
  1302. #else
  1303. Play_Sample(keystrok, 255, Options.Normalize_Volume(105));
  1304. #endif
  1305. objindex = Alloc_Object(new ScoreScaleClass(str+index, xpos+(index*6), ypos, pal));
  1306. while (ScoreObjs[objindex]) Call_Back_Delay(1);
  1307. if (index < (MAX_FAMENAME_LENGTH-2) ) index++;
  1308. }
  1309. }
  1310. }
  1311. } while (key != KA_RETURN); // } while(key != KN_RETURN && key!=KN_KEYPAD_RETURN);
  1312. }
  1313. void Animate_Cursor(int pos, int ypos)
  1314. {
  1315. static int _lastpos = 0, _state;
  1316. static CDTimerClass<SystemTimerClass> _timer;
  1317. ypos += 6; // move cursor to bottom of letter
  1318. ypos *= RESFACTOR;
  1319. // If they moved the cursor, erase old one and force state=0, to make green draw right away
  1320. if (pos != _lastpos) {
  1321. HidPage.Blit(SeenPage, (HALLFAME_X + (_lastpos*6))*RESFACTOR, ypos-100*RESFACTOR, (HALLFAME_X + (_lastpos*6))*RESFACTOR, ypos, 6*RESFACTOR, 1*RESFACTOR);
  1322. #ifdef WIN32
  1323. HidPage.Blit(*PseudoSeenBuff, (HALLFAME_X + (_lastpos*6))*RESFACTOR, ypos-100*RESFACTOR, (HALLFAME_X + (_lastpos*6))*RESFACTOR, ypos, 6*RESFACTOR, 1*RESFACTOR);
  1324. #endif
  1325. _lastpos = pos;
  1326. _state = 0;
  1327. }
  1328. SeenBuff.Draw_Line((HALLFAME_X + (pos*6))*RESFACTOR, ypos, (HALLFAME_X + (pos*6)+5)*RESFACTOR, ypos, _state ? LTBLUE : TBLACK);
  1329. #ifdef WIN32
  1330. PseudoSeenBuff->Draw_Line((HALLFAME_X + (pos*6))*RESFACTOR, ypos, (HALLFAME_X + (pos*6)+5)*RESFACTOR, ypos, _state ? LTBLUE : TBLACK);
  1331. #endif
  1332. /*
  1333. ** Toggle the color of the cursor, green or black, if it's time to do so.
  1334. */
  1335. if (!_timer) {
  1336. _state ^= 1;
  1337. _timer = 5;
  1338. }
  1339. }
  1340. /***************************************************************************
  1341. * Draw_InfantryMen -- Draw all the guys on the score screen *
  1342. * *
  1343. * *
  1344. * *
  1345. * INPUT: *
  1346. * *
  1347. * OUTPUT: *
  1348. * *
  1349. * WARNINGS: *
  1350. * *
  1351. * HISTORY: *
  1352. * 04/13/1995 BWG : Created. *
  1353. *=========================================================================*/
  1354. void Draw_InfantryMen()
  1355. {
  1356. int k;
  1357. // Only draw the infantrymen if we're playing USSR... Allies wouldn't execute
  1358. // people like that.
  1359. /*
  1360. ** First restore the background
  1361. */
  1362. HidPage.Blit(HidPage, BARGRAPH_X, CASUALTY_Y, 0, 0, 320-BARGRAPH_X, 34);
  1363. Set_Logic_Page(HidPage);
  1364. /*
  1365. ** Then draw all the infantrymen on the clean hidpage
  1366. */
  1367. for (k = 0; k < NUMINFANTRYMEN; k++) Draw_InfantryMan(k);
  1368. /*
  1369. ** They'll all be blitted over to the seenpage after the graphs are drawn
  1370. */
  1371. }
  1372. /***************************************************************************
  1373. * Draw_InfantryMan -- Draw one guy in score screen, update animation *
  1374. * *
  1375. * This routine draws one of the infantrymen in the "Casualties" area *
  1376. * *
  1377. * INPUT: *
  1378. * *
  1379. * OUTPUT: *
  1380. * *
  1381. * WARNINGS: *
  1382. * *
  1383. * HISTORY: *
  1384. * 04/13/1995 BWG : Created. *
  1385. *=========================================================================*/
  1386. void Draw_InfantryMan(int index)
  1387. {
  1388. int stage;
  1389. /* If the infantryman's dead, just abort this function */
  1390. if (InfantryMan[index].anim == -1) return;
  1391. stage = InfantryMan[index].stage + InfantryMan[index].Class->DoControls[InfantryMan[index].anim].Frame;
  1392. CC_Draw_Shape(InfantryMan[index].shapefile,
  1393. stage,
  1394. InfantryMan[index].xpos,
  1395. InfantryMan[index].ypos,
  1396. WINDOW_MAIN,
  1397. SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_GHOST,
  1398. InfantryMan[index].remap,
  1399. DisplayClass::UnitShadow);
  1400. /*
  1401. ** see if it's time to run a new anim
  1402. */
  1403. if (--InfantryMan[index].delay <= 0) {
  1404. InfantryMan[index].delay = 3;
  1405. if (++InfantryMan[index].stage >= InfantryMan[index].Class->DoControls[InfantryMan[index].anim].Count) {
  1406. /*
  1407. ** was he playing a death anim? If so, and it's done, erase him
  1408. */
  1409. if (InfantryMan[index].anim >= DO_GUN_DEATH) {
  1410. InfantryMan[index].anim = -1;
  1411. } else {
  1412. New_Infantry_Anim(index, DO_STAND_READY);
  1413. }
  1414. }
  1415. }
  1416. }
  1417. /***************************************************************************
  1418. * New_Infantry_Anim -- Start up a new animation for one of the infantrymen*
  1419. * *
  1420. * *
  1421. * *
  1422. * INPUT: index: which of the 30 infantrymen to affect *
  1423. * anim: which animation sequence to start him into *
  1424. * OUTPUT: *
  1425. * *
  1426. * WARNINGS: *
  1427. * *
  1428. * HISTORY: *
  1429. * 04/13/1995 BWG : Created. *
  1430. *=========================================================================*/
  1431. void New_Infantry_Anim(int index, int anim)
  1432. {
  1433. InfantryMan[index].anim = anim;
  1434. InfantryMan[index].stage = 0;
  1435. if (anim >= DO_GUN_DEATH) {
  1436. InfantryMan[index].delay = 1; // start right away
  1437. } else {
  1438. InfantryMan[index].delay = NonCriticalRandomNumber & 15;
  1439. }
  1440. }
  1441. /***************************************************************************
  1442. * Draw_Bar_Graphs -- Draw "Casualties" bar graphs *
  1443. * *
  1444. * *
  1445. * *
  1446. * INPUT: i = current count of how far to draw graph *
  1447. * gkilled = # of GDI forces killed (adjusted to fit in space) *
  1448. * nkilled = # of Nod forces killed (adjusted to fit in space) *
  1449. * OUTPUT: *
  1450. * *
  1451. * WARNINGS: *
  1452. * *
  1453. * HISTORY: *
  1454. * 04/13/1995 BWG : Created. *
  1455. * 07/02/1996 BWG : Removed references to civilians. *
  1456. *=========================================================================*/
  1457. void Draw_Bar_Graphs(int i, int gkilled, int nkilled)
  1458. {
  1459. if (gkilled) {
  1460. LogicPage->Fill_Rect(0, 0+4*RESFACTOR, 0+min(i, gkilled)*RESFACTOR, 0+5*RESFACTOR, RED);
  1461. LogicPage->Draw_Line(0+1*RESFACTOR, 0+6*RESFACTOR, (0+min(i, gkilled)+1)*RESFACTOR, 0+6*RESFACTOR, TBLACK);
  1462. LogicPage->Draw_Line((0+MIN(i, gkilled)+1)*RESFACTOR, 0+5*RESFACTOR, (0+min(i, gkilled)+1)*RESFACTOR, 0+5*RESFACTOR, TBLACK);
  1463. if (i <= gkilled) {
  1464. int anim = InfantryMan[i/11].anim;
  1465. if (anim!=-1 && anim < DO_GUN_DEATH) {
  1466. if (i/11) {
  1467. New_Infantry_Anim(i/11, DO_GUN_DEATH + (NonCriticalRandomNumber & 3));
  1468. } else {
  1469. New_Infantry_Anim(i/11, DO_GUN_DEATH);
  1470. }
  1471. // Sound_Effect(Random_Pick(VOC_SCREAM1, VOC_SCREAM5));
  1472. }
  1473. }
  1474. }
  1475. if (nkilled) {
  1476. LogicPage->Fill_Rect( 0, 0+16*RESFACTOR, 0+min(i, nkilled)*RESFACTOR, 0+17*RESFACTOR, LTCYAN);
  1477. LogicPage->Draw_Line( 0+1*RESFACTOR, 0+18*RESFACTOR, (0+min(i, nkilled)+1)*RESFACTOR, 0+18*RESFACTOR, TBLACK);
  1478. LogicPage->Draw_Line((0+MIN(i, nkilled)+1)*RESFACTOR, 0+17*RESFACTOR, (0+min(i, nkilled)+1)*RESFACTOR, 0+17*RESFACTOR, TBLACK);
  1479. if (i <= nkilled) {
  1480. int anim = InfantryMan[(NUMINFANTRYMEN/2)+(i/11)].anim;
  1481. if (anim!=-1 && anim < DO_GUN_DEATH) {
  1482. if (i/11) {
  1483. New_Infantry_Anim((NUMINFANTRYMEN/2)+(i/11), DO_GUN_DEATH + (NonCriticalRandomNumber & 3));
  1484. } else {
  1485. New_Infantry_Anim((NUMINFANTRYMEN/2)+(i/11), DO_GUN_DEATH);
  1486. }
  1487. // Sound_Effect(Random_Pick(VOC_SCREAM1, VOC_SCREAM5));
  1488. }
  1489. }
  1490. }
  1491. }
  1492. /***************************************************************************
  1493. * Call_Back_Delay -- Combines Call_Back() and Delay() functions *
  1494. * *
  1495. * This is just to cut down on code size and typing a little. *
  1496. * *
  1497. * INPUT: *
  1498. * *
  1499. * OUTPUT: *
  1500. * *
  1501. * WARNINGS: *
  1502. * *
  1503. * HISTORY: *
  1504. * 04/13/1995 BWG : Created. *
  1505. *=========================================================================*/
  1506. void Call_Back_Delay(int time)
  1507. {
  1508. if (time < 0 ) time = 0;
  1509. if (time > 60) time = 60;
  1510. CDTimerClass<SystemTimerClass> cd;
  1511. CDTimerClass<SystemTimerClass> callbackcd = 0;
  1512. if (!ControlQ) {
  1513. if (Keyboard->Down(KN_LCTRL) && Keyboard->Down(KN_Q)) {
  1514. ControlQ = 1;
  1515. Keyboard->Clear();
  1516. }
  1517. }
  1518. if (ControlQ) time=0;
  1519. cd = time;
  1520. StreamLowImpact = true;
  1521. do {
  1522. if (callbackcd == 0) {
  1523. Call_Back();
  1524. callbackcd = TIMER_SECOND/4;
  1525. }
  1526. Animate_Score_Objs();
  1527. } while (cd);
  1528. StreamLowImpact = false;
  1529. }
  1530. void Animate_Score_Objs()
  1531. {
  1532. #ifdef WIN32
  1533. StillUpdating = false;
  1534. /*
  1535. ** If we have just received input focus again after running in the background then
  1536. ** we need to redraw.
  1537. */
  1538. if (AllSurfaces.SurfacesRestored) {
  1539. AllSurfaces.SurfacesRestored=FALSE;
  1540. PseudoSeenBuff->Blit(SeenPage);
  1541. }
  1542. #endif
  1543. for (int i = 0; i < MAXSCOREOBJS; i++) {
  1544. if (ScoreObjs[i]) {
  1545. ScoreObjs[i]->Update();
  1546. }
  1547. }
  1548. }
  1549. char *Int_Print(int a)
  1550. {
  1551. static char str[10];
  1552. sprintf(str, "%d", a);
  1553. return str;
  1554. }
  1555. /***********************************************************************************************
  1556. * Multi_Score_Presentation -- Multiplayer routine to display score screen. *
  1557. * *
  1558. * *
  1559. * INPUT: none *
  1560. * *
  1561. * OUTPUT: none *
  1562. * *
  1563. * WARNINGS: none *
  1564. * *
  1565. * HISTORY: *
  1566. * 06/11/1995 BWG: Created. *
  1567. *=============================================================================================*/
  1568. extern int CopyType;
  1569. void Multi_Score_Presentation(void)
  1570. {
  1571. char remap[16];
  1572. #ifdef WIN32
  1573. GraphicBufferClass *pseudoseenbuff = new GraphicBufferClass(320, 200, (void*)NULL);
  1574. PseudoSeenBuff = new GraphicBufferClass(SeenBuff.Get_Width(),SeenBuff.Get_Height(),(void*)NULL);
  1575. #endif
  1576. int i,k;
  1577. void *oldfont;
  1578. int oldfontxspacing = FontXSpacing;
  1579. FontXSpacing = 0;
  1580. Map.Override_Mouse_Shape(MOUSE_NORMAL);
  1581. // Theme.Queue_Song(THEME_WIN);
  1582. BlackPalette.Set();
  1583. SeenPage.Clear();
  1584. HidPage.Clear();
  1585. Hide_Mouse();
  1586. void *anim = Open_Animation("MLTIPLYR.WSA", NULL, 0L, (WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE), ScorePalette);
  1587. /*
  1588. ** Display the background animation
  1589. */
  1590. #ifdef WIN32
  1591. pseudoseenbuff->Clear();
  1592. Animate_Frame(anim, *pseudoseenbuff, 1);
  1593. for(int x=0; x<256; x++) memset(&PaletteInterpolationTable[x][0],x,256);
  1594. CopyType = 1;
  1595. Interpolate_2X_Scale(pseudoseenbuff , &SeenBuff , 0);
  1596. #else
  1597. Animate_Frame(anim, HidPage, 1);
  1598. HidPage.Blit(SeenPage);
  1599. #endif
  1600. ScorePalette.Set(FADE_PALETTE_FAST, Call_Back);
  1601. int frame = 1;
  1602. while (frame < Get_Animation_Frame_Count(anim)) {
  1603. #ifdef WIN32
  1604. Animate_Frame(anim, *pseudoseenbuff, frame++);
  1605. CopyType = 1;
  1606. Interpolate_2X_Scale(pseudoseenbuff , &SeenBuff , NULL);
  1607. CopyType = 0;
  1608. #else
  1609. Animate_Frame(anim, SeenPage, frame++);
  1610. #endif
  1611. Call_Back_Delay(2);
  1612. }
  1613. Close_Animation(anim);
  1614. #ifdef WIN32
  1615. CopyType = 1;
  1616. Interpolate_2X_Scale(pseudoseenbuff , PseudoSeenBuff , NULL);
  1617. CopyType = 0;
  1618. #endif
  1619. /* Change to the six-point font for Text_Print */
  1620. oldfont = Set_Font(ScoreFontPtr);
  1621. Call_Back();
  1622. Set_Logic_Page(SeenBuff);
  1623. #ifdef FRENCH
  1624. Alloc_Object(new ScorePrintClass(TXT_SCORE_TOP, 113, 13, _greenpal));
  1625. #else
  1626. Alloc_Object(new ScorePrintClass(TXT_SCORE_TOP, 130, 13, _greenpal));
  1627. #endif
  1628. Call_Back_Delay(5);
  1629. Alloc_Object(new ScorePrintClass(TXT_COMMANDER, 27, 31, _greenpal));
  1630. Call_Back_Delay(10);
  1631. #ifdef FRENCH
  1632. Alloc_Object(new ScorePrintClass(TXT_BATTLES_WON, 113, 31, _greenpal));
  1633. #endif
  1634. #ifdef GERMAN
  1635. Alloc_Object(new ScorePrintClass(TXT_BATTLES_WON, 118, 31, _greenpal));
  1636. #endif
  1637. #ifdef ENGLISH
  1638. Alloc_Object(new ScorePrintClass(TXT_BATTLES_WON, 126, 31, _greenpal));
  1639. #endif
  1640. Call_Back_Delay(13);
  1641. Alloc_Object(new ScorePrintClass(TXT_KILLS_COLON, 249, 31, _greenpal));
  1642. Call_Back_Delay(6);
  1643. /*
  1644. ** Move all the scores over a notch if there's more games than can be
  1645. ** shown (which is known by Session.CurGame == MAX_MULTI_GAMES-1);
  1646. */
  1647. if (Session.CurGame == MAX_MULTI_GAMES-1) {
  1648. for (i = 0; i < MAX_MULTI_NAMES; i++) {
  1649. for (k = 0; k < MAX_MULTI_GAMES-1; k++) {
  1650. Session.Score[i].Kills[k] = Session.Score[i].Kills[k+1];
  1651. }
  1652. }
  1653. }
  1654. int y = 41;
  1655. for (i = 0; i < MAX_MULTI_NAMES; i++) {
  1656. if (strlen(Session.Score[i].Name)) {
  1657. int color = Session.Score[i].Color;
  1658. remap[ 8] = ColorRemaps[color].FontRemap[11];
  1659. remap[ 6] = ColorRemaps[color].FontRemap[12];
  1660. remap[ 4] = ColorRemaps[color].FontRemap[13];
  1661. remap[ 2] = ColorRemaps[color].FontRemap[14];
  1662. remap[14] = ColorRemaps[color].FontRemap[15];
  1663. Alloc_Object(new ScorePrintClass(Session.Score[i].Name, 15, y, remap));
  1664. Call_Back_Delay(20);
  1665. Alloc_Object(new ScorePrintClass(Int_Print(Session.Score[i].Wins), 118, y, remap));
  1666. Call_Back_Delay(6);
  1667. for (k = 0; k <= min(Session.CurGame, MAX_MULTI_GAMES-2); k++) {
  1668. if (Session.Score[i].Kills[k] >= 0) {
  1669. Alloc_Object(new ScorePrintClass(Int_Print(Session.Score[i].Kills[k]), 225+(24*k), y, remap));
  1670. Call_Back_Delay(6);
  1671. }
  1672. }
  1673. y += 12;
  1674. }
  1675. }
  1676. #if defined(GERMAN) || defined(FRENCH)
  1677. Alloc_Object(new ScorePrintClass(TXT_CLICK_CONTINUE, 95 /*(320-strlen(Text_String(TXT_MAP_CLICK2)))/2*/, 190, _yellowpal));
  1678. #else
  1679. Alloc_Object(new ScorePrintClass(TXT_CLICK_CONTINUE, 109 /*(320-strlen(Text_String(TXT_MAP_CLICK2)))/2*/, 190, _yellowpal));
  1680. #endif
  1681. Cycle_Wait_Click(false);
  1682. /* get rid of all the animating objects */
  1683. for (i = 0; i < MAXSCOREOBJS; i++) if (ScoreObjs[i]) {
  1684. delete ScoreObjs[i];
  1685. ScoreObjs[i] = 0;
  1686. }
  1687. Theme.Queue_Song(THEME_NONE);
  1688. BlackPalette.Set(FADE_PALETTE_FAST, NULL);
  1689. SeenPage.Clear();
  1690. GamePalette.Set();
  1691. #ifdef WIN32
  1692. delete PseudoSeenBuff;
  1693. #endif
  1694. Set_Font(oldfont);
  1695. FontXSpacing = oldfontxspacing;
  1696. ControlQ = 0;
  1697. Show_Mouse();
  1698. }
  1699. void ScoreClass::Init(void)
  1700. {
  1701. Score = 0;
  1702. NKilled = 0;
  1703. GKilled = 0;
  1704. CKilled = 0;
  1705. NBKilled = 0;
  1706. GBKilled = 0;
  1707. CBKilled = 0;
  1708. NHarvested = 0;
  1709. GHarvested = 0;
  1710. CHarvested = 0;
  1711. ElapsedTime = 0;
  1712. RealTime = 0;
  1713. ChangingGun = 0;
  1714. }