Torque3D Documentation / _generateds / guiAnimBitmapCtrl.cpp

guiAnimBitmapCtrl.cpp

Engine/source/gui/controls/guiAnimBitmapCtrl.cpp

More...

Public Functions

IMPLEMENT_CALLBACK(guiAnimBitmapCtrl , onCompleted , void , () , () , "triggered when an animation completes" )
IMPLEMENT_CALLBACK(guiAnimBitmapCtrl , onFrame , void , (S32 frameIndex, S32 frame) , (frameIndex, frame) , "triggered when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> frame increments" )
IMPLEMENT_CALLBACK(guiAnimBitmapCtrl , onLoop , void , () , () , "triggered when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> loop completes" )

Detailed Description

Public Functions

IMPLEMENT_CALLBACK(guiAnimBitmapCtrl , onCompleted , void , () , () , "triggered when an animation completes" )

IMPLEMENT_CALLBACK(guiAnimBitmapCtrl , onFrame , void , (S32 frameIndex, S32 frame) , (frameIndex, frame) , "triggered when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> frame increments" )

IMPLEMENT_CALLBACK(guiAnimBitmapCtrl , onLoop , void , () , () , "triggered when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> loop completes" )

IMPLEMENT_CONOBJECT(guiAnimBitmapCtrl )

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "platform/platform.h"
 25#include "gui/controls/guiAnimBitmapCtrl.h"
 26
 27#include "console/console.h"
 28#include "console/consoleTypes.h"
 29#include "console/engineAPI.h"
 30#include "gfx/gfxDevice.h"
 31#include "gfx/gfxDrawUtil.h"
 32
 33
 34
 35IMPLEMENT_CONOBJECT(guiAnimBitmapCtrl);
 36
 37IMPLEMENT_CALLBACK(guiAnimBitmapCtrl, onLoop, void, (),
 38   (), "triggered when a loop completes");
 39
 40IMPLEMENT_CALLBACK(guiAnimBitmapCtrl, onCompleted, void, (),
 41   (), "triggered when an animation completes");
 42
 43IMPLEMENT_CALLBACK(guiAnimBitmapCtrl, onFrame, void, (S32 frameIndex, S32 frame),
 44   (frameIndex, frame), "triggered when a frame increments");
 45
 46guiAnimBitmapCtrl::guiAnimBitmapCtrl(void)
 47{
 48   mAnimTexTiling = Point2I::One;
 49   mAnimTexFramesString = NULL;
 50   mAnimTexFrames.clear();
 51   mNumFrames = 0;
 52   mCurFrameIndex = 0;
 53   mFramesPerSec = 60;
 54   mAnimateTexture = false;
 55   mFrameTime = PlatformTimer::create();
 56   mLoop = true;
 57   mPlay = true;
 58   mReverse = false;
 59   mFinished = false;
 60}
 61
 62guiAnimBitmapCtrl::~guiAnimBitmapCtrl(void)
 63{
 64   mAnimTexFrames.clear();
 65}
 66void guiAnimBitmapCtrl::initPersistFields()
 67{
 68   addField("AnimTexTiling", TYPEID< Point2I >(), Offset(mAnimTexTiling, guiAnimBitmapCtrl),
 69      "@brief The number of frames, in rows and columns stored in textureName "
 70      "(when animateTexture is true).\n\n"
 71      "A maximum of 256 frames can be stored in a single texture when using "
 72      "mAnimTexTiling. Value should be \"NumColumns NumRows\", for example \"4 4\".");
 73   addProtectedField("AnimTexFrames", TYPEID< StringTableEntry >(), Offset(mAnimTexFramesString, guiAnimBitmapCtrl), &ptSetFrameRanges, &defaultProtectedGetFn,
 74      "@brief A list of frames and/or frame ranges to use for particle "
 75      "animation if animateTexture is true.\n\n"
 76      "Each frame token must be separated by whitespace. A frame token must be "
 77      "a positive integer frame number or a range of frame numbers separated "
 78      "with a '-'. The range separator, '-', cannot have any whitspace around "
 79      "it.\n\n"
 80      "Ranges can be specified to move through the frames in reverse as well "
 81      "as forward (eg. 19-14). Frame numbers exceeding the number of tiles will "
 82      "wrap.\n"
 83      "@tsexample\n"
 84      "mAnimTexFrames = \"0-16 20 19 18 17 31-21\";\n"
 85      "@endtsexample\n");
 86
 87   addField("loop", TypeBool, Offset(mLoop, guiAnimBitmapCtrl), "loop?");
 88   addField("play", TypeBool, Offset(mPlay, guiAnimBitmapCtrl), "play?");
 89   addField("reverse", TypeBool, Offset(mReverse, guiAnimBitmapCtrl), "play reversed?");
 90   addField("fps", TypeS32, Offset(mFramesPerSec, guiAnimBitmapCtrl), "Frame Rate");
 91
 92   addProtectedField("curFrame", TypeS32, Offset(mCurFrameIndex, guiAnimBitmapCtrl), &ptSetFrame, &defaultProtectedGetFn, "Index of currently Displaying Frame ");
 93
 94   Parent::initPersistFields();
 95   removeField("wrap");
 96}
 97
 98bool guiAnimBitmapCtrl::onAdd()
 99{
100   if (Parent::onAdd() == false)
101      return false;
102
103   if (!mAnimTexFramesString || !mAnimTexFramesString[0])
104   {
105      S32 n_tiles = mAnimTexTiling.x * mAnimTexTiling.y - 1;
106      for (S32 i = 0; i <= n_tiles; i++)
107         mAnimTexFrames.push_back(i);
108      mNumFrames = mAnimTexFrames.size() - 1;
109      if (mCurFrameIndex > mNumFrames)
110         mCurFrameIndex = mNumFrames;
111      return true;
112   }
113
114   return true;
115}
116
117bool guiAnimBitmapCtrl::ptSetFrame(void *object, const char *index, const char *data)
118{
119   guiAnimBitmapCtrl *pData = static_cast<guiAnimBitmapCtrl*>(object);
120
121   if (!pData->mNumFrames)
122   {
123      pData->mCurFrameIndex = 0;
124      return false;
125   }
126
127   S32 val = dAtoi(data);
128
129   if (val < 0)
130   {
131      pData->mCurFrameIndex = pData->mNumFrames;
132      return false;
133   }
134   else if (val > pData->mNumFrames)
135   {
136      pData->mCurFrameIndex = 0;
137      return false;
138   };
139
140   pData->mCurFrameIndex = val;
141   return true;
142}
143
144bool guiAnimBitmapCtrl::ptSetFrameRanges(void *object, const char *index, const char *data)
145{
146   guiAnimBitmapCtrl *pData = static_cast<guiAnimBitmapCtrl*>(object);
147
148   // Here we parse mAnimTexFramesString into byte-size frame numbers in mAnimTexFrames.
149   // Each frame token must be separated by whitespace.
150   // A frame token must be a positive integer frame number or a range of frame numbers
151   // separated with a '-'. 
152   // The range separator, '-', cannot have any whitspace around it.
153   // Ranges can be specified to move through the frames in reverse as well as forward.
154   // Frame numbers exceeding the number of tiles will wrap.
155   //   example:
156   //     "0-16 20 19 18 17 31-21"
157
158   S32 n_tiles = pData->mAnimTexTiling.x * pData->mAnimTexTiling.y - 1;
159
160   pData->mAnimTexFrames.clear();
161
162   if (!data || !data[0])
163   {
164      for (S32 i = 0; i <= n_tiles; i++)
165         pData->mAnimTexFrames.push_back(i);
166      pData->mNumFrames = pData->mAnimTexFrames.size() - 1;
167      if (pData->mCurFrameIndex > pData->mNumFrames)
168         pData->mCurFrameIndex = pData->mNumFrames;
169      return true;
170   }
171   dsize_t tokLen = dStrlen(data) + 1;
172   char* tokCopy = new char[tokLen];
173   dStrcpy(tokCopy, data, tokLen);
174
175   char* currTok = dStrtok(tokCopy, " \t");
176   while (currTok != NULL)
177   {
178      char* minus = dStrchr(currTok, '-');
179      if (minus)
180      {
181         // add a range of frames
182         *minus = '\0';
183         S32 range_a = dAtoi(currTok);
184         S32 range_b = dAtoi(minus + 1);
185         if (range_b < range_a)
186         {
187            // reverse frame range
188            for (S32 i = range_a; i >= range_b; i--)
189               pData->mAnimTexFrames.push_back(i);
190         }
191         else
192         {
193            // forward frame range
194            for (S32 i = range_a; i <= range_b; i++)
195               pData->mAnimTexFrames.push_back(i);
196         }
197      }
198      else
199      {
200         // add one frame
201         pData->mAnimTexFrames.push_back(dAtoi(currTok));
202      }
203      currTok = dStrtok(NULL, " \t");
204   }
205
206   // cleanup
207   delete[] tokCopy;
208   pData->mNumFrames = pData->mAnimTexFrames.size() - 1;
209   if (pData->mCurFrameIndex > pData->mNumFrames)
210      pData->mCurFrameIndex = pData->mNumFrames;
211   return true;
212}
213
214void guiAnimBitmapCtrl::onRender(Point2I offset, const RectI &updateRect)
215{
216   if (mTextureObject)
217   {
218      if (mFrameTime->getElapsedMs() > 1000 / mFramesPerSec) //fps to msfp conversion
219      {
220         mFrameTime->reset();
221
222         if (mPlay)
223         {
224            if (mReverse) //play backward
225            {
226               mCurFrameIndex--;
227               if (mCurFrameIndex < 0)
228               {
229                  if (mLoop)
230                  {
231                     mCurFrameIndex = mNumFrames;
232                     onLoop_callback();
233                     mFinished = false;
234                  }
235                  else
236                  {
237                     mCurFrameIndex = 0;
238                     if (!mFinished)
239                        onCompleted_callback();
240                     mFinished = true;
241                  }
242               }
243               else
244                  onFrame_callback(mCurFrameIndex, mAnimTexFrames[mCurFrameIndex]);
245            }
246            else // play forward
247            {
248               mCurFrameIndex++;
249
250               if (mCurFrameIndex > mNumFrames)
251               {
252                  if (mLoop)
253                  {
254                     mCurFrameIndex = 0;
255                     onLoop_callback();
256                     mFinished = false;
257                  }
258                  else
259                  {
260                     mCurFrameIndex = mNumFrames;
261                     if (!mFinished)
262                        onCompleted_callback();
263                     mFinished = true;
264                  }
265               }
266               else
267                  onFrame_callback(mCurFrameIndex, mAnimTexFrames[mCurFrameIndex]);
268            }
269         }
270      }
271
272      GFX->getDrawUtil()->clearBitmapModulation();
273      GFX->getDrawUtil()->setBitmapModulation(mColor);
274
275      GFXTextureObject* texture = mTextureObject;
276
277      Point2I modifiedSRC = Point2I(texture->mBitmapSize.x / mAnimTexTiling.x, texture->mBitmapSize.y / mAnimTexTiling.y);
278      RectI srcRegion;
279      Point2I offsetSRC = Point2I::Zero;
280
281      offsetSRC.x = (texture->mBitmapSize.x / mAnimTexTiling.x) * (mAnimTexFrames[mCurFrameIndex] % mAnimTexTiling.x);
282      offsetSRC.y = (texture->mBitmapSize.y / mAnimTexTiling.y) * (mAnimTexFrames[mCurFrameIndex] / mAnimTexTiling.x);
283
284      srcRegion.set(offsetSRC, modifiedSRC);
285
286      GFX->getDrawUtil()->drawBitmapStretchSR(texture, updateRect, srcRegion, GFXBitmapFlip_None, GFXTextureFilterLinear, false);
287   }
288
289   if (mProfile->mBorder || !mTextureObject)
290   {
291      RectI rect(offset, getExtent());
292      GFX->getDrawUtil()->drawRect(rect, mProfile->mBorderColor);
293   }
294
295   renderChildControls(offset, updateRect);
296}
297