Beispiel #1
0
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;
		}
	}
}