Beispiel #1
0
bool CClientFXDB::LoadFxGroups(ILTClient* pClient, const char *sFileName )
{
	ILTStream *pFxFile;

	// Attempt to open the client fx file
	pClient->OpenFile(sFileName, &pFxFile);

	if(!pFxFile)
		return false;

	char szTag[MAX_TAG_SIZE] = {0};

	//remember where we are in our list of effects, so that we don't reinitalize keys that are already
	//in the list
	CLinkListNode<FX_GROUP *> *pTailNode = m_collGroupFX.GetTail();

	// Figure out if we are reading a binary file or text...
	pFxFile->Read( szTag, 7 );
	pFxFile->SeekTo( 0 );

	// This is a text file if we can read an asci "Groups:".
	bool bText = !_stricmp( szTag, "Groups:" );
	ReadFXGroups( bText, pFxFile, m_collGroupFX );

	//clean up the file
	pFxFile->Release();
	pFxFile = NULL;


	// Run through the FX groups we added to the end of the list and setup any non-instance specific
	// information
	CLinkListNode<FX_GROUP *> *pFxGroupNode = (pTailNode) ? pTailNode : m_collGroupFX.GetHead();

	while (pFxGroupNode)
	{
		uint32 nNumKeys = pFxGroupNode->m_Data->m_nNumKeys;

		for(uint32 nCurrKey = 0; nCurrKey < nNumKeys; nCurrKey++)
		{
			FX_KEY *pKey = &pFxGroupNode->m_Data->m_pKeys[nCurrKey];

			float tmLength = pKey->m_tmEnd - pKey->m_tmStart;

			if (tmLength >= pFxGroupNode->m_Data->m_tmTotalTime - 0.01f)
			{
				pKey->m_bContinualLoop = true;
			}
			else
			{
				pKey->m_bContinualLoop = false;
			}
		}

		pFxGroupNode = pFxGroupNode->m_pNext;
	}

	// Success !!
	return true;
}
//loads the specified script
bool CTextureScriptInterpreter::LoadScript(const char* pszFilename)
{
	//clear out any old script
	Free();

	//now we need to open up the new file
	FileRef Ref; 
	Ref.m_FileType			= TYPECODE_UNKNOWN;
	Ref.m_pFilename			= pszFilename;
	FileIdentifier* pIdent	= g_pIClientFileMgr->GetFileIdentifier(&Ref, TYPECODE_UNKNOWN);

	//open up the stream
	ILTStream* pStream = g_pIClientFileMgr->OpenFile(&Ref);

	if(!pStream)
		return false;

	//read in the version
	uint16 nVersion;
	*pStream >> nVersion;

	//make sure the version is correct
	if(nVersion != TS_CURR_VERSION)
	{
		pStream->Release();
		return false;
	}
	//now read in the size of the variable names
	uint32 nVarSize;
	*pStream >> nVarSize;

	//skip over the variables
	pStream->SeekTo(pStream->GetPos() + nVarSize);

	//read in our input type, output type and our dirty flags
	uint32 nInput;
	uint32 nOutput;
	uint32 nDirty;

	*pStream >> nInput >> nOutput >> nDirty;

	//now read in the constant table
	uint32 nNumConstants;
	*pStream >> nNumConstants;
	assert(nNumConstants < TS_NUMCONSTANTS);

	//now read all the constants into the table
	for(uint32 nCurrConstant = 0; nCurrConstant < nNumConstants; nCurrConstant++)
	{
		*pStream >> m_fVarList[TSVAR_CONSTANT + nCurrConstant];
	}

	//now it is time to read in the actual bytecode
	*pStream >> m_nByteCodeLen;

	//allocate our buffer
	LT_MEM_TRACK_ALLOC(m_pByteCode = new uint8 [m_nByteCodeLen],LT_MEM_TYPE_RENDER_TEXTURESCRIPT);

	//check the allocation
	if(!m_pByteCode)
	{
		pStream->Release();
		m_nByteCodeLen = 0;
		return false;
	}

	//read in our buffer
	pStream->Read(m_pByteCode, m_nByteCodeLen);

	//close our stream
	pStream->Release();

	//now we need to figure out our internal flags
	m_nFlags = 0;

	//setup info based upon input
	switch(nInput)
	{
	case TSINPUT_CSNORMAL:		m_eInput = INPUT_NORMAL;		break;
	case TSINPUT_CSPOS:			m_eInput = INPUT_POS;			break;
	case TSINPUT_CSREFLECTION:	m_eInput = INPUT_REFLECTION;	break;
	case TSINPUT_UV:			m_eInput = INPUT_UV;			break;
	case TSINPUT_WSNORMAL:		m_eInput = INPUT_NORMAL;		m_nFlags |= FLAG_WORLDSPACE; break;
	case TSINPUT_WSPOS:			m_eInput = INPUT_POS;			m_nFlags |= FLAG_WORLDSPACE; break;
	case TSINPUT_WSREFLECTION:	m_eInput = INPUT_REFLECTION;	m_nFlags |= FLAG_WORLDSPACE; break;
	default:
		assert(false);
		break;
	}

	//setup info based upon output
	switch(nOutput)
	{
	case TSOUTPUT_2:		m_nFlags |= FLAG_COORD2;					break;
	case TSOUTPUT_3:		m_nFlags |= FLAG_COORD3;					break;
	case TSOUTPUT_3PROJ:	m_nFlags |= FLAG_COORD3 | FLAG_PROJECTED;	break;
	case TSOUTPUT_4PROJ:	m_nFlags |= FLAG_COORD4 | FLAG_PROJECTED;	break;
	default:
		assert(false);
		break;
	}

	//setup info based upon dirty flags
	if(nDirty & TSDIRTY_EVERYUPDATE)
		m_nFlags |= FLAG_DIRTYONFRAME;
	if(nDirty & TSDIRTY_USERVARCHANGED)
		m_nFlags |= FLAG_DIRTYONVAR;	

	//success
	return true;
}
STDMETHODIMP CLTDMFileStream::Seek( LARGE_INTEGER dlibMove, unsigned long dwOrigin, ULARGE_INTEGER* plibNewPosition )
{
#ifdef USE_DSTREAM
	// make sure our file item pointer is valid
	if (m_pOpenQueueItem == NULL) 
	{
		return E_FAIL;
	}

	// make sure the file is open and get a pointer to the ILTStream
	ILTStream* pLTStream = m_pOpenQueueItem->LockDStream();
	if (pLTStream == LTNULL)
	{
		return E_FAIL;
	}

	// current position in an item
	DWORD nSeekPos;
	
	// figure out the seek position relative to the origin
	if (dwOrigin == SEEK_SET)
	{
		nSeekPos =  dlibMove.LowPart;
	}
	else
	{
		// relative to current position
		if (dwOrigin == SEEK_CUR)
		{
			LARGE_INTEGER nCurPos;
			if (pLTStream->GetPos((uint32*)&nCurPos.LowPart) != LT_OK) 
			{
				m_pOpenQueueItem->UnLockDStream();
				return E_FAIL;
			}
			nCurPos.HighPart = 0;
			
			LARGE_INTEGER nNewPos;
			nNewPos.QuadPart = nCurPos.QuadPart + dlibMove.QuadPart;

			nSeekPos = nNewPos.LowPart;

			// we don't need to seek if we didn't ask to move anywhere
			if (dlibMove.QuadPart == 0) 
			{
				// set the return current position if it was not NULL
				if( plibNewPosition != NULL )
				{
					plibNewPosition->QuadPart = nCurPos.QuadPart;
				}

				m_pOpenQueueItem->UnLockDStream();
				return S_OK;
			}
		}
		else
		{
			if (dwOrigin == SEEK_END)
			{
				LARGE_INTEGER nSize;
				pLTStream->GetLen((uint32*)&nSize.LowPart);
				nSize.HighPart = 0;

				LARGE_INTEGER nNewPos;
				nNewPos.QuadPart = nSize.QuadPart + dlibMove.QuadPart;

				nSeekPos = nNewPos.LowPart;
			}
			else
			{
				// unknown origin we must fail
				m_pOpenQueueItem->UnLockDStream();
				return E_FAIL;
			}
		}
	}

	// do the seek
	if (pLTStream->SeekTo(nSeekPos) != LT_OK)
	{
		// return fail if we failed
		m_pOpenQueueItem->UnLockDStream();
		return E_FAIL;
	}

	// set the return current position if it was not NULL
	if( plibNewPosition != NULL )
	{
		pLTStream->GetPos((uint32*)&plibNewPosition->LowPart);
		if( dlibMove.LowPart < 0 )
		{
			plibNewPosition->HighPart = (uint32)-1;
		}
		else
		{
			plibNewPosition->HighPart = 0;
		}
	}

	// everything worked so we return successful
	m_pOpenQueueItem->UnLockDStream();
    return S_OK;
#endif

#ifdef USE_REZMGR
	// if the loader doesn't exist fail
	if (m_pLoader == NULL) 
	{
		LTDMConOutError("LTDirectMusic loader failed to seek from file because no directmusic loader exists\n");
		return E_FAIL;
	}

	m_pLoader->EnterRezMgrCriticalSection();

	// if the rezmgr is not open
	if (!m_pLoader->GetRezMgr()->IsOpen()) 
	{
		LTDMConOutError("LTDirectMusic loader failed to seek from file because rez file was not open\n");
		m_pLoader->LeaveRezMgrCriticalSection();
		return E_FAIL;
	}

	// current position in an item
	DWORD nSeekPos;
	
	// figure out the seek position relative to the origin
	if (dwOrigin == SEEK_SET)
	{
		nSeekPos =  dlibMove.LowPart;
	}
	else
	{
		// relative to current position
		if (dwOrigin == SEEK_CUR)
		{
			LARGE_INTEGER nCurPos;
			nCurPos.LowPart = m_nCurPos;;
			nCurPos.HighPart = 0;
			
			LARGE_INTEGER nNewPos;
			nNewPos.QuadPart = nCurPos.QuadPart + dlibMove.QuadPart;

			nSeekPos = nNewPos.LowPart;
		}
		else
		{
			if (dwOrigin == SEEK_END)
			{
				LARGE_INTEGER nSize;
				nSize.LowPart = m_pRezItem->GetSize();
				nSize.HighPart = 0;

				LARGE_INTEGER nNewPos;
				nNewPos.QuadPart = nSize.QuadPart + dlibMove.QuadPart;

				nSeekPos = nNewPos.LowPart;
			}
			else
			{
				// unknown origin we must fail
				LTDMConOutError("LTDirectMusic failed to seek in file %s invalid seek origin\n",m_pRezItem->GetName());
				m_pLoader->LeaveRezMgrCriticalSection();
				return E_FAIL;
			}
		}
	}

	// do the seek
	m_nCurPos = nSeekPos;

	// set the return current position if it was not NULL
	if( plibNewPosition != NULL )
	{
		plibNewPosition->LowPart = m_nCurPos;
		plibNewPosition->HighPart = 0;
	}

	// everything worked so we return successful
	m_pLoader->LeaveRezMgrCriticalSection();
    return S_OK;
#endif

#ifdef USE_FILE
	// fseek can't handle a LARGE_INTEGER seek...
	long lOffset;

	lOffset = dlibMove.LowPart;

	int i = fseek( m_pFile, lOffset, dwOrigin );
	if( i ) 
	{
		return E_FAIL;
	}

	if( plibNewPosition != NULL )
	{
		plibNewPosition->LowPart = ftell( m_pFile );
		if( lOffset < 0 )
		{
			plibNewPosition->HighPart = -1;
		}
		else
		{
			plibNewPosition->HighPart = 0;
		}
	}
    return S_OK;
#endif
}
STDMETHODIMP CLTDMFileStream::Clone( IStream** ppstm )
{ 
	HRESULT hr;

	// allocate a new stream object
	CLTDMFileStream* pStream = new CLTDMFileStream( m_pLoader );

	if ( !pStream )
		return E_FAIL;

	// get the IStream interface
	hr = pStream->QueryInterface( IID_IStream, (void**) ppstm );	

	// if everything is OK, set up the seek position
	if ( SUCCEEDED( hr ) )
	{
#ifdef USE_FILE
		pStream->m_pFile = this->m_pFile;
#endif

#ifdef USE_REZMGR
		pStream->m_pRezItem = this->m_pRezItem;
		pStream->m_nCurPos = this->m_nCurPos;
#endif

#ifdef USE_DSTREAM
		pStream->m_pLoader = this->m_pLoader;

		// add a new queue item, identical to the current one
		const char* sFileName = this->m_pOpenQueueItem->GetFileName();
	    CDStreamOpenQueueItem* pOpenQueueItem;
		
		pOpenQueueItem = g_LTDMDStreamOpenQueueMgr.Create(sFileName);
		pStream->m_pOpenQueueItem = pOpenQueueItem;

		if ( !pOpenQueueItem )
			return E_FAIL;

		// now set the seek parameter

		// make sure the file is open and get a pointer to the ILTStream
		ILTStream* pLTStream = pOpenQueueItem->LockDStream();

		if (pLTStream == LTNULL)
		{
			return E_FAIL;
		}

		// current position in an item
		DWORD nSeekPos;
		LARGE_INTEGER nCurPos;
		if (pLTStream->GetPos((uint32*)&nCurPos.LowPart) != LT_OK) 
		{
			pOpenQueueItem->UnLockDStream();
			return E_FAIL;
		}
		nCurPos.HighPart = 0;
		
		LARGE_INTEGER nNewPos;
		nNewPos.QuadPart = nCurPos.QuadPart;

		nSeekPos = nNewPos.LowPart;

		// do the seek
		if (pLTStream->SeekTo(nSeekPos) != LT_OK)
		{		
			// return fail if we failed
			pOpenQueueItem->UnLockDStream();
			return E_FAIL;
		}

		pOpenQueueItem->UnLockDStream();		
#endif
	}

	return S_OK; 
}