Tile Cache.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. #ifdef PRECOMPILEDHEADERS
  2. #include "TileEngine All.h"
  3. #else
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include "wcheck.h"
  7. #include "stdlib.h"
  8. #include "debug.h"
  9. #include "tiledef.h"
  10. #include "Animation Cache.h"
  11. #include "Animation Data.h"
  12. #include "Animation Control.h"
  13. #include "sys globals.h"
  14. #include "Debug Control.h"
  15. #include "tile surface.h"
  16. #include "tile cache.h"
  17. #include "fileman.h"
  18. #endif
  19. UINT32 guiNumTileCacheStructs = 0;
  20. UINT32 guiMaxTileCacheSize = 50;
  21. UINT32 guiCurTileCacheSize = 0;
  22. INT32 giDefaultStructIndex = -1;
  23. TILE_CACHE_ELEMENT *gpTileCache = NULL;
  24. TILE_CACHE_STRUCT *gpTileCacheStructInfo = NULL;
  25. BOOLEAN InitTileCache( )
  26. {
  27. UINT32 cnt;
  28. GETFILESTRUCT FileInfo;
  29. INT16 sFiles = 0;
  30. gpTileCache = MemAlloc( sizeof( TILE_CACHE_ELEMENT ) * guiMaxTileCacheSize );
  31. // Zero entries
  32. for ( cnt = 0; cnt < guiMaxTileCacheSize; cnt++ )
  33. {
  34. gpTileCache[ cnt ].pImagery = NULL;
  35. gpTileCache[ cnt ].sStructRefID = -1;
  36. }
  37. guiCurTileCacheSize = 0;
  38. // OK, look for JSD files in the tile cache directory and
  39. // load any we find....
  40. if( GetFileFirst("TILECACHE\\*.jsd", &FileInfo) )
  41. {
  42. while( GetFileNext(&FileInfo) )
  43. {
  44. sFiles++;
  45. }
  46. GetFileClose(&FileInfo);
  47. }
  48. // Allocate memory...
  49. if ( sFiles > 0 )
  50. {
  51. cnt = 0;
  52. guiNumTileCacheStructs = sFiles;
  53. gpTileCacheStructInfo = MemAlloc( sizeof( TILE_CACHE_STRUCT ) * sFiles );
  54. // Loop through and set filenames
  55. if( GetFileFirst("TILECACHE\\*.jsd", &FileInfo) )
  56. {
  57. while( GetFileNext(&FileInfo) )
  58. {
  59. sprintf( gpTileCacheStructInfo[ cnt ].Filename, "TILECACHE\\%s", FileInfo.zFileName );
  60. // Get root name
  61. GetRootName( gpTileCacheStructInfo[ cnt ].zRootName, gpTileCacheStructInfo[ cnt ].Filename );
  62. // Load struc data....
  63. gpTileCacheStructInfo[ cnt ].pStructureFileRef = LoadStructureFile( gpTileCacheStructInfo[ cnt ].Filename );
  64. #ifdef JA2TESTVERSION
  65. if ( gpTileCacheStructInfo[ cnt ].pStructureFileRef == NULL )
  66. {
  67. SET_ERROR( "Cannot load tilecache JSD: %s", gpTileCacheStructInfo[ cnt ].Filename );
  68. }
  69. #endif
  70. if ( stricmp( gpTileCacheStructInfo[ cnt ].zRootName, "l_dead1" ) == 0 )
  71. {
  72. giDefaultStructIndex = cnt;
  73. }
  74. cnt++;
  75. }
  76. GetFileClose(&FileInfo);
  77. }
  78. }
  79. return( TRUE );
  80. }
  81. void DeleteTileCache( )
  82. {
  83. UINT32 cnt;
  84. // Allocate entries
  85. if ( gpTileCache != NULL )
  86. {
  87. // Loop through and delete any entries
  88. for ( cnt = 0; cnt < guiMaxTileCacheSize; cnt++ )
  89. {
  90. if ( gpTileCache[ cnt ].pImagery != NULL )
  91. {
  92. DeleteTileSurface( gpTileCache[ cnt ].pImagery );
  93. }
  94. }
  95. MemFree( gpTileCache );
  96. }
  97. if ( gpTileCacheStructInfo != NULL )
  98. {
  99. MemFree( gpTileCacheStructInfo );
  100. }
  101. guiCurTileCacheSize = 0;
  102. }
  103. INT16 FindCacheStructDataIndex( INT8 *cFilename )
  104. {
  105. UINT32 cnt;
  106. for ( cnt = 0; cnt < guiNumTileCacheStructs; cnt++ )
  107. {
  108. if ( _stricmp( gpTileCacheStructInfo[ cnt ].zRootName, cFilename ) == 0 )
  109. {
  110. return( (INT16)cnt );
  111. }
  112. }
  113. return( -1 );
  114. }
  115. INT32 GetCachedTile( INT8 *cFilename )
  116. {
  117. UINT32 cnt;
  118. UINT32 ubLowestIndex = 0;
  119. INT16 sMostHits = (INT16)15000;
  120. // Check to see if surface exists already
  121. for ( cnt = 0; cnt < guiCurTileCacheSize; cnt++ )
  122. {
  123. if ( gpTileCache[ cnt ].pImagery != NULL )
  124. {
  125. if ( _stricmp( gpTileCache[ cnt ].zName, cFilename ) == 0 )
  126. {
  127. // Found surface, return
  128. gpTileCache[ cnt ].sHits++;
  129. return( (INT32)cnt );
  130. }
  131. }
  132. }
  133. // Check if max size has been reached
  134. if ( guiCurTileCacheSize == guiMaxTileCacheSize )
  135. {
  136. // cache out least used file
  137. for ( cnt = 0; cnt < guiCurTileCacheSize; cnt++ )
  138. {
  139. if ( gpTileCache[ cnt ].sHits < sMostHits )
  140. {
  141. sMostHits = gpTileCache[ cnt ].sHits;
  142. ubLowestIndex = cnt;
  143. }
  144. }
  145. // Bump off lowest index
  146. DeleteTileSurface( gpTileCache[ ubLowestIndex ].pImagery );
  147. // Decrement
  148. gpTileCache[ ubLowestIndex ].sHits = 0;
  149. gpTileCache[ ubLowestIndex ].pImagery = NULL;
  150. gpTileCache[ ubLowestIndex ].sStructRefID = -1;
  151. }
  152. // If here, Insert at an empty slot
  153. // Find an empty slot
  154. for ( cnt = 0; cnt < guiMaxTileCacheSize; cnt++ )
  155. {
  156. if ( gpTileCache[ cnt ].pImagery == NULL )
  157. {
  158. // Insert here
  159. gpTileCache[ cnt ].pImagery = LoadTileSurface( cFilename );
  160. if ( gpTileCache[ cnt ].pImagery == NULL )
  161. {
  162. return( -1 );
  163. }
  164. strcpy( gpTileCache[ cnt ].zName, cFilename );
  165. gpTileCache[ cnt ].sHits = 1;
  166. // Get root name
  167. GetRootName( gpTileCache[ cnt ].zRootName, cFilename );
  168. gpTileCache[ cnt ].sStructRefID = FindCacheStructDataIndex( gpTileCache[ cnt ].zRootName );
  169. // ATE: Add z-strip info
  170. if ( gpTileCache[ cnt ].sStructRefID != -1 )
  171. {
  172. AddZStripInfoToVObject( gpTileCache[ cnt ].pImagery->vo, gpTileCacheStructInfo[ gpTileCache[ cnt ].sStructRefID ].pStructureFileRef, TRUE, 0 );
  173. }
  174. if ( gpTileCache[ cnt ].pImagery->pAuxData != NULL )
  175. {
  176. gpTileCache[ cnt ].ubNumFrames = gpTileCache[ cnt ].pImagery-> pAuxData->ubNumberOfFrames;
  177. }
  178. else
  179. {
  180. gpTileCache[ cnt ].ubNumFrames = 1;
  181. }
  182. // Has our cache size increased?
  183. if ( cnt >= guiCurTileCacheSize )
  184. {
  185. guiCurTileCacheSize = cnt + 1;;
  186. }
  187. return( cnt );
  188. }
  189. }
  190. // Can't find one!
  191. return( -1 );
  192. }
  193. BOOLEAN RemoveCachedTile( INT32 iCachedTile )
  194. {
  195. UINT32 cnt;
  196. // Find tile
  197. for ( cnt = 0; cnt < guiCurTileCacheSize; cnt++ )
  198. {
  199. if ( gpTileCache[ cnt ].pImagery != NULL )
  200. {
  201. if ( cnt == (UINT32)iCachedTile )
  202. {
  203. // Found surface, decrement hits
  204. gpTileCache[ cnt ].sHits--;
  205. // Are we at zero?
  206. if ( gpTileCache[ cnt ].sHits == 0 )
  207. {
  208. DeleteTileSurface( gpTileCache[ cnt ].pImagery );
  209. gpTileCache[ cnt ].pImagery = NULL;
  210. gpTileCache[ cnt ].sStructRefID = -1;
  211. return( TRUE );;
  212. }
  213. }
  214. }
  215. }
  216. return( FALSE );
  217. }
  218. HVOBJECT GetCachedTileVideoObject( INT32 iIndex )
  219. {
  220. if ( iIndex == -1 )
  221. {
  222. return( NULL );
  223. }
  224. if ( gpTileCache[ iIndex ].pImagery == NULL )
  225. {
  226. return( NULL );
  227. }
  228. return( gpTileCache[ iIndex ].pImagery->vo );
  229. }
  230. STRUCTURE_FILE_REF *GetCachedTileStructureRef( INT32 iIndex )
  231. {
  232. if ( iIndex == -1 )
  233. {
  234. return( NULL );
  235. }
  236. if ( gpTileCache[ iIndex ].sStructRefID == -1 )
  237. {
  238. return( NULL );
  239. }
  240. return( gpTileCacheStructInfo[ gpTileCache[ iIndex ].sStructRefID ].pStructureFileRef );
  241. }
  242. STRUCTURE_FILE_REF *GetCachedTileStructureRefFromFilename( INT8 *cFilename )
  243. {
  244. INT16 sStructDataIndex;
  245. // Given filename, look for index
  246. sStructDataIndex = FindCacheStructDataIndex( cFilename );
  247. if ( sStructDataIndex == -1 )
  248. {
  249. return( NULL );
  250. }
  251. return( gpTileCacheStructInfo[ sStructDataIndex ].pStructureFileRef );
  252. }
  253. void CheckForAndAddTileCacheStructInfo( LEVELNODE *pNode, INT16 sGridNo, UINT16 usIndex, UINT16 usSubIndex )
  254. {
  255. STRUCTURE_FILE_REF *pStructureFileRef;
  256. pStructureFileRef = GetCachedTileStructureRef( usIndex );
  257. if ( pStructureFileRef != NULL)
  258. {
  259. if ( !AddStructureToWorld( sGridNo, 0, &( pStructureFileRef->pDBStructureRef[ usSubIndex ] ), pNode ) )
  260. {
  261. if ( giDefaultStructIndex != -1 )
  262. {
  263. pStructureFileRef = gpTileCacheStructInfo[ giDefaultStructIndex ].pStructureFileRef;
  264. if ( pStructureFileRef != NULL)
  265. {
  266. AddStructureToWorld( sGridNo, 0, &( pStructureFileRef->pDBStructureRef[ usSubIndex ] ), pNode );
  267. }
  268. }
  269. }
  270. }
  271. }
  272. void CheckForAndDeleteTileCacheStructInfo( LEVELNODE *pNode, UINT16 usIndex )
  273. {
  274. STRUCTURE_FILE_REF *pStructureFileRef;
  275. if ( usIndex >= TILE_CACHE_START_INDEX )
  276. {
  277. pStructureFileRef = GetCachedTileStructureRef( ( usIndex - TILE_CACHE_START_INDEX ) );
  278. if ( pStructureFileRef != NULL)
  279. {
  280. DeleteStructureFromWorld( pNode->pStructureData );
  281. }
  282. }
  283. }
  284. void GetRootName( INT8 *pDestStr, INT8 *pSrcStr )
  285. {
  286. // Remove path and extension
  287. INT8 cTempFilename[ 120 ];
  288. STR cEndOfName;
  289. // Remove path
  290. strcpy( cTempFilename, pSrcStr );
  291. cEndOfName = strrchr( cTempFilename, '\\' );
  292. if (cEndOfName != NULL)
  293. {
  294. cEndOfName++;
  295. strcpy( pDestStr, cEndOfName );
  296. }
  297. else
  298. {
  299. strcpy( pDestStr, cTempFilename );
  300. }
  301. // Now remove extension...
  302. cEndOfName = strchr( pDestStr, '.' );
  303. if (cEndOfName != NULL)
  304. {
  305. *cEndOfName = '\0';
  306. }
  307. }