mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@21 3b4a5df2-a311-0410-b5c6-a8a6f20db521
381 lines
8.4 KiB
C++
381 lines
8.4 KiB
C++
#ifdef PRECOMPILEDHEADERS
|
|
#include "TileEngine All.h"
|
|
#else
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "wcheck.h"
|
|
#include "stdlib.h"
|
|
#include "debug.h"
|
|
#include "tiledef.h"
|
|
#include "Animation Cache.h"
|
|
#include "Animation Data.h"
|
|
#include "Animation Control.h"
|
|
#include "sys globals.h"
|
|
#include "Debug Control.h"
|
|
#include "tile surface.h"
|
|
#include "tile cache.h"
|
|
#include "fileman.h"
|
|
#endif
|
|
|
|
|
|
UINT32 guiNumTileCacheStructs = 0;
|
|
UINT32 guiMaxTileCacheSize = 50;
|
|
UINT32 guiCurTileCacheSize = 0;
|
|
INT32 giDefaultStructIndex = -1;
|
|
|
|
TILE_CACHE_ELEMENT *gpTileCache = NULL;
|
|
TILE_CACHE_STRUCT *gpTileCacheStructInfo = NULL;
|
|
|
|
|
|
|
|
BOOLEAN InitTileCache( )
|
|
{
|
|
UINT32 cnt;
|
|
GETFILESTRUCT FileInfo;
|
|
INT16 sFiles = 0;
|
|
|
|
gpTileCache = (TILE_CACHE_ELEMENT *)MemAlloc( sizeof( TILE_CACHE_ELEMENT ) * guiMaxTileCacheSize );
|
|
|
|
// Zero entries
|
|
for ( cnt = 0; cnt < guiMaxTileCacheSize; cnt++ )
|
|
{
|
|
gpTileCache[ cnt ].pImagery = NULL;
|
|
gpTileCache[ cnt ].sStructRefID = -1;
|
|
}
|
|
|
|
guiCurTileCacheSize = 0;
|
|
|
|
|
|
// OK, look for JSD files in the tile cache directory and
|
|
// load any we find....
|
|
if( GetFileFirst("TILECACHE\\*.jsd", &FileInfo) )
|
|
{
|
|
while( GetFileNext(&FileInfo) )
|
|
{
|
|
sFiles++;
|
|
}
|
|
GetFileClose(&FileInfo);
|
|
}
|
|
|
|
// Allocate memory...
|
|
if ( sFiles > 0 )
|
|
{
|
|
cnt = 0;
|
|
|
|
guiNumTileCacheStructs = sFiles;
|
|
|
|
gpTileCacheStructInfo = (TILE_CACHE_STRUCT *)MemAlloc( sizeof( TILE_CACHE_STRUCT ) * sFiles );
|
|
|
|
// Loop through and set filenames
|
|
if( GetFileFirst("TILECACHE\\*.jsd", &FileInfo) )
|
|
{
|
|
while( GetFileNext(&FileInfo) )
|
|
{
|
|
sprintf( gpTileCacheStructInfo[ cnt ].Filename, "TILECACHE\\%s", FileInfo.zFileName );
|
|
|
|
// Get root name
|
|
GetRootName( (INT8 *)gpTileCacheStructInfo[ cnt ].zRootName, (INT8 *)gpTileCacheStructInfo[ cnt ].Filename );
|
|
|
|
// Load struc data....
|
|
gpTileCacheStructInfo[ cnt ].pStructureFileRef = LoadStructureFile( gpTileCacheStructInfo[ cnt ].Filename );
|
|
|
|
#ifdef JA2TESTVERSION
|
|
if ( gpTileCacheStructInfo[ cnt ].pStructureFileRef == NULL )
|
|
{
|
|
SET_ERROR( "Cannot load tilecache JSD: %s", gpTileCacheStructInfo[ cnt ].Filename );
|
|
}
|
|
#endif
|
|
if ( stricmp( gpTileCacheStructInfo[ cnt ].zRootName, "l_dead1" ) == 0 )
|
|
{
|
|
giDefaultStructIndex = cnt;
|
|
}
|
|
|
|
cnt++;
|
|
}
|
|
GetFileClose(&FileInfo);
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
void DeleteTileCache( )
|
|
{
|
|
UINT32 cnt;
|
|
|
|
// Allocate entries
|
|
if ( gpTileCache != NULL )
|
|
{
|
|
// Loop through and delete any entries
|
|
for ( cnt = 0; cnt < guiMaxTileCacheSize; cnt++ )
|
|
{
|
|
if ( gpTileCache[ cnt ].pImagery != NULL )
|
|
{
|
|
DeleteTileSurface( gpTileCache[ cnt ].pImagery );
|
|
}
|
|
}
|
|
MemFree( gpTileCache );
|
|
}
|
|
|
|
if ( gpTileCacheStructInfo != NULL )
|
|
{
|
|
MemFree( gpTileCacheStructInfo );
|
|
}
|
|
|
|
guiCurTileCacheSize = 0;
|
|
}
|
|
|
|
INT16 FindCacheStructDataIndex( INT8 * cFilename )
|
|
{
|
|
UINT32 cnt;
|
|
|
|
for ( cnt = 0; cnt < guiNumTileCacheStructs; cnt++ )
|
|
{
|
|
if ( _stricmp( gpTileCacheStructInfo[ cnt ].zRootName, cFilename ) == 0 )
|
|
{
|
|
return( (INT16)cnt );
|
|
}
|
|
}
|
|
|
|
return( -1 );
|
|
}
|
|
|
|
INT32 GetCachedTile( INT8 * cFilename )
|
|
{
|
|
UINT32 cnt;
|
|
UINT32 ubLowestIndex = 0;
|
|
INT16 sMostHits = (INT16)15000;
|
|
|
|
// Check to see if surface exists already
|
|
for ( cnt = 0; cnt < guiCurTileCacheSize; cnt++ )
|
|
{
|
|
if ( gpTileCache[ cnt ].pImagery != NULL )
|
|
{
|
|
if ( _stricmp( gpTileCache[ cnt ].zName, cFilename ) == 0 )
|
|
{
|
|
// Found surface, return
|
|
gpTileCache[ cnt ].sHits++;
|
|
return( (INT32)cnt );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if max size has been reached
|
|
if ( guiCurTileCacheSize == guiMaxTileCacheSize )
|
|
{
|
|
// cache out least used file
|
|
for ( cnt = 0; cnt < guiCurTileCacheSize; cnt++ )
|
|
{
|
|
if ( gpTileCache[ cnt ].sHits < sMostHits )
|
|
{
|
|
sMostHits = gpTileCache[ cnt ].sHits;
|
|
ubLowestIndex = cnt;
|
|
}
|
|
}
|
|
|
|
// Bump off lowest index
|
|
DeleteTileSurface( gpTileCache[ ubLowestIndex ].pImagery );
|
|
|
|
// Decrement
|
|
gpTileCache[ ubLowestIndex ].sHits = 0;
|
|
gpTileCache[ ubLowestIndex ].pImagery = NULL;
|
|
gpTileCache[ ubLowestIndex ].sStructRefID = -1;
|
|
}
|
|
|
|
// If here, Insert at an empty slot
|
|
// Find an empty slot
|
|
for ( cnt = 0; cnt < guiMaxTileCacheSize; cnt++ )
|
|
{
|
|
if ( gpTileCache[ cnt ].pImagery == NULL )
|
|
{
|
|
// Insert here
|
|
gpTileCache[ cnt ].pImagery = LoadTileSurface( (char *)cFilename );
|
|
|
|
if ( gpTileCache[ cnt ].pImagery == NULL )
|
|
{
|
|
return( -1 );
|
|
}
|
|
|
|
strcpy( gpTileCache[ cnt ].zName, cFilename );
|
|
gpTileCache[ cnt ].sHits = 1;
|
|
|
|
// Get root name
|
|
GetRootName( (INT8 *)gpTileCache[ cnt ].zRootName, cFilename );
|
|
|
|
gpTileCache[ cnt ].sStructRefID = FindCacheStructDataIndex( (INT8 *)gpTileCache[ cnt ].zRootName );
|
|
|
|
// ATE: Add z-strip info
|
|
if ( gpTileCache[ cnt ].sStructRefID != -1 )
|
|
{
|
|
AddZStripInfoToVObject( gpTileCache[ cnt ].pImagery->vo, gpTileCacheStructInfo[ gpTileCache[ cnt ].sStructRefID ].pStructureFileRef, TRUE, 0 );
|
|
}
|
|
|
|
if ( gpTileCache[ cnt ].pImagery->pAuxData != NULL )
|
|
{
|
|
gpTileCache[ cnt ].ubNumFrames = gpTileCache[ cnt ].pImagery-> pAuxData->ubNumberOfFrames;
|
|
}
|
|
else
|
|
{
|
|
gpTileCache[ cnt ].ubNumFrames = 1;
|
|
}
|
|
|
|
// Has our cache size increased?
|
|
if ( cnt >= guiCurTileCacheSize )
|
|
{
|
|
guiCurTileCacheSize = cnt + 1;;
|
|
}
|
|
|
|
return( cnt );
|
|
}
|
|
}
|
|
|
|
// Can't find one!
|
|
return( -1 );
|
|
}
|
|
|
|
|
|
BOOLEAN RemoveCachedTile( INT32 iCachedTile )
|
|
{
|
|
UINT32 cnt;
|
|
|
|
// Find tile
|
|
for ( cnt = 0; cnt < guiCurTileCacheSize; cnt++ )
|
|
{
|
|
if ( gpTileCache[ cnt ].pImagery != NULL )
|
|
{
|
|
if ( cnt == (UINT32)iCachedTile )
|
|
{
|
|
// Found surface, decrement hits
|
|
gpTileCache[ cnt ].sHits--;
|
|
|
|
// Are we at zero?
|
|
if ( gpTileCache[ cnt ].sHits == 0 )
|
|
{
|
|
DeleteTileSurface( gpTileCache[ cnt ].pImagery );
|
|
gpTileCache[ cnt ].pImagery = NULL;
|
|
gpTileCache[ cnt ].sStructRefID = -1;
|
|
return( TRUE );;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
HVOBJECT GetCachedTileVideoObject( INT32 iIndex )
|
|
{
|
|
if ( iIndex == -1 )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
if ( gpTileCache[ iIndex ].pImagery == NULL )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
return( gpTileCache[ iIndex ].pImagery->vo );
|
|
}
|
|
|
|
|
|
STRUCTURE_FILE_REF *GetCachedTileStructureRef( INT32 iIndex )
|
|
{
|
|
if ( iIndex == -1 )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
if ( gpTileCache[ iIndex ].sStructRefID == -1 )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
return( gpTileCacheStructInfo[ gpTileCache[ iIndex ].sStructRefID ].pStructureFileRef );
|
|
}
|
|
|
|
|
|
STRUCTURE_FILE_REF *GetCachedTileStructureRefFromFilename( INT8 *cFilename )
|
|
{
|
|
INT16 sStructDataIndex;
|
|
|
|
// Given filename, look for index
|
|
sStructDataIndex = FindCacheStructDataIndex( cFilename );
|
|
|
|
if ( sStructDataIndex == -1 )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
return( gpTileCacheStructInfo[ sStructDataIndex ].pStructureFileRef );
|
|
}
|
|
|
|
|
|
void CheckForAndAddTileCacheStructInfo( LEVELNODE *pNode, INT16 sGridNo, UINT16 usIndex, UINT16 usSubIndex )
|
|
{
|
|
STRUCTURE_FILE_REF *pStructureFileRef;
|
|
|
|
pStructureFileRef = GetCachedTileStructureRef( usIndex );
|
|
|
|
if ( pStructureFileRef != NULL)
|
|
{
|
|
if ( !AddStructureToWorld( sGridNo, 0, &( pStructureFileRef->pDBStructureRef[ usSubIndex ] ), pNode ) )
|
|
{
|
|
if ( giDefaultStructIndex != -1 )
|
|
{
|
|
pStructureFileRef = gpTileCacheStructInfo[ giDefaultStructIndex ].pStructureFileRef;
|
|
|
|
if ( pStructureFileRef != NULL)
|
|
{
|
|
AddStructureToWorld( sGridNo, 0, &( pStructureFileRef->pDBStructureRef[ usSubIndex ] ), pNode );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CheckForAndDeleteTileCacheStructInfo( LEVELNODE *pNode, UINT16 usIndex )
|
|
{
|
|
STRUCTURE_FILE_REF *pStructureFileRef;
|
|
|
|
if ( usIndex >= TILE_CACHE_START_INDEX )
|
|
{
|
|
pStructureFileRef = GetCachedTileStructureRef( ( usIndex - TILE_CACHE_START_INDEX ) );
|
|
|
|
if ( pStructureFileRef != NULL)
|
|
{
|
|
DeleteStructureFromWorld( pNode->pStructureData );
|
|
}
|
|
}
|
|
}
|
|
|
|
void GetRootName( INT8 * pDestStr, INT8 * pSrcStr )
|
|
{
|
|
// Remove path and extension
|
|
INT8 cTempFilename[ 120 ];
|
|
STR cEndOfName;
|
|
|
|
// Remove path
|
|
strcpy( cTempFilename, pSrcStr );
|
|
cEndOfName = strrchr( cTempFilename, '\\' );
|
|
if (cEndOfName != NULL)
|
|
{
|
|
cEndOfName++;
|
|
strcpy( pDestStr, cEndOfName );
|
|
}
|
|
else
|
|
{
|
|
strcpy( pDestStr, cTempFilename );
|
|
}
|
|
|
|
// Now remove extension...
|
|
cEndOfName = strchr( (const char *)pDestStr, '.' );
|
|
if (cEndOfName != NULL)
|
|
{
|
|
*cEndOfName = '\0';
|
|
}
|
|
|
|
}
|
|
|