00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "ext/tinyxml/fife_tinyxml.h"
00031 #include "vfs/fife_boost_filesystem.h"
00032 #include "vfs/vfs.h"
00033 #include "vfs/raw/rawdata.h"
00034 #include "video/imagemanager.h"
00035 #include "video/image.h"
00036 #include "video/animation.h"
00037 #include "util/base/exception.h"
00038 #include "util/log/logger.h"
00039 #include "util/resource/resource.h"
00040 #include "util/resource/resourcemanager.h"
00041
00042 #include "animationloader.h"
00043
00044 namespace FIFE {
00045 static Logger _log(LM_NATIVE_LOADERS);
00046
00047 AnimationLoader::AnimationLoader(VFS* vfs, ImageManager* imageManager)
00048 : m_vfs(vfs), m_imageManager(imageManager) {
00049
00050 }
00051
00052 bool AnimationLoader::isLoadable(const std::string& filename) {
00053 bfs::path animPath(filename);
00054
00055 std::string animationFilename = animPath.string();
00056
00057 try {
00058 RawData* data = m_vfs->open(animationFilename);
00059
00060 if (data) {
00061 if (data->getDataLength() != 0) {
00062
00063 TiXmlDocument doc;
00064 doc.Parse(data->readString(data->getDataLength()).c_str());
00065
00066 if (doc.Error()) {
00067 return false;
00068 }
00069 }
00070
00071
00072 delete data;
00073 data = 0;
00074 }
00075 }
00076 catch (NotFound&) {
00077 return false;
00078 }
00079
00080 return true;
00081 }
00082
00083 AnimationPtr AnimationLoader::load(const std::string& filename) {
00084 bfs::path animPath(filename);
00085
00086 std::string animationFilename = animPath.string();
00087
00088 TiXmlDocument doc;
00089
00090 AnimationPtr animation;
00091
00092 try {
00093 RawData* data = m_vfs->open(animationFilename);
00094
00095 if (data) {
00096 if (data->getDataLength() != 0) {
00097 doc.Parse(data->readString(data->getDataLength()).c_str());
00098
00099 if (doc.Error()) {
00100 return animation;
00101 }
00102
00103
00104 delete data;
00105 data = 0;
00106 }
00107 }
00108 }
00109 catch (NotFound& e) {
00110 FL_ERR(_log, e.what());
00111
00112
00113
00114
00115
00116 return animation;
00117 }
00118
00119
00120
00121 TiXmlElement* root = doc.RootElement();
00122
00123 if (root) {
00124 animation.reset(new Animation());
00125
00126 int animDelay = 0;
00127 root->QueryValueAttribute("delay", &animDelay);
00128
00129 int animXoffset = 0;
00130 int animYoffset = 0;
00131 int action = -1;
00132 root->QueryValueAttribute("x_offset", &animXoffset);
00133 root->QueryValueAttribute("y_offset", &animYoffset);
00134 root->QueryValueAttribute("action", &action);
00135
00136 for (TiXmlElement* frameElement = root->FirstChildElement("frame"); frameElement; frameElement = frameElement->NextSiblingElement("frame")) {
00137 if (animation) {
00138 animation->setActionFrame(action);
00139
00140 const std::string* sourceId = frameElement->Attribute(std::string("source"));
00141
00142 if (sourceId) {
00143 bfs::path framePath(filename);
00144
00145 if (HasParentPath(framePath)) {
00146 framePath = GetParentPath(framePath) / *sourceId;
00147 } else {
00148 framePath = bfs::path(*sourceId);
00149 }
00150
00151 ImagePtr imagePtr;
00152 if(!m_imageManager->exists(framePath.string())) {
00153 imagePtr = m_imageManager->create(framePath.string());
00154 }
00155 else {
00156 imagePtr = m_imageManager->getPtr(framePath.string());
00157 }
00158
00159 if (imagePtr) {
00160 int frameXoffset = 0;
00161 int frameYoffset = 0;
00162
00163 int success = root->QueryValueAttribute("x_offset", &frameXoffset);
00164
00165 if (success == TIXML_SUCCESS) {
00166 imagePtr->setXShift(frameXoffset);
00167 }
00168 else {
00169 imagePtr->setXShift(animXoffset);
00170 }
00171
00172 success = root->QueryValueAttribute("y_offset", &frameYoffset);
00173
00174 if (success == TIXML_SUCCESS) {
00175 imagePtr->setYShift(frameYoffset);
00176 }
00177 else {
00178 imagePtr->setYShift(animYoffset);
00179 }
00180
00181 int frameDelay = 0;
00182 success = root->QueryValueAttribute("delay", &frameDelay);
00183
00184 if (success == TIXML_SUCCESS) {
00185 animation->addFrame(imagePtr, frameDelay);
00186 }
00187 else {
00188 animation->addFrame(imagePtr, animDelay);
00189 }
00190 }
00191 }
00192 }
00193 }
00194 }
00195
00196 return animation;
00197 }
00198 }