TerrTxm.cpp 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517
  1. //---------------------------------------------------------------------------
  2. //
  3. // TerrTxm.cpp -- File contains class code for the Terrain Textures
  4. //
  5. //---------------------------------------------------------------------------//
  6. // Copyright (C) Microsoft Corporation. All rights reserved. //
  7. //===========================================================================//
  8. //---------------------------------------------------------------------------
  9. // Include Files
  10. #ifndef TERRTXM_H
  11. #include "terrtxm.h"
  12. #endif
  13. #ifndef MATHFUNC_H
  14. #include "mathfunc.h"
  15. #endif
  16. #ifndef CIDENT_H
  17. #include "cident.h"
  18. #endif
  19. #ifndef PATHS_H
  20. #include "paths.h"
  21. #endif
  22. #ifndef INIFILE_H
  23. #include "inifile.h"
  24. #endif
  25. #ifndef TGAINFO_H
  26. #include "tgainfo.h"
  27. #endif
  28. #ifndef TERRAIN_H
  29. #include "terrain.h"
  30. #endif
  31. #include "windows.h"
  32. //---------------------------------------------------------------------------
  33. // Static Globals
  34. #define TILE_THRESHOLD 0
  35. long tileCacheReqs = 0;
  36. long tileCacheHits = 0;
  37. long tileCacheMiss = 0;
  38. long TERRAIN_TXM_SIZE = 64;
  39. #define MAX_MASK_NUM 14
  40. #define USE_TRANSITIONS
  41. #define MAX_MC2_TRANSITIONS 8192
  42. bool TerrainTextures::terrainTexturesInstrumented = false;
  43. long TerrainTextures::nextAvailable = 0;
  44. long TerrainTextures::numTxms = 0;
  45. extern bool InEditor;
  46. //---------------------------------------------------------------------------
  47. // Class TerrainTextures
  48. //
  49. // At Present, this class doesn't load textures til it needs 'em. Once loaded
  50. // they are loaded forever. This may not be a problem, but if it becomes one,
  51. // the textures can be preloaded during the init.
  52. long TerrainTextures::init (char *fileName, char *baseName)
  53. {
  54. if (InEditor)
  55. quickLoad = false;
  56. else
  57. {
  58. quickLoad = true;
  59. //Check for the magic list and then for all of the textures on the magic list.
  60. FullPathFileName listPath;
  61. listPath.init(texturePath,baseName,".lst");
  62. File listFile;
  63. long result = listFile.open(listPath);
  64. if (result == NO_ERR)
  65. {
  66. while (!listFile.eof())
  67. {
  68. char listName[1024];
  69. listFile.readString((MemoryPtr)listName);
  70. if (!fileExists(listName))
  71. {
  72. quickLoad = false;
  73. break;
  74. }
  75. }
  76. }
  77. else
  78. {
  79. quickLoad = false;
  80. }
  81. }
  82. tileCacheReqs = 0;
  83. tileCacheHits = 0;
  84. tileCacheMiss = 0;
  85. globalMipLevel = 0;
  86. FullPathFileName txmFileName;
  87. //--------------------------------------------------------
  88. // First setup the user heap with amount of RAM requested
  89. tileHeap = new UserHeap;
  90. gosASSERT(tileHeap != NULL);
  91. tileRAMHeap = new UserHeap;
  92. gosASSERT(tileRAMHeap != NULL);
  93. txmFileName.init(texturePath,fileName,".FIT");
  94. FitIniFile textureFile;
  95. long result = textureFile.open(txmFileName);
  96. gosASSERT(result == NO_ERR);
  97. result = textureFile.seekBlock("Main");
  98. gosASSERT(result == NO_ERR);
  99. result = textureFile.readIdLong("MaxTerrainTextures",numTxms);
  100. gosASSERT(result == NO_ERR);
  101. result = textureFile.readIdLong("MaxTerrainTypes",numTypes);
  102. gosASSERT(result == NO_ERR);
  103. result = textureFile.readIdLong("MaxTerrainOverlays",numOverlays);
  104. gosASSERT(result == NO_ERR);
  105. result = textureFile.readIdLong("MaxTerrainDetails",numDetails);
  106. gosASSERT(result == NO_ERR);
  107. //result = textureFile.readIdLong("MaxTerrainTransitions",numTransitions);
  108. //gosASSERT(result == NO_ERR);
  109. numTransitions = MAX_MC2_TRANSITIONS;
  110. unsigned long terrainTileCacheSize = 0;
  111. result = textureFile.readIdULong("TextureMemSize",terrainTileCacheSize);
  112. gosASSERT(result == NO_ERR);
  113. result = tileHeap->init(65536,"TextureRAM");
  114. gosASSERT(result == NO_ERR);
  115. result = tileRAMHeap->init(terrainTileCacheSize,"TextureRAM");
  116. gosASSERT(result == NO_ERR);
  117. localBaseName = (char *)tileRAMHeap->Malloc(strlen(baseName)+1);
  118. strcpy(localBaseName,baseName);
  119. //--------------------------------------------------------
  120. // Create the lists of pointers to the textures.
  121. textures = (TerrainTXMPtr)tileHeap->Malloc(numTxms * sizeof(TerrainTXM));
  122. gosASSERT(textures != NULL);
  123. memset(textures,-1,numTxms * sizeof(TerrainTXM));
  124. types = (MC_TerrainTypePtr)tileRAMHeap->Malloc(numTypes * sizeof(MC_TerrainType));
  125. gosASSERT(types != NULL);
  126. memset(types,0,numTypes * sizeof(MC_TerrainType));
  127. overlays = (MC_OverlayTypePtr)tileRAMHeap->Malloc(numOverlays * sizeof(MC_OverlayType));
  128. gosASSERT(overlays != NULL);
  129. memset(overlays, 0, numOverlays * sizeof(MC_OverlayType));
  130. details = (MC_DetailTypePtr)tileHeap->Malloc(numDetails * sizeof(MC_DetailType));
  131. gosASSERT(details != NULL);
  132. memset(details, 0, numDetails * sizeof(MC_DetailType));
  133. transitions = (TransitionTypePtr)tileRAMHeap->Malloc(numTransitions * sizeof(TransitionType));
  134. gosASSERT(transitions != NULL);
  135. memset(transitions, -1, numTransitions * sizeof(TransitionType));
  136. //-----------------------------------
  137. // Read in the Base Terrain Textures.
  138. for (long i=0;i<numTypes;i++)
  139. {
  140. char blockName[512];
  141. sprintf(blockName,"TerrainType%d",i);
  142. result = textureFile.seekBlock(blockName);
  143. if (result == NO_ERR)
  144. {
  145. result = textureFile.readIdLong("TerrainId",types[i].terrainId);
  146. gosASSERT(result == NO_ERR);
  147. char tmpy[2048];
  148. result = textureFile.readIdString("TerrainName",tmpy,2047);
  149. gosASSERT(result == NO_ERR);
  150. types[i].terrainName = (char *)tileRAMHeap->Malloc(strlen(tmpy)+1);
  151. gosASSERT(types[i].terrainName != NULL);
  152. strcpy(types[i].terrainName,tmpy);
  153. result = textureFile.readIdString("MaskName",tmpy,2047);
  154. gosASSERT(result == NO_ERR);
  155. types[i].maskName = (char *)tileRAMHeap->Malloc(strlen(tmpy)+1);
  156. gosASSERT(types[i].maskName != NULL);
  157. strcpy(types[i].maskName,tmpy);
  158. result = textureFile.readIdLong("TerrainPriority",types[i].terrainPriority);
  159. gosASSERT(result == NO_ERR);
  160. result = textureFile.readIdULong("TerrainTacRGB",types[i].terrainMapRGB);
  161. gosASSERT(result == NO_ERR);
  162. result = textureFile.readIdLong( "NameID", types[i].nameId );
  163. gosASSERT( result == NO_ERR );
  164. types[i].textureData = NULL;
  165. types[i].maskData = NULL;
  166. }
  167. else //MUST load up blank ones or overlays will get trashed whenever we add a terrain type!!
  168. {
  169. types[i].terrainId = types[0].terrainId;
  170. types[i].terrainName = NULL;
  171. types[i].maskName = NULL;
  172. types[i].terrainPriority = types[0].terrainPriority;
  173. types[i].terrainMapRGB = types[0].terrainMapRGB;
  174. types[i].textureData = NULL;
  175. types[i].maskData = NULL;
  176. }
  177. }
  178. //-------------------------------------------------------------
  179. // Now preload the masks and base texture data
  180. // Assume as per art lead on 4/1/99 only one txm and 14 masks.
  181. for (i=0;i<numTypes;i++)
  182. {
  183. if ((i && (types[i].terrainId != types[0].terrainId)) || !i)
  184. {
  185. types[i].textureData = (MemoryPtr *)tileRAMHeap->Malloc(sizeof(MemoryPtr) * MC_MAX_MIP_LEVELS);
  186. gosASSERT(types[i].textureData != NULL);
  187. memset(types[i].textureData,0,sizeof(MemoryPtr) * MC_MAX_MIP_LEVELS);
  188. types[i].maskData = (MemoryPtr *)tileRAMHeap->Malloc(sizeof(MemoryPtr) * MC_MASK_NUM * MC_MAX_MIP_LEVELS);
  189. gosASSERT(types[i].maskData != NULL);
  190. memset(types[i].maskData,0,sizeof(MemoryPtr) * MC_MASK_NUM);
  191. long terrainTextureIndex = initTexture(i);
  192. types[i].baseTXMIndex = terrainTextureIndex;
  193. initMask(i);
  194. }
  195. else if (i && (types[i].terrainId == types[0].terrainId))
  196. {
  197. MemoryPtr ourRAM = (MemoryPtr)tileRAMHeap->Malloc(16 * 16 * sizeof(DWORD));
  198. gosASSERT(ourRAM != NULL);
  199. memset(ourRAM,0,16 * 16 * sizeof(DWORD));
  200. textures[nextAvailable].mcTextureNodeIndex = mcTextureManager->textureFromMemory((DWORD *)ourRAM,gos_Texture_Solid,gosHint_DisableMipmap | gosHint_DontShrink,16);
  201. nextAvailable++;
  202. if (nextAvailable > numTxms)
  203. STOP(("Too Many Terrain Textures! Its at %d right now!",numTxms));
  204. types[i].baseTXMIndex = nextAvailable-1;
  205. }
  206. }
  207. //------------------------------------------
  208. // Read in the Overlay Textures and Shapes.
  209. for (i=0;i<numOverlays;i++)
  210. {
  211. char blockName[512];
  212. sprintf(blockName,"OverlayType%d",i);
  213. result = textureFile.seekBlock(blockName);
  214. gosASSERT(result == NO_ERR);
  215. result = textureFile.readIdLong("OverlayId",overlays[i].overlayId);
  216. gosASSERT(result == NO_ERR);
  217. char tmpy[2048];
  218. result = textureFile.readIdString("OverlayName",tmpy,2047);
  219. gosASSERT(result == NO_ERR);
  220. overlays[i].overlayName = (char *)tileRAMHeap->Malloc(strlen(tmpy)+1);
  221. gosASSERT(overlays[i].overlayName != NULL);
  222. strcpy(overlays[i].overlayName,tmpy);
  223. result = textureFile.readIdLong("NumOverlays",overlays[i].numTextures);
  224. gosASSERT(result == NO_ERR);
  225. result = textureFile.readIdLong("OldOverlayNum",overlays[i].oldOverlayId);
  226. gosASSERT(result == NO_ERR);
  227. result = textureFile.readIdBoolean("IsMLR",overlays[i].isMLRAppearance);
  228. gosASSERT(result == NO_ERR);
  229. result = textureFile.readIdULong("TerrainTacRGB",overlays[i].terrainMapRGB);
  230. gosASSERT(result == NO_ERR);
  231. overlays[i].overlayData = NULL; //Contains MLR shape or TerrainTXM Data
  232. }
  233. //--------------------------------------------------------------
  234. // Now preload the overlay texture data
  235. for (i=0;i<numOverlays;i++)
  236. {
  237. overlays[i].overlayData = (MemoryPtr *)tileRAMHeap->Malloc(sizeof(MemoryPtr) * overlays[i].numTextures * MC_MAX_MIP_LEVELS);
  238. gosASSERT(overlays[i].overlayData != NULL);
  239. memset(overlays[i].overlayData,0,sizeof(MemoryPtr) * overlays[i].numTextures * MC_MAX_MIP_LEVELS);
  240. for (long j=0;j<overlays[i].numTextures;j++)
  241. {
  242. long overlayTextureIndex = initOverlay(i,j,overlays[i].overlayName);
  243. if (!j)
  244. overlays[i].baseTXMIndex = overlayTextureIndex;
  245. if (!i && !j)
  246. firstOverlay = overlayTextureIndex;
  247. }
  248. }
  249. //------------------------------------------
  250. // Read in the Detail Textures
  251. for (i=0;i<numDetails;i++)
  252. {
  253. char blockName[512];
  254. sprintf(blockName,"DetailType%d",i);
  255. result = textureFile.seekBlock(blockName);
  256. gosASSERT(result == NO_ERR);
  257. result = textureFile.readIdLong("DetailId",details[i].detailId);
  258. gosASSERT(result == NO_ERR);
  259. char tmpy[2048];
  260. result = textureFile.readIdString("DetailName",tmpy,2047);
  261. gosASSERT(result == NO_ERR);
  262. details[i].detailName = (char *)tileRAMHeap->Malloc(strlen(tmpy)+1);
  263. gosASSERT(details[i].detailName != NULL);
  264. strcpy(details[i].detailName,tmpy);
  265. result = textureFile.readIdLong("NumDetails",details[i].numDetails);
  266. gosASSERT(result == NO_ERR);
  267. result = textureFile.readIdFloat("FrameRate",details[i].frameRate);
  268. gosASSERT(result == NO_ERR);
  269. result = textureFile.readIdFloat("TilingFactor",details[i].tilingFactor);
  270. gosASSERT(result == NO_ERR);
  271. details[i].detailData = NULL;
  272. }
  273. //--------------------------------------------------------------
  274. // Now preload the detail texture data
  275. for (i=0;i<numDetails;i++)
  276. {
  277. details[i].detailData = (MemoryPtr *)tileRAMHeap->Malloc(sizeof(MemoryPtr) * details[i].numDetails * MC_MAX_MIP_LEVELS);
  278. gosASSERT(details[i].detailData != NULL);
  279. memset(details[i].detailData,0,sizeof(MemoryPtr) * details[i].numDetails * MC_MAX_MIP_LEVELS);
  280. for (long j=0;j < details[i].numDetails; j++)
  281. {
  282. long detailTextureIndex = initDetail(i,j);
  283. if (j==0)
  284. details[i].baseTXMIndex = detailTextureIndex;
  285. }
  286. }
  287. return(NO_ERR);
  288. }
  289. void TerrainTextures::initializeStatistics()
  290. {
  291. if (!terrainTexturesInstrumented)
  292. {
  293. StatisticFormat( "" );
  294. StatisticFormat( "MechCommander 2 Terrain Texture" );
  295. StatisticFormat( "===============================" );
  296. StatisticFormat( "" );
  297. AddStatistic("Total Textures","Textures",gos_DWORD, (void*)&(numTxms), Stat_Total);
  298. AddStatistic("Textures Used ","Textures",gos_DWORD, (void*)&(nextAvailable), Stat_Total);
  299. StatisticFormat( "" );
  300. StatisticFormat( "" );
  301. terrainTexturesInstrumented = true;
  302. }
  303. }
  304. //---------------------------------------------------------------------------
  305. long TerrainTextures::textureFromMemoryAlpha (MemoryPtr ourRAM, long mipLevel)
  306. {
  307. textures[nextAvailable].mcTextureNodeIndex = mcTextureManager->textureFromMemory((DWORD *)ourRAM,gos_Texture_Keyed,gosHint_DisableMipmap | gosHint_DontShrink,mipLevel);
  308. nextAvailable++;
  309. if (nextAvailable > numTxms)
  310. STOP(("Too Many Terrain Textures! Its at %d right now!",numTxms));
  311. return(nextAvailable-1);
  312. }
  313. //---------------------------------------------------------------------------
  314. long TerrainTextures::textureFromMemory (MemoryPtr ourRAM, long mipLevel)
  315. {
  316. textures[nextAvailable].mcTextureNodeIndex = mcTextureManager->textureFromMemory((DWORD *)ourRAM,gos_Texture_Solid,gosHint_DisableMipmap | gosHint_DontShrink,mipLevel);
  317. nextAvailable++;
  318. if (nextAvailable > numTxms)
  319. STOP(("Too Many Terrain Textures! Its at %d right now!",numTxms));
  320. return(nextAvailable-1);
  321. }
  322. //---------------------------------------------------------------------------
  323. long TerrainTextures::loadTextureMemory (char *textureName, long mipSize)
  324. {
  325. textures[nextAvailable].mcTextureNodeIndex = mcTextureManager->loadTexture(textureName,gos_Texture_Solid,gosHint_DisableMipmap | gosHint_DontShrink);
  326. nextAvailable++;
  327. if (nextAvailable > numTxms)
  328. STOP(("Too Many Terrain Textures! Its at %d right now!",numTxms));
  329. return(nextAvailable-1);
  330. }
  331. //---------------------------------------------------------------------------
  332. long TerrainTextures::loadDetailMemory (char *textureName, long mipSize)
  333. {
  334. textures[nextAvailable].mcTextureNodeIndex = mcTextureManager->loadTexture(textureName,gos_Texture_Alpha,gosHint_DontShrink);
  335. nextAvailable++;
  336. if (nextAvailable > numTxms)
  337. STOP(("Too Many Terrain Textures! Its at %d right now!",numTxms));
  338. return(nextAvailable-1);
  339. }
  340. //---------------------------------------------------------------------------
  341. long TerrainTextures::loadOverlayMemory (char *textureName)
  342. {
  343. textures[nextAvailable].mcTextureNodeIndex = mcTextureManager->loadTexture(textureName,gos_Texture_Alpha,gosHint_DisableMipmap | gosHint_DontShrink);
  344. nextAvailable++;
  345. if (nextAvailable > numTxms)
  346. STOP(("Too Many Terrain Textures! Its at %d right now!",numTxms));
  347. return(nextAvailable-1);
  348. }
  349. //---------------------------------------------------------------------------
  350. long TerrainTextures::initDetail (long typeNum, long detailNum)
  351. {
  352. //-----------------------------------------------------------------------
  353. // This function loads the TGA pointed to by name and number into sysRAM
  354. // It then copies the raw TGA texture to GOS Texture Memory.
  355. // We now control the MIP levels. Load all MIP levels here!
  356. long txmResult = -1;
  357. for (long j=0;j<MC_MAX_MIP_LEVELS;j++)
  358. {
  359. //---------------------------------------------
  360. // Change Texture Path to reflect texture size
  361. char mipPath[512];
  362. long mipSize = 0;
  363. switch (j)
  364. {
  365. case 0:
  366. sprintf(mipPath,"%s%d\\",texturePath,TERRAIN_TXM_SIZE);
  367. mipSize = TERRAIN_TXM_SIZE;
  368. break;
  369. case 1:
  370. sprintf(mipPath,"%s%d\\",texturePath,(TERRAIN_TXM_SIZE>>1));
  371. mipSize = (TERRAIN_TXM_SIZE>>1);
  372. break;
  373. case 2:
  374. sprintf(mipPath,"%s%d\\",texturePath,(TERRAIN_TXM_SIZE>>2));
  375. mipSize = (TERRAIN_TXM_SIZE>>2);
  376. break;
  377. case 3:
  378. sprintf(mipPath,"%s%d\\",texturePath,(TERRAIN_TXM_SIZE>>3));
  379. mipSize = (TERRAIN_TXM_SIZE>>3);
  380. break;
  381. }
  382. char tmpy[512];
  383. sprintf(tmpy,"%s%04d",details[typeNum].detailName,detailNum);
  384. FullPathFileName fileName;
  385. fileName.init(mipPath,tmpy,".tga");
  386. long result = loadDetailMemory(fileName,mipSize);
  387. if (j==0)
  388. txmResult = result;
  389. }
  390. return(txmResult);
  391. }
  392. //---------------------------------------------------------------------------
  393. long TerrainTextures::initTexture (long typeNum)
  394. {
  395. //-----------------------------------------------------------------------
  396. // This function loads the TGA pointed to by name and number into sysRAM
  397. // It then copies the raw TGA texture to GOS Texture Memory.
  398. // We now control the MIP levels. Load all MIP levels here!
  399. long txmResult = -1;
  400. for (long j=0;j<MC_MAX_MIP_LEVELS;j++)
  401. {
  402. //---------------------------------------------
  403. // Change Texture Path to reflect texture size
  404. char mipPath[512];
  405. long mipSize = 0;
  406. switch (j)
  407. {
  408. case 0:
  409. sprintf(mipPath,"%s%d\\",texturePath,TERRAIN_TXM_SIZE);
  410. mipSize = TERRAIN_TXM_SIZE;
  411. break;
  412. case 1:
  413. sprintf(mipPath,"%s%d\\",texturePath,(TERRAIN_TXM_SIZE>>1));
  414. mipSize = (TERRAIN_TXM_SIZE>>1);
  415. break;
  416. case 2:
  417. sprintf(mipPath,"%s%d\\",texturePath,(TERRAIN_TXM_SIZE>>2));
  418. mipSize = (TERRAIN_TXM_SIZE>>2);
  419. break;
  420. case 3:
  421. sprintf(mipPath,"%s%d\\",texturePath,(TERRAIN_TXM_SIZE>>3));
  422. mipSize = (TERRAIN_TXM_SIZE>>3);
  423. break;
  424. }
  425. FullPathFileName fileName;
  426. fileName.init(mipPath,types[typeNum].terrainName,".tga");
  427. long result = 0;
  428. if (InEditor || !quickLoad)
  429. {
  430. File tgaFile;
  431. result = tgaFile.open(fileName);
  432. gosASSERT(result == NO_ERR);
  433. struct TGAFileHeader header;
  434. tgaFile.read((MemoryPtr)&header,sizeof(TGAFileHeader));
  435. if (mipSize != header.width)
  436. mipSize = header.width;
  437. tgaFile.seek(0);
  438. MemoryPtr ourRAM = (MemoryPtr)tileRAMHeap->Malloc(mipSize * mipSize * sizeof(DWORD));
  439. gosASSERT(ourRAM != NULL);
  440. loadTGATexture(&tgaFile,ourRAM,mipSize,mipSize);
  441. types[typeNum].textureData[j] = ourRAM;
  442. tgaFile.close();
  443. }
  444. result = loadTextureMemory(fileName,mipSize);
  445. if (j==0)
  446. txmResult = result;
  447. }
  448. return(txmResult);
  449. }
  450. //---------------------------------------------------------------------------
  451. void TerrainTextures::initMask (long typeNum)
  452. {
  453. if (quickLoad)
  454. return;
  455. //----------------------------------------------------------------------------
  456. // The masks are stored in sysRAM only. Need to load MC_MASK_NUM * miplevels
  457. // per terrain type.
  458. for (long i=0;i<MC_MAX_MIP_LEVELS;i++)
  459. {
  460. //---------------------------------------------
  461. // Change Texture Path to reflect texture size
  462. char mipPath[512];
  463. long mipSize = 0;
  464. switch (i)
  465. {
  466. case 0:
  467. sprintf(mipPath,"%s%dmask\\",texturePath,(TERRAIN_TXM_SIZE>>0));
  468. mipSize = (TERRAIN_TXM_SIZE>>0);
  469. break;
  470. case 1:
  471. sprintf(mipPath,"%s%dmask\\",texturePath,(TERRAIN_TXM_SIZE>>1));
  472. mipSize = (TERRAIN_TXM_SIZE>>1);
  473. break;
  474. case 2:
  475. sprintf(mipPath,"%s%dmask\\",texturePath,(TERRAIN_TXM_SIZE>>2));
  476. mipSize = (TERRAIN_TXM_SIZE>>2);
  477. break;
  478. case 3:
  479. sprintf(mipPath,"%s%dmask\\",texturePath,(TERRAIN_TXM_SIZE>>3));
  480. mipSize = (TERRAIN_TXM_SIZE>>3);
  481. break;
  482. }
  483. for (long j=0;j<MC_MASK_NUM;j++)
  484. {
  485. char tmpy[512];
  486. sprintf(tmpy,"%s%04d",types[typeNum].maskName,j);
  487. FullPathFileName fileName;
  488. fileName.init(mipPath,tmpy,".tga");
  489. File tgaFile;
  490. #ifdef _DEBUG
  491. long result =
  492. #endif
  493. tgaFile.open(fileName);
  494. gosASSERT(result == NO_ERR);
  495. MemoryPtr ourRAM = (MemoryPtr)tileRAMHeap->Malloc(mipSize * mipSize * sizeof(BYTE));
  496. gosASSERT(ourRAM != NULL);
  497. loadTGAMask(&tgaFile,ourRAM,mipSize,mipSize);
  498. types[typeNum].maskData[j+(i*MC_MASK_NUM)] = ourRAM;
  499. tgaFile.close();
  500. }
  501. }
  502. }
  503. //---------------------------------------------------------------------------
  504. long TerrainTextures::initOverlay (long overlayNum, long txmNum, char *txmName)
  505. {
  506. long txmResult = -1;
  507. for (long j=0;j<MC_MAX_MIP_LEVELS;j++)
  508. {
  509. //---------------------------------------------
  510. // Change Texture Path to reflect texture size
  511. char mipPath[512];
  512. long mipSize = 0;
  513. switch (j)
  514. {
  515. case 0:
  516. sprintf(mipPath,"%s%dOverlays\\",texturePath,TERRAIN_TXM_SIZE);
  517. mipSize = TERRAIN_TXM_SIZE;
  518. break;
  519. case 1:
  520. sprintf(mipPath,"%s%dOverlays\\",texturePath,(TERRAIN_TXM_SIZE>>1));
  521. mipSize = (TERRAIN_TXM_SIZE>>1);
  522. break;
  523. case 2:
  524. sprintf(mipPath,"%s%dOverlays\\",texturePath,(TERRAIN_TXM_SIZE>>2));
  525. mipSize = (TERRAIN_TXM_SIZE>>2);
  526. break;
  527. case 3:
  528. sprintf(mipPath,"%s%dOverlays\\",texturePath,(TERRAIN_TXM_SIZE>>3));
  529. mipSize = (TERRAIN_TXM_SIZE>>3);
  530. break;
  531. }
  532. char tmpy[512];
  533. sprintf(tmpy,"%s%04d",txmName,txmNum);
  534. FullPathFileName fileName;
  535. fileName.init(mipPath,tmpy,".tga");
  536. long result = 0;
  537. //------------------------------------------------------------
  538. if (InEditor || !quickLoad)
  539. {
  540. File tgaFile;
  541. result = tgaFile.open(fileName);
  542. gosASSERT(result == NO_ERR);
  543. MemoryPtr ourRAM = (MemoryPtr)tileRAMHeap->Malloc(mipSize * mipSize * sizeof(DWORD));
  544. gosASSERT(ourRAM != NULL);
  545. loadTGATexture(&tgaFile,ourRAM,mipSize,mipSize);
  546. overlays[overlayNum].overlayData[txmNum] = ourRAM;
  547. tgaFile.close();
  548. }
  549. //------------------------------------------------------------
  550. result = loadOverlayMemory(fileName);
  551. if (j==0)
  552. txmResult = result;
  553. }
  554. return(txmResult);
  555. }
  556. //---------------------------------------------------------------------------
  557. long TerrainTextures::setOverlay (DWORD overlayInfo)
  558. {
  559. //-------------------------------------------------------------
  560. // This still uses the old Overlay Indicies from MC1 and MCX!
  561. long txmHandle = 0xffff0000;
  562. for (long i=0;i<numOverlays;i++)
  563. {
  564. if ((overlayInfo >= overlays[i].oldOverlayId) &&
  565. (overlayInfo <= (overlays[i].oldOverlayId+18)))
  566. {
  567. int index = (overlayInfo - overlays[i].oldOverlayId);
  568. if ( overlays[i].numTextures> 9 ) // roads have new indices
  569. {
  570. switch( index )
  571. {
  572. case 0:
  573. case 1:
  574. case 2:
  575. index = 0;
  576. break;
  577. case 3:
  578. case 4:
  579. case 5:
  580. index = 1;
  581. break;
  582. case 6:
  583. case 7:
  584. case 8:
  585. case 9:
  586. case 10:
  587. case 11:
  588. case 12:
  589. case 13:
  590. case 14:
  591. index = index - 4;
  592. break;
  593. case 15:
  594. index = 9;
  595. break;
  596. case 17:
  597. index = 7;
  598. break;
  599. case 18:
  600. case 16:
  601. index = index - 8;
  602. break;
  603. }
  604. }
  605. txmHandle = overlays[i].baseTXMIndex + ( index * MC_MAX_MIP_LEVELS);
  606. txmHandle <<= 16;
  607. }
  608. }
  609. return(txmHandle);
  610. }
  611. //---------------------------------------------------------------------------
  612. // this doesn't use the old indices. Those shouldn't be necessary.
  613. long TerrainTextures::getOverlayHandle( Overlays id, int Offset )
  614. {
  615. long txmHandle = 0xffff0000;
  616. gosASSERT( id > -2 && id < numOverlays );
  617. if ( id > -1 && id < numOverlays )
  618. {
  619. txmHandle = overlays[id].baseTXMIndex + (Offset * MC_MAX_MIP_LEVELS );
  620. txmHandle <<= 16;
  621. }
  622. return(txmHandle);
  623. }
  624. void TerrainTextures::getOverlayInfoFromHandle( long handle, Overlays& id, unsigned long& Offset )
  625. {
  626. id = INVALID_OVERLAY;
  627. Offset = -1;
  628. for ( int i = 0; i < numOverlays; ++i )
  629. {
  630. if ( (handle >> 16) >= overlays[i].baseTXMIndex
  631. && (handle >> 16) < overlays[i].baseTXMIndex + overlays[i].numTextures * MC_MAX_MIP_LEVELS )
  632. {
  633. id = (Overlays)i;
  634. long tmp = (handle >> 16) - overlays[i].baseTXMIndex;
  635. Offset = tmp/MC_MAX_MIP_LEVELS;
  636. }
  637. }
  638. }
  639. //---------------------------------------------------------------------------
  640. void TerrainTextures::combineTxm (MemoryPtr dest, DWORD binNumber, long type, long mipLevel)
  641. {
  642. MemoryPtr combineRAM = types[type].textureData[mipLevel];
  643. MemoryPtr maskRAM = types[type].maskData[(binNumber-1) + (mipLevel * MC_MASK_NUM)];
  644. long mipSize = 0;
  645. switch (mipLevel)
  646. {
  647. case 0:
  648. mipSize = (TERRAIN_TXM_SIZE>>0);
  649. break;
  650. case 1:
  651. mipSize = (TERRAIN_TXM_SIZE>>1);
  652. break;
  653. case 2:
  654. mipSize = (TERRAIN_TXM_SIZE>>2);
  655. break;
  656. case 3:
  657. mipSize = (TERRAIN_TXM_SIZE>>3);
  658. break;
  659. }
  660. for (long i=0;i<(mipSize * mipSize);i++)
  661. {
  662. if (maskRAM[i])
  663. {
  664. float combPercent = float(maskRAM[i]) / 255.0f;
  665. float destPercent = 1.0f - combPercent;
  666. if (combPercent == 1.0f)
  667. {
  668. *dest = *combineRAM;
  669. dest++;
  670. combineRAM++;
  671. *dest = *combineRAM;
  672. dest++;
  673. combineRAM++;
  674. *dest = *combineRAM;
  675. dest++;
  676. combineRAM++;
  677. if (*dest < maskRAM[i])
  678. *dest = maskRAM[i];
  679. dest++;
  680. combineRAM++;
  681. }
  682. else
  683. {
  684. float combValue = combPercent * float(*combineRAM);
  685. float destValue = destPercent * float(*dest);
  686. combValue += destValue;
  687. unsigned char value = (unsigned char)combValue;
  688. *dest = value;
  689. dest++;
  690. combineRAM++;
  691. combValue = combPercent * float(*combineRAM);
  692. destValue = destPercent * float(*dest);
  693. combValue += destValue;
  694. value = (unsigned char)combValue;
  695. *dest = value;
  696. dest++;
  697. combineRAM++;
  698. combValue = combPercent * float(*combineRAM);
  699. destValue = destPercent * float(*dest);
  700. combValue += destValue;
  701. value = (unsigned char)combValue;
  702. *dest = value;
  703. dest++;
  704. combineRAM++;
  705. //This is the alpha channel. DO NOT COMBINE!!!
  706. // Just copy in the CombineTXM AlphA!!
  707. //combValue = combPercent * float(*combineRAM);
  708. //destValue = destPercent * float(*dest);
  709. //combValue += destValue;
  710. //value = (unsigned char)combValue;
  711. if (*dest < maskRAM[i])
  712. *dest = maskRAM[i];
  713. dest++;
  714. combineRAM++;
  715. }
  716. }
  717. else
  718. {
  719. dest += 4;
  720. combineRAM += 4;
  721. }
  722. }
  723. }
  724. //---------------------------------------------------------------------------
  725. void forceAlphaOpaque(MemoryPtr dest, long mipLevel)
  726. {
  727. long mipSize = 0;
  728. switch (mipLevel)
  729. {
  730. case 0:
  731. mipSize = (TERRAIN_TXM_SIZE>>0);
  732. break;
  733. case 1:
  734. mipSize = (TERRAIN_TXM_SIZE>>1);
  735. break;
  736. case 2:
  737. mipSize = (TERRAIN_TXM_SIZE>>2);
  738. break;
  739. case 3:
  740. mipSize = (TERRAIN_TXM_SIZE>>3);
  741. break;
  742. }
  743. for (long i=0;i<(mipSize * mipSize);i++)
  744. {
  745. dest++;
  746. dest++;
  747. dest++;
  748. *dest = 0xff;
  749. dest++;
  750. }
  751. }
  752. //---------------------------------------------------------------------------
  753. void TerrainTextures::combineOverlayTxm (MemoryPtr dest, long type, long mipLevel)
  754. {
  755. //Convert overlay Type to actual overlay Index.
  756. long oType = 0;
  757. long oIndx = 0;
  758. for (long i=0;i<numOverlays;i++)
  759. {
  760. if ((type >= overlays[i].baseTXMIndex) &&
  761. (type < (overlays[i].baseTXMIndex + overlays[i].numTextures)))
  762. {
  763. oIndx = type - overlays[i].baseTXMIndex;
  764. oType = i;
  765. break;
  766. }
  767. }
  768. MemoryPtr combineRAM = overlays[oType].overlayData[oIndx];
  769. gosASSERT(combineRAM != NULL);
  770. long mipSize = 0;
  771. switch (mipLevel)
  772. {
  773. case 0:
  774. mipSize = (TERRAIN_TXM_SIZE>>0);
  775. break;
  776. case 1:
  777. mipSize = (TERRAIN_TXM_SIZE>>1);
  778. break;
  779. case 2:
  780. mipSize = (TERRAIN_TXM_SIZE>>2);
  781. break;
  782. case 3:
  783. mipSize = (TERRAIN_TXM_SIZE>>3);
  784. break;
  785. }
  786. for (i=0;i<(mipSize * mipSize);i++)
  787. {
  788. float combPercent = float(*(combineRAM+3)) / 255.0f;
  789. float destPercent = 1.0f - combPercent;
  790. if (combPercent != 0.0)
  791. {
  792. if (combPercent == 1.0f)
  793. {
  794. *dest = *combineRAM;
  795. dest++;
  796. combineRAM++;
  797. *dest = *combineRAM;
  798. dest++;
  799. combineRAM++;
  800. *dest = *combineRAM;
  801. dest++;
  802. combineRAM++;
  803. if (*dest < *combineRAM)
  804. *dest = *combineRAM;
  805. dest++;
  806. combineRAM++;
  807. }
  808. else
  809. {
  810. float combValue = combPercent * float(*combineRAM);
  811. float destValue = destPercent * float(*dest);
  812. combValue += destValue;
  813. unsigned char value = (unsigned char)combValue;
  814. *dest = value;
  815. dest++;
  816. combineRAM++;
  817. combValue = combPercent * float(*combineRAM);
  818. destValue = destPercent * float(*dest);
  819. combValue += destValue;
  820. value = (unsigned char)combValue;
  821. *dest = value;
  822. dest++;
  823. combineRAM++;
  824. combValue = combPercent * float(*combineRAM);
  825. destValue = destPercent * float(*dest);
  826. combValue += destValue;
  827. value = (unsigned char)combValue;
  828. *dest = value;
  829. dest++;
  830. combineRAM++;
  831. //combValue = combPercent * float(*combineRAM);
  832. //destValue = destPercent * float(*dest);
  833. //combValue += destValue;
  834. //value = (unsigned char)combValue;
  835. if (*dest < *combineRAM)
  836. *dest = *combineRAM;
  837. dest++;
  838. combineRAM++;
  839. }
  840. }
  841. else
  842. {
  843. dest += 4;
  844. combineRAM += 4;
  845. }
  846. }
  847. }
  848. //---------------------------------------------------------------------------
  849. void TerrainTextures::purgeTransitions (void)
  850. {
  851. for (long i=0;i<nextTransition;i++)
  852. {
  853. mcTextureManager->removeTextureNode(textures[transitions[i].baseTXMIndex].mcTextureNodeIndex);
  854. }
  855. nextTransition = 0;
  856. nextAvailable = firstTransition;
  857. }
  858. //---------------------------------------------------------------------------
  859. inline bool isCementType (DWORD type)
  860. {
  861. bool isCement = ((type == BASE_CEMENT_TYPE) ||
  862. ((type >= START_CEMENT_TYPE) && (type <= END_CEMENT_TYPE)));
  863. return isCement;
  864. }
  865. //---------------------------------------------------------------------------
  866. long TerrainTextures::createTransition (DWORD typeInfo, DWORD overlayInfo)
  867. {
  868. long result = -1;
  869. long txmResult = 0;
  870. if (nextTransition < MAX_MC2_TRANSITIONS)
  871. {
  872. //------------------------------------------------------
  873. // Search Existing Transitions for this typeInfo.
  874. // Does not need to be fast yet. May not ever since we
  875. // only do this on load can be done on Heidi's end.
  876. for (long i=0;i<nextTransition;i++)
  877. {
  878. if ((typeInfo == transitions[i].transitionIndex) &&
  879. (overlayInfo == transitions[i].overlayIndex))
  880. {
  881. return(transitions[i].baseTXMIndex);
  882. }
  883. }
  884. //---------------------------------------------
  885. // TESTING......
  886. // We may have already saved out a texture which
  887. // is the combined version. Check for it. Load it, if its there and move on.
  888. //-----------------------------------------------------------
  889. // TEST.....
  890. // What if we saved off all of the textures instead of combining
  891. // every time we load? Should lower load time. Lets see how big
  892. // for all of the textures...
  893. // About 600K for mc2_01. With redundancies, assume about 600K per...
  894. // About 20 Mb larger build.
  895. if (quickLoad)
  896. {
  897. char nameData[256];
  898. sprintf(nameData,"%08d.%08d.txm",typeInfo,overlayInfo);
  899. FullPathFileName testPath;
  900. testPath.init(texturePath,nameData,"");
  901. File txmFile;
  902. long fr = txmFile.open(testPath);
  903. if (fr == NO_ERR)
  904. {
  905. long mipSize = TERRAIN_TXM_SIZE;
  906. DWORD fileSize = txmFile.fileSize();
  907. MemoryPtr fileRAM = (MemoryPtr)malloc(fileSize);
  908. long result = txmFile.read(fileRAM,fileSize);
  909. if (result != fileSize)
  910. STOP(("Read Error with Texture %s",testPath));
  911. MemoryPtr lzBuffer = (MemoryPtr)malloc(mipSize * mipSize * sizeof(DWORD));
  912. long bufferSize = LZDecomp(lzBuffer,fileRAM,fileSize);
  913. if (bufferSize != (mipSize * mipSize * sizeof(DWORD)))
  914. STOP(("Texture not correct size!"));
  915. txmFile.close();
  916. result = textureFromMemoryAlpha(lzBuffer,mipSize);
  917. txmResult = result;
  918. free(fileRAM);
  919. free(lzBuffer);
  920. transitions[nextTransition].transitionIndex = typeInfo;
  921. transitions[nextTransition].baseTXMIndex = txmResult;
  922. transitions[nextTransition].overlayIndex = overlayInfo;
  923. nextTransition++;
  924. return (txmResult);
  925. }
  926. }
  927. if (!listTransitionFile)
  928. {
  929. //Check for the magic list and then for all of the textures on the magic list.
  930. CreateDirectory(texturePath,NULL);
  931. FullPathFileName listPath;
  932. listPath.init(texturePath,localBaseName,".lst");
  933. listTransitionFile = new File;
  934. listTransitionFile->create(listPath);
  935. }
  936. //---------------------------------
  937. // No transition yet. Make it go!
  938. for (long kmp=0;kmp<MC_MAX_MIP_LEVELS;kmp++)
  939. {
  940. //---------------------------------------------
  941. // Change Texture Path to reflect texture size
  942. char mipPath[512];
  943. long mipSize = 0;
  944. switch (kmp)
  945. {
  946. case 0:
  947. sprintf(mipPath,"%s%d\\",texturePath,(TERRAIN_TXM_SIZE>>0));
  948. mipSize = (TERRAIN_TXM_SIZE>>0);
  949. break;
  950. case 1:
  951. sprintf(mipPath,"%s%d\\",texturePath,(TERRAIN_TXM_SIZE>>1));
  952. mipSize = (TERRAIN_TXM_SIZE>>1);
  953. break;
  954. case 2:
  955. sprintf(mipPath,"%s%d\\",texturePath,(TERRAIN_TXM_SIZE>>2));
  956. mipSize = (TERRAIN_TXM_SIZE>>2);
  957. break;
  958. case 3:
  959. sprintf(mipPath,"%s%d\\",texturePath,(TERRAIN_TXM_SIZE>>3));
  960. mipSize = (TERRAIN_TXM_SIZE>>3);
  961. break;
  962. }
  963. //-------------------------------------------------------
  964. // This one does not exist. Make it.
  965. MemoryPtr ourRAM = (MemoryPtr)tileRAMHeap->Malloc(mipSize * mipSize * sizeof(DWORD));
  966. BYTE v0Type = typeInfo & 0x000000ff;
  967. BYTE v1Type = typeInfo >> 8;
  968. BYTE v2Type = typeInfo >> 16;
  969. BYTE v3Type = typeInfo >> 24;
  970. BYTE priTypes[4];
  971. priTypes[0] = typeInfo & 0x000000ff;
  972. priTypes[1] = typeInfo >> 8;
  973. priTypes[2] = typeInfo >> 16;
  974. priTypes[3] = typeInfo >> 24;
  975. //------------------------------------------
  976. // Sort types by priority.
  977. for (i=0;i<4;i++)
  978. {
  979. for (long j=i;j<4;j++)
  980. {
  981. if (types[priTypes[j]].terrainPriority < types[priTypes[i]].terrainPriority)
  982. {
  983. BYTE t = priTypes[i];
  984. priTypes[i] = priTypes[j];
  985. priTypes[j] = t;
  986. }
  987. }
  988. }
  989. //-----------------------------------------------
  990. // Draw by Priority and Mask.
  991. // Priority 0 is ALWAYS just copy that texture.
  992. // Use a random one if possible.
  993. MemoryPtr texture = types[priTypes[0]].textureData[kmp];
  994. if (!Terrain::terrainTextures2 || isCementType(priTypes[0]))
  995. {
  996. //Base is now a BLANK ALPHA MASK for new Terrain
  997. //This means we shove a blank transparent texture
  998. //into the starting buffer. Easily done with memset(dest,0,sizeof);
  999. memcpy(ourRAM,texture,mipSize * mipSize * sizeof(DWORD));
  1000. forceAlphaOpaque(ourRAM,kmp);
  1001. }
  1002. else
  1003. memset(ourRAM,0x01,mipSize * mipSize * sizeof(DWORD));
  1004. //-------------------------------------------------------------
  1005. // Create Binary number based on types which MATCH priType[1].
  1006. DWORD binNumber = 0;
  1007. if (priTypes[0] != priTypes[1])
  1008. {
  1009. binNumber = ((v0Type == priTypes[1])*8) +
  1010. ((v1Type == priTypes[1])*4) +
  1011. ((v2Type == priTypes[1])*2) +
  1012. ((v3Type == priTypes[1]));
  1013. //--------------------------------------------------------------
  1014. // We now have the mask number, send texture to Combiner school
  1015. // ONLY send it to school in the new universe if its type is cement.
  1016. // Otherwise, NO!
  1017. if (!Terrain::terrainTextures2 || isCementType(priTypes[1]))
  1018. combineTxm(ourRAM,binNumber,priTypes[1],kmp);
  1019. }
  1020. if (priTypes[1] != priTypes[2])
  1021. {
  1022. binNumber = ((v0Type == priTypes[2])*8) +
  1023. ((v1Type == priTypes[2])*4) +
  1024. ((v2Type == priTypes[2])*2) +
  1025. ((v3Type == priTypes[2]));
  1026. //--------------------------------------------------------------
  1027. // We now have the mask number, send texture to Combiner school
  1028. // ONLY send it to school in the new universe if its type is cement.
  1029. // Otherwise, NO!
  1030. if (!Terrain::terrainTextures2 || isCementType(priTypes[2]))
  1031. combineTxm(ourRAM,binNumber,priTypes[2],kmp);
  1032. }
  1033. if (priTypes[2] != priTypes[3])
  1034. {
  1035. binNumber = ((v0Type == priTypes[3])*8) +
  1036. ((v1Type == priTypes[3])*4) +
  1037. ((v2Type == priTypes[3])*2) +
  1038. ((v3Type == priTypes[3]));
  1039. //--------------------------------------------------------------
  1040. // We now have the mask number, send texture to Combiner school
  1041. // ONLY send it to school in the new universe if its type is cement.
  1042. // Otherwise, NO!
  1043. if (!Terrain::terrainTextures2 || isCementType(priTypes[3]))
  1044. combineTxm(ourRAM,binNumber,priTypes[3],kmp);
  1045. }
  1046. if (overlayInfo != 0xffff)
  1047. {
  1048. //ONLY Combine certain overlays to prevent dumb things from old universe from showing up
  1049. if (!Terrain::terrainTextures2)
  1050. combineOverlayTxm(ourRAM,overlayInfo,kmp);
  1051. else
  1052. {
  1053. if ((overlayInfo < 285) || (overlayInfo > 292)) //Don't draw the stupid rough stuff
  1054. combineOverlayTxm(ourRAM,overlayInfo,kmp);
  1055. }
  1056. }
  1057. //-------------------------------------------------
  1058. // OurRAM at this point is the new magical Texture
  1059. if (!Terrain::terrainTextures2)
  1060. result = textureFromMemory(ourRAM,mipSize);
  1061. else
  1062. result = textureFromMemoryAlpha(ourRAM,mipSize);
  1063. //-----------------------------------------------------------
  1064. // TEST.....
  1065. // What if we saved off all of the textures instead of combining
  1066. // every time we load? Should lower load time. Lets see how big
  1067. // for all of the textures...
  1068. //
  1069. char nameData[256];
  1070. sprintf(nameData,"%08d.%08d.txm",typeInfo,overlayInfo);
  1071. FullPathFileName testPath;
  1072. testPath.init(texturePath,nameData,"");
  1073. if (listTransitionFile)
  1074. {
  1075. listTransitionFile->writeString(testPath);
  1076. listTransitionFile->writeByte(0);
  1077. }
  1078. MemoryPtr lzBuffer = (MemoryPtr)malloc(mipSize * mipSize * sizeof(DWORD) * 2);
  1079. long bufferSize = LZCompress(lzBuffer,ourRAM,(mipSize * mipSize * sizeof(DWORD)));
  1080. File txmFile;
  1081. txmFile.create(testPath);
  1082. txmFile.write(lzBuffer,bufferSize);
  1083. txmFile.close();
  1084. if (kmp == 0)
  1085. txmResult = result;
  1086. tileRAMHeap->Free(ourRAM);
  1087. free(lzBuffer);
  1088. }
  1089. transitions[nextTransition].transitionIndex = typeInfo;
  1090. transitions[nextTransition].baseTXMIndex = txmResult;
  1091. transitions[nextTransition].overlayIndex = overlayInfo;
  1092. nextTransition++;
  1093. }
  1094. return(txmResult);
  1095. }
  1096. //---------------------------------------------------------------------------
  1097. long TerrainTextures::setTexture (DWORD typeInfo, DWORD overlayInfo)
  1098. {
  1099. BYTE v0Type = typeInfo & 0x000000ff;
  1100. BYTE v1Type = typeInfo >> 8;
  1101. BYTE v2Type = typeInfo >> 16;
  1102. BYTE v3Type = typeInfo >> 24;
  1103. gosASSERT(v0Type < numTypes);
  1104. gosASSERT(v1Type < numTypes);
  1105. gosASSERT(v2Type < numTypes);
  1106. gosASSERT(v3Type < numTypes);
  1107. if ((v0Type == v1Type) && (v2Type == v3Type) && (v1Type == v3Type) && (overlayInfo == 0xffff))
  1108. {
  1109. long txmHandle = types[v0Type].baseTXMIndex;
  1110. if (
  1111. ((v0Type == BASE_CEMENT_TYPE) ||
  1112. ((v0Type >= START_CEMENT_TYPE) && (v0Type <= END_CEMENT_TYPE))) ||
  1113. ((v1Type == BASE_CEMENT_TYPE) ||
  1114. ((v1Type >= START_CEMENT_TYPE) && (v1Type <= END_CEMENT_TYPE))) ||
  1115. ((v2Type == BASE_CEMENT_TYPE) ||
  1116. ((v2Type >= START_CEMENT_TYPE) && (v2Type <= END_CEMENT_TYPE))) ||
  1117. ((v3Type == BASE_CEMENT_TYPE) ||
  1118. ((v3Type >= START_CEMENT_TYPE) && (v3Type <= END_CEMENT_TYPE)))
  1119. )
  1120. textures[txmHandle].flags = MC2_TERRAIN_CEMENT_FLAG; //No ALPHA. Its a Solid cement texture.
  1121. else
  1122. textures[txmHandle].flags = 0;
  1123. return(txmHandle);
  1124. }
  1125. else
  1126. {
  1127. #ifdef USE_TRANSITIONS
  1128. //------------------------------
  1129. // Must create Transition here.
  1130. // BUT NOW we only create them for CEMENT!!
  1131. // New Terrain you know!!
  1132. long txmHandle = 0xffffffff;
  1133. if ( (overlayInfo != 0xffff) ||
  1134. ((v0Type == BASE_CEMENT_TYPE) ||
  1135. ((v0Type >= START_CEMENT_TYPE) && (v0Type <= END_CEMENT_TYPE))) ||
  1136. ((v1Type == BASE_CEMENT_TYPE) ||
  1137. ((v1Type >= START_CEMENT_TYPE) && (v1Type <= END_CEMENT_TYPE))) ||
  1138. ((v2Type == BASE_CEMENT_TYPE) ||
  1139. ((v2Type >= START_CEMENT_TYPE) && (v2Type <= END_CEMENT_TYPE))) ||
  1140. ((v3Type == BASE_CEMENT_TYPE) ||
  1141. ((v3Type >= START_CEMENT_TYPE) && (v3Type <= END_CEMENT_TYPE)))
  1142. )
  1143. {
  1144. txmHandle = createTransition(typeInfo,overlayInfo);
  1145. if (firstTransition == -1)
  1146. firstTransition = txmHandle;
  1147. textures[txmHandle].flags = MC2_TERRAIN_CEMENT_FLAG;
  1148. }
  1149. else
  1150. {
  1151. txmHandle = types[v0Type].baseTXMIndex;
  1152. textures[txmHandle].flags = 0;
  1153. }
  1154. //Complex here. If we are a cement texture and ANY other vxType was NOT cement, ALPHA is TRUE.
  1155. // If we are a road and ANY other vxType was NOT cement, ALPHA is TRUE,
  1156. // Otherwise, its false. Thus, simply mark it true for any non-solid cement!!
  1157. // We simply won't use anything that's not cement or road or runway, etc.
  1158. if ((textures[txmHandle].flags & MC2_TERRAIN_CEMENT_FLAG) == MC2_TERRAIN_CEMENT_FLAG)
  1159. {
  1160. if (
  1161. ((v0Type != BASE_CEMENT_TYPE) &&
  1162. (v0Type < START_CEMENT_TYPE) || (v0Type > END_CEMENT_TYPE))
  1163. )
  1164. textures[txmHandle].flags |= MC2_TERRAIN_ALPHA_FLAG;
  1165. if (
  1166. ((v1Type != BASE_CEMENT_TYPE) &&
  1167. (v1Type < START_CEMENT_TYPE) || (v1Type > END_CEMENT_TYPE))
  1168. )
  1169. textures[txmHandle].flags |= MC2_TERRAIN_ALPHA_FLAG;
  1170. if (
  1171. ((v2Type != BASE_CEMENT_TYPE) &&
  1172. (v2Type < START_CEMENT_TYPE) || (v2Type > END_CEMENT_TYPE))
  1173. )
  1174. textures[txmHandle].flags |= MC2_TERRAIN_ALPHA_FLAG;
  1175. if (
  1176. ((v3Type != BASE_CEMENT_TYPE) &&
  1177. (v3Type < START_CEMENT_TYPE) || (v3Type > END_CEMENT_TYPE))
  1178. )
  1179. textures[txmHandle].flags |= MC2_TERRAIN_ALPHA_FLAG;
  1180. }
  1181. #else
  1182. long txmHandle = types[v0Type].baseTXMIndex;
  1183. #endif
  1184. return(txmHandle);
  1185. }
  1186. }
  1187. //---------------------------------------------------------------------------
  1188. long TerrainTextures::setDetail (DWORD typeInfo, DWORD frameNum)
  1189. {
  1190. if (typeInfo < numDetails)
  1191. {
  1192. long txmHandle = details[typeInfo].baseTXMIndex + (frameNum * MC_MAX_MIP_LEVELS );
  1193. return(txmHandle);
  1194. }
  1195. return 0xffffffff;
  1196. }
  1197. //---------------------------------------------------------------------------
  1198. void TerrainTextures::update (void)
  1199. {
  1200. if (tileRAMHeap)
  1201. {
  1202. //We can now safely purge all transitions cause the MC2 texture manager has them all!!
  1203. numTypes = 0;
  1204. types = NULL;
  1205. numOverlays = 0;
  1206. overlays = NULL;
  1207. numTransitions = 0;
  1208. transitions = NULL;
  1209. nextTransition = 0;
  1210. for (long i=0;i<numDetails;i++)
  1211. {
  1212. details[i].detailName = NULL;
  1213. details[i].detailData = NULL;
  1214. }
  1215. if (listTransitionFile)
  1216. {
  1217. listTransitionFile->close();
  1218. delete listTransitionFile;
  1219. listTransitionFile = NULL;
  1220. }
  1221. localBaseName = NULL;
  1222. delete tileRAMHeap;
  1223. tileRAMHeap = NULL;
  1224. }
  1225. }
  1226. //---------------------------------------------------------------------------
  1227. void TerrainTextures::destroy (void)
  1228. {
  1229. update();
  1230. delete tileHeap;
  1231. tileHeap = NULL;
  1232. }
  1233. //---------------------------------------------------------------------------
  1234. //
  1235. // Edit Log
  1236. //
  1237. //---------------------------------------------------------------------------