Added map-specific closed captioning files

This commit is contained in:
Blixibon 2021-07-24 01:52:38 -05:00
parent 4957311523
commit 3656ea3082
3 changed files with 166 additions and 36 deletions

View File

@ -2630,6 +2630,124 @@ void CHudCloseCaption::InitCaptionDictionary( const char *dbfile )
g_AsyncCaptionResourceManager.SetDbInfo( m_AsyncCaptions );
}
#ifdef MAPBASE
void CHudCloseCaption::AddAdditionalCaptionDictionary( const char *dbfile, CUtlVector<CUtlSymbol> &outPathSymbols )
{
CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Adding additional caption dictionary \"%s\"\n", dbfile );
g_AsyncCaptionResourceManager.Clear();
char searchPaths[4096];
filesystem->GetSearchPath( "MOD", true, searchPaths, sizeof( searchPaths ) );
for ( char *path = strtok( searchPaths, ";" ); path; path = strtok( NULL, ";" ) )
{
if ( IsX360() && ( filesystem->GetDVDMode() == DVDMODE_STRICT ) && !V_stristr( path, ".zip" ) )
{
// only want zip paths
continue;
}
char fullpath[MAX_PATH];
Q_snprintf( fullpath, sizeof( fullpath ), "%s%s", path, dbfile );
Q_FixSlashes( fullpath );
if ( IsX360() )
{
char fullpath360[MAX_PATH];
UpdateOrCreateCaptionFile( fullpath, fullpath360, sizeof( fullpath360 ) );
Q_strncpy( fullpath, fullpath360, sizeof( fullpath ) );
}
// Seach for this dictionary. If it already exists, remove it.
for (int i = 0; i < m_AsyncCaptions.Count(); ++i)
{
if (FStrEq( m_AsyncCaptions[i].m_DataBaseFile.String(), fullpath ))
{
m_AsyncCaptions.Remove( i );
break;
}
}
FileHandle_t fh = filesystem->Open( fullpath, "rb" );
if ( FILESYSTEM_INVALID_HANDLE != fh )
{
MEM_ALLOC_CREDIT();
CUtlBuffer dirbuffer;
AsyncCaption_t& entry = m_AsyncCaptions[ m_AsyncCaptions.AddToTail() ];
// Read the header
filesystem->Read( &entry.m_Header, sizeof( entry.m_Header ), fh );
if ( entry.m_Header.magic != COMPILED_CAPTION_FILEID )
Error( "Invalid file id for %s\n", fullpath );
if ( entry.m_Header.version != COMPILED_CAPTION_VERSION )
Error( "Invalid file version for %s\n", fullpath );
if ( entry.m_Header.directorysize < 0 || entry.m_Header.directorysize > 64 * 1024 )
Error( "Invalid directory size %d for %s\n", entry.m_Header.directorysize, fullpath );
//if ( entry.m_Header.blocksize != MAX_BLOCK_SIZE )
// Error( "Invalid block size %d, expecting %d for %s\n", entry.m_Header.blocksize, MAX_BLOCK_SIZE, fullpath );
int directoryBytes = entry.m_Header.directorysize * sizeof( CaptionLookup_t );
entry.m_CaptionDirectory.EnsureCapacity( entry.m_Header.directorysize );
dirbuffer.EnsureCapacity( directoryBytes );
filesystem->Read( dirbuffer.Base(), directoryBytes, fh );
filesystem->Close( fh );
entry.m_CaptionDirectory.CopyArray( (const CaptionLookup_t *)dirbuffer.PeekGet(), entry.m_Header.directorysize );
entry.m_CaptionDirectory.RedoSort( true );
entry.m_DataBaseFile = fullpath;
outPathSymbols.AddToTail( entry.m_DataBaseFile );
}
}
g_AsyncCaptionResourceManager.SetDbInfo( m_AsyncCaptions );
}
void CHudCloseCaption::AddCustomCaptionFile( char const *file, CUtlVector<CUtlSymbol> &outPathSymbols )
{
//
// 'file' should be something like "maps/mapbase_demo01_closecaption_%language%"
//
CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Adding custom caption file \"%s\"\n", file );
if (!IsX360())
{
g_pVGuiLocalize->AddFile( file, "MOD", true );
}
char uilanguage[64];
engine->GetUILanguage( uilanguage, sizeof( uilanguage ) );
char dbfile[512];
V_StrSubst( file, "%language%", uilanguage, dbfile, sizeof( dbfile ) );
V_SetExtension( dbfile, ".dat", sizeof( dbfile ) );
AddAdditionalCaptionDictionary( dbfile, outPathSymbols );
}
void CHudCloseCaption::RemoveCaptionDictionary( const CUtlSymbol &dbFileSymbol )
{
//
// 'file' should be something like "maps/mapbase_demo01_closecaption_%language%"
//
CGMsg( 1, CON_GROUP_MAPBASE_MISC, "Removing custom caption file \"%s\"\n", dbFileSymbol.String() );
for (int i = 0; i < m_AsyncCaptions.Count(); ++i)
{
if ( m_AsyncCaptions[i].m_DataBaseFile == dbFileSymbol )
{
m_AsyncCaptions.Remove( i );
break;
}
}
}
#endif
void CHudCloseCaption::OnFinishAsyncLoad( int nFileIndex, int nBlockNum, AsyncCaptionData_t *pData )
{
// Fill in data for all users of pData->m_nBlockNum

View File

@ -111,6 +111,11 @@ public:
void PlayRandomCaption();
void InitCaptionDictionary( char const *dbfile );
#ifdef MAPBASE
void AddAdditionalCaptionDictionary( char const *dbfile, CUtlVector<CUtlSymbol> &outPathSymbols );
void AddCustomCaptionFile( char const *file, CUtlVector<CUtlSymbol> &outPathSymbols );
void RemoveCaptionDictionary( const CUtlSymbol &dbFileSymbol );
#endif
void OnFinishAsyncLoad( int nFileIndex, int nBlockNum, AsyncCaptionData_t *pData );
void Flush();

View File

@ -47,27 +47,12 @@ extern ISoundEmitterSystemBase *soundemitterbase;
ConVar mapbase_load_default_manifest("mapbase_load_default_manifest", "1", FCVAR_ARCHIVE, "Should we automatically load our default manifest file? (\"maps/%mapname%_manifest.txt\")");
ConVar mapbase_load_soundscripts("mapbase_load_soundscripts", "1", FCVAR_ARCHIVE, "Should we load map-specific soundscripts? e.g. \"maps/mapname_level_sounds.txt\"");
//ConVar mapbase_load_propdata("mapbase_load_propdata", "1", FCVAR_ARCHIVE, "Should we load map-specific propdata files? e.g. \"maps/mapname_propdata.txt\"");
//ConVar mapbase_load_soundscapes("mapbase_load_soundscapes", "1", FCVAR_ARCHIVE, "Should we load map-specific soundscapes? e.g. \"maps/mapname_soundscapes.txt\"");
ConVar mapbase_load_localization( "mapbase_load_localization", "1", FCVAR_ARCHIVE, "Should we load map-specific localized text files? e.g. \"maps/mapname_english.txt\"" );
ConVar mapbase_load_surfaceprops( "mapbase_load_surfaceprops", "1", FCVAR_ARCHIVE, "Should we load map-specific surfaceproperties files? e.g. \"maps/mapname_surfaceproperties.txt\"" );
#ifdef GAME_DLL
// This constant should change with each Mapbase update
ConVar mapbase_version( "mapbase_version", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's server.dll" );
ConVar mapbase_load_sentences("mapbase_load_sentences", "1", FCVAR_ARCHIVE, "Should we load map-specific sentences? e.g. \"maps/mapname_sentences.txt\"");
ConVar mapbase_load_talker("mapbase_load_talker", "1", FCVAR_ARCHIVE, "Should we load map-specific talker files? e.g. \"maps/mapname_talker.txt\"");
ConVar mapbase_flush_talker("mapbase_flush_talker", "1", FCVAR_NONE, "Normally, when a map with custom talker files is unloaded, the response system resets to rid itself of the custom file(s). Turn this convar off to prevent that from happening.");
ConVar mapbase_load_actbusy("mapbase_load_actbusy", "1", FCVAR_ARCHIVE, "Should we load map-specific actbusy files? e.g. \"maps/mapname_actbusy.txt\"");
extern void MapbaseGameLog_Init();
extern void ParseCustomActbusyFile(const char *file);
@ -81,8 +66,6 @@ static bool g_bMapContainsCustomTalker;
// This constant should change with each Mapbase update
ConVar mapbase_version_client( "mapbase_version_client", MAPBASE_VERSION, FCVAR_NONE, "The version of Mapbase currently being used in this mod's client.dll" );
//ConVar mapbase_load_cc("mapbase_load_cc", "1", FCVAR_ARCHIVE, "Should we load map-specific closed captioning? e.g. \"maps/mapname_closecaption_english.txt\" and \"maps/mapname_closecaption_english.dat\"");
#endif
extern void AddSurfacepropFile( const char *pFileName, IPhysicsSurfaceProps *pProps, IFileSystem *pFileSystem );
@ -101,11 +84,11 @@ enum
MANIFEST_LOCALIZATION,
MANIFEST_SURFACEPROPS,
#ifdef CLIENT_DLL
//MANIFEST_CLOSECAPTION,
MANIFEST_CLOSECAPTION,
MANIFEST_VGUI,
#else
MANIFEST_TALKER,
MANIFEST_SENTENCES,
//MANIFEST_SENTENCES,
MANIFEST_ACTBUSY,
#endif
@ -115,25 +98,32 @@ enum
struct ManifestType_t
{
ManifestType_t( const char *_string, const char *cvarname, const char *cvardesc ) : cvar( cvarname, "1", FCVAR_ARCHIVE, cvardesc )
{
string = _string;
}
//int type;
const char *string;
ConVar *cvar;
ConVar cvar;
};
#define DECLARE_MANIFEST_TYPE(name, cvar, desc) { #name, ConVar(#cvar, "1", FCVAR_ARCHIVE, #desc) }
// KEEP THS IN SYNC WITH THE ENUM!
static const ManifestType_t gm_szManifestFileStrings[MANIFEST_NUM_TYPES] = {
{ "soundscripts", &mapbase_load_soundscripts },
//{ "propdata", &mapbase_load_propdata },
//{ "soundscapes", &mapbase_load_soundscapes },
{ "localization", &mapbase_load_localization },
{ "surfaceprops", &mapbase_load_surfaceprops },
{ "soundscripts", "mapbase_load_soundscripts", "Should we load map-specific soundscripts? e.g. \"maps/<mapname>_level_sounds.txt\"" },
//{ "propdata", "mapbase_load_propdata", "Should we load map-specific soundscripts? e.g. \"maps/<mapname>_level_sounds.txt\"" },
//{ "soundscapes", "mapbase_load_soundscapes", "Should we load map-specific soundscapes? e.g. \"maps/<mapname>_soundscapes.txt\"" },
{ "localization", "mapbase_load_localization", "Should we load map-specific localized text files? e.g. \"maps/<mapname>_english.txt\"" },
{ "surfaceprops", "mapbase_load_surfaceprops", "Should we load map-specific surfaceproperties files? e.g. \"maps/<mapname>_surfaceproperties.txt\"" },
#ifdef CLIENT_DLL
//{ "closecaption", &mapbase_load_cc },
{ "vgui", NULL },
{ "closecaption", "mapbase_load_closecaption", "Should we load map-specific closed captioning? e.g. \"maps/<mapname>_closecaption_english.txt\" and \"maps/<mapname>_closecaption_english.dat\"" },
{ "vgui", "mapbase_load_vgui", "Should we load map-specific VGUI screens? e.g. \"maps/<mapname>_screens.txt\"" },
#else
{ "talker", &mapbase_load_talker },
{ "sentences", &mapbase_load_sentences },
{ "actbusy", &mapbase_load_actbusy },
{ "talker", "mapbase_load_talker", "Should we load map-specific talker files? e.g. \"maps/<mapname>_talker.txt\"" },
//{ "sentences", "mapbase_load_sentences", "Should we load map-specific sentences? e.g. \"maps/<mapname>_sentences.txt\"" },
{ "actbusy", "mapbase_load_actbusy", "Should we load map-specific actbusy files? e.g. \"maps/<mapname>_actbusy.txt\"" },
#endif
};
@ -262,6 +252,14 @@ public:
g_MapName = NULL;
RefreshCustomTalker();
#ifdef CLIENT_DLL
CHudCloseCaption *hudCloseCaption = GET_HUDELEMENT( CHudCloseCaption );
FOR_EACH_VEC( m_CloseCaptionFileNames, i )
{
hudCloseCaption->RemoveCaptionDictionary( m_CloseCaptionFileNames[i] );
}
#endif
}
bool RefreshMapName()
@ -284,9 +282,6 @@ public:
}
#ifdef CLIENT_DLL
bool m_bInitializedRTs = false;
CUtlVector<CTextureReference> m_CameraTextures;
//-----------------------------------------------------------------------------
// Initialize custom RT textures if necessary
//-----------------------------------------------------------------------------
@ -389,7 +384,10 @@ public:
case MANIFEST_LOCALIZATION: { g_pVGuiLocalize->AddFile( value, "MOD", true ); } break;
case MANIFEST_SURFACEPROPS: { AddSurfacepropFile( value, physprops, filesystem ); } break;
#ifdef CLIENT_DLL
//case MANIFEST_CLOSECAPTION: { todo } break;
case MANIFEST_CLOSECAPTION: {
if ( GET_HUDELEMENT( CHudCloseCaption ) )
(GET_HUDELEMENT( CHudCloseCaption ))->AddCustomCaptionFile( value, m_CloseCaptionFileNames );
} break;
case MANIFEST_VGUI: { PanelMetaClassMgr()->LoadMetaClassDefinitionFile( value ); } break;
//case MANIFEST_SOUNDSCAPES: { Soundscape_AddFile(value); } break;
#else
@ -398,7 +396,7 @@ public:
LoadResponseSystemFile(value); //PrecacheCustomResponseSystem( value );
} break;
//case MANIFEST_SOUNDSCAPES: { g_SoundscapeSystem.AddSoundscapeFile(value); } break;
case MANIFEST_SENTENCES: { engine->PrecacheSentenceFile(value); } break;
//case MANIFEST_SENTENCES: { engine->PrecacheSentenceFile(value); } break;
case MANIFEST_ACTBUSY: { ParseCustomActbusyFile(value); } break;
#endif
}
@ -457,7 +455,7 @@ public:
{
if (FStrEq(name, gm_szManifestFileStrings[i].string))
{
if (!gm_szManifestFileStrings[i].cvar || gm_szManifestFileStrings[i].cvar->GetBool())
if (gm_szManifestFileStrings[i].cvar.GetBool())
{
LoadFromValue(value, i, bDontWarn);
}
@ -484,6 +482,15 @@ public:
g_pScriptVM->RegisterInstance( this, "Mapbase" );
}
#endif
private:
#ifdef CLIENT_DLL
bool m_bInitializedRTs = false;
CUtlVector<CTextureReference> m_CameraTextures;
CUtlVector<CUtlSymbol> m_CloseCaptionFileNames;
#endif
};
CMapbaseSystem g_MapbaseSystem;