bool IterateAnimObjDrawInfo(const SuperAnimHandler &theHandler, SuperAnimObjDrawInfo& theOutputObjDrawInfo){ if (!sShouldStartAnimObjDrawItr) { assert(false && "Forgot to call BeginIterateAnimObjDrawInfo?"); return false; } if (!theHandler.IsValid()) { assert(false && "The Animation handler is not valid."); return false; } SuperAnimMainDef *aMainDef = SuperAnimDefMgr::GetInstance()->Load_GetSuperAnimMainDef(theHandler.mMainDefKey); if (aMainDef == NULL) { assert(false && "I can't find the Animation definition."); return false; } int aCurFrameNum = (int)theHandler.mCurFrameNum; SuperAnimFrame *aCurFrame = &aMainDef->mFrames[aCurFrameNum]; if (sAnimObjIndex >= aCurFrame->mObjectVector.size()) { // we have iterated all objects in this frame sShouldStartAnimObjDrawItr = false; return false; } SuperAnimObject *aCurObject = &aCurFrame->mObjectVector[sAnimObjIndex]; // find the image, fill the sprite id SuperAnimImage *aSuperAnimImage = &aMainDef->mImageVector[aCurObject->mResNum]; theOutputObjDrawInfo.mSpriteId = aSuperAnimImage->mSpriteId; // do the interpolateion to next frame for transform & color if (aCurFrameNum == aMainDef->mEndFrameNum) { // reach the end frame, don't need to do any interpolation theOutputObjDrawInfo.mTransform = aCurObject->mTransform; theOutputObjDrawInfo.mColor = aCurObject->mColor; } else { int aNextFrameNum = aCurFrameNum + 1; bool finishedInterp = false; SuperAnimFrame *aNextFrame = &aMainDef->mFrames[aNextFrameNum]; for (int i = 0; i < aNextFrame->mObjectVector.size(); ++i) { SuperAnimObject *anObj = &aNextFrame->mObjectVector[i]; if (anObj->mObjectNum == aCurObject->mObjectNum) { float anInterp = theHandler.mCurFrameNum - aCurFrameNum; theOutputObjDrawInfo.mTransform = aCurObject->mTransform.InterpolateTo(anObj->mTransform, anInterp); theOutputObjDrawInfo.mColor = aCurObject->mColor.InterpolateTo(anObj->mColor, anInterp); finishedInterp = true; break; } } if (!finishedInterp) { // we miss the object in next frame? // never mind theOutputObjDrawInfo.mTransform = aCurObject->mTransform; theOutputObjDrawInfo.mColor = aCurObject->mColor; } } theOutputObjDrawInfo.mTransform = theOutputObjDrawInfo.mTransform.TransformSrc(aSuperAnimImage->mTransform); SuperAnimMatrix3 aMatrix; aMatrix.LoadIdentity(); aMatrix.m02 = aSuperAnimImage->mWidth * 0.5f; aMatrix.m12 = aSuperAnimImage->mHeight * 0.5f; theOutputObjDrawInfo.mTransform.mMatrix = theOutputObjDrawInfo.mTransform.mMatrix * aMatrix; sAnimObjIndex++; return true; }
bool SuperAnimDefMgr::LoadSuperAnimMainDef(std::string theSuperAnimFile) { std::string aFullPath = theSuperAnimFile; std::string aCurDir = ""; int aLastSlash = max((int) theSuperAnimFile.rfind('\\'), (int) theSuperAnimFile.rfind('/')); if (aLastSlash != std::string::npos){ aCurDir = theSuperAnimFile.substr(0, aLastSlash); } FILE *aFile = fopen(aFullPath.c_str(), "rb"); if (aFile == NULL) { assert(false && "Can't open animation file."); return false; } fseek(aFile, 0, SEEK_END); unsigned long aFileSize = ftell(aFile); fseek(aFile, 0, SEEK_SET); unsigned char *aFileBuffer = new unsigned char[aFileSize]; if (aFileBuffer == NULL) { assert(false && "Cannot allocate memory."); return false; } aFileSize = fread(aFileBuffer, sizeof(unsigned char), aFileSize, aFile); fclose(aFile); BufferReader aBuffer; aBuffer.SetData(aFileBuffer, aFileSize); // free memory delete[] aFileBuffer; aFileBuffer = NULL; if (aBuffer.ReadLong() != 0x2E53414D) { assert(false && "Bad file format."); return false; } int aVersion = aBuffer.ReadLong(); if (aVersion != SAM_VERSION) { assert(false && "Wrong version."); return false; } SuperAnimMainDef &aMainDef = mMainDefCache[theSuperAnimFile]; aMainDef.mAnimRate = aBuffer.ReadByte(); aMainDef.mX = aBuffer.ReadShort() / TWIPS_PER_PIXEL; aMainDef.mY = aBuffer.ReadShort() / TWIPS_PER_PIXEL; aMainDef.mWidth = aBuffer.ReadShort() / TWIPS_PER_PIXEL; aMainDef.mHeight = aBuffer.ReadShort() / TWIPS_PER_PIXEL; int aNumImages = aBuffer.ReadShort(); aMainDef.mImageVector.resize(aNumImages); for (int anImageNum = 0; anImageNum < aNumImages; ++anImageNum) { SuperAnimImage &aSuperAnimImage = aMainDef.mImageVector[anImageNum]; aSuperAnimImage.mImageName = aBuffer.ReadString(); aSuperAnimImage.mWidth = aBuffer.ReadShort(); aSuperAnimImage.mHeight = aBuffer.ReadShort(); aSuperAnimImage.mTransform.mMatrix.m00 = aBuffer.ReadLong() / (LONG_TO_FLOAT * TWIPS_PER_PIXEL); aSuperAnimImage.mTransform.mMatrix.m01 = -aBuffer.ReadLong() / (LONG_TO_FLOAT * TWIPS_PER_PIXEL); aSuperAnimImage.mTransform.mMatrix.m10 = -aBuffer.ReadLong() / (LONG_TO_FLOAT * TWIPS_PER_PIXEL); aSuperAnimImage.mTransform.mMatrix.m11 = aBuffer.ReadLong() / (LONG_TO_FLOAT * TWIPS_PER_PIXEL); aSuperAnimImage.mTransform.mMatrix.m02 = aBuffer.ReadShort() / TWIPS_PER_PIXEL; aSuperAnimImage.mTransform.mMatrix.m12 = aBuffer.ReadShort() / TWIPS_PER_PIXEL; std::string aImagePath; if (aCurDir.empty()) { aImagePath = aSuperAnimImage.mImageName; } else { aImagePath = aCurDir + '/' + aSuperAnimImage.mImageName; } aSuperAnimImage.mSpriteId = LoadSuperAnimSprite(aImagePath); } int aNumFrames = aBuffer.ReadShort(); assert(aNumFrames > 0 && "We don't have valid frames."); aMainDef.mStartFrameNum = 0; aMainDef.mEndFrameNum = aNumFrames - 1; aMainDef.mFrames.resize(aNumFrames); IntToSuperAnimObjectMap aCurObjectMap; for (int aFrameNum = 0; aFrameNum < aNumFrames; ++aFrameNum) { SuperAnimFrame &aFrame = aMainDef.mFrames[aFrameNum]; uchar aFrameFlags = aBuffer.ReadByte(); if (aFrameFlags & FRAMEFLAGS_REMOVES) { int aNumRemoves = aBuffer.ReadByte(); for (int aRemoveNum = 0; aRemoveNum < aNumRemoves; ++ aRemoveNum) { int anObjectId = aBuffer.ReadShort(); IntToSuperAnimObjectMap::iterator anIt = aCurObjectMap.find(anObjectId); if (anIt != aCurObjectMap.end()) { aCurObjectMap.erase(anIt); } } } if (aFrameFlags & FRAMEFLAGS_ADDS) { int aNumAdds = aBuffer.ReadByte(); for(int anAddNum = 0; anAddNum < aNumAdds; ++anAddNum) { SuperAnimObject aSuperAnimObject; aSuperAnimObject.mObjectNum = (aBuffer.ReadShort() & 0x07FF); aSuperAnimObject.mResNum = aBuffer.ReadByte(); aSuperAnimObject.mColor = Color(255, 255, 255, 255); aCurObjectMap.insert(IntToSuperAnimObjectMap::value_type(aSuperAnimObject.mObjectNum, aSuperAnimObject)); } } if (aFrameFlags & FRAMEFLAGS_MOVES) { int aNumMoves = aBuffer.ReadByte(); for (int aMoveNum = 0; aMoveNum < aNumMoves; ++ aMoveNum) { unsigned short aFlagsAndObjectNum = aBuffer.ReadShort(); int anObjectNum = aFlagsAndObjectNum & 0x03FF; IntToSuperAnimObjectMap::iterator anIt = aCurObjectMap.find(anObjectNum); if (anIt == aCurObjectMap.end()) continue; SuperAnimObject &aSuperAnimObject = anIt->second; aSuperAnimObject.mTransform.mMatrix.LoadIdentity(); if (aFlagsAndObjectNum & MOVEFLAGS_MATRIX) { aSuperAnimObject.mTransform.mMatrix.m00 = aBuffer.ReadLong() / LONG_TO_FLOAT; aSuperAnimObject.mTransform.mMatrix.m01 = -aBuffer.ReadLong() / LONG_TO_FLOAT; aSuperAnimObject.mTransform.mMatrix.m10 = -aBuffer.ReadLong() / LONG_TO_FLOAT; aSuperAnimObject.mTransform.mMatrix.m11 = aBuffer.ReadLong() / LONG_TO_FLOAT; } else if (aFlagsAndObjectNum & MOVEFLAGS_ROTATE) { float aRot = aBuffer.ReadShort() / 1000.0f; float sinRot = sinf(aRot); float cosRot = cosf(aRot); aSuperAnimObject.mTransform.mMatrix.m00 = cosRot; aSuperAnimObject.mTransform.mMatrix.m01 = sinRot; aSuperAnimObject.mTransform.mMatrix.m10 = -sinRot; aSuperAnimObject.mTransform.mMatrix.m11 = cosRot; } SuperAnimMatrix3 aMatrix; aMatrix.LoadIdentity(); if (aFlagsAndObjectNum & MOVEFLAGS_LONGCOORDS) { aMatrix.m02 = aBuffer.ReadLong() / TWIPS_PER_PIXEL; aMatrix.m12 = aBuffer.ReadLong() / TWIPS_PER_PIXEL; } else { aMatrix.m02 = aBuffer.ReadShort() / TWIPS_PER_PIXEL; aMatrix.m12 = aBuffer.ReadShort() / TWIPS_PER_PIXEL; } aSuperAnimObject.mTransform.mMatrix = aMatrix * aSuperAnimObject.mTransform.mMatrix; if (aFlagsAndObjectNum & MOVEFLAGS_COLOR) { aSuperAnimObject.mColor.mRed = aBuffer.ReadByte(); aSuperAnimObject.mColor.mGreen = aBuffer.ReadByte(); aSuperAnimObject.mColor.mBlue = aBuffer.ReadByte(); aSuperAnimObject.mColor.mAlpha = aBuffer.ReadByte(); } } } if (aFrameFlags & FRAMEFLAGS_FRAME_NAME) { std::string aFrameName = aBuffer.ReadString(); aMainDef.mLabels.insert(StringToIntMap::value_type(aFrameName, aFrameNum)); } aFrame.mObjectVector.resize(aCurObjectMap.size()); int anObjectNum = 0; for (IntToSuperAnimObjectMap::iterator anIt = aCurObjectMap.begin(); anIt != aCurObjectMap.end(); ++anIt, ++anObjectNum) { SuperAnimObject &anObject = anIt->second; aFrame.mObjectVector[anObjectNum] = anObject; } } return true; }
bool SuperAnimDefMgr::LoadSuperAnimMainDef(const std::string &theSuperAnimFile) { std::string aFullPath = theSuperAnimFile; std::string aCurDir = ""; int aLastSlash = max((int) theSuperAnimFile.rfind('\\'), (int) theSuperAnimFile.rfind('/')); if (aLastSlash != std::string::npos){ aCurDir = theSuperAnimFile.substr(0, aLastSlash); } size_t aFileSize = 0; unsigned char *aFileBuffer = CCFileUtils::sharedFileUtils()->getFileData(aFullPath.c_str(), "rb", &aFileSize); if (aFileBuffer == NULL) { assert(false && "Cannot allocate memory."); return false; } BufferReader aBuffer; aBuffer.SetData(aFileBuffer, (int)aFileSize); // free memory delete[] aFileBuffer; if (aBuffer.ReadLong() != 0x2E53414D) { assert(false && "Bad file format."); return false; } int aVersion = (int)aBuffer.ReadLong(); if (aVersion != SAM_VERSION) { assert(false && "Wrong version."); return false; } SuperAnimMainDef &aMainDef = mMainDefCache[theSuperAnimFile]; aMainDef.mAnimRate = aBuffer.ReadByte(); aMainDef.mX = aBuffer.ReadLong() / TWIPS_PER_PIXEL; aMainDef.mY = aBuffer.ReadLong() / TWIPS_PER_PIXEL; aMainDef.mWidth = aBuffer.ReadLong() / TWIPS_PER_PIXEL; aMainDef.mHeight = aBuffer.ReadLong() / TWIPS_PER_PIXEL; SuperAnimLabelArray aSuperAnimLabelArray; int aNumImages = aBuffer.ReadShort(); aMainDef.mImageVector.resize(aNumImages); for (int anImageNum = 0; anImageNum < aNumImages; ++anImageNum) { SuperAnimImage &aSuperAnimImage = aMainDef.mImageVector[anImageNum]; aSuperAnimImage.mImageName = aBuffer.ReadString(); aSuperAnimImage.mWidth = aBuffer.ReadShort(); aSuperAnimImage.mHeight = aBuffer.ReadShort(); aSuperAnimImage.mTransform.mMatrix.m00 = aBuffer.ReadLong() / (LONG_TO_FLOAT * TWIPS_PER_PIXEL); aSuperAnimImage.mTransform.mMatrix.m01 = -aBuffer.ReadLong() / (LONG_TO_FLOAT * TWIPS_PER_PIXEL); aSuperAnimImage.mTransform.mMatrix.m10 = -aBuffer.ReadLong() / (LONG_TO_FLOAT * TWIPS_PER_PIXEL); aSuperAnimImage.mTransform.mMatrix.m11 = aBuffer.ReadLong() / (LONG_TO_FLOAT * TWIPS_PER_PIXEL); aSuperAnimImage.mTransform.mMatrix.m02 = aBuffer.ReadShort() / TWIPS_PER_PIXEL; aSuperAnimImage.mTransform.mMatrix.m12 = aBuffer.ReadShort() / TWIPS_PER_PIXEL; std::string aImagePath; if (aCurDir.empty()) { aImagePath = aSuperAnimImage.mImageName; } else { aImagePath = aCurDir + '/' + aSuperAnimImage.mImageName; } aSuperAnimImage.mSpriteId = LoadSuperAnimSprite(aImagePath); } int aNumFrames = aBuffer.ReadShort(); assert(aNumFrames > 0 && "We don't have valid frames."); aMainDef.mStartFrameNum = 0; aMainDef.mEndFrameNum = aNumFrames - 1; aMainDef.mFrames.resize(aNumFrames); IntToSuperAnimObjectMap aCurObjectMap; for (int aFrameNum = 0; aFrameNum < aNumFrames; ++aFrameNum) { SuperAnimFrame &aFrame = aMainDef.mFrames[aFrameNum]; uchar aFrameFlags = aBuffer.ReadByte(); if (aFrameFlags & FRAMEFLAGS_REMOVES) { int aNumRemoves = aBuffer.ReadByte(); for (int aRemoveNum = 0; aRemoveNum < aNumRemoves; ++ aRemoveNum) { int anObjectId = aBuffer.ReadShort(); IntToSuperAnimObjectMap::iterator anIt = aCurObjectMap.find(anObjectId); if (anIt != aCurObjectMap.end()) { aCurObjectMap.erase(anIt); } } } if (aFrameFlags & FRAMEFLAGS_ADDS) { int aNumAdds = aBuffer.ReadByte(); for(int anAddNum = 0; anAddNum < aNumAdds; ++anAddNum) { int anObjNum = (aBuffer.ReadShort() & 0x07FF); SuperAnimObject& aSuperAnimObject = aCurObjectMap[anObjNum]; aSuperAnimObject.mObjectNum = anObjNum; aSuperAnimObject.mResNum = aBuffer.ReadByte(); aSuperAnimObject.mColor = Color(255, 255, 255, 255); } } if (aFrameFlags & FRAMEFLAGS_MOVES) { int aNumMoves = aBuffer.ReadByte(); for (int aMoveNum = 0; aMoveNum < aNumMoves; ++ aMoveNum) { unsigned short aFlagsAndObjectNum = aBuffer.ReadShort(); int anObjectNum = aFlagsAndObjectNum & 0x03FF; IntToSuperAnimObjectMap::iterator anIt = aCurObjectMap.find(anObjectNum); if (anIt == aCurObjectMap.end()) continue; SuperAnimObject &aSuperAnimObject = anIt->second; aSuperAnimObject.mTransform.mMatrix.LoadIdentity(); if (aFlagsAndObjectNum & MOVEFLAGS_MATRIX) { aSuperAnimObject.mTransform.mMatrix.m00 = aBuffer.ReadLong() / LONG_TO_FLOAT; aSuperAnimObject.mTransform.mMatrix.m01 = -aBuffer.ReadLong() / LONG_TO_FLOAT; aSuperAnimObject.mTransform.mMatrix.m10 = -aBuffer.ReadLong() / LONG_TO_FLOAT; aSuperAnimObject.mTransform.mMatrix.m11 = aBuffer.ReadLong() / LONG_TO_FLOAT; } else if (aFlagsAndObjectNum & MOVEFLAGS_ROTATE) { float aRot = aBuffer.ReadShort() / 1000.0f; float sinRot = sinf(aRot); float cosRot = cosf(aRot); aSuperAnimObject.mTransform.mMatrix.m00 = cosRot; aSuperAnimObject.mTransform.mMatrix.m01 = sinRot; aSuperAnimObject.mTransform.mMatrix.m10 = -sinRot; aSuperAnimObject.mTransform.mMatrix.m11 = cosRot; } SuperAnimMatrix3 aMatrix; aMatrix.LoadIdentity(); if (aFlagsAndObjectNum & MOVEFLAGS_LONGCOORDS) { aMatrix.m02 = aBuffer.ReadLong() / TWIPS_PER_PIXEL; aMatrix.m12 = aBuffer.ReadLong() / TWIPS_PER_PIXEL; } else { aMatrix.m02 = aBuffer.ReadShort() / TWIPS_PER_PIXEL; aMatrix.m12 = aBuffer.ReadShort() / TWIPS_PER_PIXEL; } aSuperAnimObject.mTransform.mMatrix = aMatrix * aSuperAnimObject.mTransform.mMatrix; if (aFlagsAndObjectNum & MOVEFLAGS_COLOR) { aSuperAnimObject.mColor.mRed = aBuffer.ReadByte(); aSuperAnimObject.mColor.mGreen = aBuffer.ReadByte(); aSuperAnimObject.mColor.mBlue = aBuffer.ReadByte(); aSuperAnimObject.mColor.mAlpha = aBuffer.ReadByte(); } } } if (aFrameFlags & FRAMEFLAGS_FRAME_NAME) { std::string aFrameName = aBuffer.ReadString(); SuperAnimLabel aLabel; aLabel.mLabelName = aFrameName; aLabel.mStartFrameNum = aFrameNum; //aMainDef.mLabels.insert(StringToIntMap::value_type(aFrameName, aFrameNum)); aSuperAnimLabelArray.push_back(aLabel); } aFrame.mObjectVector.resize(aCurObjectMap.size()); aFrame.mObjectVector.clear(); for (IntToSuperAnimObjectMap::iterator anIt = aCurObjectMap.begin(); anIt != aCurObjectMap.end(); ++anIt) { SuperAnimObject &anObject = anIt->second; aFrame.mObjectVector.push_back(anObject); } } // sort the label array & calculate the end frame for each label std::sort(aSuperAnimLabelArray.begin(), aSuperAnimLabelArray.end(), SuperAnimLabelLess); if (aSuperAnimLabelArray.size() > 1) { for (int i = 0; i < aSuperAnimLabelArray.size() - 1; i++) { SuperAnimLabel& aCurLabel = aSuperAnimLabelArray[i]; const SuperAnimLabel& aNextLabel = aSuperAnimLabelArray[i + 1]; aCurLabel.mEndFrameNum = aNextLabel.mStartFrameNum - 1; } SuperAnimLabel& aLastLabel = aSuperAnimLabelArray[aSuperAnimLabelArray.size() - 1]; aLastLabel.mEndFrameNum = aMainDef.mEndFrameNum; } else { // only have one section SuperAnimLabel& aLabel = aSuperAnimLabelArray[0]; aLabel.mEndFrameNum = aMainDef.mEndFrameNum; } aMainDef.mLabels.clear(); for (int i = 0; i < aSuperAnimLabelArray.size(); i++) { aMainDef.mLabels.push_back(aSuperAnimLabelArray[i]); } return true; }