SCORE.CPP 64 KB

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