X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FAnimation.cc;h=bd31f9b5dc26a8248952d8d7b5d5028bc6e45a63;hp=477997037230b125635f28cf4980d8ffa3d3cc3a;hb=c78934a448d0126709fccec3d5a636b3baa87da4;hpb=e973a129b5b83b628ba3f09e8c95682fc74080cd diff --git a/src/Animation.cc b/src/Animation.cc index 4779970..bd31f9b 100644 --- a/src/Animation.cc +++ b/src/Animation.cc @@ -1,34 +1,18 @@ -/******************************************************************************* - - Copyright (c) 2009, Charles McGarvey - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*******************************************************************************/ +/*] Copyright (c) 2009-2010, Charles McGarvey [************************** +**] All rights reserved. +* +* vi:ts=4 sw=4 tw=75 +* +* Distributable under the terms and conditions of the 2-clause BSD license; +* see the file COPYING for a complete text of the license. +* +**************************************************************************/ #include #include +#include #include #include #include @@ -37,12 +21,12 @@ /** - * The collection of nested animation classes. The animation implementation - * consists of an Impl class which is allocated and initialized with the - * interface object. This class contains the specific fields which are required - * to run a single instance of an animation. The sequence data is loaded in a - * different class which can be shared amongst multiple animation implementation - * instances. + * The collection of nested animation classes. The animation + * implementation consists of an Impl class which is allocated and + * initialized with the interface object. This class contains the specific + * fields which are required to run a single instance of an animation. The + * sequence data is loaded in a different class which can be shared amongst + * multiple animation implementation instances. */ class Animation::Impl @@ -50,9 +34,9 @@ class Animation::Impl public: /** - * Contains "global" animation data for the various animations which get - * loaded. This is a mippleton, so it will be shared amongst any animation - * which wants to use these loaded sequences. + * Contains "global" animation data for the various animations which + * get loaded. This is a mippleton, so it will be shared amongst any + * animation which wants to use these loaded sequences. */ class Data : public Mf::Manager @@ -60,9 +44,10 @@ public: public: /** - * A frame of an animation sequence. A frame is merely an index which - * presumably represents a "slide" or tile which should be displayed, - * and the duration that is how long the slide will be shown. + * A frame of an animation sequence. A frame is merely an index + * which presumably represents a "slide" or tile which should be + * displayed, and the duration that is how long the slide will be + * shown. */ class Frame @@ -73,103 +58,97 @@ public: Mf::Scalar mDuration; ///< Frame duration. /** - * Construction is initialization. The frame data is loaded from a - * frame map which is probably loaded within an animation file. + * Construction is initialization. The frame data is loaded + * from a frame map which is probably loaded within an + * animation file. */ - Frame(Mf::Script& script, Mf::Script::Slot table) : + Frame(const Mf::Script::Slot& table) : mIndex(0), mDuration(1.0) { - table.pushField("index"); - script[-1].get(mIndex); - script.pop(); - - table.pushField("duration"); - script[-1].get(mDuration); - script.pop(); + table.get(mIndex, "index"); + table.get(mDuration, "duration"); } }; /** - * A sequence is just a few attributes and a list of frames in the order - * that they should be played. + * A sequence is just a few attributes and a list of frames in the + * order that they should be played. */ class Sequence { public: - std::vector mFrames; ///< List of frames. - Mf::Scalar mDelay; ///< Scale frame durations. - bool mLoop; ///< Does the sequence repeat? - std::string mNext; ///< Next sequence name. + std::vector mFrames; ///< List of frames. + Mf::Scalar mDelay; ///< Scale frame durations. + bool mLoop; ///< Does the sequence repeat? + std::string mNext; ///< Next sequence name. /** - * Construction is initialization. The constructor loads sequence - * data from the sequence map, presumably loaded from an animation - * file. The rest of the loading takes place in the frame's - * constructor which loads each individual frame. + * Construction is initialization. The constructor loads + * sequence data from the sequence map, presumably loaded from + * an animation file. The rest of the loading takes place in + * the frame's constructor which loads each individual frame. */ - Sequence(Mf::Script& script, Mf::Script::Slot table) : + Sequence(const Mf::Script::Slot& table) : mDelay(0.0), mLoop(true) { - table.pushField("delay"); - script[-1].get(mDelay); - script.pop(); - - table.pushField("loop"); - script[-1].get(mLoop); - script.pop(); - - table.pushField("next"); - script[-1].get(mNext); - script.pop(); + table.get(mDelay, "delay"); + table.get(mLoop, "loop"); + table.get(mNext, "next"); // TODO - sequence class/type not yet implemented - table.pushField("frames"); - Mf::Script::Slot frameTable = script.getTop(); + Mf::Script::Slot frameTable = table.pushField("frames"); if (frameTable.isTable()) { - Mf::Script::Slot top = script[-1]; - int index = 1; - - for (;;) + int max = frameTable.length(); + for (int index = 1; index <= max; ++index) { - script.push(index); - frameTable.pushField(); - - if (top.isTable()) mFrames.push_back(Frame(script, top)); - else break; - - ++index; + Mf::Script::Slot top = frameTable.pushField(index); + + if (top.isTable()) + { + mFrames.push_back(Frame(top)); + } + else + { + Mf::logWarning << "invalid frame at index " + << index << std::endl; + } } } - script.pop(); + frameTable.remove(); } }; /** - * Starts loading a file with animation data. Such a file is formatted - * as a map of named sequences. The sequence constructor loads each - * individual sequence. + * Starts loading a file with animation data. Such a file is + * formatted as a map of named sequences. The sequence + * constructor loads each individual sequence. */ void init(const std::string& name) { Mf::Script script; - std::string filePath = Animation::getPath(name); + std::string path(name); + + if (!Animation::getPath(path)) + { + Mf::Error(Mf::Error::RESOURCE_NOT_FOUND).raise(); + } script.importBaseLibrary(); importLogFunctions(script); importAnimationBindings(script); - if (script.doFile(filePath) != Mf::Script::SUCCESS) + if (script.doFile(path) != Mf::Script::SUCCESS) { std::string str; script[-1].get(str); @@ -185,8 +164,7 @@ public: std::string nameStr; name.get(nameStr); - mSequences.insert(std::pair(nameStr, - Sequence(script, table))); + mSequences.insert(std::make_pair(nameStr, Sequence(table))); return 0; } @@ -195,19 +173,20 @@ public: void importAnimationBindings(Mf::Script& script) { script.importFunction("DefineSequence", - boost::bind(&Data::defineSequence, this, _1)); - - script.push(1); script.set("ATTACK"); - script.push(2); script.set("CHARGE"); - script.push(3); script.set("FLY"); - script.push(4); script.set("HIT"); - script.push(5); script.set("JUMP"); - script.push(6); script.set("RUN"); - script.push(7); script.set("STAND"); + boost::bind(&Data::defineSequence, + this, _1)); + + script.globals().setField("ATTACK", 1); + script.globals().setField("CHARGE", 2); + script.globals().setField("FLY", 3); + script.globals().setField("HIT", 4); + script.globals().setField("JUMP", 5); + script.globals().setField("RUN", 6); + script.globals().setField("STAND", 7); } - std::map mSequences; ///< List of sequences. + std::map mSequences; ///< List of sequences. }; @@ -225,9 +204,9 @@ public: /** - * Sets up the animation classes to "play" a named sequence. If another - * sequence was active, it will be replaced. Future updates will progress - * the new sequence. + * Sets up the animation classes to "play" a named sequence. If + * another sequence was active, it will be replaced. Future updates + * will progress the new sequence. */ void startSequence(const std::string& name) @@ -243,7 +222,7 @@ public: mFrameIndex = mCurrentSequence->mFrames[0].mIndex; mTimeAccum = 0.0; mFrameDuration = mCurrentSequence->mDelay * - mCurrentSequence->mFrames[0].mDuration; + mCurrentSequence->mFrames[0].mDuration; } } @@ -251,42 +230,41 @@ public: * Updates or progresses the animation sequence. If the time interval * surpasses the duration of the current frame, a new frame becomes the * current frame. If the last frame of a sequence expires, the active - * sequence will switch automatically to the designated "next" sequence, or - * if none is specified but the sequence is set to loop, the first frame of - * the sequence will become the current frame, and the animation essentially - * starts over again. + * sequence will switch automatically to the designated "next" + * sequence, or if none is specified but the sequence is set to loop, + * the first frame of the sequence will become the current frame, and + * the animation essentially starts over again. */ void update(Mf::Scalar t, Mf::Scalar dt) { - if (mCurrentSequence) - { - mTimeAccum += dt; + if (!mCurrentSequence) return; + + mTimeAccum += dt; - if (mTimeAccum >= mFrameDuration) + if (mTimeAccum >= mFrameDuration) + { + if (++mFrameCounter >= mCurrentSequence->mFrames.size()) { - if (++mFrameCounter >= mCurrentSequence->mFrames.size()) + if (!mCurrentSequence->mNext.empty()) { - if (!mCurrentSequence->mNext.empty()) - { - startSequence(mCurrentSequence->mNext); - } - else if (mCurrentSequence->mLoop) - { - mFrameCounter = 0; - } - else - { - mFrameCounter--; - mCurrentSequence = 0; - } + startSequence(mCurrentSequence->mNext); + } + else if (mCurrentSequence->mLoop) + { + mFrameCounter = 0; + } + else + { + mFrameCounter--; + mCurrentSequence = 0; } - - mFrameIndex = mCurrentSequence->mFrames[mFrameCounter].mIndex; - mTimeAccum = mFrameDuration - mTimeAccum; - mFrameDuration = mCurrentSequence->mDelay * - mCurrentSequence->mFrames[mFrameCounter].mDuration; } + + mFrameIndex = mCurrentSequence->mFrames[mFrameCounter].mIndex; + mTimeAccum = mFrameDuration - mTimeAccum; + mFrameDuration = mCurrentSequence->mDelay * + mCurrentSequence->mFrames[mFrameCounter].mDuration; } } @@ -330,15 +308,12 @@ unsigned Animation::getFrame() const /** - * Specialized search location for animation files. They can be found in the - * "animations" subdirectory of any of the searched directories. + * Specialized search location for animation files. They can be found in + * the "animations" subdirectory of any of the search directories. */ -std::string Animation::getPath(const std::string& name) +bool Animation::getPath(std::string& name) { - return Mf::Resource::getPath("animations/" + name + ".lua"); + return Mf::Resource::getPath(name, "animations/", "lua"); } - -/** vim: set ts=4 sw=4 tw=80: *************************************************/ -