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 }
//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::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; }