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; }
LTBOOL CScreenSpriteMgr::CacheSprite(CScreenSprite * pSprite, char * pFile) { ILTStream * pStream; char buf[1024]; pSprite->m_pName = strdup(pFile); g_pLTClient->OpenFile(pFile, &pStream); if (pStream) { int nFrames; int nFrameRate; int bTransparency; int bTranslucency; int iChromakey; pStream->Read(&nFrames, 4); pSprite->m_nFrames = nFrames; pStream->Read(&nFrameRate, 4); pSprite->m_nFrameRate = nFrameRate; pSprite->m_fOneFrameTime = 1.0f / (float)nFrameRate; pStream->Read(&bTransparency, 4); pStream->Read(&bTranslucency, 4); pStream->Read(&iChromakey, 4); if (nFrames < 1 && nFrames > 64) { // We have an error. // FIXME report it pStream->Release(); return LTFALSE; } for (int i = 0; i < nFrames; i++) { short iLen; pStream->Read(&iLen, 2); if (iLen < 1 || iLen > 1023) { // We have an error. // FIXME report it pStream->Release(); return LTFALSE; } memset(buf,0,1024); pStream->Read(&buf, iLen); int iFrameID = CacheTexture(buf); pSprite->m_FrameArray.push_back(m_FrameArray[iFrameID]); } pStream->Release(); return LTTRUE; } return (LTFALSE); }
bool CD3DSkelMesh::Load_MP(ILTStream& File) { // Read in out Min/Max Bones (effecting this guy)... File.Read(&m_iMinBone,sizeof(m_iMinBone)); File.Read(&m_iMaxBone,sizeof(m_iMaxBone)); // What type of Vert do we need? switch (m_iMaxBonesPerVert) { case 2 : m_VertType = eINDEXED_B1; break; case 3 : m_VertType = eINDEXED_B2; break; case 4 : m_VertType = eINDEXED_B3; break; default : assert(0); return false; } // If we are using re-indexed bones, read them in... if (m_bReIndexedBones) { uint32 iBoneCount = 0; File.Read(&iBoneCount,sizeof(iBoneCount)); assert(iBoneCount < 10000 && "Crazy bone count, checked your packed model format."); LT_MEM_TRACK_ALLOC(m_pReIndexedBoneList = new uint32[iBoneCount],LT_MEM_TYPE_RENDERER); File.Read(m_pReIndexedBoneList,sizeof(uint32)*iBoneCount); } // Read in our Verts... for (uint32 i=0;i<4;++i) { if (!m_VertStreamFlags[i]) continue; uint32 iVertexSize = 0; // Figure out the vertex size... uint32 iVertFlags = 0; uint32 iUVSets = 0; GetVertexFlags_and_Size(m_VertType,m_VertStreamFlags[i],iVertFlags,iVertexSize,iUVSets,m_bNonFixPipeData); uint32 iSize = iVertexSize * m_iVertCount; // Alloc the VertData... LT_MEM_TRACK_ALLOC(m_pVertData[i] = new uint8[iSize],LT_MEM_TYPE_RENDERER); File.Read(m_pVertData[i],iSize); } // Read in pIndexList... LT_MEM_TRACK_ALLOC(m_pIndexData = new uint8[sizeof(uint16) * m_iPolyCount * 3],LT_MEM_TYPE_RENDERER); File.Read(m_pIndexData,sizeof(uint16) * m_iPolyCount * 3); // Create the VBs and stuff... ReCreateObject(); return true; }
// Load a render style (ltb file) and create a render object for it... CRenderStyle* D3DRenderStyles::LoadRenderStyle(const char* szFilename) { FileRef ref; CD3DRenderStyle* pRenderStyle = NULL; ref.m_FileType = TYPECODE_RSTYLE; ref.m_pFilename = szFilename; FileIdentifier* pIdent = client_file_mgr->GetFileIdentifier(&ref, TYPECODE_RSTYLE); if (pIdent) { if (pIdent->m_pData) { // Is it already loaded? pRenderStyle = (CD3DRenderStyle*)pIdent->m_pData; pRenderStyle->IncRefCount(); } else { ILTStream* pFileStream = client_file_mgr->OpenFile(&ref); if (pFileStream) { // Create and Load it... pRenderStyle = g_Device.CreateRenderStyle(); if (!pRenderStyle) return NULL; if (!pRenderStyle->Load_LTBData(pFileStream)) { g_Device.DestroyRenderStyle(pRenderStyle); pFileStream->Release(); string szTmp = "Couldn't Load Renderstyle "; szTmp += szFilename; szTmp += "\n"; OutputDebugString(szTmp.c_str()); return false; } // We're keeping a pointer to it in the m_pData member, so inc it's ref count. // This means that all loaded render styles wont be freed until all files are flushed. pIdent->m_pData = pRenderStyle; pRenderStyle->IncRefCount(); pRenderStyle->SetFilename( szFilename ) ; pFileStream->Release(); } } } return pRenderStyle; }
bool CD3DSkelMesh::Load_RD(ILTStream& File) { // What type of Vert do we need? switch (m_iMaxBonesPerTri) { case 1 : m_VertType = eNO_WORLD_BLENDS; break; case 2 : m_VertType = eNONINDEXED_B1; break; case 3 : m_VertType = eNONINDEXED_B2; break; case 4 : m_VertType = eNONINDEXED_B3; break; default : assert(0); return false; } // Read in our Verts... for (uint32 i=0;i<4;++i) { if (!m_VertStreamFlags[i]) continue; uint32 iVertexSize = 0; // Figure out the vertex size... uint32 iVertFlags = 0; uint32 iUVSets = 0; GetVertexFlags_and_Size(m_VertType,m_VertStreamFlags[i],iVertFlags,iVertexSize,iUVSets,m_bNonFixPipeData); uint32 iSize = iVertexSize * m_iVertCount; // Alloc the VertData... LT_MEM_TRACK_ALLOC(m_pVertData[i] = new uint8[iSize],LT_MEM_TYPE_RENDERER); File.Read(m_pVertData[i],iSize); } // Read in pIndexList... LT_MEM_TRACK_ALLOC(m_pIndexData = new uint8[sizeof(uint16) * m_iPolyCount * 3],LT_MEM_TYPE_RENDERER); File.Read(m_pIndexData,sizeof(uint16) * m_iPolyCount * 3); // Allocate and read in the BoneSets... File.Read(&m_iBoneSetCount,sizeof(m_iBoneSetCount)); LT_MEM_TRACK_ALLOC(m_pBoneSetArray = new BoneSetListItem[m_iBoneSetCount],LT_MEM_TYPE_RENDERER); if (!m_pBoneSetArray) return false; File.Read(m_pBoneSetArray,sizeof(BoneSetListItem)*m_iBoneSetCount); // Create the VBs and stuff... ReCreateObject(); return true; }
LTRESULT CLTRenderMgr::AddEffectShader (const char *pFileName, int EffectShaderID, const uint32 *pVertexElements, uint32 VertexElementsSize, HEFFECTPOOL EffectPoolID) { if (!pFileName) { RETURN_ERROR(1, CLTRenderMgr::AddEffectShader, LT_INVALIDPARAMS); } FileRef ref; ref.m_FileType = FILE_ANYFILE; ref.m_pFilename = pFileName; ILTStream *pStream = client_file_mgr->OpenFile(&ref); if (!pStream) { RETURN_ERROR(3, CLTRenderMgr::AddEffectShader, LT_NOTFOUND); } if(!LTEffectShaderMgr::GetSingleton().AddEffectShader(pStream, pFileName, EffectShaderID, pVertexElements, VertexElementsSize, EffectPoolID)) { // Close the file. if (pStream != NULL) { pStream->Release(); pStream = NULL; } return LT_ERROR; } // Close the file. if (pStream != NULL) { pStream->Release(); pStream = NULL; } return LT_OK; }
// ----------------------------------------------------------------------- // // // ROUTINE: CTO2MissionButeMgr::Init // // PURPOSE: Initialization // // ----------------------------------------------------------------------- // LTBOOL CDMButeMgr::Init(const char* szAttributeFile) { if(!szAttributeFile) return LTFALSE; // See if we already have this attribute file loaded. if( m_strAttributeFile.GetLength( ) && m_strAttributeFile.CompareNoCase( szAttributeFile ) == 0 ) return LTTRUE; // Start fresh. Term( ); ILTStream* pDStream = LTNULL; LTRESULT dr = g_pLTBase->OpenFile(szAttributeFile, &pDStream); bool bFound = (dr == LT_OK && pDStream); if (pDStream) pDStream->Release(); if (!bFound || !Parse(szAttributeFile)) return LTFALSE; return LTTRUE; };
bool CD3DSkelMesh::Load(ILTStream& File, LTB_Header& LTBHeader) { if (LTBHeader.m_iFileType != LTB_D3D_MODEL_FILE) { OutputDebugString("Error: Wrong file type in CD3DSkelMesh::Load\n"); return false; } if (LTBHeader.m_iVersion != CD3D_LTB_LOAD_VERSION) { OutputDebugString("Error: Wrong file version in CD3DSkelMesh::Load\n"); return false; } // Read in the basics... uint32 iObjSize; File.Read(&iObjSize,sizeof(iObjSize)); File.Read(&m_iVertCount,sizeof(m_iVertCount)); File.Read(&m_iPolyCount,sizeof(m_iPolyCount)); File.Read(&m_iMaxBonesPerTri,sizeof(m_iMaxBonesPerTri)); File.Read(&m_iMaxBonesPerVert,sizeof(m_iMaxBonesPerVert)); File.Read(&m_bReIndexedBones,sizeof(m_bReIndexedBones)); File.Read(&m_VertStreamFlags[0],sizeof(uint32)*4); // Are we using Matrix Palettes... bool bUseMatrixPalettes; File.Read(&bUseMatrixPalettes,sizeof(bUseMatrixPalettes)); if (bUseMatrixPalettes) { m_eRenderMethod = eD3DRenderMatrixPalettes; return Load_MP(File); } else { m_eRenderMethod = eD3DRenderDirect; return Load_RD(File); } }
bool CD3DVAMesh::Load(ILTStream& File, LTB_Header& LTBHeader) { if (LTBHeader.m_iFileType != LTB_D3D_MODEL_FILE) { OutputDebugString("Error: Wrong file type in CD3DSkelMesh::Load\n"); return false; } if (LTBHeader.m_iVersion != CD3D_LTB_LOAD_VERSION) { OutputDebugString("Error: Wrong file version in CD3DSkelMesh::Load\n"); return false; } // Read in the basics... uint32 iObjSize; File.Read(&iObjSize,sizeof(iObjSize)); File.Read(&m_iVertCount,sizeof(m_iVertCount)); File.Read(&m_iUnDupVertCount,sizeof(m_iUnDupVertCount)); File.Read(&m_iPolyCount,sizeof(m_iPolyCount)); File.Read(&m_iMaxBonesPerTri,sizeof(m_iMaxBonesPerTri)); File.Read(&m_iMaxBonesPerVert,sizeof(m_iMaxBonesPerVert)); File.Read(&m_VertStreamFlags[0],sizeof(uint32)*4); File.Read(&m_iAnimNodeIdx,sizeof(m_iAnimNodeIdx)); File.Read(&m_iBoneEffector,sizeof(m_iBoneEffector)); // Read in our Verts... for (uint32 i=0;i<4;++i) { if (!m_VertStreamFlags[i]) continue; uint32 iVertexSize = 0; // Figure out the vertex size... uint32 iVertFlags = 0; uint32 iUVSets = 0; GetVertexFlags_and_Size(eNO_WORLD_BLENDS,m_VertStreamFlags[i],iVertFlags,iVertexSize,iUVSets,m_bNonFixPipeData); uint32 iSize = iVertexSize * m_iVertCount; // Alloc the VertData... LT_MEM_TRACK_ALLOC(m_pVertData[i] = new uint8[iSize],LT_MEM_TYPE_RENDERER); File.Read(m_pVertData[i],iSize); } // Read in pIndexList... LT_MEM_TRACK_ALLOC(m_pIndexData = new uint8[sizeof(uint16) * m_iPolyCount * 3],LT_MEM_TYPE_RENDERER); File.Read(m_pIndexData,sizeof(uint16) * m_iPolyCount * 3); // Read in m_pDupMapList... File.Read(&m_iDupMapListCount,sizeof(m_iDupMapListCount)); assert(m_iDupMapListCount < 1000000 && "Invalid VA VertData"); LT_MEM_TRACK_ALLOC(m_pDupMapList = new DupMap[m_iDupMapListCount],LT_MEM_TYPE_RENDERER); File.Read(m_pDupMapList,sizeof(DupMap) * m_iDupMapListCount); // Create the VBs and stuff... ReCreateObject(); return true; }
void d3d_DrawPolyGrid(const ViewParams &Params, LTObject *pObj) { //the global pixel shader to be used for the water bumpmapping and a flag indicating if //creation failed bool s_bPixelShaderFailed = false; //make sure that the polygrid is valid assert(pObj); //get our polygrid LTPolyGrid *pGrid = (LTPolyGrid*)pObj; // Make sure it's initialized. if(!pGrid->m_Data) return; //must have an index buffer if(!pGrid->m_Indices || (pGrid->m_nIndices == 0)) return; //and of course, make sure that the size is reasonable if((pGrid->m_Width < 2) || (pGrid->m_Height < 2)) return; IncFrameStat(eFS_PolyGridTriangles, pGrid->m_nTris); //cache the half dimensions float fHalfGridWidth = ((float)pGrid->m_Width - 1) * 0.5f; float fHalfGridHeight = ((float)pGrid->m_Height - 1) * 0.5f; //now we need to build our color lookup table for this polygrid, this is faster for any //polygrid that is larger than 8x8, and even then we can get a nice tight loop that //should still be rather optimal // Set the blending mode based on the flags. uint32 nSrcBlend, nDestBlend, nFog, nFogColor; d3d_GetBlendStates(pGrid, nSrcBlend, nDestBlend, nFog, nFogColor); StateSet ssSrcBlend(D3DRS_SRCBLEND, nSrcBlend); StateSet ssDestBlend(D3DRS_DESTBLEND, nDestBlend); StateSet ssFog(D3DRS_FOGENABLE, nFog); StateSet ssFogColor(D3DRS_FOGCOLOR, nFogColor); //flag indicating whether or not bool bEnvMap = false; bool bCubicEnvMap = false; bool bBumpMap = false; //vertex information uint32 nVertexSize = sizeof(CPolyGridVertex); uint32 nVertexFVF = POLYGRIDVERTEX_FORMAT; //UV scales to adjust the texture by (defaults to 1, but if we are bump mapping, this will //be set to the detail texture scale) float fPGUScale = 1.0f; float fPGVScale = 1.0f; // Set the texture if necessary. SpriteTracker* pTracker; LTPixelShader *pPixelShader = NULL; if(pGrid->m_pSprite) { pTracker = &pGrid->m_SpriteTracker; if(pTracker->m_pCurFrame) { SharedTexture* pTex = pTracker->m_pCurFrame->m_pTex; if(pTex) { //get the type of this texture ESharedTexType eTexType = pTex->m_eTexType; //the base texture SharedTexture* pBaseTex = NULL; //the environment map SharedTexture* pEnvMapTex = pGrid->m_pEnvMap; //the bumpmap SharedTexture* pBumpMapTex = NULL; //determine our texture data if(pGrid->m_nPGFlags & PG_NORMALMAPSPRITE) { //only use a bump map texture if we actually have an environment map if(pEnvMapTex) pBumpMapTex = pTex; } else { //we have a normal texture pBaseTex = pTex; } // Set up the environment mapping texture if applicable if( pEnvMapTex && g_CV_EnvMapPolyGrids.m_Val) { //see if the is a cubic environment map RTexture *pRenderTexture = (RTexture*)pEnvMapTex->m_pRenderData; if(pRenderTexture && pRenderTexture->IsCubeMap()) { bCubicEnvMap = true; } bEnvMap = true; } if( pBumpMapTex && g_CV_BumpMapPolyGrids.m_Val) { //we now need to make sure that the bump map shader is valid //see if we need to load it if (!s_bPixelShaderFailed) { // Get the pixel shader. pPixelShader = LTPixelShaderMgr::GetSingleton().GetPixelShader(LTPixelShader::PIXELSHADER_ENVBUMPMAP); if (NULL == pPixelShader) { FileRef ref; ref.m_FileType = FILE_ANYFILE; ref.m_pFilename = "ps\\envbumpmap.psh"; // Try to load it. ILTStream *pStream = g_pIClientFileMgr->OpenFile(&ref); if (NULL != pStream) { if (LTPixelShaderMgr::GetSingleton().AddPixelShader(pStream, ref.m_pFilename, LTPixelShader::PIXELSHADER_ENVBUMPMAP, true)) { pPixelShader = LTPixelShaderMgr::GetSingleton().GetPixelShader(LTPixelShader::PIXELSHADER_ENVBUMPMAP); } // Close the file. pStream->Release(); } } } // See if we can continue. if (NULL != pPixelShader && pPixelShader->IsValidShader()) { bBumpMap = true; nVertexSize = sizeof(CPolyGridBumpVertex); nVertexFVF = POLYGRIDBUMPVERTEX_FORMAT; fPGUScale = ((RTexture*)pBumpMapTex->m_pRenderData)->m_DetailTextureScale; fPGVScale = fPGUScale; } else { //we failed to create the shader, the device can't support it s_bPixelShaderFailed = true; } } //setup the textures based upon the configuration if(bBumpMap) { d3d_SetTexture(pBumpMapTex, 0, eFS_PolyGridBumpMapTexMemory); d3d_SetTexture(pEnvMapTex, 3, eFS_PolyGridEnvMapTexMemory); } else { LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pGrid->m_nEffectShaderID); if(pEffect) { ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { nVertexSize = sizeof(CPolyGridEffectVertex); RTexture* pRTexture = (RTexture*)pBaseTex->m_pRenderData; pD3DEffect->SetTexture("texture0", pRTexture->m_pD3DTexture); if(bEnvMap) { pRTexture = (RTexture*)pEnvMapTex->m_pRenderData; pD3DEffect->SetTexture("texture1", pRTexture->m_pD3DTexture); } } }else { d3d_SetTexture(pBaseTex, 0, eFS_PolyGridBaseTexMemory); if(bEnvMap) { d3d_SetTexture(pEnvMapTex, 1, eFS_PolyGridEnvMapTexMemory); } } } } else { //if we didn't set any texture, we need to make sure and clear out the texture //channel d3d_DisableTexture(0); } } } //specify that we were visible pGrid->m_Flags |= FLAG_INTERNAL1; // Build the vertex list. uint32 nBufferSize = pGrid->m_Width * pGrid->m_Height * nVertexSize; if(nBufferSize > g_TriVertListSize) { //we need to reallocate our list of vertices dfree(g_TriVertList); LT_MEM_TRACK_ALLOC(g_TriVertList = dalloc(nBufferSize),LT_MEM_TYPE_RENDERER); //check the allocation if(!g_TriVertList) { g_TriVertListSize = 0; return; } g_TriVertListSize = nBufferSize; } //determine if this polygrid should be lit or not bool bFresnel = (pGrid->m_nPGFlags & PG_FRESNEL) && (g_CV_FresnelPolyGrids.m_Val) ? true : false; //determine what alpha value we should use uint8 nColorAlpha = 0; if(!bEnvMap) nColorAlpha = 255; else if(!bFresnel) nColorAlpha = 128; float fScaledR = pGrid->m_ColorR * MATH_ONE_OVER_255; float fScaledG = pGrid->m_ColorG * MATH_ONE_OVER_255; float fScaledB = pGrid->m_ColorB * MATH_ONE_OVER_255; uint32 nColorTable[256]; for(uint32 nCurrColor = 0; nCurrColor < 256; nCurrColor++) { //Note that the color table is 0..255, object color is 0..255 as well nColorTable[nCurrColor] = D3DRGBA_255( pGrid->m_ColorTable[nCurrColor].x * fScaledR, pGrid->m_ColorTable[nCurrColor].y * fScaledG, pGrid->m_ColorTable[nCurrColor].z * fScaledB, nColorAlpha); } //setup our world matrix to represent a space that holds the orientation of the polygrid //as well as the center position. This allows all operations to take place //as if performed on the XZ plane (note that we don't do the scale as that tends //to mess up normals) LTMatrix mWorldTrans; LTVector vUnitScale(1.0f, 1.0f, 1.0f); d3d_SetupTransformation(&pGrid->GetPos(), (float*)&pGrid->m_Rotation, &vUnitScale, &mWorldTrans); d3d_SetD3DMat(D3DTS_WORLD, &mWorldTrans); //calculate our position increments float fXInc = pGrid->GetDims().x * 2.0f / (pGrid->m_Width - 1); float fZInc = pGrid->GetDims().z * 2.0f / (pGrid->m_Height - 1); float fYScale = pGrid->GetDims().y / 127.0f; float fXStart = -fHalfGridWidth * fXInc; float fCurrX = fXStart; float fCurrZ = -fHalfGridHeight * fZInc; int8* pDataPos = (int8*)pGrid->m_Data; int8* pDataEnd = pDataPos + pGrid->m_Width * pGrid->m_Height; int8* pLineDataEnd = pDataPos + pGrid->m_Width; uint32* pColor = nColorTable + 128; float fXScale = pGrid->m_xScale / ((pGrid->m_Width - 1) * fXInc); float fZScale = pGrid->m_yScale / ((pGrid->m_Height - 1) * fZInc); float fStartU = (float)fmod(pGrid->m_xPan * fPGUScale, 1.0f); float fStartV = (float)fmod(pGrid->m_yPan * fPGVScale, 1.0f); float fCurrU = fStartU; float fCurrV = fStartV; float fUInc = fXInc * fXScale * fPGUScale; float fVInc = fZInc * fZScale * fPGVScale; int32 nWidth = pGrid->m_Width; float fSpacingX = fXInc * 2.0f; float fSpacingZ = fZInc * 2.0f; uint32 nNumVerts; bool bEffect = false; LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pGrid->m_nEffectShaderID); if(pEffect) { ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { bEffect = true; } } if(bBumpMap) { CPolyGridBumpVertex* pVertexPos = (CPolyGridBumpVertex*)g_TriVertList; if(pGrid->m_pValidMask) { //this polygrid has a valid mask, meaning that we need to skip over vertices //as needed uint32* pCurrMask = pGrid->m_pValidMask; //amount to adjust the mask at the end of a line uint32 nMaskLineAdjust = (pGrid->m_Width % 32) ? 1 : 0; uint32 nShift; uint32 nNormalY1 = 0; uint32 nNormalY2 = nWidth; float fWidthTimesHeight = fSpacingX * fSpacingZ; while(pDataPos < pDataEnd) { nShift = 0x1; while(pDataPos < pLineDataEnd) { if(*pCurrMask & nShift) { //this is valid, add this vertex d3d_SetupVertexPos(pVertexPos, fCurrX, *pDataPos * fYScale, fCurrZ, pColor[*pDataPos], fCurrU, fCurrV); //generate a normal for it GenerateBasisSpace(pDataPos, pVertexPos, -1, 1, nNormalY1, nNormalY2, fSpacingX, fSpacingZ, fWidthTimesHeight, fYScale); //move along to the next vertex pVertexPos++; } pDataPos++; fCurrX += fXInc; fCurrU += fUInc; if(nShift == 0x80000000) { pCurrMask++; nShift = 1; } else { nShift <<= 1; } } //reset the line fCurrX = fXStart; //update our threshold for when to move onto the next line pLineDataEnd += pGrid->m_Width; pCurrMask += nMaskLineAdjust; //update our position fCurrZ += fZInc; fCurrU = fStartU; fCurrV += fVInc; //update the normal offsets to ensure we don't go outside of our buffer nNormalY1 = -nWidth; if(pLineDataEnd >= pDataEnd) nNormalY2 = 0; } nNumVerts = pVertexPos - (CPolyGridBumpVertex*)g_TriVertList; } else { nNumVerts = pGrid->m_Width * pGrid->m_Height; while(pDataPos < pDataEnd) { while(pDataPos < pLineDataEnd) { d3d_SetupVertexPos(pVertexPos, fCurrX, *pDataPos * fYScale, fCurrZ, pColor[*pDataPos], fCurrU, fCurrV); pDataPos++; pVertexPos++; fCurrX += fXInc; fCurrU += fUInc; } //reset the line fCurrX = fXStart; //update our threshold for when to move onto the next line pLineDataEnd += pGrid->m_Width; //update our position fCurrZ += fZInc; fCurrU = fStartU; fCurrV += fVInc; } //now we need to generate the normals for the polygrid GeneratePolyGridVectors(pGrid, (CPolyGridBumpVertex*)g_TriVertList, GenerateBasisSpace); } } else if(bEffect) { CPolyGridEffectVertex* pVertexPos = (CPolyGridEffectVertex*)g_TriVertList; if(pGrid->m_pValidMask) { //this polygrid has a valid mask, meaning that we need to skip over vertices //as needed uint32* pCurrMask = pGrid->m_pValidMask; //amount to adjust the mask at the end of a line uint32 nMaskLineAdjust = (pGrid->m_Width % 32) ? 1 : 0; uint32 nShift; uint32 nNormalY1 = 0; uint32 nNormalY2 = nWidth; float fWidthTimesHeight = fSpacingX * fSpacingZ; while(pDataPos < pDataEnd) { nShift = 0x1; while(pDataPos < pLineDataEnd) { if(*pCurrMask & nShift) { //this is valid, add this vertex d3d_SetupVertexPos(pVertexPos, fCurrX, *pDataPos * fYScale, fCurrZ, pColor[*pDataPos], fCurrU, fCurrV); //generate a normal for it GenerateEffectBasisSpace(pDataPos, pVertexPos, -1, 1, nNormalY1, nNormalY2, fSpacingX, fSpacingZ, fWidthTimesHeight, fYScale); //move along to the next vertex pVertexPos++; } pDataPos++; fCurrX += fXInc; fCurrU += fUInc; if(nShift == 0x80000000) { pCurrMask++; nShift = 1; } else { nShift <<= 1; } } //reset the line fCurrX = fXStart; //update our threshold for when to move onto the next line pLineDataEnd += pGrid->m_Width; pCurrMask += nMaskLineAdjust; //update our position fCurrZ += fZInc; fCurrU = fStartU; fCurrV += fVInc; //update the normal offsets to ensure we don't go outside of our buffer nNormalY1 = -nWidth; if(pLineDataEnd >= pDataEnd) nNormalY2 = 0; } nNumVerts = pVertexPos - (CPolyGridEffectVertex*)g_TriVertList; } else { nNumVerts = pGrid->m_Width * pGrid->m_Height; while(pDataPos < pDataEnd) { while(pDataPos < pLineDataEnd) { d3d_SetupVertexPos(pVertexPos, fCurrX, *pDataPos * fYScale, fCurrZ, pColor[*pDataPos], fCurrU, fCurrV); pDataPos++; pVertexPos++; fCurrX += fXInc; fCurrU += fUInc; } //reset the line fCurrX = fXStart; //update our threshold for when to move onto the next line pLineDataEnd += pGrid->m_Width; //update our position fCurrZ += fZInc; fCurrU = fStartU; fCurrV += fVInc; } //now we need to generate the normals for the polygrid LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pGrid->m_nEffectShaderID); if(pEffect) { ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { GeneratePolyGridVectors(pGrid, (CPolyGridEffectVertex*)g_TriVertList, GenerateEffectBasisSpace); } } else { GeneratePolyGridVectors(pGrid, (CPolyGridVertex*)g_TriVertList, GenerateNormal); } } } else //fixed function { CPolyGridVertex* pVertexPos = (CPolyGridVertex*)g_TriVertList; if(pGrid->m_pValidMask) { //this polygrid has a valid mask, meaning that we need to skip over vertices //as needed uint32* pCurrMask = pGrid->m_pValidMask; //amount to adjust the mask at the end of a line uint32 nMaskLineAdjust = (pGrid->m_Width % 32) ? 1 : 0; uint32 nShift; uint32 nNormalY1 = 0; uint32 nNormalY2 = nWidth; float fWidthTimesHeight = fSpacingX * fSpacingZ; while(pDataPos < pDataEnd) { nShift = 0x1; while(pDataPos < pLineDataEnd) { if(*pCurrMask & nShift) { //this is valid, add this vertex d3d_SetupVertexPos(pVertexPos, fCurrX, *pDataPos * fYScale, fCurrZ, pColor[*pDataPos], fCurrU, fCurrV); //generate a normal for it GenerateNormal(pDataPos, pVertexPos, -1, 1, nNormalY1, nNormalY2, fSpacingX, fSpacingZ, fWidthTimesHeight, fYScale); //move along to the next vertex pVertexPos++; } pDataPos++; fCurrX += fXInc; fCurrU += fUInc; if(nShift == 0x80000000) { pCurrMask++; nShift = 1; } else { nShift <<= 1; } } //reset the line fCurrX = fXStart; //update our threshold for when to move onto the next line pLineDataEnd += pGrid->m_Width; pCurrMask += nMaskLineAdjust; //update our position fCurrZ += fZInc; fCurrU = fStartU; fCurrV += fVInc; //update the normal offsets to ensure we don't go outside of our buffer nNormalY1 = -nWidth; if(pLineDataEnd >= pDataEnd) nNormalY2 = 0; } nNumVerts = pVertexPos - (CPolyGridVertex*)g_TriVertList; } else { nNumVerts = pGrid->m_Width * pGrid->m_Height; while(pDataPos < pDataEnd) { while(pDataPos < pLineDataEnd) { d3d_SetupVertexPos(pVertexPos, fCurrX, *pDataPos * fYScale, fCurrZ, pColor[*pDataPos], fCurrU, fCurrV); pDataPos++; pVertexPos++; fCurrX += fXInc; fCurrU += fUInc; } //reset the line fCurrX = fXStart; //update our threshold for when to move onto the next line pLineDataEnd += pGrid->m_Width; //update our position fCurrZ += fZInc; fCurrU = fStartU; fCurrV += fVInc; } //now we need to generate the normals for the polygrid LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pGrid->m_nEffectShaderID); if(pEffect) { ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { GeneratePolyGridVectors(pGrid, (CPolyGridEffectVertex*)g_TriVertList, GenerateEffectBasisSpace); } } else { GeneratePolyGridVectors(pGrid, (CPolyGridVertex*)g_TriVertList, GenerateNormal); } } } // Set environment map texture coordinates. if(bEnvMap && !bBumpMap) { d3d_SetEnvMapTextureStates(Params, pTracker->m_pCurFrame->m_pTex->m_eTexType, pGrid, bCubicEnvMap); } //see if we are just doing a base texture if(!bEnvMap && !bBumpMap) { d3d_SetDefaultBlendStates(); } //generate the alpha if we can use it if(bBumpMap) { GeneratePolyGridFresnelAlphaAndCamera(Params.m_Pos, (CPolyGridBumpVertex*)g_TriVertList, pGrid, nNumVerts); } else if(bFresnel) { GeneratePolyGridFresnelAlpha(Params.m_Pos, (CPolyGridVertex*)g_TriVertList, pGrid, nNumVerts); } //make the backfacing polygons cull StateSet ssCullMode(D3DRS_CULLMODE, (pGrid->m_nPGFlags & PG_NOBACKFACECULL) ? D3DCULL_NONE : D3DCULL_CCW); //setup the pixel shader if we are bumpmapping if(bBumpMap) { assert(NULL != pPixelShader && pPixelShader->IsValidShader()); // Set the pixel shader constants. float *pConstants = pPixelShader->GetConstants(); pConstants[0] = 0.0f; pConstants[1] = 0.0f; pConstants[2] = 0.0f; pConstants[3] = pGrid->m_ColorA / 255.0f; LTPixelShaderMgr::GetSingleton().SetPixelShaderConstants(pPixelShader); // Install the pixel shader. LTPixelShaderMgr::GetSingleton().InstallPixelShader(pPixelShader); //now actually draw the polygrid D3D_CALL(PD3DDEVICE->SetVertexShader(NULL)); D3D_CALL(PD3DDEVICE->SetFVF(nVertexFVF)); int nNumPolies = (pGrid->m_nIndices/3); // Is this polygrid larger than our buffer? If so, break it into smaller patches. if(nNumPolies > g_CV_PolyGridBufferSize) { int32 nRemainingPolies = nNumPolies; uint32 nCurrentVertPosition = 0; while(nRemainingPolies > 0) { uint32 nPoliesThisFrame = (nRemainingPolies > g_CV_PolyGridBufferSize) ? g_CV_PolyGridBufferSize: nRemainingPolies; D3D_CALL(PD3DDEVICE->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,nNumVerts,nPoliesThisFrame,&pGrid->m_Indices[nCurrentVertPosition],D3DFMT_INDEX16,g_TriVertList, nVertexSize)); nCurrentVertPosition += nPoliesThisFrame*3; nRemainingPolies -= nPoliesThisFrame; } } else { D3D_CALL(PD3DDEVICE->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,nNumVerts,(pGrid->m_nIndices)/3,pGrid->m_Indices,D3DFMT_INDEX16,g_TriVertList, nVertexSize)); } // Uninstall the pixel shader. LTPixelShaderMgr::GetSingleton().UninstallPixelShader(); d3d_DisableTexture(0); d3d_DisableTexture(3); } else { //now actually draw the polygrid D3D_CALL(PD3DDEVICE->SetVertexShader(NULL)); D3D_CALL(PD3DDEVICE->SetFVF(nVertexFVF)); int nNumPolies = (pGrid->m_nIndices/3); // Is this polygrid larger than our buffer? If so, break it into smaller patches. if(nNumPolies > g_CV_PolyGridBufferSize) { int32 nRemainingPolies = nNumPolies; uint32 nCurrentVertPosition = 0; while(nRemainingPolies > 0) { uint32 nPoliesThisFrame = (nRemainingPolies > g_CV_PolyGridBufferSize) ? g_CV_PolyGridBufferSize: nRemainingPolies; LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pGrid->m_nEffectShaderID); if(pEffect) { pEffect->UploadVertexDeclaration(); ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { i_client_shell->OnEffectShaderSetParams(pEffect, NULL, NULL, LTShaderDeviceStateImp::GetSingleton()); UINT nPasses = 0; pD3DEffect->Begin(&nPasses, 0); for(UINT i = 0; i < nPasses; ++i) { pD3DEffect->BeginPass(i); D3D_CALL(PD3DDEVICE->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,nNumVerts,nPoliesThisFrame,&pGrid->m_Indices[nCurrentVertPosition],D3DFMT_INDEX16,g_TriVertList, nVertexSize)); pD3DEffect->EndPass(); } pD3DEffect->End(); } } else { D3D_CALL(PD3DDEVICE->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,nNumVerts,nPoliesThisFrame,&pGrid->m_Indices[nCurrentVertPosition],D3DFMT_INDEX16,g_TriVertList, nVertexSize)); } nCurrentVertPosition += nPoliesThisFrame*3; nRemainingPolies -= nPoliesThisFrame; } } else { LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pGrid->m_nEffectShaderID); if(pEffect) { pEffect->UploadVertexDeclaration(); ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { i_client_shell->OnEffectShaderSetParams(pEffect, NULL, NULL, LTShaderDeviceStateImp::GetSingleton()); UINT nPasses = 0; pD3DEffect->Begin(&nPasses, 0); for(UINT i = 0; i < nPasses; ++i) { pD3DEffect->BeginPass(i); D3D_CALL(PD3DDEVICE->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,nNumVerts,(pGrid->m_nIndices)/3,pGrid->m_Indices,D3DFMT_INDEX16,g_TriVertList, nVertexSize)); pD3DEffect->EndPass(); } pD3DEffect->End(); } } else { // No Effect Shader, just fixed function. D3D_CALL(PD3DDEVICE->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,nNumVerts,(pGrid->m_nIndices)/3,pGrid->m_Indices,D3DFMT_INDEX16,g_TriVertList, nVertexSize)); } } d3d_DisableTexture(0); d3d_DisableTexture(1); } if (bEnvMap) d3d_UnsetEnvMapTextureStates(); //reset our world transform so that it won't mess up the rendering of other objects d3d_SetD3DMat(D3DTS_WORLD, &Params.m_mIdentity); }
//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; }
LTBOOL CGameButeMgr::Parse(const char* sButeFile) { // Sanity checks... if (!sButeFile) return(LTFALSE); BOOL bRet = TRUE; //if there is no g_pLTBase, then we can't read from the stream if (!g_pLTBase || !m_bInRezFile) { // Append the GAME directory onto the filename if this file is normally // stored in the .rez file... if (m_bInRezFile) { m_strAttributeFile.Format("Game\\%s", sButeFile); } else { m_strAttributeFile.Format("%s", sButeFile); } if (m_pCryptKey) { bRet = m_buteMgr.Parse(m_strAttributeFile, m_pCryptKey); } else { bRet = m_buteMgr.Parse(m_strAttributeFile); } return bRet; } // Open the file... m_strAttributeFile = sButeFile; ILTStream* pDStream = LTNULL; LTRESULT dr = g_pLTBase->OpenFile(m_strAttributeFile, &pDStream); if (dr != LT_OK || !pDStream) { char sError[512]; sprintf(sError,"ERROR CGameButeMgr couldn't open file %s!",m_strAttributeFile); GBM_DisplayError(sError); #ifdef _CLIENTBUILD g_pLTClient->ShutdownWithMessage(sError); #endif return(FALSE); } // Read the file... unsigned long uLen = pDStream->GetLen(); char* pData = debug_newa(char, uLen); if (!pData) { pDStream->Release(); GBM_DisplayError("ERROR CGameButeMgr couldn't allocate data for stream."); return(FALSE); } pDStream->Read(pData, uLen); // Setup the save file name. This is for saving the attribute file from // the game and is ONLY used during development... CString strSaveFilename = ""; #ifndef _FINAL strSaveFilename = sButeFile; if (m_bInRezFile) { strSaveFilename.Format("Game\\%s", sButeFile); } #endif // _FINAL // Parse the file... if (m_pCryptKey) { bRet = m_buteMgr.Parse(pData, uLen, m_pCryptKey, strSaveFilename); } else { bRet = m_buteMgr.Parse(pData, uLen, 0, strSaveFilename); } // Clean up... pDStream->Release(); debug_deletea(pData); // Check for an error... if (!bRet) { TRACE("ERROR CGameButeMgr::Parse() (%s)!\n", sButeFile); return(FALSE); } // All done... return(TRUE); }
// Loads the texture and installs it. LTRESULT r_LoadSystemTexture(SharedTexture *pSharedTexture) { LTRESULT dResult; FileRef ref; FileIdentifier *pIdent = pSharedTexture->m_pFile; if (!pIdent) return LT_NOTINITIALIZED; uint32 nBaseWidth; uint32 nBaseHeight; //the texture data that is associated with the texture TextureData* pTextureData = NULL; ILTStream *pStream = client_file_mgr->OpenFileIdentifier(pIdent); if (pStream) { dResult = dtx_Create(pStream, &pTextureData, nBaseWidth, nBaseHeight); pStream->Release(); if (dResult != LT_OK) return dResult; } else { RETURN_ERROR_PARAM(1, r_LoadSystemTexture, LT_MISSINGFILE, pIdent->m_Filename); } //make sure to setup the texture information pSharedTexture->SetTextureInfo(nBaseWidth, nBaseHeight, pTextureData->m_PFormat); // Add the new texture to the MRU list. dl_AddHead(&g_SysCache.m_List, &pTextureData->m_Link, pTextureData); g_SysCache.m_CurMem += pTextureData->m_AllocSize; // Store its pointer in the SharedTexture. pSharedTexture->m_pEngineData = pTextureData; pTextureData->m_pSharedTexture = pSharedTexture; // Load in any linked textures depending upon what the user entered in the command string. Note //that these are exclusive ConParse parse; //Normal detail texturing parse.Init(pTextureData->m_Header.m_CommandString); if (parse.ParseFind("DetailTex", LTFALSE, 1)) { //validate the argument count if(parse.m_nArgs < 2) { RETURN_ERROR_PARAM(1, r_LoadSystemTexture, LT_INVALIDDATA, "DetailTex : parse.m_Args[1]"); } ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[1]; pSharedTexture->SetLinkedTexture(eLinkedTex_Detail, g_pClientMgr->AddSharedTexture(&ref)); pSharedTexture->m_eTexType = eSharedTexType_Detail; return LT_OK; } //Normal environment mapping parse.Init(pTextureData->m_Header.m_CommandString); if (parse.ParseFind("EnvMap", LTFALSE, 1)) { //validate the argument count if(parse.m_nArgs < 2) { RETURN_ERROR_PARAM(1, r_LoadSystemTexture, LT_INVALIDDATA, "EnvMap : parse.m_Args[1]"); } ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[1]; pSharedTexture->SetLinkedTexture(eLinkedTex_EnvMap, g_pClientMgr->AddSharedTexture(&ref)); pSharedTexture->m_eTexType = eSharedTexType_EnvMap; return LT_OK; } //Environment mapping blended with the alpha of the base texture parse.Init(pTextureData->m_Header.m_CommandString); if (parse.ParseFind("EnvMapAlpha", LTFALSE, 1)) { //validate the argument count if(parse.m_nArgs < 2) { RETURN_ERROR_PARAM(1, r_LoadSystemTexture, LT_INVALIDDATA, "EnvMapAlpha : parse.m_Args[1]"); } ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[1]; pSharedTexture->SetLinkedTexture(eLinkedTex_EnvMap, g_pClientMgr->AddSharedTexture(&ref)); pSharedTexture->m_eTexType = eSharedTexType_EnvMapAlpha; return LT_OK; } //Environment mapping with a bumpmap texture parse.Init(pTextureData->m_Header.m_CommandString); if (parse.ParseFind("EnvBumpMap", LTFALSE, 2)) { //validate the argument count if(parse.m_nArgs < 3) { if(parse.m_nArgs < 2) { RETURN_ERROR_PARAM(1, r_LoadSystemTexture, LT_INVALIDDATA, "EnvBumpMap : parse.m_Args[1]"); } RETURN_ERROR_PARAM(1, r_LoadSystemTexture, LT_INVALIDDATA, "EnvBumpMap : parse.m_Args[2]"); } //handle loading up the environment map first ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[1]; pSharedTexture->SetLinkedTexture(eLinkedTex_EnvMap, g_pClientMgr->AddSharedTexture(&ref)); //now handle loading up the bumpmap ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[2]; pSharedTexture->SetLinkedTexture(eLinkedTex_BumpMap, g_pClientMgr->AddSharedTexture(&ref)); //setup the shader type pSharedTexture->m_eTexType = eSharedTexType_EnvBumpMap; return LT_OK; } //Environment mapping with a bumpmap texture but no fallback parse.Init(pTextureData->m_Header.m_CommandString); if (parse.ParseFind("EnvBumpMapNoFallback", LTFALSE, 2)) { //validate the argument count if(parse.m_nArgs < 3) { if(parse.m_nArgs < 2) { RETURN_ERROR_PARAM(1, r_LoadSystemTexture, LT_INVALIDDATA, "EnvBumpMapNoFallback : parse.m_Args[1]"); } RETURN_ERROR_PARAM(1, r_LoadSystemTexture, LT_INVALIDDATA, "EnvBumpMapNoFallback : parse.m_Args[2]"); } //handle loading up the environment map first ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[1]; pSharedTexture->SetLinkedTexture(eLinkedTex_EnvMap, g_pClientMgr->AddSharedTexture(&ref)); //now handle loading up the bumpmap ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[2]; pSharedTexture->SetLinkedTexture(eLinkedTex_BumpMap, g_pClientMgr->AddSharedTexture(&ref)); //setup the shader type pSharedTexture->m_eTexType = eSharedTexType_EnvBumpMap_NoFallback; return LT_OK; } //DOT3 bumpmap texture parse.Init(pTextureData->m_Header.m_CommandString); if (parse.ParseFind("DOT3BumpMap", LTFALSE, 1)) { //validate the argument count if(parse.m_nArgs < 2) { RETURN_ERROR_PARAM(1, r_LoadSystemTexture, LT_INVALIDDATA, "DOT3BumpMap : parse.m_Args[1]"); } //now handle loading up the bumpmap ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[1]; pSharedTexture->SetLinkedTexture(eLinkedTex_BumpMap, g_pClientMgr->AddSharedTexture(&ref)); //setup the shader type pSharedTexture->m_eTexType = eSharedTexType_DOT3BumpMap; return LT_OK; } //Environment mapping with a DOT3 bumpmap texture but no fallback parse.Init(pTextureData->m_Header.m_CommandString); if (parse.ParseFind("DOT3EnvBumpMap", LTFALSE, 2)) { //validate the argument count if(parse.m_nArgs < 3) { if(parse.m_nArgs < 2) { RETURN_ERROR_PARAM(1, r_LoadSystemTexture, LT_INVALIDDATA, "DOT3EnvBumpMap : parse.m_Args[1]"); } RETURN_ERROR_PARAM(1, r_LoadSystemTexture, LT_INVALIDDATA, "DOT3EnvBumpMap : parse.m_Args[2]"); } //handle loading up the environment map first ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[1]; pSharedTexture->SetLinkedTexture(eLinkedTex_EnvMap, g_pClientMgr->AddSharedTexture(&ref)); //now handle loading up the bumpmap ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[2]; pSharedTexture->SetLinkedTexture(eLinkedTex_BumpMap, g_pClientMgr->AddSharedTexture(&ref)); //setup the shader type pSharedTexture->m_eTexType = eSharedTexType_DOT3EnvBumpMap; return LT_OK; } //Effect File Support parse.Init(pTextureData->m_Header.m_CommandString); if (parse.ParseFind("Effect", LTFALSE, 1)) { //validate the argument count if(parse.m_nArgs < 2) { RETURN_ERROR_PARAM(1, r_LoadSystemTexture, LT_INVALIDDATA, "Effect : parse.m_Args[1]"); } // Set up our shader ID pSharedTexture->m_nShaderID = (int)atoi(parse.m_Args[1]); pSharedTexture->m_eTexType = eSharedTexType_Effect; if(parse.m_nArgs > 2) { ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[2]; pSharedTexture->SetLinkedTexture(eLinkedTex_EffectTexture1, g_pClientMgr->AddSharedTexture(&ref)); pSharedTexture->m_eTexType = eSharedTexType_Effect; } if(parse.m_nArgs > 3) { ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[3]; pSharedTexture->SetLinkedTexture(eLinkedTex_EffectTexture2, g_pClientMgr->AddSharedTexture(&ref)); pSharedTexture->m_eTexType = eSharedTexType_Effect; } if(parse.m_nArgs > 4) { ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[4]; pSharedTexture->SetLinkedTexture(eLinkedTex_EffectTexture3, g_pClientMgr->AddSharedTexture(&ref)); pSharedTexture->m_eTexType = eSharedTexType_Effect; } if(parse.m_nArgs > 5) { ref.m_FileType = FILE_CLIENTFILE; ref.m_pFilename = parse.m_Args[5]; pSharedTexture->SetLinkedTexture(eLinkedTex_EffectTexture4, g_pClientMgr->AddSharedTexture(&ref)); pSharedTexture->m_eTexType = eSharedTexType_Effect; } return LT_OK; } //just a normal texture... return LT_OK; }
LTBOOL CGameButeMgr::Parse(ILTCSBase *pInterface, const char* sButeFile) { // Sanity checks... if (!sButeFile) return(LTFALSE); BOOL bRet = TRUE; // NOTE!!! When _REZFILE is defined, this code will need to be // updated to support being called from DEdit!!!! // (from a IObjectPlugin::PreHook_EditStringList() call)... #if !defined(_REZFILE) // If we're going to allow the bute file to be saved by the game, it must // be read in from a file (not a .rez file)... // Append the NOLF directory onto the filename if this file is normally // stored in the .rez file... if (m_bInRezFile) { m_strAttributeFile.Format("NOLF\\%s", sButeFile); } else { m_strAttributeFile.Format("%s", sButeFile); } if (m_pCryptKey) { bRet = m_buteMgr.Parse(m_strAttributeFile, m_pCryptKey); } else { bRet = m_buteMgr.Parse(m_strAttributeFile); } return bRet; #endif // !_REZFILE m_strAttributeFile = sButeFile; // Open the file... char sConstFile[256]; strncpy(sConstFile, sButeFile, 255); ILTStream* pDStream; LTRESULT dr = pInterface->OpenFile(sConstFile, &pDStream); if (dr != LT_OK) { char sError[512]; sprintf(sError,"ERROR CGameButeMgr couldn't open file %s!",sButeFile); GBM_DisplayError(sError); #ifdef _CLIENTBUILD g_pLTClient->ShutdownWithMessage(sError); #endif return(FALSE); } // Read the file... unsigned long uLen = pDStream->GetLen(); char* pData = debug_newa(char, uLen); if (!pData) { pDStream->Release(); GBM_DisplayError("CGameButeMgr couldn't allocate data for stream."); return(FALSE); } pDStream->Read(pData, uLen); // Parse the file... if (m_pCryptKey) { bRet = m_buteMgr.Parse(pData, uLen, m_pCryptKey); } else { bRet = m_buteMgr.Parse(pData, uLen); } // Clean up... pDStream->Release(); debug_deletea(pData); // Check for an error... if (!bRet) { TRACE("CGameButeMgr::Parse() ERROR!\n"); return(FALSE); } // All done... return(TRUE); }
uint32 GetWorldTextureInfo(CPreWorld *pWorld, CGLinkedList<TInfo*> &theList) { GPOS pos; CPreSurface *pSurface; uint32 nFlagsGotten; TInfo *pFlags; char fileName[MAX_PATH]; ILTStream *pStream; TextureData *pData; char pszTextureName[MAX_PATH]; nFlagsGotten = 0; for(pos=pWorld->m_Surfaces; pos; ) { pSurface = pWorld->m_Surfaces.GetNext(pos); for(uint32 nCurrTex = 0; nCurrTex < CPreSurface::NUM_TEXTURES; nCurrTex++) { CPreTexture& Tex = pSurface->m_Texture[nCurrTex]; if(!Tex.IsValid()) continue; pFlags = FindTInfo(theList, Tex.m_pTextureName); if(pFlags) { ++nFlagsGotten; } else { //see if this is a sprite if(CSpriteFile::IsSprite(Tex.m_pTextureName)) { //build up the sprite filename sprintf(fileName, "%s\\%s", g_pGlobs->m_ProjectDir, Tex.m_pTextureName); //open up the file CSpriteFile Sprite; if(!Sprite.Load(fileName)) continue; if(Sprite.GetNumFrames() > 0) { //read in the first string strcpy(pszTextureName, Sprite.GetFrame(0)); } } else { //we have a texture, so lets copy it over strcpy(pszTextureName, Tex.m_pTextureName); } sprintf(fileName, "%s\\%s", g_pGlobs->m_ProjectDir, pszTextureName); pStream = streamsim_Open(fileName, "rb"); if(pStream) { if(dtx_Create(pStream, &pData, TRUE, TRUE) == DE_OK) { pFlags = new TInfo; pFlags->m_Width = pData->m_Header.m_BaseWidth; pFlags->m_Height = pData->m_Header.m_BaseHeight; pFlags->m_pTextureName = (char*)Tex.m_pTextureName; pFlags->m_Flags = (uint16)pData->m_Header.m_UserFlags; theList.Append(pFlags); ++nFlagsGotten; dtx_Destroy(pData); } pStream->Release(); } } } } return nFlagsGotten; }
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; }
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 }
/* IStream methods */ STDMETHODIMP CLTDMFileStream::Read( void* pv, ULONG cb, ULONG* pcbRead ) { #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; } // read in the data if (pLTStream->Read( pv, cb) != LT_OK) { m_pOpenQueueItem->UnLockDStream(); return E_FAIL; } // set the number of bytes read if (pcbRead != NULL) *pcbRead = cb; 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 read 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 read from file because rez file was not open\n"); m_pLoader->LeaveRezMgrCriticalSection(); return E_FAIL; } // variable to hold the actual number of bytes that were read in when read is called size_t nBytesRead; // read the data from the rez file nBytesRead = m_pRezItem->Read(pv, cb, m_nCurPos); // advance seek pos m_nCurPos += nBytesRead; // return OK if we read all of the requested data if(cb == nBytesRead) { // set the number of bytes read callback if it is not NULL if(pcbRead != NULL)*pcbRead = nBytesRead; m_pLoader->LeaveRezMgrCriticalSection(); return S_OK; } // if we didn't read all of the data fail else { m_pLoader->LeaveRezMgrCriticalSection(); return E_FAIL; } m_pLoader->LeaveRezMgrCriticalSection(); #endif #ifdef USE_FILE size_t dw; dw = fread( pv, sizeof(char), cb, m_pFile ); if( cb == dw ) { if( pcbRead != NULL ) { *pcbRead = cb; } return S_OK; } return E_FAIL ; #endif }