00001 #ifdef WIN32
00002 #pragma warning(disable : 4786 )
00003 #endif
00004
00005 #include "CSAction.h"
00006 #include "SDLMain.h"
00007 #include "CSXMLHelper.h"
00008
00009 CSActionLoader CSActionLoader::INSTANCE;
00010 const char *CSAction::CLASS = "CSAction";
00011
00012 CSAction::CSAction(const std::string &filename)
00013 {
00014 static char *functionName="CSAction";
00015 LOG_ENTER
00016 CSActionData data;
00017 loadActionData(filename, data);
00018 initialize(data);
00019 LOG_EXIT
00020 }
00021
00022 CSAction::CSAction(const CSAction &action)
00023 {
00024 static char *functionName="CSAction";
00025 LOG_ENTER
00026 int i;
00027 initialize();
00028 mIsBreakable = action.mIsBreakable;
00029 mRepeatable = action.mRepeatable;
00030 mSizePhases = action.mSizePhases;
00031 mEnvoker = action.mEnvoker;
00032 mType = action.mType;
00033
00034 mPhases = new unsigned int[mSizePhases];
00035 for (i=0; i<mSizePhases; i++)
00036 {
00037 mPhases[i] = action.mPhases[i];
00038 }
00039
00040 mAnimations = new CSAnimations();
00041 CSAnimations::const_iterator iter = action.mAnimations->begin();
00042 while (iter != action.mAnimations->end())
00043 {
00044
00045
00046
00047 mAnimations->push_back(*iter);
00048 iter++;
00049 }
00050 mId = strdup(action.mId);
00051 mNextAction = strdup(action.mNextAction);
00052 LOG_EXIT
00053 }
00054
00055 void CSAction::initialize(void)
00056 {
00057 static char *functionName="initialize";
00058 LOG_ENTER
00059 mIsBreakable = true;
00060 mRepeatable = CS_REPEATABLE;
00061 mSizePhases = 0;
00062 mPhases = 0;
00063 mType = 0;
00064 mEnvoker = 0;
00065 mId = 0;
00066 mNextAction = 0;
00067 mAnimations = 0;
00068 LOG_EXIT
00069 }
00070
00071 void CSAction::initialize(const CSActionData &data)
00072 {
00073 static char *functionName="initialize";
00074 LOG_ENTER
00075 int i;
00076 initialize();
00077
00078 mType = data.type;
00079 mIsBreakable = data.isBreakable;
00080 mRepeatable = data.repeatable;
00081 mSizePhases = data.sizePhases;
00082 mEnvoker = data.envoker;
00083
00084 mPhases = new unsigned int[mSizePhases];
00085 for (i=0; i<mSizePhases; i++)
00086 {
00087 mPhases[i] = data.phases[i];
00088 }
00089
00090 mAnimations = new CSAnimations();
00091 for (StringVector::iterator iter = data.animationNames->begin(); iter != data.animationNames->end(); iter++)
00092 {
00093 char *help = (char *) *iter;
00094 if (help == NULL)
00095 {
00096 LOG_EXIT
00097 SDLMain::shutdown((std::string)"Char Pointer == 0 Action Loading: " + SDL_GetError(), 1);
00098 }
00099
00100 CSAnimation *animation = CSAnimationLoader::INSTANCE.load((char *)(help));
00101 mAnimations->push_back(animation);
00102 }
00103
00104 mId = strdup(data.id);
00105 mNextAction = strdup(data.nextAction);
00106 LOG_EXIT
00107 }
00108
00109 CSAction::~CSAction()
00110 {
00111 static char *functionName="~CSAction";
00112 LOG_ENTER
00113 if (mPhases != 0)
00114 {
00115 delete []mPhases;
00116 mPhases = 0;
00117 }
00118
00119 if (mAnimations != 0)
00120 {
00121
00122
00123 delete mAnimations;
00124 mAnimations = 0;
00125 }
00126
00127 if (mId != 0)
00128 {
00129 free(mId);
00130 mId = 0;
00131 }
00132
00133 if (mNextAction != 0)
00134 {
00135 free(mNextAction);
00136 mNextAction = 0;
00137 }
00138 LOG_EXIT
00139 }
00140
00141
00142 ActionState CSAction::buildState()
00143 {
00144 static char *functionName="buildState";
00145 ActionState state;
00146 state.mFinished = false;
00147 state.mForward = true;
00148 if (mSizePhases > 0)
00149 {
00150 state.mCurrentPhase = 0;
00151 state.mCurrentAnimation = mPhases[state.mCurrentPhase];
00152 state.mAnimation = mAnimations->at(state.mCurrentAnimation);
00153 state.mAnimationState = state.mAnimation->buildState();
00154 }
00155 return state;
00156 }
00157
00158
00159
00160
00161 void CSAction::resetState(ActionState& state)
00162 {
00163 static char *functionName="resetState";
00164 state.mFinished = false;
00165 state.mForward = true;
00166 if (mSizePhases > 0)
00167 {
00168 state.mCurrentPhase = 0;
00169 state.mCurrentAnimation = mPhases[state.mCurrentPhase];
00170 state.mAnimation = mAnimations->at(state.mCurrentAnimation);
00171 state.mAnimation->resetState(state.mAnimationState);
00172 }
00173 }
00174
00175
00176
00177 void CSAction::startAction(ActionState &state)
00178 {
00179 static char *functionName="startAction";
00180 state.mFinished = false;
00181 state.mForward = true;
00182 if (mSizePhases > 0)
00183 {
00184 state.mCurrentPhase = 0;
00185 state.mCurrentAnimation = mPhases[state.mCurrentPhase];
00186 state.mAnimation = mAnimations->at(state.mCurrentAnimation);
00187 state.mAnimation->startAnimation(state.mAnimationState);
00188 }
00189 }
00190
00191
00192
00193
00194
00195
00196
00197 void CSAction::startNextAction(ActionState &state)
00198 {
00199 static char *functionName="startNextAction";
00200 state.mFinished = false;
00201 state.mForward = true;
00202 if (mSizePhases > 0)
00203 {
00204 state.mCurrentPhase = 0;
00205 state.mCurrentAnimation = mPhases[state.mCurrentPhase];
00206 state.mAnimation = mAnimations->at(state.mCurrentAnimation);
00207 state.mAnimation->startNextAnimation(state.mAnimationState);
00208 }
00209 }
00210
00211 void CSAction::setSecPerFrame(float secPerFrame)
00212 {
00213 static char *functionName="setSecPerFrame";
00214 LOG_ENTER
00215 CSAnimations::const_iterator iter = mAnimations->begin();
00216 while (iter != mAnimations->end())
00217 {
00218 CSAnimation *animation = *iter;
00219 animation->setSecPerFrame(secPerFrame);
00220 iter++;
00221 }
00222 LOG_EXIT
00223 }
00224
00225 void CSAction::setAlpha(int alpha)
00226 {
00227 static char *functionName="setAlpha";
00228 LOG_ENTER
00229 CSAnimations::const_iterator iter = mAnimations->begin();
00230 while (iter != mAnimations->end())
00231 {
00232 CSAnimation *animation = *iter;
00233 animation->setAlpha(alpha);
00234 iter++;
00235 }
00236 LOG_EXIT
00237 }
00238
00239
00240
00241 bool CSAction::next(ActionState &state)
00242 {
00243 static char *functionName="next";
00244 bool finished = false;
00245 if (state.mFinished)
00246 {
00247 return !state.mFinished;
00248 }
00249
00250 finished = !(state.mAnimation->next(state.mAnimationState));
00251 if (finished)
00252 {
00253 if (mRepeatable == CS_RANDOM)
00254 {
00255
00256 }
00257 else
00258 {
00259 if (state.mForward)
00260 {
00261 state.mCurrentPhase++;
00262 if (state.mCurrentPhase == mSizePhases)
00263 {
00264 if (mRepeatable == CS_INVERSE_REPEATABLE)
00265 {
00266 state.mForward = !state.mForward;
00267 if (mSizePhases > 1)
00268 {
00269 state.mCurrentPhase-=2;
00270 }
00271 else
00272 {
00273 state.mCurrentPhase--;
00274 }
00275 }
00276 else
00277 if (mRepeatable == CS_INVERSE_ONCE)
00278 {
00279 state.mForward = !state.mForward;
00280 if (mSizePhases > 1)
00281 {
00282 state.mCurrentPhase-=2;
00283 }
00284 else
00285 {
00286 state.mCurrentPhase--;
00287 }
00288 }
00289 else
00290 {
00291 if (mRepeatable == CS_NOT_REPEATABLE)
00292 {
00293 state.mFinished = true;
00294 return !state.mFinished;
00295 }
00296 state.mCurrentPhase = 0;
00297 }
00298 }
00299 }
00300 else
00301 {
00302 state.mCurrentPhase--;
00303 if (state.mCurrentPhase == -1)
00304 {
00305 if (mRepeatable == CS_INVERSE_REPEATABLE)
00306 {
00307 state.mForward = !state.mForward;
00308 if (mSizePhases > 1)
00309 {
00310 state.mCurrentPhase+=2;
00311 }
00312 else
00313 {
00314 state.mCurrentPhase++;
00315 }
00316 }
00317 else
00318 {
00319 if (mRepeatable == CS_INVERSE_ONCE)
00320 {
00321 state.mFinished = true;
00322 return !state.mFinished;
00323 }
00324 state.mCurrentPhase = 0;
00325 }
00326
00327 }
00328 }
00329
00330 }
00331 state.mCurrentAnimation = mPhases[state.mCurrentPhase];
00332 state.mAnimation = mAnimations->at(state.mCurrentAnimation);
00333 state.mAnimation->startAnimation(state.mAnimationState);
00334 }
00335
00336 return !state.mFinished;
00337 }
00338
00339
00340 void CSAction::display(ActionState &state)
00341 {
00342 static char *functionName="display";
00343 state.mAnimation->display(state.mAnimationState);
00344 }
00345
00346 bool CSAction::isBreakable(ActionState &state)
00347 {
00348 static char *functionName="isBreakable";
00349 if (!mIsBreakable)
00350 {
00351 return mIsBreakable;
00352 }
00353 return state.mAnimation->isBreakable();
00354 }
00355
00356 bool CSAction::isAction(char *id)
00357 {
00358 static char *functionName="isAction";
00359 return !(strcmp(id, mId));
00360 }
00361
00362
00363
00364 unsigned int CSAction::getMaxX()
00365 {
00366 static char *functionName="getMaxX";
00367 unsigned int maxX = 0;
00368 unsigned int x;
00369 for (CSAnimations::iterator iter = mAnimations->begin(); iter != mAnimations->end(); iter++)
00370 {
00371 CSAnimation *ani = *iter;
00372 x = ani->getMaxX(); if (maxX < x) maxX = x;
00373 }
00374 return maxX;
00375 }
00376
00377
00378
00379 unsigned int CSAction::getMaxY()
00380 {
00381 static char *functionName="getMaxY";
00382 unsigned int maxY = 0;
00383 unsigned int y;
00384
00385 for (CSAnimations::iterator iter = mAnimations->begin(); iter != mAnimations->end(); iter++)
00386 {
00387 CSAnimation *ani = *iter;
00388 y = ani->getMaxY(); if (maxY < y) maxY = y;
00389 }
00390 return maxY;
00391 }
00392
00393 void CSAction::loadActionData(const std::string &filename, CSActionData &data)
00394 {
00395 static char *functionName="loadActionData";
00396 LOG_ENTER
00397 char tmp[10];
00398
00399 CSXMLHelper xmlSupport(filename, "ACTION");
00400 try
00401 {
00402 if (xmlSupport.getError())
00403 {
00404 LOG_EXIT
00405 throw "error";
00406 }
00407
00408 data.id = strdup(xmlSupport.getString("ID").c_str());
00409 data.isBreakable = xmlSupport.getInt("IS_BREAKABLE") == 1;
00410 data.type = xmlSupport.getInt("TYPE");
00411 data.repeatable = xmlSupport.getInt("REPEATABLE");
00412
00413 data.envoker = xmlSupport.getInt("ENVOKER");
00414
00415 if (xmlSupport.getInt("count(/ACTION/DEFAULT_NEXT_ACTION)") == 1)
00416 {
00417 data.nextAction = strdup(xmlSupport.getString("DEFAULT_NEXT_ACTION").c_str());
00418 }
00419 data.sizePhases = xmlSupport.getInt("count(/ACTION/PHASE)");
00420 data.phases = new unsigned int[data.sizePhases];
00421 for (int i=0; i<data.sizePhases; i++)
00422 {
00423
00424 data.phases[i] = xmlSupport.getInt((std::string)"/ACTION/PHASE["+itoa(i+1,tmp,10)+"]");
00425 }
00426
00427 int animationCount = xmlSupport.getInt("count(/ACTION/ANIMATION)");
00428 data.animationNames = new StringVector();
00429 for (i=0; i<animationCount; i++)
00430 {
00431
00432 std::string a = xmlSupport.getString((std::string)"/ACTION/ANIMATION["+itoa(i+1,tmp,10)+"]");
00433 data.animationNames->push_back(strdup(a.c_str()));
00434 }
00435 }
00436 catch(...)
00437 {
00438 LOG_EXIT
00439 SDLMain::shutdown((std::string)"XML error \"" + filename + "\": " + xmlSupport.getErrorMessage().c_str(), 1);
00440 }
00441 LOG_EXIT
00442 }