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