BOOL WINAPI ExtractResource(IN HMODULE hModule, IN LPCSTR lpszResName, IN LPCSTR lpszResType, IN LPCSTR lpszFileName) { assert(lpszResName); assert(lpszResType); assert(lpszFileName); // Load the resource from the specified module LPCVOID lpvResData; DWORD dwResSize, dwBytesWritten; if (!LookupResource(hModule, lpszResName, lpszResType, &lpvResData, &dwResSize)) return FALSE; // Open the target file for writing BOOL bRetVal = FALSE; HANDLE hOutFile = CreateFile(lpszFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if (hOutFile != INVALID_HANDLE_VALUE) { // Write the resource to the file. Because the entire resource is memory mapped, we can do this in a single call. if (WriteFile(hOutFile, lpvResData, dwResSize, &dwBytesWritten, NULL) && (dwBytesWritten == dwResSize)) { SetEndOfFile(hOutFile); bRetVal = TRUE; } // Clean up. Delete the file if extraction failed. CloseHandle(hOutFile); if (!bRetVal) DeleteFile(lpszFileName); } return bRetVal; }
void CAnimationTreePackedLoader::FixUpAnimTreeData( CAnimationTreePacked* pAnimTree, const char* pszFilename ) { // Sanity check. if( !pAnimTree ) { return; } // AnimProps. // Convert strings to enums. uint32 iEnum; const char* pszName; for( iEnum=0; iEnum < pAnimTree->m_cAnimProps; ++iEnum ) { pszName = pAnimTree->m_pszStringTable + pAnimTree->m_aAnimProps[iEnum]; pAnimTree->m_aAnimProps[iEnum] = AnimPropUtils::Enum( pszName ); } // AnimDescs. // Convert strings to enums. for( iEnum=0; iEnum < pAnimTree->m_cAnimDescs; ++iEnum ) { pszName = pAnimTree->m_pszStringTable + pAnimTree->m_aAnimDescs[iEnum]; pAnimTree->m_aAnimDescs[iEnum] = GetAnimationDescriptorFromName( pszName ); } // AnimPropGroups. // Convert strings to enums and set pointers into enum array. uint32 iGroup; uint32 iEnumOffset; for( iGroup=0; iGroup < pAnimTree->m_cAnimPropGroups; ++iGroup ) { pszName = pAnimTree->m_pszStringTable + pAnimTree->m_aAnimPropGroups[iGroup].eAnimPropGroup; pAnimTree->m_aAnimPropGroups[iGroup].eAnimPropGroup = GetAnimationPropGroupFromName( pszName ); iEnumOffset = (uint32)( pAnimTree->m_aAnimPropGroups[iGroup].aAnimProps ); pAnimTree->m_aAnimPropGroups[iGroup].aAnimProps = pAnimTree->m_aAnimProps + iEnumOffset; } // AnimDescGroups. // Convert strings to enums and set pointers into enum array. for( iGroup=0; iGroup < pAnimTree->m_cAnimDescGroups; ++iGroup ) { pszName = pAnimTree->m_pszStringTable + pAnimTree->m_aAnimDescGroups[iGroup].eAnimDescGroup; pAnimTree->m_aAnimDescGroups[iGroup].eAnimDescGroup = GetAnimationDescriptorGroupFromName( pszName ); iEnumOffset = (uint32)( pAnimTree->m_aAnimDescGroups[iGroup].aAnimDescs ); pAnimTree->m_aAnimDescGroups[iGroup].aAnimDescs = pAnimTree->m_aAnimDescs + iEnumOffset; } // Transition AnimDescs. // Convert AnimDesc indices into enums. uint32 cEnums = pAnimTree->m_cTransitions * pAnimTree->m_cAnimDescGroups; for( iEnum=0; iEnum < cEnums; ++iEnum ) { iEnumOffset = pAnimTree->m_aTransitionAnimDescs[iEnum]; pAnimTree->m_aTransitionAnimDescs[iEnum] = pAnimTree->m_aAnimDescs[iEnumOffset]; } // Transitions. // Convert name string table indices to pointers. // Convert enum list indices into pointers. // Convert blend data uint32 iTrans; for( iTrans=0; iTrans < pAnimTree->m_cTransitions; ++iTrans ) { pszName = pAnimTree->m_pszStringTable + (uint32)pAnimTree->m_aTransitions[iTrans].szName; pAnimTree->m_aTransitions[iTrans].szName = pszName; iEnumOffset = (uint32)pAnimTree->m_aTransitions[iTrans].aTransitionAnimDescs; pAnimTree->m_aTransitions[iTrans].aTransitionAnimDescs = pAnimTree->m_aTransitionAnimDescs + iEnumOffset; FixUpBlendData( pAnimTree, pAnimTree->m_aTransitions[iTrans].BlendData ); } // Transition set transitions. // Convert transition IDs into pointers. for( iTrans=0; iTrans < pAnimTree->m_cTransitionSetTransitions; ++iTrans ) { iEnumOffset = (uint32)pAnimTree->m_aTransitionSetTransitions[iTrans]; pAnimTree->m_aTransitionSetTransitions[iTrans] = pAnimTree->m_aTransitions + iEnumOffset; } // Transition sets. // Convert transition ID list indices into pointers. uint32 iSetOffset; for( uint32 iSet=0; iSet < pAnimTree->m_cTransitionSets; ++iSet ) { iSetOffset = (uint32)pAnimTree->m_aTransitionSets[iSet].aTransitions; pAnimTree->m_aTransitionSets[iSet].aTransitions = pAnimTree->m_aTransitionSetTransitions + iSetOffset; } // Animation AnimDescs. // Convert AnimDesc indices into enums. cEnums = pAnimTree->m_cAnimations * pAnimTree->m_cAnimDescGroups; for( iEnum=0; iEnum < cEnums; ++iEnum ) { iEnumOffset = pAnimTree->m_aAnimationAnimDescs[iEnum]; pAnimTree->m_aAnimationAnimDescs[iEnum] = pAnimTree->m_aAnimDescs[iEnumOffset]; } // Animations. // Convert name string table indices to pointers. // Convert enum list indices into pointers. // Convert default transition IDs into pointers. // Convert transition set IDs into pointers. // Convert blend data uint32 iAnim; uint32 iTransOffset; for( iAnim=0; iAnim < pAnimTree->m_cAnimations; ++iAnim ) { pszName = pAnimTree->m_pszStringTable + (uint32)pAnimTree->m_aAnimations[iAnim].szName; pAnimTree->m_aAnimations[iAnim].szName = pszName; iEnumOffset = (uint32)pAnimTree->m_aAnimations[iAnim].aAnimationAnimDescs; pAnimTree->m_aAnimations[iAnim].aAnimationAnimDescs = pAnimTree->m_aAnimationAnimDescs + iEnumOffset; iTransOffset = (uint32)pAnimTree->m_aAnimations[iAnim].pDefaultTransitionIn; pAnimTree->m_aAnimations[iAnim].pDefaultTransitionIn = NULL; if( iTransOffset != -1 ) { pAnimTree->m_aAnimations[iAnim].pDefaultTransitionIn = pAnimTree->m_aTransitions + iTransOffset; } iTransOffset = (uint32)pAnimTree->m_aAnimations[iAnim].pDefaultTransitionOut; pAnimTree->m_aAnimations[iAnim].pDefaultTransitionOut = NULL; if( iTransOffset != -1 ) { pAnimTree->m_aAnimations[iAnim].pDefaultTransitionOut = pAnimTree->m_aTransitions + iTransOffset; } iSetOffset = (uint32)pAnimTree->m_aAnimations[iAnim].pTransitionSetIn; pAnimTree->m_aAnimations[iAnim].pTransitionSetIn = NULL; if( iSetOffset != -1 ) { pAnimTree->m_aAnimations[iAnim].pTransitionSetIn = pAnimTree->m_aTransitionSets + iSetOffset; } iSetOffset = (uint32)pAnimTree->m_aAnimations[iAnim].pTransitionSetOut; pAnimTree->m_aAnimations[iAnim].pTransitionSetOut = NULL; if( iSetOffset != -1 ) { pAnimTree->m_aAnimations[iAnim].pTransitionSetOut = pAnimTree->m_aTransitionSets + iSetOffset; } FixUpBlendData( pAnimTree, pAnimTree->m_aAnimations[iAnim].BlendData ); } // Pattern AnimProps. // Convert AnimProp list indices into enums. cEnums = pAnimTree->m_cPatterns * pAnimTree->m_cAnimPropGroups; for( iEnum=0; iEnum < cEnums; ++iEnum ) { iEnumOffset = pAnimTree->m_aPatternAnimProps[iEnum]; pAnimTree->m_aPatternAnimProps[iEnum] = pAnimTree->m_aAnimProps[iEnumOffset]; } // Patterns. // Convert enum list indices into pointers. // Convert anim list indices into pointers. float fTotalWeight; uint32 iAnimOffset; AT_ANIMATION* pAnim; for( uint32 iPattern=0; iPattern < pAnimTree->m_cPatterns; ++iPattern ) { iEnumOffset = (uint32)pAnimTree->m_aPatterns[iPattern].aAnimProps; pAnimTree->m_aPatterns[iPattern].aAnimProps = pAnimTree->m_aPatternAnimProps + iEnumOffset; iAnimOffset = (uint32)pAnimTree->m_aPatterns[iPattern].aAnimations; pAnimTree->m_aPatterns[iPattern].aAnimations = pAnimTree->m_aAnimations + iAnimOffset; // Fixup pointers inside of anim structs to pattern's anim prop list. // Convert the random weights into random upper limits. fTotalWeight = 0.f; for( iAnim=0; iAnim < pAnimTree->m_aPatterns[iPattern].cAnimations; ++iAnim ) { pAnim = &( pAnimTree->m_aPatterns[iPattern].aAnimations[iAnim] ); pAnim->aAnimationAnimProps = pAnimTree->m_aPatterns[iPattern].aAnimProps; fTotalWeight += pAnim->fRandomWeightUpperLimit; pAnim->fRandomWeightUpperLimit = fTotalWeight; } } // Tree nodes. // Convert AnimProp list indices into enums. // Convert AnimPropGroup list indices into enums. // Convert pattern list indices into pointers. // Convert node list indices into pointers. uint32 iPatternOffset; uint32 iNodeOffset; for( uint32 iNode=0; iNode < pAnimTree->m_cTreeNodes; ++iNode ) { // Branch node. iEnumOffset = pAnimTree->m_aTreeNodes[iNode].eSplittingAnimProp; if( iEnumOffset != -1 ) { pAnimTree->m_aTreeNodes[iNode].eSplittingAnimProp = pAnimTree->m_aAnimProps[iEnumOffset]; iEnumOffset = pAnimTree->m_aTreeNodes[iNode].eSplittingAnimPropGroup; pAnimTree->m_aTreeNodes[iNode].eSplittingAnimPropGroup = pAnimTree->m_aAnimPropGroups[iEnumOffset].eAnimPropGroup; pAnimTree->m_aTreeNodes[iNode].pPattern = NULL; iNodeOffset = (uint32)pAnimTree->m_aTreeNodes[iNode].pNodePositive; LookupResource( &pAnimTree->m_aTreeNodes[iNode].pNodePositive, iNodeOffset, pAnimTree->m_aTreeNodes, pAnimTree->m_cTreeNodes, pszFilename ); iNodeOffset = (uint32)pAnimTree->m_aTreeNodes[iNode].pNodeNegative; LookupResource( &pAnimTree->m_aTreeNodes[iNode].pNodeNegative, iNodeOffset, pAnimTree->m_aTreeNodes, pAnimTree->m_cTreeNodes, pszFilename ); } // Leaf node. else { pAnimTree->m_aTreeNodes[iNode].eSplittingAnimProp = kAP_Invalid; pAnimTree->m_aTreeNodes[iNode].eSplittingAnimPropGroup = kAPG_Invalid; iPatternOffset = (uint32)pAnimTree->m_aTreeNodes[iNode].pPattern; LookupResource( &pAnimTree->m_aTreeNodes[iNode].pPattern, iPatternOffset, pAnimTree->m_aPatterns, pAnimTree->m_cPatterns, pszFilename ); pAnimTree->m_aTreeNodes[iNode].pNodePositive = NULL; pAnimTree->m_aTreeNodes[iNode].pNodeNegative = NULL; } } }