⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vox.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		memcpy( tempBuffer + tempBufferPos, pSentenceData, length );
		
		// Move the copy position
		tempBufferPos += length;

		pSentenceData = pNext;
		
		// Skip ahead of the opening brace
		if ( *pSentenceData )
			pSentenceData++;
		
		// Skip whitespace
		while ( *pSentenceData && *pSentenceData <= 32 )
			pSentenceData++;

		// Simple comparison of string commands:
		switch( tolower(*pSentenceData) )
		{
		case 'l':
			// All commands starting with the letter 'l' here
			if ( !strnicmp( pSentenceData, "len", 3 ) )
			{
				g_Sentences[sentenceIndex].length = atof( pSentenceData + 3 ) ;
			}
			break;

		case 0:
		default:
			break;
		}

		pSentenceData = ScanForwardUntil( pSentenceData, '}' );
		
		// Skip the closing brace
		if ( *pSentenceData )
			pSentenceData++;

		// Skip trailing whitespace
		while ( *pSentenceData && *pSentenceData <= 32 )
			pSentenceData++;
	}

	if ( tempBufferPos < sizeof(tempBuffer) )
	{
		// terminate cleaned up copy
		tempBuffer[ tempBufferPos ] = 0;
		
		// Copy it over the original data
		strcpy( pStart, tempBuffer );
	}
}

#define CSENTENCE_LRU_MAX		32

struct sentencegroup_t
{
	char szgroupname[CVOXSENTENCEMAX];
	int count;
	unsigned char rgblru[CSENTENCE_LRU_MAX];

};

CUtlVector<sentencegroup_t> g_SentenceGroups;

//-----------------------------------------------------------------------------
// Purpose: Add a new group or increment count of the existing one
// Input  : *pSentenceName - text of the sentence name
//-----------------------------------------------------------------------------
void VOX_GroupAdd( const char *pSentenceName )
{
	int len = strlen( pSentenceName ) - 1;
	char groupName[CVOXSENTENCEMAX];

	// group members end in a number
	if ( len <= 0 || !isdigit(pSentenceName[len]) )
		return;

	// truncate away the index
	while ( len > 0 && isdigit(pSentenceName[len]) )
		len--;

	if ( len > sizeof(groupName)-1 )
	{
		Msg( "Group %s name too long (%d chars max)\n", pSentenceName, sizeof(groupName)-1 );
		return;
	}

	// make a copy of the actual group name
	Q_strncpy( groupName, pSentenceName, len+2 );

	// check for it in the list
	int i;
	sentencegroup_t *pGroup;

	int groupCount = g_SentenceGroups.Size();
	for ( i = 0; i < groupCount; i++ )
	{
		int groupIndex = (i + groupCount-1) % groupCount;
		// Start at the last group a loop around
		pGroup = &g_SentenceGroups[groupIndex];
		if ( !strcmp( pGroup->szgroupname, groupName ) )
		{
			// Matches previous group, bump count
			pGroup->count++;
			return;
		}
	}

	// new group
	int addIndex = g_SentenceGroups.AddToTail();
	sentencegroup_t *group = &g_SentenceGroups[addIndex];
	strcpy( group->szgroupname, groupName );
	group->count = 1;
}



#if DEAD
//-----------------------------------------------------------------------------
// Purpose: clear the sentence groups
//-----------------------------------------------------------------------------
void VOX_GroupClear( void )
{
	g_SentenceGroups.RemoveAll();
}
#endif


void VOX_LRUInit( sentencegroup_t *pGroup )
{
	int i, n1, n2, temp;

	if ( pGroup->count )
	{
		if (pGroup->count > CSENTENCE_LRU_MAX)
			pGroup->count = CSENTENCE_LRU_MAX;

		for (i = 0; i < pGroup->count; i++)
			pGroup->rgblru[i] = (unsigned char) i;

		// randomize array by swapping random elements
		for (i = 0; i < (pGroup->count * 4); i++)
		{
			// FIXME: This should probably call through g_pSoundServices
			// or some other such call?
			n1 = RandomInt(0,pGroup->count-1);
			n2 = RandomInt(0,pGroup->count-1);
			temp = pGroup->rgblru[n1];
			pGroup->rgblru[n1] = pGroup->rgblru[n2];
			pGroup->rgblru[n2] = temp;
		}
	}
}


//-----------------------------------------------------------------------------
// Purpose: Init the LRU for each sentence group
//-----------------------------------------------------------------------------
void VOX_GroupInitAllLRUs( void )
{
	int i;

	for ( i = 0; i < g_SentenceGroups.Size(); i++ )
	{
		VOX_LRUInit( &g_SentenceGroups[i] );
	}
}


//-----------------------------------------------------------------------------
// Purpose: Given a group name, return that group's index
// Input  : *pGroupName - name of the group
// Output : int - index in group table, returns -1 if no matching group is found
//-----------------------------------------------------------------------------
int VOX_GroupIndexFromName( const char *pGroupName )
{
	int i;

	if ( pGroupName )
	{
		// search rgsentenceg for match on szgroupname
		for ( i = 0; i < g_SentenceGroups.Size(); i++ )
		{
			if ( !strcmp( g_SentenceGroups[i].szgroupname, pGroupName ) )
				return i;
		}
	}

	return -1;
}


//-----------------------------------------------------------------------------
// Purpose: return the group's name
// Input  : groupIndex - index of the group
// Output : const char * - name pointer
//-----------------------------------------------------------------------------
const char *VOX_GroupNameFromIndex( int groupIndex )
{
	if ( groupIndex >= 0 && groupIndex < g_SentenceGroups.Size() )
		return g_SentenceGroups[groupIndex].szgroupname;

	return NULL;
}

// ignore lru. pick next sentence from sentence group. Go in order until we hit the last sentence, 
// then repeat list if freset is true.  If freset is false, then repeat last sentence.
// ipick is passed in as the requested sentence ordinal.
// ipick 'next' is returned.  
// return of -1 indicates an error.

int VOX_GroupPickSequential( int isentenceg, char *szfound, int szfoundLen, int ipick, int freset )
{
	char *szgroupname;
	unsigned char count;
	
	if (isentenceg < 0 || isentenceg > g_SentenceGroups.Size())
		return -1;

	szgroupname = g_SentenceGroups[isentenceg].szgroupname;
	count = g_SentenceGroups[isentenceg].count;
	
	if (count == 0)
		return -1;

	if (ipick >= count)
		ipick = count-1;

	Q_snprintf( szfound, szfoundLen, "!%s%d", szgroupname, ipick );
	
	if (ipick >= count)
	{
		if (freset)
			// reset at end of list
			return 0;
		else
			return count;
	}

	return ipick + 1;
}



// pick a random sentence from rootname0 to rootnameX.
// picks from the rgsentenceg[isentenceg] least
// recently used, modifies lru array. returns the sentencename.
// note, lru must be seeded with 0-n randomized sentence numbers, with the
// rest of the lru filled with -1. The first integer in the lru is
// actually the size of the list.  Returns ipick, the ordinal
// of the picked sentence within the group.

int VOX_GroupPick( int isentenceg, char *szfound, int strLen )
{
	char *szgroupname;
	unsigned char *plru;
	unsigned char i;
	unsigned char count;
	unsigned char ipick=0;
	int ffound = FALSE;
	
	if (isentenceg < 0 || isentenceg > g_SentenceGroups.Size())
		return -1;

	szgroupname = g_SentenceGroups[isentenceg].szgroupname;
	count = g_SentenceGroups[isentenceg].count;
	plru = g_SentenceGroups[isentenceg].rgblru;

	while (!ffound)
	{
		for (i = 0; i < count; i++)
			if (plru[i] != 0xFF)
			{
				ipick = plru[i];
				plru[i] = 0xFF;
				ffound = TRUE;
				break;
			}

		if (!ffound)
		{
			VOX_LRUInit( &g_SentenceGroups[isentenceg] );
		}
		else
		{
			Q_snprintf( szfound, strLen, "!%s%d", szgroupname, ipick );
			return ipick;
		}
	}
	return -1;
}


typedef struct filelist_s filelist_t;
struct filelist_s
{
	const char	*pFileName;
	byte		*pFileData;
	filelist_t	*pNext;
};

static filelist_t *g_pSentenceFileList = NULL;

//-----------------------------------------------------------------------------
// Purpose: clear / reinitialize the vox list
//-----------------------------------------------------------------------------
void VOX_ListClear( void )
{
	filelist_t *pList, *pNext;
	
	pList = g_pSentenceFileList;
	
	while ( pList )
	{
		pNext = pList->pNext;

		COM_FreeFile( pList->pFileData );
		free( pList );

		pList = pNext;
	}

	g_pSentenceFileList = NULL;
}

//-----------------------------------------------------------------------------
// Purpose: Check to see if this file is in the list
// Input  : *psentenceFileName - 
// Output : int, true if the file is in the list, false if not
//-----------------------------------------------------------------------------
int VOX_ListFileIsLoaded( const char *psentenceFileName )
{
	filelist_t *pList = g_pSentenceFileList;
	while ( pList )
	{
		if ( !strcmp( psentenceFileName, pList->pFileName ) )
			return true;

		pList = pList->pNext;
	}

	return false;
}


//-----------------------------------------------------------------------------
// Purpose: Add this file name to the sentence list
// Input  : *psentenceFileName - 
//-----------------------------------------------------------------------------
void VOX_ListMarkFileLoaded( const char *psentenceFileName, byte *pFileData )
{
	filelist_t	*pEntry;
	char		*pName;

	pEntry = (filelist_t *)malloc( sizeof(filelist_t) + strlen( psentenceFileName ) + 1);

	if ( pEntry )
	{
		pName = (char *)(pEntry+1);
		strcpy( pName, psentenceFileName );

		pEntry->pFileName = pName;
		pEntry->pFileData = pFileData;
		pEntry->pNext = g_pSentenceFileList;

		g_pSentenceFileList = pEntry;
	}
}

// Load sentence file into memory, insert null terminators to
// delimit sentence name/sentence pairs.  Keep pointer to each
// sentence name so we can search later.

void VOX_ReadSentenceFile( const char *psentenceFileName )
{
	char *pch, *pFileData;
	int fileSize;
	char c;
	char *pchlast, *pSentenceData;
	characterset_t whitespace;


	// Have we already loaded this file?
	if ( VOX_ListFileIsLoaded( psentenceFileName ) )
		return;

	// load file

	// USES malloc()
	pFileData = (char*)COM_LoadFileForMe( psentenceFileName, &fileSize );

	if (!pFileData)
	{
		DevMsg ("Couldn't load %s\n", psentenceFileName);
		return;
	} 

	pch = pFileData;
	pchlast = pch + fileSize;
	CharacterSetBuild( &whitespace, "\n\r\t " );
	while (pch < pchlast)
	{
		// Only process this pass on sentences
		pSentenceData = NULL;

		// skip newline, cr, tab, space

		c = *pch;
		while (pch < pchlast && IN_CHARACTERSET( whitespace, c ))
			c = *(++pch);

		// skip entire line if first char is /
		if (*pch != '/')
		{
			int addIndex = g_Sentences.AddToTail();
			sentence_t *pSentence = &g_Sentences[addIndex];
			pSentence->pName = pch;
			pSentence->length = 0;

			// scan forward to first space, insert null terminator
			// after sentence name

			c = *pch;
			while (pch < pchlast && c != ' ')
				c = *(++pch);

			if (pch < pchlast)
				*pch++ = 0;

			// A sentence may have some line commands, make an extra pass
			pSentenceData = pch;
		}
		// scan forward to end of sentence or eof
		while (pch < pchlast && pch[0] != '\n' && pch[0] != '\r')
			pch++;
	
		// insert null terminator
		if (pch < pchlast)
			*pch++ = 0;

		// If we have some sentence data, parse out any line commands
		if ( pSentenceData && pSentenceData < pchlast )
		{
			int index = g_Sentences.Size()-1;
			// The current sentence has an index of count-1
			VOX_ParseLineCommands( pSentenceData, index );

			// Add a new group or increment count of the existing one
			VOX_GroupAdd( g_Sentences[index].pName );
		}
	}
	VOX_GroupInitAllLRUs();
	VOX_ListMarkFileLoaded( psentenceFileName, (unsigned char*)pFileData );
}


//-----------------------------------------------------------------------------
// Purpose: Get the current number of sentences in the database
// Output : int
//-----------------------------------------------------------------------------
int VOX_SentenceCount( void )
{
	return g_Sentences.Size();
}


float VOX_SentenceLength( int sentence_num )
{
	if ( sentence_num < 0 || sentence_num > g_Sentences.Size()-1 )
		return 0.0f;
	
	return g_Sentences[ sentence_num ].length;
}

// scan g_Sentences, looking for pszin sentence name
// return pointer to sentence data if found, null if not
// CONSIDER: if we have a large number of sentences, should
// CONSIDER: sort strings in g_Sentences and do binary search.
char *VOX_LookupString(const char *pSentenceName, int *psentencenum)
{
	int i;
	for (i = 0; i < g_Sentences.Size(); i++)
	{
		if (!stricmp(pSentenceName, g_Sentences[i].pName))
		{
			if (psentencenum)
				*psentencenum = i;
			return (g_Sentences[i].pName + strlen(g_Sentences[i].pName) + 1);
		}
	}
	return NULL;
}


// Abstraction for sentence name array
const char *VOX_SentenceNameFromIndex( int sentencenum )
{
	if ( sentencenum < g_Sentences.Size() )
		return g_Sentences[sentencenum].pName;
	return NULL;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -