INIT.CPP.BAK 96 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758
  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: F:\projects\c&c0\vcs\code\init.cpv 4.82 24 Oct 1996 12:53:00 JOE_BOSTIC $ */
  19. /***********************************************************************************************
  20. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Command & Conquer *
  24. * *
  25. * File Name : INIT.CPP *
  26. * *
  27. * Programmer : Joe L. Bostic *
  28. * *
  29. * Start Date : January 20, 1992 *
  30. * *
  31. *---------------------------------------------------------------------------------------------*
  32. * Functions: *
  33. * Anim_Init -- Initialize the VQ animation control structure. *
  34. * Bootstrap -- Perform the initial bootstrap procedure. *
  35. * Calculate_CRC -- Calculates a one-way hash from a data block. *
  36. * Init_Authorization -- Verifies that the player is authorized to play the game. *
  37. * Init_Bootstrap_Mixfiles -- Registers and caches any mixfiles needed for bootstrapping. *
  38. * Init_Bulk_Data -- Initialize the time-consuming mixfile caching. *
  39. * Init_CDROM_Access -- Initialize the CD-ROM access handler. *
  40. * Init_Color_Remaps -- Initialize the text remap tables. *
  41. * Init_Expansion_Files -- Fetch any override expansion mixfiles. *
  42. * Init_Fonts -- Initialize all the game font pointers. *
  43. * Init_Game -- Main game initialization routine. *
  44. * Init_Heaps -- Initialize the game heaps and buffers. *
  45. * Init_Keys -- Initialize the cryptographic keys. *
  46. * Init_Mouse -- Initialize the mouse system. *
  47. * Init_One_Time_Systems -- Initialize internal pointers to the bulk data. *
  48. * Init_Random -- Initializes the random-number generator *
  49. * Init_Secondary_Mixfiles -- Register and cache secondary mixfiles. *
  50. * Load_Recording_Values -- Loads recording values from recording file *
  51. * Load_Title_Page -- Load the background art for the title page. *
  52. * Obfuscate -- Sufficiently transform parameter to thwart casual hackers. *
  53. * Parse_Command_Line -- Parses the command line parameters. *
  54. * Parse_INI_File -- Parses CONQUER.INI for special options *
  55. * Play_Intro -- plays the introduction & logo movies *
  56. * Save_Recording_Values -- Saves recording values to a recording file *
  57. * Select_Game -- The game's main menu *
  58. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  59. #include "function.h"
  60. #include "loaddlg.h"
  61. #ifdef WIN32
  62. #include "tcpip.h"
  63. #endif
  64. #include <conio.h>
  65. #include <dos.h>
  66. #ifndef WIN32
  67. #include <sys\timeb.h>
  68. #endif
  69. #include "ccdde.h"
  70. #include <time.h>
  71. RemapControlType SidebarScheme;
  72. /****************************************
  73. ** Function prototypes for this module **
  74. *****************************************/
  75. static void Play_Intro(bool sequenced=false);
  76. static void Init_Color_Remaps(void);
  77. static void Init_Heaps(void);
  78. static void Init_Expansion_Files(void);
  79. static void Init_One_Time_Systems(void);
  80. static void Init_Fonts(void);
  81. static void Init_CDROM_Access(void);
  82. static void Init_Bootstrap_Mixfiles(void);
  83. static void Init_Secondary_Mixfiles(void);
  84. static void Init_Mouse(void);
  85. static void Bootstrap(void);
  86. //static void Init_Authorization(void);
  87. static void Init_Bulk_Data(void);
  88. static void Init_Keys(void);
  89. extern "C" {
  90. extern long RandNumb;
  91. }
  92. #ifndef WIN32
  93. static int UsePageFaultHandler = 1; // 1 = install PFH
  94. #endif //WIN32
  95. //extern int SimRandIndex;
  96. void Init_Random(void);
  97. #define ATTRACT_MODE_TIMEOUT 3600 // timeout for attract mode
  98. bool Load_Recording_Values(CCFileClass & file);
  99. bool Save_Recording_Values(CCFileClass & file);
  100. /***********************************************************************************************
  101. * Init_Game -- Main game initialization routine. *
  102. * *
  103. * Perform all one-time game initializations here. This includes all *
  104. * allocations and table setups. The intro and other one-time startup *
  105. * tasks are also performed here. *
  106. * *
  107. * INPUT: argc,argv -- Command line arguments. *
  108. * *
  109. * OUTPUT: none *
  110. * *
  111. * WARNINGS: Only call this ONCE! 
  112. *
  113. * *
  114. * HISTORY: *
  115. * 10/07/1992 JLB : Created. *
  116. *=============================================================================================*/
  117. #include "sha.h"
  118. //#include <locale.h>
  119. bool Init_Game(int , char * [])
  120. {
  121. //must set international locale up front
  122. //V.Grippi 10/22/96
  123. //#ifdef WIN32
  124. //#ifdef German
  125. // setlocale(LC_ALL, "German");
  126. //#endif
  127. //#endif
  128. /*
  129. ** Allocate the benchmark tracking objects only if the machine and
  130. ** compile flags indicate.
  131. */
  132. #ifdef CHEAT_KEYS
  133. if (Processor() >= 2) {
  134. Benches = new Benchmark [BENCH_COUNT];
  135. }
  136. #endif
  137. /*
  138. ** Initialize the encryption keys.
  139. */
  140. Init_Keys();
  141. /*
  142. ** Bootstrap as much as possible before error-prone initializations are
  143. ** performed. This bootstrap process will enable the error message
  144. ** handler to function.
  145. */
  146. //VG_MONO
  147. Mono_Print("about to BOOTSTRAP ourselves!!!!\n");
  148. Bootstrap();
  149. /*
  150. ** Check for an initialize a working mouse pointer. Display error and bail if
  151. ** no mouse driver is installed.
  152. */
  153. Init_Mouse();
  154. /*
  155. ** Initialize access to the CD-ROM and ensure that the CD is inserted. This can, and
  156. ** most likely will, result in a visible prompt.
  157. */
  158. Init_CDROM_Access();
  159. /*
  160. ** Register and cache any secondary mixfiles.
  161. */
  162. //VG_MONO
  163. Mono_Print("about to call init secondary mixfiles\n");
  164. Init_Secondary_Mixfiles();
  165. /*
  166. ** This is a special hack to initialize the heaps that must be in place before the
  167. ** rules file is processed. These heaps should properly be allocated as a consequence
  168. ** of processing the rules.ini file, but that is a bit beyond the capabilities of
  169. ** the rule parser routine (currently).
  170. */
  171. HouseTypes.Set_Heap(HOUSE_COUNT);
  172. BuildingTypes.Set_Heap(STRUCT_COUNT);
  173. AircraftTypes.Set_Heap(AIRCRAFT_COUNT);
  174. InfantryTypes.Set_Heap(INFANTRY_COUNT);
  175. BulletTypes.Set_Heap(BULLET_COUNT);
  176. AnimTypes.Set_Heap(ANIM_COUNT);
  177. UnitTypes.Set_Heap(UNIT_COUNT);
  178. VesselTypes.Set_Heap(VESSEL_COUNT);
  179. TemplateTypes.Set_Heap(TEMPLATE_COUNT);
  180. TerrainTypes.Set_Heap(TERRAIN_COUNT);
  181. OverlayTypes.Set_Heap(OVERLAY_COUNT);
  182. SmudgeTypes.Set_Heap(SMUDGE_COUNT);
  183. HouseTypeClass::Init_Heap();
  184. BuildingTypeClass::Init_Heap();
  185. AircraftTypeClass::Init_Heap();
  186. InfantryTypeClass::Init_Heap();
  187. BulletTypeClass::Init_Heap();
  188. AnimTypeClass::Init_Heap();
  189. UnitTypeClass::Init_Heap();
  190. VesselTypeClass::Init_Heap();
  191. TemplateTypeClass::Init_Heap();
  192. TerrainTypeClass::Init_Heap();
  193. OverlayTypeClass::Init_Heap();
  194. SmudgeTypeClass::Init_Heap();
  195. /*
  196. ** Find and process any rules for this game.
  197. */
  198. if (RuleINI.Load(CCFileClass("RULES.INI"), false)) {
  199. Rule.Process(RuleINI);
  200. }
  201. Session.MaxPlayers = Rule.MaxPlayers;
  202. /*
  203. ** Initialize the game object heaps as well as other rules-dependant buffer allocations.
  204. */
  205. Init_Heaps();
  206. /*
  207. ** Initialize the animation system.
  208. */
  209. Anim_Init();
  210. if (SpawnedFromWChat){
  211. Special.IsFromWChat = true;
  212. }
  213. /*
  214. ** Play the startup animation.
  215. */
  216. if (!Special.IsFromInstall && !Special.IsFromWChat) {
  217. VisiblePage.Clear();
  218. Play_Intro();
  219. memset(CurrentPalette, 0x01, 768);
  220. WhitePalette.Set();
  221. } else {
  222. memset(CurrentPalette, 0x01, 768);
  223. }
  224. /*
  225. ** Initialize the text remap tables.
  226. */
  227. Init_Color_Remaps();
  228. /*
  229. ** Get authorization to access the game.
  230. */
  231. // Init_Authorization();
  232. // Show_Mouse();
  233. /*
  234. ** If not automatically launching into the intro, then display the title
  235. ** page while the bulk data is cached.
  236. */
  237. if (!Special.IsFromInstall) {
  238. // Hide_Mouse();
  239. Load_Title_Page(true);
  240. CCPalette.Set(FADE_PALETTE_SLOW);
  241. // HidPage.Blit(SeenPage);
  242. // Show_Mouse();
  243. Call_Back();
  244. }
  245. /*
  246. ** Initialize the bulk data. This takes the longest time and must be performed once
  247. ** before the regular game starts.
  248. */
  249. Init_Bulk_Data();
  250. /*
  251. ** Initialize the multiplayer score values
  252. */
  253. Session.GamesPlayed = 0;
  254. Session.NumScores = 0;
  255. Session.CurGame = 0;
  256. for (int i = 0; i < MAX_MULTI_NAMES; i++) {
  257. Session.Score[i].Name[0] = '\0';
  258. Session.Score[i].Wins = 0;
  259. for (int j = 0; j < MAX_MULTI_GAMES; j++) {
  260. Session.Score[i].Kills[j] = -1; // -1 = this player didn't play this round
  261. }
  262. }
  263. /*
  264. ** Copy the title screen's palette into the GamePalette & OriginalPalette,
  265. ** because the options Load routine uses these palettes to set the brightness, etc.
  266. */
  267. GamePalette = CCPalette;
  268. // InGamePalette = CCPalette;
  269. OriginalPalette = CCPalette;
  270. /*
  271. ** Read game options, so the GameSpeed is initialized when multiplayer
  272. ** dialogs are invoked. (GameSpeed must be synchronized between systems.)
  273. */
  274. Options.Load_Settings();
  275. return(true);
  276. }
  277. /***********************************************************************************************
  278. * Select_Game -- The game's main menu *
  279. * *
  280. * INPUT: *
  281. * fade if true, will fade the palette in gradually *
  282. * *
  283. * OUTPUT: *
  284. * none. *
  285. * *
  286. * WARNINGS: *
  287. * none. *
  288. * *
  289. * HISTORY: *
  290. * 06/05/1995 BRR : Created. *
  291. *=============================================================================================*/
  292. bool Select_Game(bool fade)
  293. {
  294. enum {
  295. SEL_TIMEOUT = -1, // main menu timeout--go into attract mode
  296. SEL_NEW_SCENARIO, // Expansion scenario to play.
  297. SEL_START_NEW_GAME, // start a new game
  298. #ifdef WIN32
  299. SEL_INTERNET,
  300. #endif //WIN32
  301. SEL_LOAD_MISSION, // load a saved game
  302. SEL_MULTIPLAYER_GAME, // play modem/null-modem/network game
  303. SEL_INTRO, // couch-potato mode
  304. SEL_EXIT, // exit to DOS
  305. SEL_FAME, // view the hall o' fame
  306. SEL_NONE, // placeholder default value
  307. };
  308. bool gameloaded=false; // Has the game been loaded from the menu?
  309. int selection; // the default selection
  310. bool process = true; // false = break out of while loop
  311. bool display = true;
  312. if (Special.IsFromInstall) {
  313. display = false;
  314. }
  315. Show_Mouse();
  316. #ifdef WIN32
  317. /*
  318. ** Enable the DDE Server so we can get internet start game packets from WChat
  319. */
  320. DDEServer.Enable();
  321. #endif //WIN32
  322. /*
  323. ** [Re]set any globals that need it, in preparation for a new scenario
  324. */
  325. GameActive = true;
  326. DoList.Init();
  327. #ifdef MIRROR_QUEUE
  328. MirrorList.Init();
  329. #endif
  330. OutList.Init();
  331. Frame = 0;
  332. Scen.MissionTimer = 0;
  333. Scen.MissionTimer.Stop();
  334. PlayerWins = false;
  335. PlayerLoses = false;
  336. Session.ObiWan = false;
  337. Debug_Unshroud = false;
  338. Map.Set_Cursor_Shape(0);
  339. Map.PendingObjectPtr = 0;
  340. Map.PendingObject = 0;
  341. Map.PendingHouse = HOUSE_NONE;
  342. Session.ProcessTicks = 0;
  343. Session.ProcessFrames = 0;
  344. Session.DesiredFrameRate = 30;
  345. /*
  346. ** Init multiplayer game scores. Let Wins accumulate; just init the current
  347. ** Kills for this game. Kills of -1 means this player didn't play this round.
  348. */
  349. for (int i = 0 ; i < MAX_MULTI_GAMES; i++) {
  350. Session.Score[i].Kills[Session.CurGame] = -1;
  351. }
  352. /*
  353. ** Set default mouse shape
  354. */
  355. Map.Set_Default_Mouse(MOUSE_NORMAL, false);
  356. /*
  357. ** If the last game we played was a multiplayer game, jump right to that
  358. ** menu by pre-setting 'selection'.
  359. */
  360. if (Session.Type == GAME_NORMAL) {
  361. selection = SEL_NONE;
  362. } else {
  363. selection = SEL_MULTIPLAYER_GAME;
  364. }
  365. /*
  366. ** Main menu processing; only do this if we're not in editor mode.
  367. */
  368. if (!Debug_Map) {
  369. /*
  370. ** Menu selection processing loop
  371. */
  372. Theme.Queue_Song(THEME_CRUS);
  373. /*
  374. ** If we're playing back a recording, load all pertinent values & skip
  375. ** the menu loop. Hide the now-useless mouse pointer.
  376. */
  377. if (Session.Play && Session.RecordFile.Is_Available()) {
  378. if (Session.RecordFile.Open(READ)) {
  379. Load_Recording_Values(Session.RecordFile);
  380. process = false;
  381. Theme.Fade_Out();
  382. } else
  383. Session.Play = false;
  384. }
  385. #ifdef WIN32
  386. /*
  387. ** Handle case where we were spawned from Wchat
  388. */
  389. if (SpawnedFromWChat) {
  390. Special.IsFromInstall = false; //Dont play intro if we were spawned from wchat
  391. selection = SEL_INTERNET;
  392. Theme.Queue_Song(THEME_QUIET);
  393. Session.Type = GAME_INTERNET;
  394. display = false;
  395. Set_Logic_Page(SeenBuff);
  396. }
  397. #endif //WIN32
  398. while (process) {
  399. /*
  400. ** Redraw the title page if needed
  401. */
  402. if (display) {
  403. Hide_Mouse();
  404. /*
  405. ** Display the title page; fade it in if this is the first time
  406. ** through the loop, and the 'fade' flag is true
  407. */
  408. Load_Title_Page();
  409. GamePalette = CCPalette;
  410. HidPage.Blit(SeenPage);
  411. // if (fade) {
  412. // WhitePalette.Set();
  413. // CCPalette.Set(FADE_PALETTE_SLOW, Call_Back);
  414. // fade = false;
  415. // } else {
  416. CCPalette.Set();
  417. // }
  418. Set_Logic_Page(SeenBuff);
  419. display = false;
  420. Show_Mouse();
  421. }
  422. /*
  423. ** Display menu and fetch selection from player.
  424. */
  425. if (Special.IsFromInstall) selection = SEL_START_NEW_GAME;
  426. #ifdef WIN32
  427. /*
  428. ** Handle case where we were spawned from Wchat and our start game
  429. ** packet has already arrived
  430. */
  431. if (Special.IsFromWChat && DDEServer.Get_MPlayer_Game_Info()) {
  432. Check_From_WChat(NULL);
  433. selection = SEL_MULTIPLAYER_GAME;
  434. Theme.Queue_Song(THEME_QUIET);
  435. Session.Type = GAME_INTERNET;
  436. } else {
  437. /*
  438. ** We werent spawned but we could still receive a DDE packet from wchat
  439. */
  440. if (DDEServer.Get_MPlayer_Game_Info()) {
  441. Check_From_WChat(NULL);
  442. /*
  443. ** Make sure top and bottom of screen are clear in 640x480 mode
  444. */
  445. if (ScreenHeight == 480) {
  446. VisiblePage.Fill_Rect (0, 0, 639, 40, 0);
  447. VisiblePage.Fill_Rect (0, 440, 639, 479, 0);
  448. }
  449. }
  450. }
  451. #endif //WIN32
  452. if (selection == SEL_NONE) {
  453. selection = Main_Menu(ATTRACT_MODE_TIMEOUT);
  454. }
  455. Call_Back();
  456. switch (selection) {
  457. /*
  458. ** Pick an expansion scenario.
  459. */
  460. case SEL_NEW_SCENARIO:
  461. Scen.CarryOverMoney = 0;
  462. IsTanyaDead = false;
  463. SaveTanya = false;
  464. Expansion_Dialog();
  465. Theme.Fade_Out();
  466. Theme.Queue_Song(THEME_FIRST);
  467. Session.Type = GAME_NORMAL;
  468. process = false;
  469. break;
  470. /*
  471. ** SEL_START_NEW_GAME: Play the game
  472. */
  473. case SEL_START_NEW_GAME:
  474. if (Special.IsFromInstall) {
  475. Scen.CDifficulty = DIFF_NORMAL;
  476. Scen.Difficulty = DIFF_NORMAL;
  477. } else {
  478. switch (Fetch_Difficulty()) {
  479. case 0:
  480. Scen.CDifficulty = DIFF_HARD;
  481. Scen.Difficulty = DIFF_EASY;
  482. break;
  483. case 1:
  484. Scen.CDifficulty = DIFF_HARD;
  485. Scen.Difficulty = DIFF_NORMAL;
  486. break;
  487. case 2:
  488. Scen.CDifficulty = DIFF_NORMAL;
  489. Scen.Difficulty = DIFF_NORMAL;
  490. break;
  491. case 3:
  492. Scen.CDifficulty = DIFF_EASY;
  493. Scen.Difficulty = DIFF_NORMAL;
  494. break;
  495. case 4:
  496. Scen.CDifficulty = DIFF_EASY;
  497. Scen.Difficulty = DIFF_HARD;
  498. break;
  499. }
  500. }
  501. Scen.CarryOverMoney = 0;
  502. BuildLevel = 1;
  503. IsTanyaDead = false;
  504. SaveTanya = false;
  505. Whom = HOUSE_GOOD;
  506. if (!Special.IsFromInstall) {
  507. switch (WWMessageBox().Process(TXT_CHOOSE, TXT_ALLIES, TXT_SOVIET)) {
  508. default:
  509. case 0:
  510. Scen.Set_Scenario_Name("SCG01EA.INI");
  511. break;
  512. case 1:
  513. Scen.Set_Scenario_Name("SCU01EA.INI");
  514. break;
  515. }
  516. Theme.Fade_Out();
  517. Load_Title_Page();
  518. } else {
  519. Theme.Fade_Out();
  520. Hide_Mouse();
  521. Choose_Side();
  522. if (CurrentCD == 0) {
  523. Scen.Set_Scenario_Name("SCG01EA.INI");
  524. } else {
  525. Scen.Set_Scenario_Name("SCU01EA.INI");
  526. }
  527. }
  528. Session.Type = GAME_NORMAL;
  529. process = false;
  530. break;
  531. #ifdef WIN32
  532. /*
  533. ** Internet game is requested
  534. */
  535. case SEL_INTERNET:
  536. /*
  537. ** Only call up the internet menu code if we dont already have connect info from WChat
  538. */
  539. if (!DDEServer.Get_MPlayer_Game_Info()) {
  540. if (Do_The_Internet_Menu_Thang() && DDEServer.Get_MPlayer_Game_Info()) {
  541. Check_From_WChat(NULL);
  542. selection = SEL_MULTIPLAYER_GAME;
  543. display = false;
  544. Session.Type = GAME_INTERNET;
  545. } else {
  546. selection = SEL_NONE;
  547. display = true;
  548. }
  549. } else {
  550. Check_From_WChat(NULL);
  551. display = false;
  552. Session.Type = GAME_INTERNET;
  553. selection = SEL_MULTIPLAYER_GAME;
  554. }
  555. break;
  556. #endif //WIN32
  557. /*
  558. ** Load a saved game.
  559. */
  560. case SEL_LOAD_MISSION:
  561. if (LoadOptionsClass(LoadOptionsClass::LOAD).Process()) {
  562. Theme.Queue_Song(THEME_FIRST);
  563. process = false;
  564. gameloaded = true;
  565. } else {
  566. display = true;
  567. selection = SEL_NONE;
  568. }
  569. break;
  570. /*
  571. ** SEL_MULTIPLAYER_GAME: set 'Session.Type' to NULL-modem, modem, or
  572. ** network play.
  573. */
  574. case SEL_MULTIPLAYER_GAME:
  575. switch (Session.Type) {
  576. /*
  577. ** If 'Session.Type' isn't already set up for a multiplayer game,
  578. ** we must prompt the user for which type of multiplayer game
  579. ** they want.
  580. */
  581. case GAME_NORMAL:
  582. Session.Type = Select_MPlayer_Game();
  583. if (Session.Type == GAME_NORMAL) { // 'Cancel'
  584. display = true;
  585. selection = SEL_NONE;
  586. }
  587. break;
  588. case GAME_SKIRMISH:
  589. if ( !Com_Scenario_Dialog(true) ) {
  590. Session.Type = Select_MPlayer_Game();
  591. if (Session.Type == GAME_NORMAL) { // user hit Cancel
  592. display = true;
  593. selection = SEL_NONE;
  594. }
  595. }
  596. break;
  597. case GAME_NULL_MODEM:
  598. case GAME_MODEM:
  599. if ( Session.Type != GAME_SKIRMISH && NullModem.Num_Connections() ) {
  600. NullModem.Init_Send_Queue();
  601. if ((Session.Type == GAME_NULL_MODEM &&
  602. Session.ModemType == MODEM_NULL_HOST) ||
  603. (Session.Type == GAME_MODEM &&
  604. Session.ModemType == MODEM_DIALER) ) {
  605. if ( !Com_Scenario_Dialog() ) {
  606. Session.Type = Select_Serial_Dialog();
  607. if (Session.Type == GAME_NORMAL) { // user hit Cancel
  608. display = true;
  609. selection = SEL_NONE;
  610. }
  611. }
  612. } else {
  613. if ( !Com_Show_Scenario_Dialog() ) {
  614. Session.Type = Select_Serial_Dialog();
  615. if (Session.Type == GAME_NORMAL) { // user hit Cancel
  616. display = true;
  617. selection = SEL_NONE;
  618. }
  619. }
  620. }
  621. } else {
  622. Session.Type = Select_MPlayer_Game();
  623. if (Session.Type == GAME_NORMAL) { // 'Cancel'
  624. display = true;
  625. selection = SEL_NONE;
  626. }
  627. }
  628. break;
  629. #ifdef WIN32
  630. /*
  631. ** Handle being spawned from WChat. Internet play based on IPX code.
  632. */
  633. case GAME_INTERNET:
  634. if (Special.IsFromWChat) {
  635. /*
  636. ** Give myself focus.
  637. */
  638. SetForegroundWindow ( MainWindow );
  639. ShowWindow ( MainWindow, ShowCommand );
  640. OutputDebugString ("RA95 - About to initialise Winsock.\n");
  641. if (Winsock.Init()) {
  642. OutputDebugString ("RA95 - About to read multiplayer settings.\n");
  643. Session.Read_MultiPlayer_Settings ();
  644. Server = PlanetWestwoodIsHost;
  645. OutputDebugString ("RA95 - About to set addresses.\n");
  646. Winsock.Set_Host_Address(PlanetWestwoodIPAddress);
  647. OutputDebugString ("RA95 - About to call Start_Server or Start_Client.\n");
  648. if (Server) {
  649. Winsock.Start_Server();
  650. } else {
  651. Winsock.Start_Client();
  652. }
  653. /*
  654. ** Flush out any pending packets from a previous game.
  655. */
  656. OutputDebugString ("RA95 - About to flush packet queue.\n");
  657. OutputDebugString ("RA95 - Allocating scrap memory.\n");
  658. char *temp_buffer = new char[1024];
  659. OutputDebugString ("RA95 - Creating timer class instance.\n");
  660. CountDownTimerClass ptimer;
  661. OutputDebugString ("RA95 - Entering read loop.\n");
  662. while (Winsock.Read(temp_buffer, 1024)) {
  663. OutputDebugString ("RA95 - Discarding a packet.\n");
  664. ptimer.Set (30, true);
  665. while (ptimer.Time()) {};
  666. OutputDebugString ("RA95 - Ready to check for more packets.\n");
  667. }
  668. OutputDebugString ("RA95 - About to delete scrap memory.\n");
  669. delete temp_buffer;
  670. } else {
  671. OutputDebugString ("RA95 - Winsock failed to initialise.\n");
  672. Session.Type = GAME_NORMAL;
  673. selection = SEL_EXIT;
  674. Special.IsFromWChat = false;
  675. break;
  676. }
  677. OutputDebugString ("RA95 - About to call Init_Network.\n");
  678. Init_Network();
  679. if (DDEServer.Get_MPlayer_Game_Info()) {
  680. OutputDebugString ("RA95 - About to call Read_Game_Options.\n");
  681. Read_Game_Options( NULL );
  682. } else {
  683. Read_Game_Options( "C&CSPAWN.INI" );
  684. }
  685. if (Server) {
  686. OutputDebugString ("RA95 - About to call Server_Remote_Connect.\n");
  687. if (Server_Remote_Connect()) {
  688. OutputDebugString ("RA95 - Server_Remote_Connect returned success.\n");
  689. break;
  690. } else {
  691. /*
  692. ** We failed to connect to the other player
  693. *
  694. * SEND FAILURE PACKET TO WCHAT HERE !!!!!
  695. *
  696. */
  697. Winsock.Close();
  698. Session.Type = GAME_NORMAL;
  699. selection = SEL_NONE;
  700. DDEServer.Delete_MPlayer_Game_Info(); // Make sure we dont go round in an infinite loop
  701. break;
  702. }
  703. } else {
  704. OutputDebugString ("RA95 - About to call Client_Remote_Connect.\n");
  705. if (Client_Remote_Connect()) {
  706. OutputDebugString ("RA95 - Client_Remote_Connect returned success.\n");
  707. break;
  708. } else {
  709. /*
  710. ** We failed to connect to the other player
  711. *
  712. * SEND FAILURE PACKET TO WCHAT HERE !!!!!
  713. *
  714. */
  715. Winsock.Close();
  716. Session.Type = GAME_NORMAL;
  717. selection = SEL_NONE;
  718. DDEServer.Delete_MPlayer_Game_Info(); // Make sure we dont go round in an infinite loop
  719. break;
  720. }
  721. }
  722. } else {
  723. Session.Type = Select_MPlayer_Game();
  724. if (Session.Type == GAME_NORMAL) { // 'Cancel'
  725. display = true;
  726. selection = SEL_NONE;
  727. }
  728. }
  729. break;
  730. #endif //WIN32
  731. }
  732. switch (Session.Type) {
  733. /*
  734. ** Modem, Null-Modem or internet
  735. */
  736. case GAME_MODEM:
  737. case GAME_NULL_MODEM:
  738. case GAME_INTERNET:
  739. case GAME_SKIRMISH:
  740. Theme.Fade_Out();
  741. process = false;
  742. Options.ScoreVolume = 0;
  743. break;
  744. /*
  745. ** Network (IPX): start a new network game.
  746. */
  747. case GAME_IPX:
  748. /*
  749. ** Init network system & remote-connect
  750. */
  751. if (Session.Type == GAME_IPX && Init_Network() && Remote_Connect()) {
  752. Options.ScoreVolume = 0;
  753. process = false;
  754. Theme.Fade_Out();
  755. } else { // user hit cancel, or init failed
  756. Session.Type = GAME_NORMAL;
  757. display = true;
  758. selection = SEL_NONE;
  759. }
  760. break;
  761. }
  762. break;
  763. /*
  764. ** Play a VQ
  765. */
  766. case SEL_INTRO:
  767. Theme.Fade_Out();
  768. if (Debug_Flag) {
  769. Play_Intro(Debug_Flag);
  770. } else {
  771. Hide_Mouse();
  772. VisiblePage.Clear();
  773. Show_Mouse();
  774. Play_Movie(VQ_INTRO_MOVIE, THEME_NONE, true); // no transition picture to briefing
  775. // Play_Movie(VQ_INTRO_MOVIE, THEME_NONE, false); // has transitino picture to briefing
  776. }
  777. Theme.Queue_Song(THEME_CRUS);
  778. display = true;
  779. fade = true;
  780. selection = SEL_NONE;
  781. break;
  782. /*
  783. ** Exit to DOS.
  784. */
  785. case SEL_EXIT:
  786. Theme.Fade_Out();
  787. BlackPalette.Set(FADE_PALETTE_SLOW);
  788. return(false);
  789. /*
  790. ** Display the hall of fame.
  791. */
  792. case SEL_FAME:
  793. break;
  794. case SEL_TIMEOUT:
  795. if (Session.Attract && Session.RecordFile.Is_Available()) {
  796. Session.Play = true;
  797. if (Session.RecordFile.Open(READ)) {
  798. Load_Recording_Values(Session.RecordFile);
  799. process = false;
  800. Theme.Fade_Out();
  801. } else {
  802. Session.Play = false;
  803. selection = SEL_NONE;
  804. }
  805. } else {
  806. selection = SEL_NONE;
  807. }
  808. break;
  809. default:
  810. break;
  811. }
  812. }
  813. } else {
  814. /*
  815. ** For Debug_Map (editor) mode to load scenario
  816. */
  817. Scen.Set_Scenario_Name("SCG01EA.INI");
  818. }
  819. /*
  820. ** Don't carry stray keystrokes into game.
  821. */
  822. Keyboard->Clear();
  823. /*
  824. ** Initialize the random number generator(s)
  825. */
  826. //VG_MONO
  827. Mono_Print("about to call Init_Random, COOL!!\n");
  828. Init_Random();
  829. /*
  830. ** Save initialization values if we're recording this game.
  831. */
  832. if (Session.Record) {
  833. if (Session.RecordFile.Open(WRITE)) {
  834. Save_Recording_Values(Session.RecordFile);
  835. } else {
  836. Session.Record = false;
  837. }
  838. }
  839. /*
  840. ** Load the scenario. Specify variation 'A' for the editor; for the game,
  841. ** don't specify a variation, to make 'Set_Scenario_Name()' pick a random one.
  842. ** Skip this if we've already loaded a save-game.
  843. */
  844. if (!gameloaded && !Session.LoadGame) {
  845. // if (Debug_Map) {
  846. // Set_Scenario_Name(Scen.ScenarioName, Scen.Scenario, Scen.ScenPlayer, Scen.ScenDir, SCEN_VAR_A);
  847. // } else {
  848. // Set_Scenario_Name(Scen.ScenarioName, Scen.Scenario, Scen.ScenPlayer, Scen.ScenDir);
  849. // }
  850. /*
  851. ** Start_Scenario() changes the palette; so, fade out & clear the screen
  852. ** before calling it.
  853. */
  854. Hide_Mouse();
  855. if (selection != SEL_START_NEW_GAME) {
  856. BlackPalette.Set(FADE_PALETTE_MEDIUM, Call_Back);
  857. #ifdef WIN32
  858. //VG_MONO
  859. Mono_Print("about tocall hiddenpage clear\n");
  860. HiddenPage.Clear();
  861. VisiblePage.Clear();
  862. #else
  863. HidPage.Clear();
  864. SeenPage.Clear();
  865. #endif //WIN32
  866. }
  867. Show_Mouse();
  868. //VG_MONO
  869. Mono_Print("about to call start_scenario\n");
  870. if (!Start_Scenario(Scen.ScenarioName)) {
  871. return(false);
  872. }
  873. if (Special.IsFromInstall) Show_Mouse();
  874. Special.IsFromInstall = false;
  875. }
  876. /*
  877. ** For multiplayer games, initialize the inter-player message system.
  878. ** Do this after loading the scenario, so the map's upper-left corner is
  879. ** properly set.
  880. */
  881. Session.Messages.Init(
  882. Map.TacPixelX, Map.TacPixelY, // x,y for messages
  883. 6, // max # msgs
  884. MAX_MESSAGE_LENGTH-14, // max msg length
  885. 7 * RESFACTOR, // font height in pixels
  886. -1, -1, // x,y for edit line (appears above msgs)
  887. 0,//BG 1, // enable edit overflow
  888. 20, // min,
  889. MAX_MESSAGE_LENGTH - 14, // max for trimming overflow
  890. #ifdef WIN32
  891. Lepton_To_Pixel(Map.TacLeptonWidth)); // Width in pixels of buffer
  892. #else
  893. (320-SIDEBAR_WID)); // Width in pixels of buffer
  894. #endif
  895. if (Session.Type != GAME_NORMAL && Session.Type != GAME_SKIRMISH && !Session.Play) {
  896. Session.Create_Connections();
  897. }
  898. /*
  899. ** Hide the SeenPage; force the map to render one frame. The caller can
  900. ** then fade the palette in.
  901. ** (If we loaded a game, this step will fade out the title screen. If we
  902. ** started a scenario, Start_Scenario() will have played a couple of VQ
  903. ** movies, which will have cleared the screen to black already.)
  904. */
  905. //VG_MONO
  906. Mono_Print("about to call Call_Back \n");
  907. Call_Back();
  908. Hide_Mouse();
  909. BlackPalette.Set(FADE_PALETTE_MEDIUM, Call_Back);
  910. // Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back);
  911. #ifdef WIN32
  912. HiddenPage.Clear();
  913. VisiblePage.Clear();
  914. #else
  915. HidPage.Clear();
  916. SeenPage.Clear();
  917. #endif //WIN32
  918. Show_Mouse();
  919. Set_Logic_Page(SeenBuff);
  920. #ifdef WIN32
  921. /*
  922. ** Sidebar is always active in hi-res.
  923. */
  924. //VG_MONO
  925. Mono_Print("about to call map sidebar class::activate\n");
  926. if (!Debug_Map) {
  927. Map.SidebarClass::Activate(1);
  928. }
  929. #endif //WIN32
  930. Map.Flag_To_Redraw();
  931. Call_Back();
  932. //VG_MONO
  933. Mono_Print("about to call Map.Render \n");
  934. Map.Render();
  935. Mono_Print("just returned from Map.Render \n");
  936. return(true);
  937. }
  938. /***********************************************************************************************
  939. * Pla
  940. y_Intro -- plays the introduction & logo movies *
  941. * *
  942. * INPUT: *
  943. * *
  944. * OUTPUT: *
  945. * none. *
  946. * *
  947. * WARNINGS: *
  948. * none. *
  949. * *
  950. * HISTORY: *
  951. * 06/06/1995 BRR : Created. *
  952. * 05/08/1996 JLB : Modified for Red Alert and direction control. *
  953. *=============================================================================================*/
  954. static void Play_Intro(bool sequenced)
  955. {
  956. static VQType _counter = VQ_FIRST;
  957. Keyboard->Clear();
  958. if (sequenced) {
  959. if (_counter <= VQ_FIRST) _counter = VQ_COUNT;
  960. if (_counter == VQ_COUNT) _counter--;
  961. if (_counter == VQ_REDINTRO) _counter--;
  962. if (_counter == VQ_TITLE) _counter--;
  963. Hide_Mouse();
  964. VisiblePage.Clear();
  965. Show_Mouse();
  966. Play_Movie(VQType(_counter--), THEME_NONE);
  967. // Show_Mouse();
  968. } else {
  969. Hide_Mouse();
  970. VisiblePage.Clear();
  971. Show_Mouse();
  972. #ifdef WIN32
  973. Play_Movie(VQ_REDINTRO, THEME_NONE, false);
  974. #else
  975. Play_Movie(VQ_TITLE, THEME_NONE, false);
  976. #endif
  977. }
  978. }
  979. /***********************************************************************************************
  980. * Anim_Init -- Initialize the VQ animation control structure. *
  981. * *
  982. * VQ animations are controlled by a structure passed to the VQ player. This routine *
  983. * initializes the structure to values required by C&C. *
  984. * *
  985. * INPUT: none *
  986. * *
  987. * OUTPUT: none *
  988. * *
  989. * WARNINGS: Only need to call this routine once at the beginning of the game. *
  990. * *
  991. * HISTORY: *
  992. * 12/20/1994 JLB : Created. *
  993. *=============================================================================================*/
  994. #ifdef WIN32
  995. #ifdef MOVIE640
  996. GraphicBufferClass VQ640(640, 400, (void *)NULL);
  997. #endif
  998. #endif
  999. void Anim_Init(void)
  1000. {
  1001. #ifdef WIN32
  1002. /* Configure player with INI file */
  1003. VQA_DefaultConfig(&AnimControl);
  1004. AnimControl.DrawFlags = VQACFGF_TOPLEFT;
  1005. AnimControl.DrawFlags |= VQACFGF_BUFFER;
  1006. //AnimControl.DrawFlags |= VQACFGF_NODRAW;
  1007. //BG - M. Grayford says turn this off AnimControl.DrawFlags |= VQACFGF_NOSKIP;
  1008. AnimControl.DrawFlags |= VQACFGF_NOSKIP;
  1009. AnimControl.FrameRate = -1;
  1010. AnimControl.DrawRate = -1;
  1011. AnimControl.DrawerCallback = VQ_Call_Back;
  1012. AnimControl.ImageWidth = 320;
  1013. AnimControl.ImageHeight = 200;
  1014. AnimControl.ImageBuf = (unsigned char *)SysMemPage.Get_Offset();
  1015. #ifdef MOVIE640
  1016. if(IsVQ640) {
  1017. AnimControl.ImageWidth = 640;
  1018. AnimControl.ImageHeight = 400;
  1019. AnimControl.ImageBuf = (unsigned char *)VQ640.Get_Offset();
  1020. }
  1021. #endif
  1022. AnimControl.Vmode = 0;
  1023. AnimControl.OptionFlags |= VQAOPTF_CAPTIONS|VQAOPTF_EVA;
  1024. if (SlowPalette) {
  1025. AnimControl.OptionFlags |= VQAOPTF_SLOWPAL;
  1026. }
  1027. AnimControl.SoundObject = SoundObject;
  1028. AnimControl.PrimaryBufferPtr = PrimaryBufferPtr;
  1029. if (MonoClass::Is_Enabled()) {
  1030. AnimControl.OptionFlags |= VQAOPTF_MONO;
  1031. }
  1032. #else //WIN32
  1033. /* Configure player with INI file */
  1034. VQA_DefaultConfig(&AnimControl);
  1035. // void const * font = Load_Font(FONT8);
  1036. // AnimControl.EVAFont = (char *)font;
  1037. // AnimControl.CapFont = (char *)font;
  1038. AnimControl.DrawerCallback = VQ_Call_Back;
  1039. AnimControl.ImageWidth = 320;
  1040. AnimControl.ImageHeight = 200;
  1041. AnimControl.Vmode = MCGA_MODE;
  1042. AnimControl.VBIBit = VertBlank;
  1043. AnimControl.DrawFlags |= VQACFGF_TOPLEFT;
  1044. AnimControl.OptionFlags |= VQAOPTF_HMIINIT|VQAOPTF_CAPTIONS|VQAOPTF_EVA;
  1045. // AnimControl.AudioBuf = (unsigned char *)HidPage.Get_Buffer();
  1046. // AnimControl.AudioBufSize = 32768U;
  1047. AnimControl.DigiCard = NewConfig.DigitCard;
  1048. AnimControl.HMIBufSize = 8192;
  1049. AnimControl.DigiHandle = Get_Digi_Handle();
  1050. AnimControl.Volume = 0x00FF;
  1051. AnimControl.AudioRate = 22050;
  1052. // if (NewConfig.Speed) AnimControl.AudioRate = 11025;
  1053. if (!Debug_Quiet && Get_Digi_Handle() != -1) {
  1054. AnimControl.OptionFlags |= VQAOPTF_AUDIO;
  1055. }
  1056. if (MonoClass::Is_Enabled()) {
  1057. AnimControl.OptionFlags |= VQAOPTF_MONO;
  1058. }
  1059. #endif //WIN32
  1060. }
  1061. /***********************************************************************************************
  1062. * Parse_Command_Line -- Parses the command line parameters. *
  1063. * *
  1064. * This routine should be called before the graphic mode is initialized. It examines the *
  1065. * command line parameters and sets the appropriate globals. If there is an error, then *
  1066. * it outputs a command summary and then returns false. *
  1067. * *
  1068. * INPUT: argc -- The number of command line arguments. *
  1069. * *
  1070. * argv -- Pointer to character string array that holds the individual arguments. *
  1071. * *
  1072. * OUTPUT: bool; Was the command line parsed successfully? *
  1073. * *
  1074. * WARNINGS: none *
  1075. * *
  1076. * HISTORY: *
  1077. * 03/18/1995 JLB : Created. *
  1078. *=============================================================================================*/
  1079. bool Parse_Command_Line(int argc, char * argv[])
  1080. {
  1081. /*
  1082. ** Parse the command line and set globals to reflect the parameters
  1083. ** passed in.
  1084. */
  1085. Whom = HOUSE_GOOD;
  1086. Special.Init();
  1087. Debug_Map = false;
  1088. Debug_Unshroud = false;
  1089. for (int index = 1; index < argc; index++) {
  1090. char * string; // Pointer to argument.
  1091. long code = 0;
  1092. string = strupr(argv[index]);
  1093. /*
  1094. ** Print usage text only if requested.
  1095. */
  1096. if (stricmp("/?", string) == 0 || stricmp("-?", string) == 0 || stricmp("-h", string) == 0 || stricmp("/h", string) == 0) {
  1097. /*
  1098. ** Unrecognized command line parameter... Display usage
  1099. ** and then exit.
  1100. */
  1101. puts(TEXT_OPTIONS);
  1102. return(false);
  1103. }
  1104. bool processed = true;
  1105. long ob = Obfuscate(string);
  1106. /*
  1107. ** Check to see if the parameter is a cheat enabling one.
  1108. */
  1109. long const * optr = &CheatCodes[0];
  1110. while (*optr) {
  1111. if (*optr++ == ob) {
  1112. Debug_Playtest = true;
  1113. Debug_Flag = true;
  1114. break;
  1115. }
  1116. }
  1117. /*
  1118. ** Check to see if the parameter is a cheat enabling one.
  1119. */
  1120. optr = &PlayCodes[0];
  1121. while (*optr) {
  1122. if (*optr++ == ob) {
  1123. Debug_Playtest = true;
  1124. Debug_Flag = true;
  1125. break;
  1126. }
  1127. }
  1128. /*
  1129. ** Check to see if the parameter is a scenario editor
  1130. ** enabling one.
  1131. */
  1132. optr = &EditorCodes[0];
  1133. while (*optr) {
  1134. if (*optr++ == ob) {
  1135. Debug_Map = true;
  1136. Debug_Unshroud = true;
  1137. Debug_Flag = true;
  1138. Debug_Playtest = true;
  1139. break;
  1140. }
  1141. }
  1142. switch (ob) {
  1143. #ifdef VIRGIN_CHEAT_KEYS
  1144. case PARM_PLAYTEST:
  1145. Debug_Playtest = true;
  1146. break;
  1147. #endif
  1148. /*
  1149. ** Special flag - is C&C being run from the install program?
  1150. */
  1151. case PARM_INSTALL:
  1152. Special.IsFromInstall = true;
  1153. BreakoutAllowed = false;
  1154. break;
  1155. default:
  1156. processed = false;
  1157. break;
  1158. }
  1159. if (processed) continue;
  1160. #ifdef CHEAT_KEYS
  1161. /*
  1162. ** Scenario Editor Mode
  1163. */
  1164. if (stricmp(string, "-CHECKMAP") == 0) {
  1165. Debug_Check_Map = true;
  1166. continue;
  1167. }
  1168. #endif
  1169. /*
  1170. ** File search path override.
  1171. */
  1172. if (strstr(string, "-CD")) {
  1173. CCFileClass::Set_Search_Drives(&string[3]);
  1174. continue;
  1175. }
  1176. /*
  1177. ** Specify destination connection for network play
  1178. */
  1179. if (strstr(string, "-DESTNET")) {
  1180. NetNumType net;
  1181. NetNodeType node;
  1182. /*
  1183. ** Scan the command-line string, pulling off each address piece
  1184. */
  1185. int i = 0;
  1186. char * p = strtok(string + 8, ".");
  1187. while (p) {
  1188. int x;
  1189. sscanf(p, "%x", &x); // convert from hex string to int
  1190. if (i < 4) {
  1191. net[i] = (char)x; // fill NetNum
  1192. } else {
  1193. node[i-4] = (char)x; // fill NetNode
  1194. }
  1195. i++;
  1196. p = strtok(NULL, ".");
  1197. }
  1198. /*
  1199. ** If all the address components were successfully read, fill in the
  1200. ** BridgeNet with a broadcast address to the network across the bridge.
  1201. */
  1202. if (i >= 4) {
  1203. Session.IsBridge = 1;
  1204. memset(node, 0xff, 6);
  1205. Session.BridgeNet = IPXAddressClass(net, node);
  1206. }
  1207. continue;
  1208. }
  1209. /*
  1210. ** Specify socket ID, as an offset from 0x4000.
  1211. */
  1212. if (strstr(string, "-SOCKET")) {
  1213. unsigned short socket;
  1214. socket = (unsigned short)(atoi(string + strlen("SOCKET")));
  1215. socket += 0x4000;
  1216. if (socket >= 0x4000 && socket < 0x8000) {
  1217. Ipx.Set_Socket (socket);
  1218. }
  1219. continue;
  1220. }
  1221. /*
  1222. ** Set the Net Stealth option
  1223. */
  1224. if (strstr(string, "-STEALTH")) {
  1225. Session.NetStealth = true;
  1226. continue;
  1227. }
  1228. /*
  1229. ** Set the Net Protection option
  1230. */
  1231. if (strstr(string, "-MESSAGES")) {
  1232. Session.NetProtect = false;
  1233. continue;
  1234. }
  1235. /*
  1236. ** Allow "attract" mode
  1237. */
  1238. if (strstr(string, "-ATTRACT")) {
  1239. Session.Attract = true;
  1240. continue;
  1241. }
  1242. #ifdef WIN32
  1243. /*
  1244. ** Set screen to 640x480 instead of 640x400
  1245. */
  1246. if (strstr(string, "-480")) {
  1247. ScreenHeight = 480;
  1248. continue;
  1249. }
  1250. #endif
  1251. #ifdef CHEAT_KEYS
  1252. /*
  1253. ** Specify the random number seed (for debugging)
  1254. */
  1255. if (strstr(string, "-SEED")) {
  1256. CustomSeed = (unsigned short)(atoi(string + strlen("SEED")));
  1257. continue;
  1258. }
  1259. #ifndef WIN32
  1260. /*
  1261. ** Don't install Page Fault Handler (MUST use this for debugger)
  1262. */
  1263. if (stricmp(string, "-NOPFS") == 0) {
  1264. UsePageFaultHandler = 0;
  1265. continue;
  1266. }
  1267. #endif
  1268. #endif
  1269. #ifdef NEVER
  1270. /*
  1271. ** Handle the prog init differently in this case.
  1272. */
  1273. if (strstr(string, "-V")) {
  1274. continue;
  1275. }
  1276. #endif
  1277. /*
  1278. ** look for passed-in video mode to default to
  1279. */
  1280. #ifndef WIN32
  1281. if (strnicmp(string, "-V", strlen("-V")) == 0) {
  1282. Set_Video_Mode(MCGA_MODE); // do this to get around first_time variable...
  1283. Set_Original_Video_Mode(atoi(string+2));
  1284. continue;
  1285. }
  1286. #endif
  1287. /*
  1288. ** Special command line control parsing.
  1289. */
  1290. if (strnicmp(string, "-X", strlen("-O")) == 0) {
  1291. string += strlen("-X");
  1292. while (*string) {
  1293. char code = *string++;
  1294. switch (toupper(code)) {
  1295. #ifdef CHEAT_KEYS
  1296. /*
  1297. ** Monochrome debug screen enable.
  1298. */
  1299. case 'M':
  1300. MonoClass::Enable();
  1301. break;
  1302. /*
  1303. ** Inert weapons -- no units take damage.
  1304. */
  1305. case 'I':
  1306. Special.IsInert = true;
  1307. break;
  1308. /*
  1309. ** Hussled recharge timer.
  1310. */
  1311. case 'H':
  1312. Special.IsSpeedBuild = true;
  1313. break;
  1314. /*
  1315. ** "Record" a multi-player game
  1316. */
  1317. case 'X':
  1318. Session.Record = 1;
  1319. break;
  1320. /*
  1321. ** "Play Back" a multi-player game
  1322. */
  1323. case 'Y':
  1324. Session.Play = 1;
  1325. break;
  1326. /*
  1327. ** Print lots of debug stuff about events & packets
  1328. */
  1329. case 'P':
  1330. Debug_Print_Events = true;
  1331. break;
  1332. #endif
  1333. /*
  1334. ** Quiet mode override control.
  1335. */
  1336. case 'Q':
  1337. Debug_Quiet = true;
  1338. break;
  1339. default:
  1340. puts(TEXT_INVALID);
  1341. return(false);
  1342. }
  1343. }
  1344. continue;
  1345. }
  1346. }
  1347. return(true);
  1348. }
  1349. /***********************************************************************************************
  1350. * Obfuscate -- Sufficiently transform parameter to thwart casual hackers. *
  1351. * *
  1352. * This routine borrows from CRC and PGP technology to sufficiently alter the parameter *
  1353. * in order to make it difficult to reverse engineer the key phrase. This is designed to *
  1354. * be used for hidden game options that will be released at a later time over Westwood's *
  1355. * Web page or through magazine hint articles. *
  1356. * *
  1357. * This algorithm is cryptographically categorized as a "one way hash". *
  1358. * *
  1359. * Since this is a one way transformation, it becomes much more difficult to reverse *
  1360. * engineer the pass phrase even if the resultant pass code is known. This has an added *
  1361. * benefit of making this algorithm immune to traditional cryptographic attacks. *
  1362. * *
  1363. * The largest strength of this transformation algorithm lies in the restriction on the *
  1364. * source vector being legal ASCII uppercase characters. This restriction alone makes even *
  1365. * a simple CRC transformation practically impossible to reverse engineer. This algorithm *
  1366. * uses far more than a simple CRC transformation to achieve added strength from advanced *
  1367. * attack methods. *
  1368. * *
  1369. * INPUT: string -- Pointer to the key phrase that will be transformed into a code. *
  1370. * *
  1371. * OUTPUT: Returns with the code that the key phrase is translated into. *
  1372. * *
  1373. * WARNINGS: A zero length pass phrase results in a 0x00000000 result code. *
  1374. * *
  1375. * HISTORY: *
  1376. * 08/19/1995 JLB : Created. *
  1377. *=============================================================================================*/
  1378. long Obfuscate(char const * string)
  1379. {
  1380. char buffer[128];
  1381. if (!string) return(0);
  1382. memset(buffer, '\xA5', sizeof(buffer));
  1383. /*
  1384. ** Copy key phrase into a working buffer. This hides any transformation done
  1385. ** to the string.
  1386. */
  1387. strncpy(buffer, string, sizeof(buffer));
  1388. buffer[sizeof(buffer)-1] = '\0';
  1389. int length = strlen(buffer);
  1390. /*
  1391. ** Only upper case letters are significant.
  1392. */
  1393. strupr(buffer);
  1394. /*
  1395. ** Ensure that only visible ASCII characters compose the key phrase. This
  1396. ** discourages the direct forced illegal character input method of attack.
  1397. */
  1398. for (int index = 0; index < length; index++) {
  1399. if (!isgraph(buffer[index])) {
  1400. buffer[index] = 'A' + (index%26);
  1401. }
  1402. }
  1403. /*
  1404. ** Increase the strength of even short pass phrases by extending the
  1405. ** length to be at least a minimum number of characters. This helps prevent
  1406. ** a weak pass phrase from compromising the obfuscation process. This
  1407. ** process also forces the key phrase to be an even multiple of four.
  1408. ** This is necessary to support the cypher process that occurs later.
  1409. */
  1410. if (length < 16 || (length & 0x03)) {
  1411. int maxlen = 16;
  1412. if (((length+3) & 0x00FC) > maxlen) {
  1413. maxlen = ((length+3) & 0x00FC);
  1414. }
  1415. for (index = length; index < maxlen; index++) {
  1416. buffer[index] = 'A' + ((('?' ^ buffer[index-length]) + index) % 26);
  1417. }
  1418. length = index;
  1419. buffer[length] = '\0';
  1420. }
  1421. /*
  1422. ** Transform the buffer into a number. This transformation is character
  1423. ** order dependant.
  1424. */
  1425. long code = Calculate_CRC(buffer, length);
  1426. /*
  1427. ** Record a copy of this initial transformation to be used in a later
  1428. ** self referential transformation.
  1429. */
  1430. long copy = code;
  1431. /*
  1432. ** Reverse the character string and combine with the previous transformation.
  1433. ** This doubles the workload of trying to reverse engineer the CRC calculation.
  1434. */
  1435. strrev(buffer);
  1436. code ^= Calculate_CRC(buffer, length);
  1437. /*
  1438. ** Perform a self referential transformation. This makes a reverse engineering
  1439. ** by using a cause and effect attack more difficult.
  1440. */
  1441. code = code ^ copy;
  1442. /*
  1443. ** Unroll and combine the code value into the pass phrase and then perform
  1444. ** another self referential transformation. Although this is a trivial cypher
  1445. ** process, it gives the sophisticated hacker false hope since the strong
  1446. ** cypher process occurs later.
  1447. */
  1448. strrev(buffer); // Restore original string order.
  1449. for (index = 0; index < length; index++) {
  1450. code ^= (unsigned char)buffer[index];
  1451. unsigned char temp = (unsigned char)code;
  1452. buffer[index] ^= temp;
  1453. code >>= 8;
  1454. code |= (((long)temp)<<24);
  1455. }
  1456. /*
  1457. ** Introduce loss into the vector. This strengthens the key against traditional
  1458. ** cryptographic attack engines. Since this also weakens the key against
  1459. ** unconventional attacks, the loss is limited to less than 10%.
  1460. */
  1461. for (index = 0; index < length; index++) {
  1462. static unsigned char _lossbits[] = {0x00,0x08,0x00,0x20,0x00,0x04,0x10,0x00};
  1463. static unsigned char _addbits[] = {0x10,0x00,0x00,0x80,0x40,0x00,0x00,0x04};
  1464. buffer[index] |= _addbits[index % (sizeof(_addbits)/sizeof(_addbits[0]))];
  1465. buffer[index] &= ~_lossbits[index % (sizeof(_lossbits)/sizeof(_lossbits[0]))];
  1466. }
  1467. /*
  1468. ** Perform a general cypher transformation on the vector
  1469. ** and use the vector itself as the cypher key. This is a variation on the
  1470. ** cypher process used in PGP. It is a very strong cypher process with no known
  1471. ** weaknesses. However, in this case, the cypher key is the vector itself and this
  1472. ** opens up a weakness against attacks that have access to this transformation
  1473. ** algorithm. The sheer workload of reversing this transformation should be enough
  1474. ** to discourage even the most determined hackers.
  1475. */
  1476. for (index = 0; index < length; index += 4) {
  1477. short key1 = buffer[index];
  1478. short key2 = buffer[index+1];
  1479. short key3 = buffer[index+2];
  1480. short key4 = buffer[index+3];
  1481. short val1 = key1;
  1482. short val2 = key2;
  1483. short val3 = key3;
  1484. short val4 = key4;
  1485. val1 *= key1;
  1486. val2 += key2;
  1487. val3 += key3;
  1488. val4 *= key4;
  1489. short s3 = val3;
  1490. val3 ^= val1;
  1491. val3 *= key1;
  1492. short s2 = val2;
  1493. val2 ^= val4;
  1494. val2 += val3;
  1495. val2 *= key3;
  1496. val3 += val2;
  1497. val1 ^= val2;
  1498. val4 ^= val3;
  1499. val2 ^= s3;
  1500. val3 ^= s2;
  1501. buffer[index] = val1;
  1502. buffer[index+1] = val2;
  1503. buffer[index+2] = val3;
  1504. buffer[index+3] = val4;
  1505. }
  1506. /*
  1507. ** Convert this final vector into a cypher key code to be
  1508. ** returned by this routine.
  1509. */
  1510. code = Calculate_CRC(buffer, length);
  1511. /*
  1512. ** Return the final code value.
  1513. */
  1514. return(code);
  1515. }
  1516. /***********************************************************************************************
  1517. * Calculate_CRC -- Calculates a one-way hash from a data block. *
  1518. * *
  1519. * This routine is used to create a hash value from a data block. The algorithm is similar *
  1520. * to a CRC, but is faster. *
  1521. * *
  1522. * INPUT: buffer -- Pointer to a buffer of data to be 'hashed'. *
  1523. * *
  1524. * len -- The length of the buffer to compute the hash upon. *
  1525. * *
  1526. * OUTPUT: Returns with a 32bit hash value calculated from the specified buffer. *
  1527. * *
  1528. * WARNINGS: none *
  1529. * *
  1530. * HISTORY: *
  1531. * 03/02/1996 JLB : Created. *
  1532. *=============================================================================================*/
  1533. extern "C" {
  1534. long Calculate_CRC(void * buffer, long len)
  1535. {
  1536. return(CRCEngine()(buffer, len));
  1537. }
  1538. }
  1539. /***************************************************************************
  1540. * Init_Random -- Initializes the random-number generator *
  1541. * *
  1542. * INPUT: *
  1543. * none. *
  1544. * *
  1545. * OUTPUT: *
  1546. * none. *
  1547. * *
  1548. * WARNINGS: *
  1549. * none. *
  1550. * *
  1551. * HISTORY: *
  1552. * 12/04/1995 BRR : Created. *
  1553. *=========================================================================*/
  1554. void Init_Random(void)
  1555. {
  1556. #ifdef WIN32
  1557. /*
  1558. ** Gather some "random" bits from the system timer. Actually, only the
  1559. ** low order millisecond bits are secure. The other bits could be
  1560. ** easily guessed from the system clock (most clocks are fairly accurate
  1561. ** and thus predictable).
  1562. */
  1563. SYSTEMTIME t;
  1564. GetSystemTime(&t);
  1565. CryptRandom.Seed_Byte(t.wMilliseconds);
  1566. CryptRandom.Seed_Bit(t.wSecond);
  1567. CryptRandom.Seed_Bit(t.wSecond>>1);
  1568. CryptRandom.Seed_Bit(t.wSecond>>2);
  1569. CryptRandom.Seed_Bit(t.wSecond>>3);
  1570. CryptRandom.Seed_Bit(t.wSecond>>4);
  1571. CryptRandom.Seed_Bit(t.wMinute);
  1572. CryptRandom.Seed_Bit(t.wMinute>>1);
  1573. CryptRandom.Seed_Bit(t.wMinute>>2);
  1574. CryptRandom.Seed_Bit(t.wMinute>>3);
  1575. CryptRandom.Seed_Bit(t.wMinute>>4);
  1576. CryptRandom.Seed_Bit(t.wHour);
  1577. CryptRandom.Seed_Bit(t.wDay);
  1578. CryptRandom.Seed_Bit(t.wDayOfWeek);
  1579. CryptRandom.Seed_Bit(t.wMonth);
  1580. CryptRandom.Seed_Bit(t.wYear);
  1581. #else
  1582. /*
  1583. ** Gather some "random" bits from the DOS mode timer.
  1584. */
  1585. struct timeb t;
  1586. ftime(&t);
  1587. CryptRandom.Seed_Byte(t.millitm);
  1588. CryptRandom.Seed_Byte(t.time);
  1589. #endif
  1590. /*
  1591. ** Do nothing if we've loaded a multiplayer game, or we're playing back
  1592. ** a recording; the random number generator is initialized by loading
  1593. ** the game.
  1594. */
  1595. if (Session.LoadGame || Session.Play) {
  1596. RandNumb = Seed;
  1597. Scen.RandomNumber = Seed;
  1598. return;
  1599. }
  1600. /*
  1601. ** Initialize the random number Seed. For multiplayer, this will have been done
  1602. ** in the connection dialogs. For single-player games, AND if we're not playing
  1603. ** back a recording, init the Seed to a random value.
  1604. */
  1605. if (Session.Type == GAME_NORMAL || Session.Type == GAME_SKIRMISH &&
  1606. !Session.Play) {
  1607. /*
  1608. ** Set the optional user-specified seed
  1609. */
  1610. if (CustomSeed != 0) {
  1611. Seed = CustomSeed;
  1612. } else {
  1613. srand(time(NULL));
  1614. Seed = rand();
  1615. }
  1616. }
  1617. /*
  1618. ** Initialize the random-number generators
  1619. */
  1620. Scen.RandomNumber = Seed;
  1621. RandNumb = Seed;
  1622. }
  1623. /***********************************************************************************************
  1624. * Load_Title_Page -- Load the background art for the title page. *
  1625. * *
  1626. * This routine will load the background art in a machine independent format. There is *
  1627. * different art required for the hi-res and lo-res versions of the game. *
  1628. * *
  1629. * INPUT: visible -- Should the title page art be copied to the visible page by this *
  1630. * routine? *
  1631. * *
  1632. * OUTPUT: none *
  1633. * *
  1634. * WARNINGS: Be sure the mouse is hidden if the image is to be copied to the visible page. *
  1635. * *
  1636. * HISTORY: *
  1637. * 06/03/1996 JLB : Created. *
  1638. *=============================================================================================*/
  1639. void Load_Title_Page(bool visible)
  1640. {
  1641. #ifdef WIN32
  1642. Load_Title_Screen("TITLE.PCX", &HidPage, CCPalette);
  1643. if (visible) {
  1644. HidPage.Blit(SeenPage);
  1645. }
  1646. #else
  1647. Load_Picture("TITLE.CPS", HidPage, HidPage, CCPalette, BM_DEFAULT);
  1648. if (visible) {
  1649. HidPage.Blit(SeenPage);
  1650. }
  1651. #endif
  1652. }
  1653. /***********************************************************************************************
  1654. * Init_Color_Remaps -- Initialize the text remap tables. *
  1655. * *
  1656. * There are various color scheme remap tables that are dependant upon the color remap *
  1657. * information embedded within the palette control file. This routine will fetch that *
  1658. * data and build the text remap tables as indicated. *
  1659. * *
  1660. * INPUT: none *
  1661. * *
  1662. * OUTPUT: none *
  1663. * *
  1664. * WARNINGS: none *
  1665. * *
  1666. * HISTORY: *
  1667. * 06/03/1996 JLB : Created. *
  1668. *=============================================================================================*/
  1669. static void Init_Color_Remaps(void)
  1670. {
  1671. /*
  1672. ** Setup the remap tables. PALETTE.CPS contains a special set of pixels in
  1673. ** the upper-left corner. Each row of 16 pixels is one range of colors. The
  1674. ** first row represents unity (the default color units are drawn in); rows
  1675. ** after that are the remap colors.
  1676. */
  1677. #ifdef WIN32
  1678. SysMemPage.Clear();
  1679. Load_Picture("PALETTE.CPS", SysMemPage, SysMemPage, NULL, BM_DEFAULT);
  1680. SysMemPage.Blit(HidPage);
  1681. #else
  1682. Load_Picture("PALETTE.CPS", HidPage, HidPage, NULL, BM_DEFAULT);
  1683. #endif
  1684. for (PlayerColorType pcolor = PCOLOR_FIRST; pcolor < PCOLOR_COUNT; pcolor++) {
  1685. unsigned char * ptr = ColorRemaps[pcolor].RemapTable;
  1686. for (int color = 0; color < 256; color++) {
  1687. ptr[color] = color;
  1688. }
  1689. for (int index = 0; index < 16; index++) {
  1690. ptr[HidPage.Get_Pixel(index, 0)] = HidPage.Get_Pixel(index, pcolor);
  1691. }
  1692. for (index = 0; index < 6; index++) {
  1693. ColorRemaps[pcolor].FontRemap[10+index] = HidPage.Get_Pixel(2+index, pcolor);
  1694. }
  1695. ColorRemaps[pcolor].BrightColor = HidPage.Get_Pixel(2, pcolor);
  1696. ColorRemaps[pcolor].Color = HidPage.Get_Pixel(4, pcolor);
  1697. ColorRemaps[pcolor].Shadow = HidPage.Get_Pixel(10, pcolor);
  1698. ColorRemaps[pcolor].Background = HidPage.Get_Pixel(9, pcolor);
  1699. ColorRemaps[pcolor].Corners = HidPage.Get_Pixel(8, pcolor);
  1700. ColorRemaps[pcolor].Highlight = HidPage.Get_Pixel(4, pcolor);
  1701. ColorRemaps[pcolor].Bright = HidPage.Get_Pixel(0, pcolor);
  1702. ColorRemaps[pcolor].Underline = HidPage.Get_Pixel(0, pcolor);
  1703. ColorRemaps[pcolor].Bar = HidPage.Get_Pixel(6, pcolor);
  1704. ColorRemaps[pcolor].Box = HidPage.Get_Pixel(4, pcolor);
  1705. }
  1706. /*
  1707. ** Now do the special dim grey scheme
  1708. */
  1709. for (int color = 0; color < 256; color++) {
  1710. GreyScheme.RemapTable[color] = color;
  1711. }
  1712. for (int index = 0; index < 6; index++) {
  1713. GreyScheme.FontRemap[10+index] = HidPage.Get_Pixel(9+index, PCOLOR_GREY) & 0x00FF;
  1714. }
  1715. GreyScheme.BrightColor = HidPage.Get_Pixel(3, PCOLOR_GREY) & 0x00FF;
  1716. GreyScheme.Color = HidPage.Get_Pixel(7, PCOLOR_GREY) & 0x00FF;
  1717. GreyScheme.Shadow = ColorRemaps[PCOLOR_GREY].RemapTable[HidPage.Get_Pixel(15, PCOLOR_GREY) & 0x00FF];
  1718. GreyScheme.Background = ColorRemaps[PCOLOR_GREY].RemapTable[HidPage.Get_Pixel(14, PCOLOR_GREY) & 0x00FF];
  1719. GreyScheme.Corners = ColorRemaps[PCOLOR_GREY].RemapTable[HidPage.Get_Pixel(13, PCOLOR_GREY) & 0x00FF];
  1720. GreyScheme.Highlight = ColorRemaps[PCOLOR_GREY].RemapTable[HidPage.Get_Pixel(9, PCOLOR_GREY) & 0x00FF];
  1721. GreyScheme.Bright = ColorRemaps[PCOLOR_GREY].RemapTable[HidPage.Get_Pixel(5, PCOLOR_GREY) & 0x00FF];
  1722. GreyScheme.Underline = ColorRemaps[PCOLOR_GREY].RemapTable[HidPage.Get_Pixel(5, PCOLOR_GREY) & 0x00FF];
  1723. GreyScheme.Bar = ColorRemaps[PCOLOR_GREY].RemapTable[HidPage.Get_Pixel(11, PCOLOR_GREY) & 0x00FF];
  1724. GreyScheme.Box = ColorRemaps[PCOLOR_GREY].RemapTable[HidPage.Get_Pixel(11, PCOLOR_GREY) & 0x00FF];
  1725. /*
  1726. ** Set up the metallic remap table for the font that prints over the tabs
  1727. */
  1728. memset ((void*)&MetalScheme, 4, sizeof(MetalScheme));
  1729. for (int color_counter = 0; color_counter < 16; color_counter++) {
  1730. MetalScheme.FontRemap[color_counter] = color_counter;
  1731. }
  1732. MetalScheme.FontRemap[1] = 128;
  1733. MetalScheme.FontRemap[2] = 12;
  1734. MetalScheme.FontRemap[3] = 13;
  1735. MetalScheme.FontRemap[4] = 14;
  1736. MetalScheme.Color = 128;
  1737. MetalScheme.Background = 0;
  1738. MetalScheme.Underline = 128;
  1739. /*
  1740. ** Set up the font remap table for the mission briefing font
  1741. */
  1742. for (int colr = 0; colr < 16; colr++) {
  1743. ColorRemaps[PCOLOR_TYPE].FontRemap[colr] = HidPage.Get_Pixel(colr, PCOLOR_TYPE);
  1744. }
  1745. ColorRemaps[PCOLOR_TYPE].Shadow = 11;
  1746. ColorRemaps[PCOLOR_TYPE].Background = 10;
  1747. ColorRemaps[PCOLOR_TYPE].Corners = 10;
  1748. ColorRemaps[PCOLOR_TYPE].Highlight = 9;
  1749. ColorRemaps[PCOLOR_TYPE].Bright = 15;
  1750. ColorRemaps[PCOLOR_TYPE].Underline = 11;
  1751. ColorRemaps[PCOLOR_TYPE].Bar = 11;
  1752. ColorRemaps[PCOLOR_TYPE].Box = 10;
  1753. ColorRemaps[PCOLOR_TYPE].BrightColor = 15;
  1754. ColorRemaps[PCOLOR_TYPE].Color = 9;
  1755. GadgetClass::Set_Color_Scheme(&ColorRemaps[PCOLOR_BLUE]);
  1756. }
  1757. /***********************************************************************************************
  1758. * Init_Heaps -- Initialize the game heaps and buffers. *
  1759. * *
  1760. * This routine will allocate the game heaps and buffers. The rules file has already been *
  1761. * processed by the time that this routine is called. *
  1762. * *
  1763. * INPUT: none *
  1764. * *
  1765. * OUTPUT: none *
  1766. * *
  1767. * WARNINGS: none *
  1768. * *
  1769. * HISTORY: *
  1770. * 06/03/1996 JLB : Created. *
  1771. *=============================================================================================*/
  1772. static void Init_Heaps(void)
  1773. {
  1774. /*
  1775. ** Initialize the game object heaps.
  1776. */
  1777. Vessels.Set_Heap(Rule.VesselMax);
  1778. Units.Set_Heap(Rule.UnitMax);
  1779. Factories.Set_Heap(Rule.FactoryMax);
  1780. Terrains.Set_Heap(Rule.TerrainMax);
  1781. Templates.Set_Heap(Rule.TemplateMax);
  1782. Smudges.Set_Heap(Rule.SmudgeMax);
  1783. Overlays.Set_Heap(Rule.OverlayMax);
  1784. Infantry.Set_Heap(Rule.InfantryMax);
  1785. Bullets.Set_Heap(Rule.BulletMax);
  1786. Buildings.Set_Heap(Rule.BuildingMax);
  1787. Anims.Set_Heap(Rule.AnimMax);
  1788. Aircraft.Set_Heap(Rule.AircraftMax);
  1789. Triggers.Set_Heap(Rule.TriggerMax);
  1790. TeamTypes.Set_Heap(Rule.TeamTypeMax);
  1791. Teams.Set_Heap(Rule.TeamMax);
  1792. Houses.Set_Heap(HOUSE_MAX);
  1793. TriggerTypes.Set_Heap(Rule.TrigTypeMax);
  1794. // Weapons.Set_Heap(Rule.WeaponMax);
  1795. /*
  1796. ** Speech holding tank buffer. Since speech does not mix, it can be placed
  1797. ** into a custom holding tank only as large as the largest speech file to
  1798. ** be played.
  1799. */
  1800. for (int index = 0; index < ARRAY_SIZE(SpeechBuffer); index++) {
  1801. SpeechBuffer[index] = new char [SPEECH_BUFFER_SIZE];
  1802. SpeechRecord[index] = VOX_NONE;
  1803. assert(SpeechBuffer[index] != NULL);
  1804. }
  1805. /*
  1806. ** Allocate the theater buffer block.
  1807. */
  1808. TheaterBuffer = new Buffer(THEATER_BUFFER_SIZE);
  1809. assert(TheaterBuffer != NULL);
  1810. }
  1811. /***********************************************************************************************
  1812. * Init_Expansion_Files -- Fetch any override expansion mixfiles. *
  1813. * *
  1814. * This routine will search for and register/cache any override mixfiles found. *
  1815. * *
  1816. * INPUT: none *
  1817. * *
  1818. * OUTPUT: none *
  1819. * *
  1820. * WARNINGS: none *
  1821. * *
  1822. * HISTORY: *
  1823. * 06/03/1996 JLB : Created. *
  1824. *=============================================================================================*/
  1825. static void Init_Expansion_Files(void)
  1826. {
  1827. /*
  1828. ** Before all else, cache any additional mixfiles.
  1829. */
  1830. struct find_t ff; // for _dos_findfirst
  1831. if (!_dos_findfirst("SC*.MIX", _A_NORMAL, &ff)) {
  1832. char * ptr;
  1833. do {
  1834. ptr = strdup(ff.name);
  1835. new MFCD(ptr, &FastKey);
  1836. MFCD::Cache(ptr);
  1837. } while (!_dos_findnext(&ff));
  1838. }
  1839. if (!_dos_findfirst("SS*.MIX", _A_NORMAL, &ff)) {
  1840. char * ptr;
  1841. do {
  1842. ptr = strdup(ff.name);
  1843. new MFCD(ptr, &FastKey);
  1844. } while (!_dos_findnext(&ff));
  1845. }
  1846. }
  1847. /***********************************************************************************************
  1848. * Init_One_Time_Systems -- Initialize internal pointers to the bulk data. *
  1849. * *
  1850. * This performs the one-time processing required after the bulk data has been cached but *
  1851. * before the game actually starts. Typically, this routine extracts pointers to all the *
  1852. * embedded data sub-files within the main game data mixfile. This routine must be called *
  1853. * AFTER the bulk data has been cached. *
  1854. * *
  1855. * INPUT: none *
  1856. * *
  1857. * OUTPUT: none *
  1858. * *
  1859. * WARNINGS: Call this routine AFTER the bulk data has been cached. *
  1860. * *
  1861. * HISTORY: *
  1862. * 06/03/1996 JLB : Created. *
  1863. *=============================================================================================*/
  1864. static void Init_One_Time_Systems(void)
  1865. {
  1866. Call_Back();
  1867. Map.One_Time();
  1868. Logic.One_Time();
  1869. Options.One_Time();
  1870. Session.One_Time();
  1871. ObjectTypeClass::One_Time();
  1872. BuildingTypeClass::One_Time();
  1873. BulletTypeClass::One_Time();
  1874. HouseTypeClass::One_Time();
  1875. TemplateTypeClass::One_Time();
  1876. OverlayTypeClass::One_Time();
  1877. SmudgeTypeClass::One_Time();
  1878. TerrainTypeClass::One_Time();
  1879. UnitTypeClass::One_Time();
  1880. VesselTypeClass::One_Time();
  1881. InfantryTypeClass::One_Time();
  1882. AnimTypeClass::One_Time();
  1883. AircraftTypeClass::One_Time();
  1884. HouseClass::One_Time();
  1885. }
  1886. /***********************************************************************************************
  1887. * Init_Fonts -- Initialize all the game font pointers. *
  1888. * *
  1889. * This routine is used to fetch pointers to the game fonts. The mixfile containing these *
  1890. * fonts must have been previously cached. This routine is a necessary prerequisite to *
  1891. * displaying any dialogs or printing any text. *
  1892. * *
  1893. * INPUT: none *
  1894. * *
  1895. * OUTPUT: none *
  1896. * *
  1897. * WARNINGS: none *
  1898. * *
  1899. * HISTORY: *
  1900. * 06/03/1996 JLB : Created. *
  1901. *=============================================================================================*/
  1902. static void Init_Fonts(void)
  1903. {
  1904. Metal12FontPtr = MFCD::Retrieve("12METFNT.FNT");
  1905. MapFontPtr = MFCD::Retrieve("HELP.FNT");
  1906. Font6Ptr = MFCD::Retrieve("6POINT.FNT");
  1907. GradFont6Ptr = MFCD::Retrieve("GRAD6FNT.FNT");
  1908. EditorFont = MFCD::Retrieve("EDITFNT.FNT");
  1909. Font8Ptr = MFCD::Retrieve("8POINT.FNT");
  1910. FontPtr = (char *)Font8Ptr;
  1911. Set_Font(FontPtr);
  1912. Font3Ptr = MFCD::Retrieve("3POINT.FNT");
  1913. ScoreFontPtr = MFCD::Retrieve("SCOREFNT.FNT");
  1914. FontLEDPtr = MFCD::Retrieve("LED.FNT");
  1915. VCRFontPtr = MFCD::Retrieve("VCR.FNT");
  1916. TypeFontPtr = MFCD::Retrieve("8POINT.FNT"); //("TYPE.FNT"); //VG 10/17/96
  1917. }
  1918. /***********************************************************************************************
  1919. * Init_CDROM_Access -- Initialize the CD-ROM access handler. *
  1920. * *
  1921. * This routine is called to setup the CD-ROM access or emulation handler. It will ensure *
  1922. * that the appropriate CD-ROM is present (dependant on the RequiredCD global). *
  1923. * *
  1924. * INPUT: none *
  1925. * *
  1926. * OUTPUT: none *
  1927. * *
  1928. * WARNINGS: The fonts, palettes, and other bootstrap systems must have been initialized *
  1929. * prior to calling this routine since this routine will quite likely display *
  1930. * a dialog box requesting the appropriate CD be inserted. *
  1931. * *
  1932. * HISTORY: *
  1933. * 06/03/1996 JLB : Created. *
  1934. *=============================================================================================*/
  1935. static void Init_CDROM_Access(void)
  1936. {
  1937. /*
  1938. ** Always try to look at the CD-ROM for data files.
  1939. */
  1940. if (!CCFileClass::Is_There_Search_Drives()) {
  1941. /*
  1942. ** This call is needed because of a side effect of this function. It will examine the
  1943. ** CD-ROMs attached to this computer and set the appropriate status values. Without this
  1944. ** call, the "?:\\" could not be filled in correctly.
  1945. */
  1946. Force_CD_Available(-1);
  1947. /*
  1948. ** If there are no search drives specified then we must be playing
  1949. ** off cd, so read files from there.
  1950. */
  1951. int error;
  1952. do {
  1953. error = CCFileClass::Set_Search_Drives("?:\\");
  1954. switch (error) {
  1955. case 1:
  1956. VisiblePage.Clear();
  1957. GamePalette.Set();
  1958. Show_Mouse();
  1959. WWMessageBox().Process(TXT_CD_ERROR1, TXT_OK);
  1960. Prog_End();
  1961. exit(EXIT_FAILURE);
  1962. case 2:
  1963. VisiblePage.Clear();
  1964. GamePalette.Set();
  1965. Show_Mouse();
  1966. if (WWMessageBox().Process(TXT_CD_DIALOG_1, TXT_OK, TXT_CANCEL) == 1) {
  1967. Prog_End();
  1968. exit(EXIT_FAILURE);
  1969. }
  1970. Hide_Mouse();
  1971. break;
  1972. default:
  1973. VisiblePage.Clear();
  1974. Show_Mouse();
  1975. if (!Force_CD_Available(RequiredCD)) {
  1976. Prog_End();
  1977. exit(EXIT_FAILURE);
  1978. }
  1979. Hide_Mouse();
  1980. break;
  1981. }
  1982. } while (error);
  1983. RequiredCD = -1;
  1984. } else {
  1985. /*
  1986. ** If there are search drives specified then all files are to be
  1987. ** considered local.
  1988. */
  1989. RequiredCD = -2;
  1990. }
  1991. }
  1992. /***********************************************************************************************
  1993. * Init_Bootstrap_Mixfiles -- Registers and caches any mixfiles needed for bootstrapping. *
  1994. * *
  1995. * This routine will register the initial mixfiles that are required to display error *
  1996. * messages and get input from the player. *
  1997. * *
  1998. * INPUT: none *
  1999. * *
  2000. * OUTPUT: none *
  2001. * *
  2002. * WARNINGS: Be sure to call this routine before any dialogs would be displayed to the *
  2003. * player. *
  2004. * *
  2005. * HISTORY: *
  2006. * 06/03/1996 JLB : Created. *
  2007. *=============================================================================================*/
  2008. static void Init_Bootstrap_Mixfiles(void)
  2009. {
  2010. int temp = RequiredCD;
  2011. RequiredCD = -2;
  2012. new MFCD("REDALERT.MIX", &FastKey);
  2013. /*
  2014. ** Bootstrap enough of the system so that the error dialog box can successfully
  2015. ** be displayed.
  2016. */
  2017. new MFCD("LOCAL.MIX", &FastKey); // Cached.
  2018. bool ok = MFCD::Cache("LOCAL.MIX");
  2019. assert(ok);
  2020. #ifdef WIN32
  2021. new MFCD("HIRES.MIX", &FastKey);
  2022. ok = MFCD::Cache("HIRES.MIX");
  2023. assert(ok);
  2024. new MFCD("NCHIRES.MIX", &FastKey); //Non-cached hires stuff incl VQ palettes
  2025. #else
  2026. new MFCD("LORES.MIX", &FastKey);
  2027. ok = MFCD::Cache("LORES.MIX");
  2028. assert(ok);
  2029. #endif //WIN32
  2030. RequiredCD = temp;
  2031. }
  2032. /***********************************************************************************************
  2033. * Init_Secondary_Mixfiles -- Register and cache secondary mixfiles. *
  2034. * *
  2035. * This routine is used to register the mixfiles that are needed for main menu processing. *
  2036. * Call this routine before the main menu is display and processed. *
  2037. * *
  2038. * INPUT: none *
  2039. * *
  2040. * OUTPUT: none *
  2041. * *
  2042. * WARNINGS: none *
  2043. * *
  2044. * HISTORY: *
  2045. * 06/03/1996 JLB : Created. *
  2046. *=============================================================================================*/
  2047. static void Init_Secondary_Mixfiles(void)
  2048. {
  2049. MainMix = new MFCD("MAIN.MIX", &FastKey);
  2050. assert(MainMix != NULL);
  2051. /*
  2052. ** Inform the file system of the various MIX files.
  2053. */
  2054. ConquerMix = new MFCD("CONQUER.MIX", &FastKey); // Cached.
  2055. // new MFCD("TRANSIT.MIX", &FastKey);
  2056. if (GeneralMix == NULL) GeneralMix = new MFCD("GENERAL.MIX", &FastKey); // Never cached.
  2057. if (CCFileClass("MOVIES1.MIX").Is_Available()) {
  2058. MoviesMix = new MFCD("MOVIES1.MIX", &FastKey); // Never cached.
  2059. } else {
  2060. MoviesMix = new MFCD("MOVIES2.MIX", &FastKey); // Never cached.
  2061. }
  2062. assert(MoviesMix != NULL);
  2063. /*
  2064. ** Register the score mixfile.
  2065. */
  2066. ScoresPresent = true;
  2067. ScoreMix = new MFCD("SCORES.MIX", &FastKey);
  2068. ThemeClass::Scan();
  2069. /*
  2070. ** These are sound card specific, but the install program would have
  2071. ** copied the correct versions to the hard drive.
  2072. */
  2073. new MFCD("SPEECH.MIX", &FastKey); // Never cached.
  2074. new MFCD("SOUNDS.MIX", &FastKey); // Cached.
  2075. new MFCD("RUSSIAN.MIX", &FastKey); // Cached.
  2076. new MFCD("ALLIES.MIX", &FastKey); // Cached.
  2077. }
  2078. /***********************************************************************************************
  2079. * Bootstrap -- Perform the initial bootstrap procedure. *
  2080. * *
  2081. * This routine will load and initialize the game engine such that a dialog box could be *
  2082. * displayed. Because this is very critical, call this routine before any other game *
  2083. * initialization code. *
  2084. * *
  2085. * INPUT: none *
  2086. * *
  2087. * OUTPUT: none *
  2088. * *
  2089. * WARNINGS: none *
  2090. * *
  2091. * HISTORY: *
  2092. * 06/03/1996 JLB : Created. *
  2093. *=============================================================================================*/
  2094. static void Bootstrap(void)
  2095. {
  2096. BlackPalette.Set();
  2097. /*
  2098. ** Be sure to short circuit the CD-ROM check if there is a CD-ROM override
  2099. ** path.
  2100. */
  2101. if (CCFileClass::Is_There_Search_Drives()) {
  2102. RequiredCD = -2;
  2103. }
  2104. /*
  2105. ** Process the message loop until we are in focus. We need to be in focus to read pixels from
  2106. ** the screen.
  2107. */
  2108. #ifdef WIN32
  2109. do {
  2110. Keyboard->Check();
  2111. } while (!GameInFocus);
  2112. AllSurfaces.SurfacesRestored = false;
  2113. #endif
  2114. /*
  2115. ** Perform any special debug-only processing. This includes preparing the
  2116. ** monochrome screen.
  2117. */
  2118. Mono_Clear_Screen();
  2119. /*
  2120. ** Register and make resident all local mixfiles with particular emphasis
  2121. ** on the mixfiles that are necessary to display and error messages and
  2122. ** process further initialization.
  2123. */
  2124. Init_Bootstrap_Mixfiles();
  2125. /*
  2126. ** Initialize the resident font pointers.
  2127. */
  2128. Init_Fonts();
  2129. #ifndef WIN32
  2130. /*
  2131. ** Install the hard error handler.
  2132. */
  2133. _harderr(harderr_handler); // BG: Install hard error handler
  2134. /*
  2135. ** Install a Page Fault handler
  2136. */
  2137. if (UsePageFaultHandler) {
  2138. Install_Page_Fault_Handle();
  2139. }
  2140. #endif
  2141. /*
  2142. ** Setup the keyboard processor in preparation for the game.
  2143. */
  2144. #ifdef WIN32
  2145. Keyboard->Clear();
  2146. #else
  2147. Keyboard_Attributes_Off(BREAKON | SCROLLLOCKON | TRACKEXT | PAUSEON | CTRLSON | CTRLCON | FILTERONLY | TASKSWITCHABLE);
  2148. Keyboard_Attributes_On(PASSBREAKS);
  2149. Keyboard->Clear();
  2150. #endif
  2151. /*
  2152. ** This is the shape staging buffer. It must always be available, so it is
  2153. ** allocated here and never freed. The library sets the globals ShapeBuffer
  2154. ** and ShapeBufferSize to these values, so it can be accessed for other
  2155. ** purposes.
  2156. */
  2157. Set_Shape_Buffer(new unsigned char[SHAPE_BUFFER_SIZE], SHAPE_BUFFER_SIZE);
  2158. /*
  2159. ** Fetch the language text from the hard drive first. If it cannot be
  2160. ** found on the hard drive, then look for it in the mixfile.
  2161. */
  2162. SystemStrings = (char const *)MFCD::Retrieve(Language_Name("CONQUER"));
  2163. DebugStrings = (char const *)MFCD::Retrieve("DEBUG.ENG");
  2164. /*
  2165. ** Default palette initialization.
  2166. */
  2167. memmove((unsigned char *)&GamePalette[0], (void *)MFCD::Retrieve("TEMPERAT.PAL"), 768L);
  2168. WhitePalette[0] = BlackPalette[0];
  2169. // GamePalette.Set();
  2170. /*
  2171. ** Initialize expansion files (if present). Expansion files must be located
  2172. ** in the current directory.
  2173. */
  2174. Init_Expansion_Files();
  2175. SidebarScheme.Background = BLACK;
  2176. SidebarScheme.Corners = LTGREY;
  2177. SidebarScheme.Shadow = DKGREY;
  2178. SidebarScheme.Highlight = WHITE;
  2179. SidebarScheme.Color = LTGREY;
  2180. SidebarScheme.Bright = WHITE;
  2181. SidebarScheme.BrightColor = WHITE;
  2182. SidebarScheme.Box = LTGREY;
  2183. GadgetClass::Set_Color_Scheme(&SidebarScheme);
  2184. }
  2185. /***********************************************************************************************
  2186. * Init_Mouse -- Initialize the mouse system. *
  2187. * *
  2188. * This routine will ensure that a valid mouse driver is present and a working mouse *
  2189. * pointer can be displayed. The mouse is hidden when this routine exits. *
  2190. * *
  2191. * INPUT: none *
  2192. * *
  2193. * OUTPUT: none *
  2194. * *
  2195. * WARNINGS: none *
  2196. * *
  2197. * HISTORY: *
  2198. * 06/03/1996 JLB : Created. *
  2199. *=============================================================================================*/
  2200. static void Init_Mouse(void)
  2201. {
  2202. /*
  2203. ** Since there is no mouse shape currently available we need
  2204. ** to set one of our own.
  2205. */
  2206. #ifdef WIN32
  2207. ShowCursor(false);
  2208. #endif
  2209. if (MouseInstalled) {
  2210. void const * temp_mouse_shapes = MFCD::Retrieve("MOUSE.SHP");
  2211. if (temp_mouse_shapes) {
  2212. Set_Mouse_Cursor(0, 0, Extract_Shape(temp_mouse_shapes, 0));
  2213. while (Get_Mouse_State() > 1) Show_Mouse();
  2214. }
  2215. } else {
  2216. char buffer[255];
  2217. GamePalette.Set();
  2218. GamePalette.Set();
  2219. sprintf(buffer, TEXT_NO_MOUSE);
  2220. VisiblePage.Clear();
  2221. WWMessageBox().Process(buffer, TXT_OK);
  2222. Prog_End();
  2223. exit(1);
  2224. }
  2225. Map.Set_Default_Mouse(MOUSE_NORMAL, false);
  2226. Show_Mouse();
  2227. while (Get_Mouse_State() > 1) Show_Mouse();
  2228. Call_Back();
  2229. Hide_Mouse();
  2230. }
  2231. #ifdef OBSOLETE
  2232. /***********************************************************************************************
  2233. * Init_Authorization -- Verifies that the player is authorized to play the game. *
  2234. * *
  2235. * This is a development routine that restricts access to the game by way of passwords. *
  2236. * *
  2237. * INPUT: none *
  2238. * *
  2239. * OUTPUT: none *
  2240. * *
  2241. * WARNINGS: none *
  2242. * *
  2243. * HISTORY: *
  2244. * 06/03/1996 JLB : Created. *
  2245. *=============================================================================================*/
  2246. static void Init_Authorization(void)
  2247. {
  2248. if (Special.IsFromInstall) return;
  2249. Load_Title_Page();
  2250. #ifdef WIN32
  2251. Wait_Vert_Blank();
  2252. #else //WIN32
  2253. Init_Delay();
  2254. Wait_Vert_Blank(VertBlank);
  2255. #endif //WIN32
  2256. CCPalette.Set();
  2257. // Set_Palette(Palette);
  2258. HidPage.Blit(SeenPage);
  2259. Show_Mouse();
  2260. /*
  2261. ** Fetch the type of game to be played. This will be either
  2262. ** C&C:Red Alert or C&C:Plus.
  2263. */
  2264. //tryagain:
  2265. bool ok = Debug_Flag;
  2266. int counter = 3;
  2267. if (Debug_Flag) ok = true;
  2268. /*
  2269. ** C&C:Red Alert requires a password for legal entry. Try (three times) to get a correct
  2270. ** password. If not found, then try again.
  2271. */
  2272. bool skipper = false;
  2273. #ifdef NEVER
  2274. while (!ok && counter) {
  2275. SmartPtr<char const> str = Fetch_Password(TXT_PASSWORD_CAPTION, TXT_PASSWORD_MESSAGE, TXT_OK);
  2276. SmartPtr<long const> lptr = &CheatCodes[0];
  2277. while (*lptr) {
  2278. if (Obfuscate(str) == *lptr++) {
  2279. ok = true;
  2280. break;
  2281. }
  2282. }
  2283. lptr = &EditorCodes[0];
  2284. while (*lptr) {
  2285. if (Obfuscate(str) == *lptr++) {
  2286. ok = true;
  2287. break;
  2288. }
  2289. }
  2290. lptr = &PlayCodes[0];
  2291. while (*lptr) {
  2292. if (Obfuscate(str) == *lptr++) {
  2293. ok = true;
  2294. skipper = true;
  2295. break;
  2296. }
  2297. }
  2298. if (ok) break;
  2299. Hide_Mouse();
  2300. Load_Title_Page();
  2301. HidPage.Blit(SeenPage);
  2302. Show_Mouse();
  2303. Delay(TIMER_SECOND*(4-counter)*1);
  2304. if (WWMessageBox().Process(TXT_PASSWORD_ERROR, TXT_TRY_AGAIN, TXT_CANCEL)) {
  2305. goto tryagain;
  2306. }
  2307. counter--;
  2308. if (counter == 0) goto tryagain;
  2309. }
  2310. #endif
  2311. if (!skipper) {
  2312. CCPalette.Set();
  2313. }
  2314. Hide_Mouse();
  2315. Load_Title_Page();
  2316. HidPage.Blit(SeenPage);
  2317. Show_Mouse();
  2318. Call_Back();
  2319. }
  2320. #endif
  2321. /***********************************************************************************************
  2322. * Init_Bulk_Data -- Initialize the time-consuming mixfile caching. *
  2323. * *
  2324. * This routine is called to handle the time consuming process of game initialization. *
  2325. * The title page will be displayed when this routine is called. *
  2326. * *
  2327. * INPUT: none *
  2328. * *
  2329. * OUTPUT: none *
  2330. * *
  2331. * WARNINGS: This routine will take a very long time. *
  2332. * *
  2333. * HISTORY: *
  2334. * 06/03/1996 JLB : Created. *
  2335. *=============================================================================================*/
  2336. static void Init_Bulk_Data(void)
  2337. {
  2338. /*
  2339. ** Cache the main game data. This operation can take a very long time.
  2340. */
  2341. MFCD::Cache("CONQUER.MIX");
  2342. if (SampleType != 0 && !Debug_Quiet) {
  2343. MFCD::Cache("SOUNDS.MIX");
  2344. MFCD::Cache("RUSSIAN.MIX");
  2345. MFCD::Cache("ALLIES.MIX");
  2346. }
  2347. Call_Back();
  2348. /*
  2349. ** Fetch the tutorial message data.
  2350. */
  2351. INIClass ini;
  2352. ini.Load(CCFileClass("TUTORIAL.INI"));
  2353. for (int index = 0; index < ARRAY_SIZE(TutorialText); index++) {
  2354. TutorialText[index] = NULL;
  2355. char buffer[128];
  2356. char num[10];
  2357. sprintf(num, "%d", index);
  2358. if (ini.Get_String("Tutorial", num, "", buffer, sizeof(buffer))) {
  2359. TutorialText[index] = strdup(buffer);
  2360. }
  2361. }
  2362. /*
  2363. ** Perform one-time game system initializations.
  2364. */
  2365. Init_One_Time_Systems();
  2366. }
  2367. /***********************************************************************************************
  2368. * Init_Keys -- Initialize the cryptographic keys. *
  2369. * *
  2370. * This routine will initialize the fast cryptographic key. It will also initialize the *
  2371. * slow one if this is a scenario editor version of the game. *
  2372. * *
  2373. * INPUT: none *
  2374. * *
  2375. * OUTPUT: none *
  2376. * *
  2377. * WARNINGS: none *
  2378. * *
  2379. * HISTORY: *
  2380. * 07/08/1996 JLB : Created. *
  2381. *=============================================================================================*/
  2382. static void Init_Keys(void)
  2383. {
  2384. RAMFileClass file((void*)Keys, strlen(Keys));
  2385. INIClass ini;
  2386. ini.Load(file);
  2387. FastKey = ini.Get_PKey(true);
  2388. #ifdef SCENARIO_EDITOR
  2389. SlowKey = ini.Get_PKey(false);
  2390. #endif
  2391. }
  2392. /***************************************************************************
  2393. * Save_Recording_Values -- Saves multiplayer-specific values *
  2394. * *
  2395. * This routine saves multiplayer values that need to be restored for a *
  2396. * save game. In addition to saving the random # seed for this scenario, *
  2397. * it saves the contents of the actual random number generator; this *
  2398. * ensures that the random # sequencer will pick up where it left off when *
  2399. * the game was saved. *
  2400. * This routine also saves the header for a Recording file, so it must *
  2401. * save some data not needed specifically by a save-game file (ie Seed). *
  2402. * *
  2403. * INPUT: *
  2404. * file file to save to *
  2405. * *
  2406. * OUTPUT: *
  2407. * true = success, false = failure *
  2408. * *
  2409. * WARNINGS: *
  2410. * none. *
  2411. * *
  2412. * HISTORY: *
  2413. * 09/28/1995 BRR : Created. *
  2414. *=========================================================================*/
  2415. bool Save_Recording_Values(CCFileClass & file)
  2416. {
  2417. Session.Save(file);
  2418. file.Write(&BuildLevel, sizeof(BuildLevel));
  2419. file.Write(&Debug_Unshroud, sizeof(Debug_Unshroud));
  2420. file.Write(&Seed, sizeof(Seed));
  2421. file.Write(&Scen.Scenario, sizeof(Scen.Scenario));
  2422. file.Write(Scen.ScenarioName, sizeof(Scen.ScenarioName));
  2423. file.Write(&Whom, sizeof(Whom));
  2424. file.Write(&Special, sizeof(SpecialClass));
  2425. file.Write(&Options, sizeof(GameOptionsClass));
  2426. return (true);
  2427. }
  2428. /***************************************************************************
  2429. * Load_Recording_Values -- Loads multiplayer-specific values *
  2430. * *
  2431. * INPUT: *
  2432. * file file to load from *
  2433. * *
  2434. * OUTPUT: *
  2435. * true = success, false = failure *
  2436. * *
  2437. * WARNINGS: *
  2438. * none. *
  2439. * *
  2440. * HISTORY: *
  2441. * 09/28/1995 BRR : Created. *
  2442. *=========================================================================*/
  2443. bool Load_Recording_Values(CCFileClass & file)
  2444. {
  2445. Session.Load(file);
  2446. file.Read(&BuildLevel, sizeof(BuildLevel));
  2447. file.Read(&Debug_Unshroud, sizeof(Debug_Unshroud));
  2448. file.Read(&Seed, sizeof(Seed));
  2449. file.Read(&Scen.Scenario, sizeof(Scen.Scenario));
  2450. file.Read(Scen.ScenarioName, sizeof(Scen.ScenarioName));
  2451. file.Read(&Whom, sizeof(Whom));
  2452. file.Read(&Special, sizeof(SpecialClass));
  2453. file.Read(&Options, sizeof(GameOptionsClass));
  2454. return (true);
  2455. }
  2456. extern "C" {
  2457. void __PRO(void) {
  2458. // printf("_pro\n");
  2459. }
  2460. }