hood.cpp 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. // hood.cpp
  19. // Project: Nostril (aka Postal)
  20. //
  21. // This module impliments the CHood class, which embodies the background,
  22. // the "building" sprites, the "opaque" sprites, and the attribute map.
  23. //
  24. // History:
  25. // 12/25/96 MJR Started.
  26. //
  27. // 01/22/97 JMI Now uses one string m_acBaseName to create the filenames
  28. // for the Background Image, the Attribute Map, and the
  29. // Alpha & Opaque layers.
  30. // Also, added GUI to get this string.
  31. //
  32. // 01/27/97 JMI Now fills the edit field with m_acBaseName before
  33. // presenting the dialog to the user in EditNew().
  34. //
  35. // 01/27/97 JMI Now loads files as %s%02dAlpha/Opaque instead of
  36. // %sAlpha/Opaque%02d. Removed #if block around some hack
  37. // I'm not sure I understood to begin with.
  38. //
  39. // 01/27/97 JMI I must've introduced a copy/paste type error or something
  40. // when I changed the Init(). But, anyways, now opaque layers
  41. // don't x-ray.
  42. //
  43. // 01/30/97 JMI Now uses FullPath() to construct paths and uses smaller
  44. // conventions for layer files to help fit into 8.3 names
  45. // for ISO 9660 (now uses a for alpha and o for opaque).
  46. // Also, positions caret at end of line of text in EditNew()'s
  47. // dialog's edit field.
  48. //
  49. // 02/03/97 JMI Now loads realm specific assets through the resource
  50. // manager.
  51. //
  52. // 02/04/97 JMI Changed LoadDib() call to Load() (which now supports
  53. // loading of DIBs).
  54. //
  55. // 02/04/97 JMI Changed all resources to pointers so we can fully utilize
  56. // the RResMgr.
  57. //
  58. // 02/07/97 JMI Now allows you to setup the world transform
  59. // (m_pRealm->m_scene.m_transWorld) via the EditNew/Modify
  60. // dialog.
  61. //
  62. // 02/07/97 JMI Now calls m_scene.SetupPipeline() to update the world
  63. // transform (which is now the view member of the scene's
  64. // pipeline).
  65. //
  66. // 02/10/97 JMI rspReleaseResource() now takes a ptr to a ptr.
  67. //
  68. // 02/13/97 JMI Changed paths for hoods to be in hoods/ instead of bg/
  69. // and also now just store the import part (like "city" instead
  70. // of "hoods/city").
  71. // Also, now gets resources for lighting effects.
  72. //
  73. // 02/13/97 JMI In previous update, forgot to release alpha related res's.
  74. //
  75. // 02/24/97 JMI No longer sets the m_type member of the m_sprite b/c it
  76. // is set by m_sprite's constructor.
  77. //
  78. // 02/26/97 JMI No longer skips map load if no layers loaded.
  79. //
  80. // 03/13/97 JMI Load now takes a version number.
  81. //
  82. // 03/25/97 JMI GetResources() now opens the hood sak with the same name as
  83. // the hood.
  84. //
  85. // 04/09/97 BRH Added RMultiGrid for the multi layer attribute maps, but
  86. // haven't taken out the RAttributeMap yet so that the
  87. // game will continue to work until we completely switch over.
  88. //
  89. // 04/18/97 JMI Now Startup() calls rspSetPalette*() and rspUpdatePalette()
  90. // instead of Init().
  91. //
  92. // 04/22/97 JMI Now ReleaseResources() purges m_pRealm->m_resmgr after
  93. // releasing the hood's resources so we get them out of memory
  94. // right away.
  95. //
  96. // 05/09/97 JMI EditNew() was not checking the result of Init() before
  97. // calling Startup(). Fixed.
  98. //
  99. // 05/13/97 JMI Casted instances of warning C4018 (signed/unsigned mismatch)
  100. // to make MSVC 4.1(Alpha) happy (these seem to fall under
  101. // Warning Level 3 in 4.1(Alpha) but not in 4.2(Intel)).
  102. //
  103. // 05/15/97 JMI As per Bill, I changed the default world X axis rotation to
  104. // 30.
  105. //
  106. // 05/26/97 JMI Now Save()s, Load()s, and EditModify()s
  107. // m_pRealm->m_dKillsPercentGoal.
  108. //
  109. // 05/29/97 JMI Changed occurences of m_pHeightMap to m_pTerrainMap.
  110. // Changed occurences of m_pAttrMap to m_pLayerMap.
  111. // Also, removed occurences of m_pattribMap.
  112. //
  113. // 05/30/97 JMI The distance between building layers was hard coded to 3.
  114. // Now that the distance is 4, I used a more dynamic value
  115. // (subtract two of the same type of building layers to get
  116. // this value now).
  117. //
  118. // 06/16/97 JMI Now CSprite::InBlitOpaque is one of the flags set for the
  119. // background image when it is added to the CScene.
  120. //
  121. // 06/16/97 JMI Added SetPalette() which can be used to set the hood's
  122. // palette at the convenience of the Realm runner.
  123. //
  124. // 06/25/97 JMI Got rid of use of the obsolete CSprite::InXrayable and now
  125. // use CSprite::InAlpha in its place. Also, now the opaques
  126. // use the CSprite::InOpaque flag.
  127. //
  128. // 06/28/97 JMI Changed m_sWorldXRot to m_sRealmRotX & GetWorldRotX() and
  129. // GetRealmRotX(), and added m_sSceneRotX & GetSceneRotX().
  130. // Also, now loads and saves m_sRealmRotX.
  131. //
  132. // 06/29/97 MJR Modified to use new RSpry interface (replaced STL).
  133. //
  134. // 06/30/97 MJR Replaced SAFE_GUI_REF with new GuiItem.h-defined macro.
  135. //
  136. // 07/01/97 JMI Added m_sNumInits. Some things in Init() should only be
  137. // done once (like getting the resources, adding them to
  138. // the scene, and allocating the smashatorium).
  139. //
  140. // 07/01/97 JMI Added m_sScaleAttribHeights indicating whether to scale
  141. // height values gotten via the terrain map.
  142. //
  143. // 07/09/97 JMI Added setting for which side view assets to use.
  144. //
  145. // 07/09/97 JMI Moved m_s2dResPathIndex from CHood to CRealm b/c of order
  146. // issues when loading.
  147. //
  148. // 07/13/97 JMI Now only attempts to allocate the smashatorium if the
  149. // preceding stuff in Init() succeeded.
  150. //
  151. // 08/03/97 JRD Added ability to save 3d scale with hood
  152. //
  153. // 08/07/97 JMI Removed call to obsoleted CScene::UpdatePipeline()
  154. // (CRealm::SetupPipeline() now does it all).
  155. //
  156. // 08/10/97 JRD Added shadow parameters to the hood & dialogue
  157. //
  158. // 08/13/97 MJR Released toolbar resources.
  159. //
  160. // 08/13/97 JRD Began adding Randy's numbers to the toolbar...
  161. //
  162. // 08/18/97 MJR Changed sprintf() from %lg to %g for ANSI-correctness
  163. // (and so it would work on the ANSI-correct mac).
  164. //
  165. // 08/17/97 JMI Added handy macro for updating hood's settings to scene's
  166. // pipeline, SetupPipeline().
  167. // Also, some spots were checking if m_dScale3d was less than
  168. // or equal to 0 and setting it to 0.2 if it was. This
  169. // allowed the value to be 0.000000000001...0.1999999999999
  170. // which resulted in some wierd behavior including divide-by-
  171. // zeroes.
  172. //
  173. // 08/20/97 JMI Now can use a listbox in the EditModify() for 2D res
  174. // paths as well as the original multibtn.
  175. //
  176. // 11/25/97 JMI Now checks for Hood SAK on HD first and then on Hoods path.
  177. // Also, added Browse For Hood button and logic.
  178. //
  179. ////////////////////////////////////////////////////////////////////////////////
  180. #include "RSPiX.h"
  181. #include "hood.h"
  182. #include "game.h"
  183. #include "realm.h"
  184. #include <string.h>
  185. ////////////////////////////////////////////////////////////////////////////////
  186. // Macros/types/etc.
  187. ////////////////////////////////////////////////////////////////////////////////
  188. #define GUI_FILE_NAME "res/editor/EditHood.gui"
  189. // IDs from loaded GUI.
  190. #define GUI_ID_OK 1
  191. #define GUI_ID_CANCEL 2
  192. #define GUI_ID_BASENAME 3
  193. #define GUI_ID_REALMXROTATE 4
  194. #define GUI_ID_REALMYROTATE 5
  195. #define GUI_ID_REALMZROTATE 6
  196. #define GUI_ID_KILLSPERCENTGOAL 7
  197. #define GUI_ID_SCENEXROTATE 8
  198. #define GUI_ID_SCALEATTRIBHEIGHTS 9
  199. #define GUI_ID_2DRESPATHS 10
  200. #define GUI_ID_3DSCALE 16
  201. #define GUI_ID_SHADOW_ANGLE 888
  202. #define GUI_ID_SHADOW_LENGTH 889
  203. #define GUI_ID_SHADOW_INTENSITY 890
  204. #define GUI_ID_BROWSE 1000
  205. ////////////////////////////////////////////////////////////////////////////////
  206. // Variables/data
  207. ////////////////////////////////////////////////////////////////////////////////
  208. ////////////////////////////////////////////////////////////////////////////////
  209. // Function prototypes
  210. ////////////////////////////////////////////////////////////////////////////////
  211. ////////////////////////////////////////////////////////////////////////////////
  212. // Constructor
  213. // (protected).
  214. ////////////////////////////////////////////////////////////////////////////////
  215. CHood::CHood(CRealm* pRealm)
  216. : CThing(pRealm, CHoodID)
  217. {
  218. // Initialize ptrs to resources.
  219. m_pimBackground = NULL;
  220. m_pTerrainMap = NULL;
  221. m_pLayerMap = NULL;
  222. short i;
  223. for (i = 0; i < MaxLayers; i++)
  224. {
  225. m_apspryAlphas[i] = NULL;
  226. m_apspryOpaques[i] = NULL;
  227. }
  228. m_pimXRayMask = NULL;
  229. m_pmaTransparency = NULL;
  230. m_pltAmbient = NULL;
  231. m_pltSpot = NULL;
  232. m_pimEmptyBar = NULL;
  233. m_pimEmptyBarSelected= NULL;
  234. m_pimFullBar = NULL;
  235. m_pimFullBarSelected = NULL;
  236. m_pimTopBar = NULL;
  237. m_pimNum = NULL;
  238. m_pimNumLite = NULL;
  239. m_pimNumLow = NULL;
  240. m_pimNumGone = NULL;
  241. // Must flag resources as not yet existing
  242. m_bResourcesExist = false;
  243. // Initialize.
  244. strcpy(m_acBaseName, "");
  245. m_sSceneRotX = 30;
  246. m_sRealmRotX = 45;
  247. m_dScale3d = 1.0;
  248. m_sShadowAngle = 0;
  249. m_dShadowLength = 1.0;
  250. m_sShadowIntensity = 64;
  251. m_sScaleAttribHeights = TRUE;
  252. // Let realm have quick access to us.
  253. pRealm->m_phood = this;
  254. // We want a Startup() call.
  255. m_sCallStartup = 1;
  256. // No Init() calls yet.
  257. m_sNumInits = 0;
  258. }
  259. ////////////////////////////////////////////////////////////////////////////////
  260. // Destructor
  261. // (public).
  262. ////////////////////////////////////////////////////////////////////////////////
  263. CHood::~CHood()
  264. {
  265. Kill();
  266. // Clear Realm's ptr.
  267. m_pRealm->m_phood = NULL;
  268. }
  269. ////////////////////////////////////////////////////////////////////////////////
  270. // Load object (should call base class version!)
  271. ////////////////////////////////////////////////////////////////////////////////
  272. short CHood::Load( // Returns 0 if successfull, non-zero otherwise
  273. RFile* pFile, // In: File to load from
  274. bool bEditMode, // In: True for edit mode, false otherwise
  275. short sFileCount, // In: File count (unique per file, never 0)
  276. ULONG ulFileVersion) // In: Version of file format to load.
  277. {
  278. short sResult = 0;
  279. // In most cases, the base class Load() should be called.
  280. sResult = CThing::Load(pFile, bEditMode, sFileCount, ulFileVersion);
  281. if (sResult == 0)
  282. {
  283. // Load object data
  284. switch (ulFileVersion)
  285. {
  286. default:
  287. case 44:
  288. pFile->Read(&m_sScaleAttribHeights);
  289. pFile->Read(&m_sRealmRotX);
  290. pFile->Read(&(m_pRealm->m_dKillsPercentGoal) );
  291. pFile->Read(m_acBaseName);
  292. pFile->Read(&m_sSceneRotX);
  293. pFile->Read(&m_dScale3d);
  294. // Some extra safety (to avoid crashing)
  295. if (m_dScale3d < 0.2) m_dScale3d = 0.2;
  296. if (m_dScale3d > 5.0) m_dScale3d = 5.0;
  297. pFile->Read(&m_sShadowAngle);
  298. pFile->Read(&m_dShadowLength);
  299. pFile->Read(&m_sShadowIntensity);
  300. // Some extra safety (to avoid crashing)
  301. if (m_dShadowLength < 0.0) m_dShadowLength = 0.0;
  302. if (m_dShadowLength > 1.5) m_dShadowLength = 1.5;
  303. break;
  304. case 43:
  305. case 42:
  306. case 41:
  307. case 40:
  308. case 39:
  309. pFile->Read(&m_sScaleAttribHeights);
  310. pFile->Read(&m_sRealmRotX);
  311. pFile->Read(&(m_pRealm->m_dKillsPercentGoal) );
  312. pFile->Read(m_acBaseName);
  313. pFile->Read(&m_sSceneRotX);
  314. pFile->Read(&m_dScale3d);
  315. // Some extra safety
  316. if (m_dScale3d < 0.2) m_dScale3d = 0.2;
  317. if (m_dScale3d > 5.0) m_dScale3d = 5.0;
  318. break;
  319. case 38:
  320. case 37:
  321. case 36:
  322. case 35:
  323. case 34:
  324. case 33:
  325. case 32:
  326. case 31:
  327. case 30:
  328. pFile->Read(&m_sScaleAttribHeights);
  329. pFile->Read(&m_sRealmRotX);
  330. pFile->Read(&(m_pRealm->m_dKillsPercentGoal) );
  331. pFile->Read(m_acBaseName);
  332. pFile->Read(&m_sSceneRotX);
  333. break;
  334. case 29:
  335. case 28:
  336. short sDummy2dResPathIndex; // This is no longer stored here.
  337. pFile->Read(&sDummy2dResPathIndex);
  338. case 27:
  339. case 26:
  340. pFile->Read(&m_sScaleAttribHeights);
  341. case 25:
  342. case 24:
  343. case 23:
  344. pFile->Read(&m_sRealmRotX);
  345. case 22:
  346. case 21:
  347. case 20:
  348. case 19:
  349. case 18:
  350. case 17:
  351. case 16:
  352. case 15:
  353. pFile->Read(&(m_pRealm->m_dKillsPercentGoal) );
  354. case 14:
  355. case 13:
  356. case 12:
  357. case 11:
  358. case 10:
  359. case 9:
  360. case 8:
  361. case 7:
  362. case 6:
  363. case 5:
  364. case 4:
  365. case 3:
  366. case 2:
  367. case 1:
  368. pFile->Read(m_acBaseName);
  369. pFile->Read(&m_sSceneRotX);
  370. break;
  371. }
  372. // Make sure there were no file errors or format errors . . .
  373. if (!pFile->Error() && sResult == 0)
  374. {
  375. sResult = Init();
  376. }
  377. else
  378. {
  379. sResult = -1;
  380. TRACE("CHood::Load(): Error reading from file!\n");
  381. }
  382. }
  383. else
  384. {
  385. TRACE("CHood::Load(): CThing::Load() failed.\n");
  386. }
  387. return sResult;
  388. }
  389. ////////////////////////////////////////////////////////////////////////////////
  390. // Save object (should call base class version!)
  391. ////////////////////////////////////////////////////////////////////////////////
  392. short CHood::Save( // Returns 0 if successfull, non-zero otherwise
  393. RFile* pFile, // In: File to save to
  394. short sFileCount) // In: File count (unique per file, never 0)
  395. {
  396. short sResult = 0;
  397. // In most cases, the base class Save() should be called.
  398. sResult = CThing::Save(pFile, sFileCount);
  399. if (sResult == 0)
  400. {
  401. // Save object data
  402. pFile->Write(m_sScaleAttribHeights);
  403. pFile->Write(m_sRealmRotX);
  404. pFile->Write(m_pRealm->m_dKillsPercentGoal);
  405. pFile->Write(m_acBaseName);
  406. pFile->Write(m_sSceneRotX);
  407. pFile->Write(m_dScale3d);
  408. pFile->Write(m_sShadowAngle);
  409. pFile->Write(m_dShadowLength);
  410. pFile->Write(m_sShadowIntensity);
  411. sResult = pFile->Error();
  412. if (sResult == 0)
  413. {
  414. }
  415. else
  416. {
  417. TRACE("CHood::Save(): Error writing to file.\n");
  418. }
  419. }
  420. else
  421. {
  422. TRACE("CHood::Save(): CThing::Save() failed.\n");
  423. }
  424. return sResult;
  425. }
  426. ////////////////////////////////////////////////////////////////////////////////
  427. // Startup object
  428. ////////////////////////////////////////////////////////////////////////////////
  429. short CHood::Startup(void) // Returns 0 if successfull, non-zero otherwise
  430. {
  431. return 0;
  432. }
  433. ////////////////////////////////////////////////////////////////////////////////
  434. // Shutdown object
  435. ////////////////////////////////////////////////////////////////////////////////
  436. short CHood::Shutdown(void) // Returns 0 if successfull, non-zero otherwise
  437. {
  438. return 0;
  439. }
  440. ////////////////////////////////////////////////////////////////////////////////
  441. // Suspend object
  442. ////////////////////////////////////////////////////////////////////////////////
  443. void CHood::Suspend(void)
  444. {
  445. }
  446. ////////////////////////////////////////////////////////////////////////////////
  447. // Resume object
  448. ////////////////////////////////////////////////////////////////////////////////
  449. void CHood::Resume(void)
  450. {
  451. }
  452. ////////////////////////////////////////////////////////////////////////////////
  453. // Update object
  454. ////////////////////////////////////////////////////////////////////////////////
  455. void CHood::Update(void)
  456. {
  457. }
  458. ////////////////////////////////////////////////////////////////////////////////
  459. // Render object
  460. ////////////////////////////////////////////////////////////////////////////////
  461. void CHood::Render(void)
  462. {
  463. }
  464. ////////////////////////////////////////////////////////////////////////////////
  465. // User callback on btn released within button.
  466. ////////////////////////////////////////////////////////////////////////////////
  467. static void BrowseBtnUp( // Returns nothing. Called on button released in
  468. // m_hot when active.
  469. RGuiItem* pgui) // this.
  470. {
  471. RGuiItem* pguiBaseName = (RGuiItem*)(pgui->m_ulUserInstance);
  472. if (pguiBaseName)
  473. {
  474. // Create full system path from existing RSPiX subpath.
  475. char szSystemPath[RSP_MAX_PATH];
  476. if (pguiBaseName->m_szText[0] == '\0')
  477. {
  478. pguiBaseName->SetText(".");
  479. }
  480. strcpy(szSystemPath, FullPathHoods("res/hoods/") );
  481. strcat(szSystemPath, pguiBaseName->m_szText);
  482. short sResult;
  483. do {
  484. sResult = SubPathOpenBox( // Returns 0 on success, negative on error, 1 if
  485. // not subpathable (i.e., returned path is full path).
  486. FullPathHoods("res/hoods"), // In: Full path to be relative to (system format).
  487. "Browse for Hood", // In: Title of box.
  488. szSystemPath, // In: Default filename (system format).
  489. szSystemPath, // Out: User's choice (system format).
  490. sizeof(szSystemPath), // In: Amount of memory pointed to by pszChosenFileName.
  491. "sak"); // In: If not NULL, '.' delimited extension based filename
  492. // filter specification. Ex: ".cpp.h.exe.lib" or "cpp.h.exe.lib"
  493. // Note: Cannot use '.' in filter. Preceding '.' ignored.
  494. if (sResult > 0)
  495. {
  496. rspMsgBox(
  497. RSP_MB_ICN_STOP | RSP_MB_BUT_OK,
  498. g_pszAppName,
  499. g_pszGenericMustBeRelativePath_s,
  500. FullPathHoods("res/hoods"));
  501. }
  502. } while (sResult > 0);
  503. // If successful in getting a relative path . . .
  504. if (sResult == 0)
  505. {
  506. // Copy back from system format to RSPiX -- we're actually only looking for one word
  507. // anyway (not a path).
  508. strcpy(szSystemPath, rspPathFromSystem(szSystemPath) );
  509. // Get rid of extension.
  510. short sIndex;
  511. for (sIndex = 0; szSystemPath[sIndex]; sIndex++)
  512. {
  513. // If this is a dot representing the beginning of an extension . . .
  514. if (szSystemPath[sIndex] == '.' && szSystemPath[sIndex + 1] != '.' && szSystemPath[sIndex + 1] != '/')
  515. {
  516. szSystemPath[sIndex] = '\0';
  517. break;
  518. }
  519. }
  520. // Udpate GUI.
  521. pguiBaseName->SetText("%s", szSystemPath );
  522. pguiBaseName->Compose();
  523. }
  524. }
  525. }
  526. ////////////////////////////////////////////////////////////////////////////////
  527. // Called by editor to init new object at specified position
  528. ////////////////////////////////////////////////////////////////////////////////
  529. short CHood::EditNew( // Returns 0 if successfull, non-zero otherwise
  530. short sX, // In: New x coord
  531. short sY, // In: New y coord
  532. short sZ) // In: New z coord
  533. {
  534. short sResult = 0;
  535. char szScale3d[256];
  536. char szShadowLength[256];
  537. // double values must be handled indirectly through strings
  538. sprintf(szScale3d,"%g",m_dScale3d);
  539. sprintf(szShadowLength,"%g",m_dShadowLength);
  540. // Load the GUI for editting.
  541. RGuiItem* pguiEdit = RGuiItem::LoadInstantiate(FullPath(GAME_PATH_HD, GUI_FILE_NAME) );
  542. if (pguiEdit != NULL)
  543. {
  544. // Get ptr to edit field . . .
  545. RGuiItem* pguiBaseName = pguiEdit->GetItemFromId(GUI_ID_BASENAME);
  546. RGuiItem* pguiSceneRotX = pguiEdit->GetItemFromId(GUI_ID_SCENEXROTATE);
  547. RGuiItem* pguiRealmRotX = pguiEdit->GetItemFromId(GUI_ID_REALMXROTATE);
  548. RGuiItem* pguiScale3d = pguiEdit->GetItemFromId(GUI_ID_3DSCALE);
  549. RGuiItem* pguiShadowAngle = pguiEdit->GetItemFromId(GUI_ID_SHADOW_ANGLE);
  550. RGuiItem* pguiShadowLength = pguiEdit->GetItemFromId(GUI_ID_SHADOW_LENGTH);
  551. RGuiItem* pguiShadowIntensity = pguiEdit->GetItemFromId(GUI_ID_SHADOW_INTENSITY);
  552. RGuiItem* pguiKillsPercentGoal = pguiEdit->GetItemFromId(GUI_ID_KILLSPERCENTGOAL);
  553. RGuiItem* pguiScaleHeights = pguiEdit->GetItemFromId(GUI_ID_SCALEATTRIBHEIGHTS);
  554. RGuiItem* pgui2dResPaths = pguiEdit->GetItemFromId(GUI_ID_2DRESPATHS);
  555. RGuiItem* pguiBrowse = pguiEdit->GetItemFromId(GUI_ID_BROWSE);
  556. if (pguiBaseName != NULL)
  557. {
  558. // Set text to start with current base name.
  559. pguiBaseName->SetText("%s", m_acBaseName);
  560. // Position caret at end of line.
  561. ((REdit*)pguiBaseName)->m_sCaretPos = strlen(pguiBaseName->m_szText);
  562. // Recompose with new text.
  563. pguiBaseName->Compose();
  564. RSP_SAFE_GUI_REF_VOID(pguiSceneRotX, SetText("%d", m_sSceneRotX) );
  565. RSP_SAFE_GUI_REF((REdit*)pguiSceneRotX, m_sCaretPos = strlen(pguiSceneRotX->m_szText) );
  566. RSP_SAFE_GUI_REF_VOID(pguiSceneRotX, Compose() );
  567. RSP_SAFE_GUI_REF_VOID(pguiRealmRotX, SetText("%d", m_sRealmRotX) );
  568. RSP_SAFE_GUI_REF((REdit*)pguiRealmRotX, m_sCaretPos = strlen(pguiRealmRotX->m_szText) );
  569. RSP_SAFE_GUI_REF_VOID(pguiRealmRotX, Compose() );
  570. RSP_SAFE_GUI_REF_VOID(pguiScale3d, SetText("%s", szScale3d) );
  571. RSP_SAFE_GUI_REF((REdit*)pguiScale3d, m_sCaretPos = strlen(pguiScale3d->m_szText) );
  572. RSP_SAFE_GUI_REF_VOID(pguiScale3d, Compose() );
  573. RSP_SAFE_GUI_REF_VOID(pguiShadowAngle, SetText("%d", m_sShadowAngle) );
  574. RSP_SAFE_GUI_REF((REdit*)pguiShadowAngle, m_sCaretPos = strlen(pguiShadowAngle->m_szText) );
  575. RSP_SAFE_GUI_REF_VOID(pguiShadowAngle, Compose() );
  576. RSP_SAFE_GUI_REF_VOID(pguiShadowLength, SetText("%s", szShadowLength) );
  577. RSP_SAFE_GUI_REF((REdit*)pguiShadowLength, m_sCaretPos = strlen(pguiShadowLength->m_szText) );
  578. RSP_SAFE_GUI_REF_VOID(pguiShadowLength, Compose() );
  579. RSP_SAFE_GUI_REF_VOID(pguiShadowIntensity, SetText("%d", m_sShadowIntensity) );
  580. RSP_SAFE_GUI_REF((REdit*)pguiShadowIntensity, m_sCaretPos = strlen(pguiShadowIntensity->m_szText) );
  581. RSP_SAFE_GUI_REF_VOID(pguiShadowIntensity, Compose() );
  582. RSP_SAFE_GUI_REF_VOID(pguiKillsPercentGoal, SetText("%g", m_pRealm->m_dKillsPercentGoal) );
  583. RSP_SAFE_GUI_REF_VOID(pguiKillsPercentGoal, Compose() );
  584. ASSERT(pguiScaleHeights->m_type == RGuiItem::MultiBtn);
  585. RSP_SAFE_GUI_REF((RMultiBtn*)pguiScaleHeights, m_sState = (m_sScaleAttribHeights == FALSE) ? 1 : 2);
  586. RSP_SAFE_GUI_REF_VOID(pguiScaleHeights, Compose() );
  587. RSP_SAFE_GUI_REF(pguiBrowse, m_bcUser = BrowseBtnUp);
  588. RSP_SAFE_GUI_REF(pguiBrowse, m_ulUserInstance = (ULONG)pguiBaseName);
  589. switch (pgui2dResPaths->m_type)
  590. {
  591. case RGuiItem::MultiBtn:
  592. RSP_SAFE_GUI_REF( (RMultiBtn*)pgui2dResPaths, m_sState = m_pRealm->m_s2dResPathIndex + 1);
  593. RSP_SAFE_GUI_REF_VOID(pgui2dResPaths, Compose() );
  594. break;
  595. case RGuiItem::ListBox:
  596. {
  597. RListBox* plb = (RListBox*)pgui2dResPaths;
  598. short sIndex;
  599. for (sIndex = 0; sIndex < CRealm::Num2dPaths; sIndex++)
  600. {
  601. RGuiItem* pgui = plb->AddString(CRealm::ms_apsz2dResPaths[sIndex]);
  602. if (pgui)
  603. {
  604. // Set ID to identify proper index.
  605. pgui->m_ulUserData = sIndex;
  606. // If this is the current one . . .
  607. if (sIndex == m_pRealm->m_s2dResPathIndex)
  608. {
  609. // Select it.
  610. plb->SetSel(pgui);
  611. }
  612. }
  613. }
  614. // Repaginate now.
  615. plb->AdjustContents();
  616. break;
  617. }
  618. default:
  619. TRACE("EditNew(): GUI %d missing!!\n", GUI_ID_2DRESPATHS);
  620. break;
  621. }
  622. if (DoGui(pguiEdit) == GUI_ID_OK)
  623. {
  624. pguiBaseName->GetText(m_acBaseName, sizeof(m_acBaseName) );
  625. m_sSceneRotX = RSP_SAFE_GUI_REF(pguiSceneRotX, GetVal() );
  626. m_sRealmRotX = RSP_SAFE_GUI_REF(pguiRealmRotX, GetVal() );
  627. m_sShadowAngle = RSP_SAFE_GUI_REF(pguiShadowAngle, GetVal() );
  628. m_sShadowIntensity = RSP_SAFE_GUI_REF(pguiShadowIntensity, GetVal() );
  629. pguiScale3d->GetText(szScale3d, sizeof(szScale3d));
  630. m_dScale3d = atof(szScale3d);
  631. if (m_dScale3d < 0.2) m_dScale3d = 0.2; // some safety
  632. if (m_dScale3d > 5.0) m_dScale3d = 5.0; // some safety
  633. pguiShadowLength->GetText(szShadowLength, sizeof(szShadowLength));
  634. m_dShadowLength = atof(szShadowLength);
  635. if (m_dShadowLength < 0.0) m_dShadowLength = 0.2; // some safety
  636. if (m_dShadowLength > 1.5) m_dShadowLength = 1.5; // some safety
  637. if (RSP_SAFE_GUI_REF((RMultiBtn*)pguiScaleHeights, m_sState) == 1)
  638. {
  639. m_sScaleAttribHeights = FALSE;
  640. }
  641. else
  642. {
  643. m_sScaleAttribHeights = TRUE;
  644. }
  645. switch (pgui2dResPaths->m_type)
  646. {
  647. case RGuiItem::MultiBtn:
  648. m_pRealm->m_s2dResPathIndex = RSP_SAFE_GUI_REF((RMultiBtn*)pgui2dResPaths, m_sState) - 1;
  649. break;
  650. case RGuiItem::ListBox:
  651. {
  652. RGuiItem* pguiSel = ( (RListBox*)pgui2dResPaths)->GetSel();
  653. if (pguiSel)
  654. {
  655. m_pRealm->m_s2dResPathIndex = pguiSel->m_ulUserData;
  656. }
  657. break;
  658. }
  659. }
  660. if (pguiKillsPercentGoal != NULL)
  661. {
  662. m_pRealm->m_dKillsPercentGoal = strtod(pguiKillsPercentGoal->m_szText, NULL);
  663. }
  664. // Init the hood
  665. sResult = Init();
  666. if (sResult == 0)
  667. {
  668. // Start it.
  669. Startup();
  670. }
  671. }
  672. else
  673. {
  674. // User abort.
  675. sResult = 1;
  676. }
  677. }
  678. else
  679. {
  680. TRACE("EditNew(): No GUI with ID %ld.\n", GUI_ID_BASENAME);
  681. sResult = -2;
  682. }
  683. // Delete GUI.
  684. delete pguiEdit;
  685. }
  686. else
  687. {
  688. TRACE("EditNew(): Failed to load GUI \"%s\".\n", GUI_FILE_NAME);
  689. sResult = -1;
  690. }
  691. return sResult;
  692. }
  693. ////////////////////////////////////////////////////////////////////////////////
  694. // Called by editor to modify object
  695. ////////////////////////////////////////////////////////////////////////////////
  696. short CHood::EditModify(void)
  697. {
  698. return EditNew(0, 0, 0);
  699. }
  700. ////////////////////////////////////////////////////////////////////////////////
  701. // Called by editor to move object to specified position
  702. ////////////////////////////////////////////////////////////////////////////////
  703. short CHood::EditMove( // Returns 0 if successfull, non-zero otherwise
  704. short /*sX*/, // In: New x coord
  705. short /*sY*/, // In: New y coord
  706. short /*sZ*/) // In: New z coord
  707. {
  708. return 0;
  709. }
  710. ////////////////////////////////////////////////////////////////////////////////
  711. // Called by editor to update object
  712. ////////////////////////////////////////////////////////////////////////////////
  713. void CHood::EditUpdate(void)
  714. {
  715. }
  716. ////////////////////////////////////////////////////////////////////////////////
  717. // Called by editor to render object
  718. ////////////////////////////////////////////////////////////////////////////////
  719. void CHood::EditRender(void)
  720. {
  721. }
  722. ////////////////////////////////////////////////////////////////////////////////
  723. // Init the hood
  724. ////////////////////////////////////////////////////////////////////////////////
  725. short CHood::Init(void) // Returns 0 if successfull, non-zero otherwise
  726. {
  727. short sResult = 0;
  728. // If first call . . .
  729. if (m_sNumInits++ == 0)
  730. {
  731. // Get resources
  732. sResult = GetResources();
  733. if (sResult == 0)
  734. {
  735. // Set the realm's pointer to point at our attribute map. This is a
  736. // shortcut to make it easier and faster for objects to access the map.
  737. m_pRealm->m_pTerrainMap = m_pTerrainMap;
  738. m_pRealm->m_pLayerMap = m_pLayerMap;
  739. // Background is only thing on rear-most layer
  740. CSprite2* pSprite2 = new CSprite2;
  741. pSprite2->m_sX2 = 0;
  742. pSprite2->m_sY2 = 0;
  743. pSprite2->m_sPriority = 0;
  744. pSprite2->m_pImage = m_pimBackground;
  745. pSprite2->m_sLayer = CRealm::LayerBg;
  746. pSprite2->m_sInFlags = CSprite::InDeleteOnClear | CSprite::InBlitOpaque;
  747. m_pRealm->m_scene.UpdateSprite(pSprite2);
  748. // Attempt to load all layers . . .
  749. long lIndex;
  750. // Put the contents of the various spry's onto the other layers
  751. for (lIndex = 0; lIndex < MaxLayers; lIndex++)
  752. {
  753. // If this layer exists . . .
  754. if (m_apspryAlphas[lIndex] != NULL)
  755. {
  756. RSpry::ListOfSprites::Pointer p = m_apspryAlphas[lIndex]->m_listSprites.GetHead();
  757. while (p)
  758. {
  759. RSprite* pSprite = m_apspryAlphas[lIndex]->m_listSprites.GetData(p);
  760. CSprite2* pSprite2 = new CSprite2;
  761. pSprite2->m_sX2 = pSprite->m_sX;
  762. pSprite2->m_sY2 = pSprite->m_sY;
  763. pSprite2->m_sPriority = pSprite->m_sZ;
  764. pSprite2->m_pImage = pSprite->m_pImage;
  765. pSprite2->m_sLayer = CRealm::LayerAlpha1 + (short)lIndex * (CRealm::LayerAlpha2 - CRealm::LayerAlpha1);
  766. pSprite2->m_sInFlags = CSprite::InDeleteOnClear | CSprite::InAlpha;
  767. m_pRealm->m_scene.UpdateSprite(pSprite2);
  768. p = m_apspryAlphas[lIndex]->m_listSprites.GetNext(p);
  769. }
  770. }
  771. // If this layer exists . . .
  772. if (m_apspryOpaques[lIndex] != NULL)
  773. {
  774. RSpry::ListOfSprites::Pointer p = m_apspryOpaques[lIndex]->m_listSprites.GetHead();
  775. while (p)
  776. {
  777. RSprite* pSprite = m_apspryOpaques[lIndex]->m_listSprites.GetData(p);
  778. CSprite2* pSprite2 = new CSprite2;
  779. pSprite2->m_sX2 = pSprite->m_sX;
  780. pSprite2->m_sY2 = pSprite->m_sY;
  781. pSprite2->m_sPriority = pSprite->m_sZ;
  782. pSprite2->m_pImage = pSprite->m_pImage;
  783. pSprite2->m_sLayer = CRealm::LayerOpaque1 + (short)lIndex * (CRealm::LayerOpaque2 - CRealm::LayerOpaque1);
  784. pSprite2->m_sInFlags = CSprite::InDeleteOnClear | CSprite::InOpaque;
  785. m_pRealm->m_scene.UpdateSprite(pSprite2);
  786. p = m_apspryOpaques[lIndex]->m_listSprites.GetNext(p);
  787. }
  788. }
  789. }
  790. }
  791. // Allocate the Smashatorium:
  792. #ifdef NEW_SMASH
  793. // This requires success in the previous ops . . .
  794. if (sResult == 0)
  795. {
  796. // Jon has PROMISED me that there is an m_pRealm which is ACCURATE.
  797. #define MAX_SMASHEE_W 72 // 40 once we deal with fat objects
  798. #define MAX_SMASHEE_H 72 // 40 once we deal with fat objects
  799. // Allocate the Smashatorium: Pick tile size greater than any normal object radius...
  800. m_pRealm->m_smashatorium.Destroy();
  801. m_pRealm->m_smashatorium.Alloc(m_pRealm->GetRealmWidth(),m_pRealm->GetRealmHeight(),
  802. short(MAX_SMASHEE_W * m_dScale3d), // I'm assuming this scales with size
  803. short(MAX_SMASHEE_H * m_dScale3d) );
  804. }
  805. #endif
  806. }
  807. // If successful so far . . .
  808. if (sResult == 0)
  809. {
  810. SetupPipeline();
  811. }
  812. return sResult;
  813. }
  814. ////////////////////////////////////////////////////////////////////////////////
  815. // Setup pipeline to hood's specifications.
  816. ////////////////////////////////////////////////////////////////////////////////
  817. void CHood::SetupPipeline(void) // Returns nothing.
  818. {
  819. // Some extra safety (to avoid crashing)
  820. if (m_dScale3d < 0.2) m_dScale3d = 0.2;
  821. if (m_dScale3d > 5.0) m_dScale3d = 5.0;
  822. // Set up world transformation matrix with CHood's little tweak on view
  823. // angle:
  824. // Create scene transform with our tweak.
  825. RTransform transScene; // Identity.
  826. transScene.Rx(m_sSceneRotX);
  827. // Create transform to convert from scene to realm.
  828. RTransform transScene2Realm; // Identity.
  829. transScene2Realm.Rx(m_sRealmRotX - m_sSceneRotX);
  830. // Re-setup with tweakage and scaling.
  831. m_pRealm->m_scene.SetupPipeline(&transScene, &transScene2Realm, m_dScale3d);
  832. }
  833. ////////////////////////////////////////////////////////////////////////////////
  834. // Kill the hood
  835. ////////////////////////////////////////////////////////////////////////////////
  836. short CHood::Kill(void) // Returns 0 if successfull, non-zero otherwise
  837. {
  838. short sResult = 0;
  839. // Free resources
  840. sResult = FreeResources();
  841. return sResult;
  842. }
  843. ////////////////////////////////////////////////////////////////////////////////
  844. // Helper to load and convert SPRYs.
  845. ////////////////////////////////////////////////////////////////////////////////
  846. inline
  847. short SpryLoadConv( // Returns 0 on success.
  848. RResMgr* presmgr, // In: ResMgr to load from.
  849. RSpry** ppspry, // Out: Ptr to SPRY resource.
  850. char* pszFileName, // In: File/Res name of .SAY file.
  851. RImage::Type type) // In: Destination type.
  852. {
  853. short sRes = 0; // Assume success.
  854. if (rspGetResource(
  855. presmgr,
  856. pszFileName,
  857. ppspry) == 0)
  858. {
  859. // If conversion specified . . .
  860. if (type != RImage::NOT_SUPPORTED)
  861. {
  862. // Convert . . .
  863. if ((*ppspry)->Convert(type) == 0)
  864. {
  865. // Success.
  866. }
  867. else
  868. {
  869. TRACE("SpryLoadConv(): (*ppspry)->Convert(type) failed.\n");
  870. sRes = -3;
  871. }
  872. }
  873. }
  874. else
  875. {
  876. // TRACE("SpryLoadConv(): Failed to load SPRY \"%s\".\n", pszFileName);
  877. sRes = -1;
  878. }
  879. return sRes;
  880. }
  881. extern int wideScreenWidth;
  882. ////////////////////////////////////////////////////////////////////////////////
  883. // Get all required resources
  884. ////////////////////////////////////////////////////////////////////////////////
  885. short CHood::GetResources(void) // Returns 0 if successfull, non-zero otherwise
  886. {
  887. short sResult = 0;
  888. // If all resources were already successfully loaded, then don't do this again.
  889. // Note that if only some of them loaded and then an error occurred, we'll
  890. // end up reloading all of them, even those that loaded okay.
  891. if (!m_bResourcesExist)
  892. {
  893. // Free any resources that might have been loaded by a previous (unsuccessfull) attempt
  894. FreeResources();
  895. char szFileName[RSP_MAX_PATH]; // Temp storage to create filenames.
  896. char szBasePath[RSP_MAX_PATH]; // Temp storage of file path.
  897. // Create the real base file path.
  898. sprintf(szBasePath, "hoods/%s/%s", m_acBaseName, m_acBaseName);
  899. // Add .ext for SAKs.
  900. sprintf(szFileName, "res/hoods/%s.sak", m_acBaseName);
  901. // Open SAK, if available . . .
  902. if (m_pRealm->m_resmgr.OpenSak(FullPathHD(szFileName)) == 0)
  903. {
  904. // Using SAK from HD.
  905. }
  906. else
  907. {
  908. if (m_pRealm->m_resmgr.OpenSak(FullPathHoods(szFileName)) == 0)
  909. {
  910. // Using SAK from hoods path.
  911. }
  912. else
  913. {
  914. // Using Disk, set path.
  915. m_pRealm->m_resmgr.SetBasePath(g_GameSettings.m_szNoSakDir);
  916. }
  917. }
  918. // Background filename.
  919. sprintf(szFileName, "%s.bmp", szBasePath);
  920. // Load background
  921. if (rspGetResource(
  922. &(m_pRealm->m_resmgr),
  923. szFileName,
  924. &m_pimBackground) != 0)
  925. {
  926. sResult = -1;
  927. TRACE("CHood::GetResources(): Couldn't load background: %s\n", szFileName);
  928. goto Error;
  929. }
  930. // Attempt to load all layers . . .
  931. long lIndex;
  932. short sNumAlphaLayersLoaded = 0;
  933. short sNumOpaqueLayersLoaded = 0;
  934. for (lIndex = 0; lIndex < MaxLayers; lIndex++)
  935. {
  936. // Make alpha layer name.
  937. sprintf(szFileName, "%s%02da.say", szBasePath, lIndex);
  938. // Load & convert . . .
  939. if (SpryLoadConv(&(m_pRealm->m_resmgr), m_apspryAlphas + lIndex, szFileName, RImage::FSPR8) == 0)
  940. {
  941. sNumAlphaLayersLoaded++;
  942. }
  943. // Make opaque layer name.
  944. sprintf(szFileName, "%s%02do.say", szBasePath, lIndex);
  945. // Load & convert . . .
  946. if (SpryLoadConv(&(m_pRealm->m_resmgr), m_apspryOpaques + lIndex, szFileName, RImage::FSPR8) == 0)
  947. {
  948. sNumOpaqueLayersLoaded++;
  949. }
  950. }
  951. // If no layers loaded . . .
  952. if (sNumOpaqueLayersLoaded == 0 && sNumAlphaLayersLoaded == 0)
  953. {
  954. TRACE("GetResources(): No alpha or opaque layers successfully loaded.\n");
  955. }
  956. else
  957. {
  958. TRACE("GetResources(): Successfully loaded %hd Alpha layer%s and %hd Opaque layer%s.\n",
  959. sNumAlphaLayersLoaded, (sNumAlphaLayersLoaded == 1 ? "" : "s"),
  960. sNumOpaqueLayersLoaded, (sNumOpaqueLayersLoaded == 1 ? "" : "s"));
  961. }
  962. sprintf(szFileName, "%s.mp1", szBasePath);
  963. // Load new multi layer attribute maps
  964. if (rspGetResource(
  965. &(m_pRealm->m_resmgr),
  966. szFileName,
  967. &m_pTerrainMap) != 0)
  968. {
  969. sResult = -1;
  970. TRACE("CHood::GetResources(): Couldn't load attribute map %s\n", szFileName);
  971. goto Error;
  972. }
  973. sprintf(szFileName, "%s.mp2", szBasePath);
  974. if (rspGetResource(
  975. &(m_pRealm->m_resmgr),
  976. szFileName,
  977. &m_pLayerMap) != 0)
  978. {
  979. sResult = -1;
  980. TRACE("CHood::GetResources(): Couldn't load attribute map %s\n", szFileName);
  981. goto Error;
  982. }
  983. // Make XRay mask name.
  984. sprintf(szFileName, "%s.XRayMask.bmp", szBasePath);
  985. if (rspGetResource(
  986. &(m_pRealm->m_resmgr),
  987. szFileName,
  988. &m_pimXRayMask) != 0)
  989. {
  990. sResult = -1;
  991. TRACE("GetResources(): Failed to load: %s.\n", szFileName);
  992. }
  993. sprintf(szFileName, "%s.Transparency.MultiAlpha", szBasePath);
  994. if (rspGetResource(
  995. &(m_pRealm->m_resmgr),
  996. szFileName,
  997. &m_pmaTransparency) != 0)
  998. {
  999. sResult = -1;
  1000. TRACE("GetResources(): Failed to load: %s.\n", szFileName);
  1001. }
  1002. sprintf(szFileName, "%s.Ambient.alpha", szBasePath);
  1003. if (rspGetResource(
  1004. &(m_pRealm->m_resmgr),
  1005. szFileName,
  1006. &m_pltAmbient) != 0)
  1007. {
  1008. sResult = -1;
  1009. TRACE("GetResources(): Failed to load: %s.\n", szFileName);
  1010. }
  1011. sprintf(szFileName, "%s.Spot.alpha", szBasePath);
  1012. if (rspGetResource(
  1013. &(m_pRealm->m_resmgr),
  1014. szFileName,
  1015. &m_pltSpot) != 0)
  1016. {
  1017. sResult = -1;
  1018. TRACE("GetResources(): Failed to load: %s.\n", szFileName);
  1019. }
  1020. // Load all the assets for the toolbar
  1021. sprintf(szFileName, "%s.emptybar.bmp", szBasePath);
  1022. if (rspGetResource(
  1023. &(m_pRealm->m_resmgr),
  1024. szFileName,
  1025. &m_pimEmptyBar) != 0)
  1026. {
  1027. sResult = -1;
  1028. TRACE("GetResources(): Failed to load: %s.\n", szFileName);
  1029. }
  1030. sprintf(szFileName, "%s.emptybarselected.bmp", szBasePath);
  1031. if (rspGetResource(
  1032. &(m_pRealm->m_resmgr),
  1033. szFileName,
  1034. &m_pimEmptyBarSelected) != 0)
  1035. {
  1036. sResult = -1;
  1037. TRACE("GetResources(): Failed to load: %s.\n", szFileName);
  1038. }
  1039. sprintf(szFileName, "%s.fullbar.bmp", szBasePath);
  1040. if (rspGetResource(
  1041. &(m_pRealm->m_resmgr),
  1042. szFileName,
  1043. &m_pimFullBar) != 0)
  1044. {
  1045. sResult = -1;
  1046. TRACE("GetResources(): Failed to load: %s.\n", szFileName);
  1047. }
  1048. sprintf(szFileName, "%s.fullbarselected.bmp", szBasePath);
  1049. if (rspGetResource(
  1050. &(m_pRealm->m_resmgr),
  1051. szFileName,
  1052. &m_pimFullBarSelected) != 0)
  1053. {
  1054. sResult = -1;
  1055. TRACE("GetResources(): Failed to load: %s.\n", szFileName);
  1056. }
  1057. sprintf(szFileName, "%s.topbar.bmp", szBasePath);
  1058. if (rspGetResource(
  1059. &(m_pRealm->m_resmgr),
  1060. szFileName,
  1061. &m_pimTopBar) != 0)
  1062. {
  1063. sResult = -1;
  1064. TRACE("GetResources(): Failed to load: %s.\n", szFileName);
  1065. }
  1066. RImage * stretched = new RImage();
  1067. stretched->CreateImage(wideScreenWidth,m_pimTopBar->GetHeight(),m_pimTopBar->GetType(),0);
  1068. //Here we create a new streched image for widescreen
  1069. float widthScale = (float)m_pimTopBar->m_sWidth / (float)stretched->m_sWidth;
  1070. for (int n=0;n<m_pimTopBar->m_sHeight;n++)
  1071. {
  1072. for (int x=0;x<stretched->m_sWidth;x++)
  1073. {
  1074. UCHAR* dest = stretched->m_pData + n * stretched->m_lPitch + x;
  1075. UCHAR* src = m_pimTopBar->m_pData + n * m_pimTopBar->m_lPitch + (int)((float)x * widthScale);
  1076. *dest = *src;
  1077. }
  1078. //memcpy(ms_pimCompositeBufferScaled->m_pData + n * ms_pimCompositeBufferScaled->m_lPitch,
  1079. // ms_pimCompositeBuffer->m_pData + n * ms_pimCompositeBuffer->m_lPitch,ms_pimCompositeBuffer->m_sWidth);
  1080. }
  1081. //TODO free m_pimTopBar
  1082. m_pimTopBar = stretched;
  1083. // Resources now exist
  1084. m_bResourcesExist = true;
  1085. }
  1086. Error:
  1087. // Close SAK, if open.
  1088. m_pRealm->m_resmgr.CloseSak();
  1089. return sResult;
  1090. }
  1091. ////////////////////////////////////////////////////////////////////////////////
  1092. // Free all resources
  1093. ////////////////////////////////////////////////////////////////////////////////
  1094. short CHood::FreeResources(void) // Returns 0 if successfull, non-zero otherwise
  1095. {
  1096. short sResult = 0;
  1097. // Don't check whether resources exist! Even if they were only partially
  1098. // loaded (due to an error during the load process) we still want to clear
  1099. // those resources that were loaded. The stuff being done here is safe
  1100. // regardless of whether or not the resource was actually loaded.
  1101. if (m_pimBackground != NULL)
  1102. rspReleaseResource(&(m_pRealm->m_resmgr), &m_pimBackground);
  1103. long lIndex;
  1104. for (lIndex = 0; lIndex < MaxLayers; lIndex++)
  1105. {
  1106. if (m_apspryAlphas[lIndex] != NULL)
  1107. rspReleaseResource(&(m_pRealm->m_resmgr), &(m_apspryAlphas[lIndex]));
  1108. if (m_apspryOpaques[lIndex] != NULL)
  1109. rspReleaseResource(&(m_pRealm->m_resmgr), &(m_apspryOpaques[lIndex]));
  1110. }
  1111. if (m_pTerrainMap != NULL)
  1112. {
  1113. rspReleaseResource(&(m_pRealm->m_resmgr), &m_pTerrainMap);
  1114. // Clear Realm's map ptr
  1115. m_pRealm->m_pTerrainMap = NULL;
  1116. }
  1117. if (m_pLayerMap != NULL)
  1118. {
  1119. rspReleaseResource(&(m_pRealm->m_resmgr), &m_pLayerMap);
  1120. // Clear Realm's map ptr
  1121. m_pRealm->m_pLayerMap = NULL;
  1122. }
  1123. if (m_pimXRayMask != NULL)
  1124. rspReleaseResource(&(m_pRealm->m_resmgr), &m_pimXRayMask);
  1125. if (m_pmaTransparency != NULL)
  1126. rspReleaseResource(&(m_pRealm->m_resmgr), &m_pmaTransparency);
  1127. if (m_pltAmbient != NULL)
  1128. rspReleaseResource(&(m_pRealm->m_resmgr), &m_pltAmbient);
  1129. if (m_pltSpot != NULL)
  1130. rspReleaseResource(&(m_pRealm->m_resmgr), &m_pltSpot);
  1131. if (m_pimEmptyBar)
  1132. rspReleaseResource(&(m_pRealm->m_resmgr), &m_pimEmptyBar);
  1133. if (m_pimEmptyBarSelected)
  1134. rspReleaseResource(&(m_pRealm->m_resmgr), &m_pimEmptyBarSelected);
  1135. if (m_pimFullBar)
  1136. rspReleaseResource(&(m_pRealm->m_resmgr), &m_pimFullBar);
  1137. if (m_pimFullBarSelected)
  1138. rspReleaseResource(&(m_pRealm->m_resmgr), &m_pimFullBarSelected);
  1139. if (m_pimTopBar)
  1140. rspReleaseResource(&(m_pRealm->m_resmgr), &m_pimTopBar);
  1141. // Resources no longer exist for sure.
  1142. m_bResourcesExist = false;
  1143. // Let's get these out of memory right away.
  1144. m_pRealm->m_resmgr.Purge();
  1145. return sResult;
  1146. }
  1147. ////////////////////////////////////////////////////////////////////////////////
  1148. // Set the hood's palette.
  1149. ////////////////////////////////////////////////////////////////////////////////
  1150. void CHood::SetPalette(void) // Returns nothing.
  1151. {
  1152. ASSERT(m_pimBackground->m_pPalette != NULL);
  1153. ASSERT(m_pimBackground->m_pPalette->m_type == RPal::PDIB);
  1154. rspSetPaletteEntries(
  1155. 0, //10,
  1156. 256, // 236,
  1157. m_pimBackground->m_pPalette->Red(0), //10
  1158. m_pimBackground->m_pPalette->Green(0), //10
  1159. m_pimBackground->m_pPalette->Blue(0), //10
  1160. m_pimBackground->m_pPalette->m_sPalEntrySize);
  1161. // This part could be left up to the caller...? should it be?
  1162. rspUpdatePalette();
  1163. }
  1164. ////////////////////////////////////////////////////////////////////////////////
  1165. // EOF
  1166. ////////////////////////////////////////////////////////////////////////////////