aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2012-01-19 20:57:07 +1000
committerQt by Nokia <qt-info@nokia.com>2012-01-27 06:17:58 +0100
commit16ca1d7d65e66969724d4b490fa9a614b88f4bc3 (patch)
treecd87312bcb9af7c9a276af666889b86250342352 /src/quick/items
parentcc3716f899fb683e1e8270ba5127f9899264072b (diff)
Implement reverse mode for sprites
Change-Id: I1e8c124e883b881938fce01aeb67ac369fe0bc28 Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquicksprite_p.h1
-rw-r--r--src/quick/items/qquickspriteengine.cpp106
-rw-r--r--src/quick/items/qquickspriteengine_p.h5
-rw-r--r--src/quick/items/qquickspriteimage.cpp2
4 files changed, 85 insertions, 29 deletions
diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h
index 2ec2380ea8..3e3c7f759a 100644
--- a/src/quick/items/qquicksprite_p.h
+++ b/src/quick/items/qquicksprite_p.h
@@ -56,6 +56,7 @@ class QQuickSprite : public QQuickStochasticState
{
Q_OBJECT
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ //Renderers have to query this hint when advancing frames
Q_PROPERTY(bool reverse READ reverse WRITE setReverse NOTIFY reverseChanged)
Q_PROPERTY(bool frameSync READ frameSync WRITE setFrameSync NOTIFY frameSyncChanged)
Q_PROPERTY(int frames READ frames WRITE setFrames NOTIFY framesChanged)
diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp
index 6e2e8764e1..d8bfacd33d 100644
--- a/src/quick/items/qquickspriteengine.cpp
+++ b/src/quick/items/qquickspriteengine.cpp
@@ -128,26 +128,41 @@ int QQuickSpriteEngine::maxFrames()
TODO: All these calculations should be pre-calculated and cached during initialization for a significant performance boost
TODO: Above idea needs to have the varying duration offset added to it
*/
-//TODO: Should these be adding advanceTime as well?
+//TODO: Should these be adding advanceTime as well? But only if advanceTime was added to your startTime...
/*
To get these working with duration=-1, m_startTimes will be messed with should duration=-1
m_startTimes will be set in advance/restart to 0->(m_framesPerRow-1) and can be used directly as extra.
This makes it 'frame' instead, but is more memory efficient than two arrays and less hideous than a vector of unions.
*/
+int QQuickSpriteEngine::pseudospriteProgress(int sprite, int state, int* rowDuration)
+{
+ int myRowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow / m_sprites[state]->m_frames;
+ if (rowDuration)
+ *rowDuration = myRowDuration;
+
+ if (m_sprites[state]->reverse()) //shift start-time back by the amount of time the first frame is smaller than rowDuration
+ return (m_timeOffset - (m_startTimes[sprite] - (myRowDuration - (m_duration[sprite] % myRowDuration))) )
+ / myRowDuration;
+ else
+ return (m_timeOffset - m_startTimes[sprite]) / myRowDuration;
+}
+
int QQuickSpriteEngine::spriteState(int sprite)
{
int state = m_things[sprite];
if (!m_sprites[state]->m_generatedCount)
return state;
+
int extra;
- if (m_sprites[state]->frameSync()) {
+ if (m_sprites[state]->frameSync())
extra = m_startTimes[sprite];
- } else {
- if (!m_duration[sprite])
- return state;
- int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow / m_sprites[state]->m_frames;
- extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
- }
+ else if (!m_duration[sprite])
+ return state;
+ else
+ extra = pseudospriteProgress(sprite, state);
+ if (m_sprites[state]->reverse())
+ extra = (m_sprites[state]->m_generatedCount - 1) - extra;
+
return state + extra;
}
@@ -158,8 +173,10 @@ int QQuickSpriteEngine::spriteStart(int sprite)
int state = m_things[sprite];
if (!m_sprites[state]->m_generatedCount)
return m_startTimes[sprite];
- int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow / m_sprites[state]->m_frames;
- int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
+ int rowDuration;
+ int extra = pseudospriteProgress(sprite, state, &rowDuration);
+ if (m_sprites[state]->reverse())
+ return m_startTimes[sprite] + (extra ? (extra - 1)*rowDuration + (m_duration[sprite] % rowDuration) : 0);
return m_startTimes[sprite] + extra*rowDuration;
}
@@ -168,15 +185,18 @@ int QQuickSpriteEngine::spriteFrames(int sprite)
int state = m_things[sprite];
if (!m_sprites[state]->m_generatedCount)
return m_sprites[state]->frames();
+
int extra;
- if (m_sprites[state]->frameSync()) {
+ if (m_sprites[state]->frameSync())
extra = m_startTimes[sprite];
- } else {
- if (!m_duration[sprite])
- return state;
- int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow / m_sprites[state]->m_frames;
- extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
- }
+ else if (!m_duration[sprite])
+ return m_sprites[state]->frames();
+ else
+ extra = pseudospriteProgress(sprite, state);
+ if (m_sprites[state]->reverse())
+ extra = (m_sprites[state]->m_generatedCount - 1) - extra;
+
+
if (extra == m_sprites[state]->m_generatedCount - 1)//last state
return m_sprites[state]->frames() % m_sprites[state]->m_framesPerRow;
else
@@ -190,8 +210,11 @@ int QQuickSpriteEngine::spriteDuration(int sprite)//Full duration, not per frame
int state = m_things[sprite];
if (!m_sprites[state]->m_generatedCount)
return m_duration[sprite];
- int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow / m_sprites[state]->m_frames;
- int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
+ int rowDuration;
+ int extra = pseudospriteProgress(sprite, state, &rowDuration);
+ if (m_sprites[state]->reverse())
+ extra = (m_sprites[state]->m_generatedCount - 1) - extra;
+
if (extra == m_sprites[state]->m_generatedCount - 1)//last state
return m_duration[sprite] % rowDuration;
else
@@ -203,18 +226,47 @@ int QQuickSpriteEngine::spriteY(int sprite)
int state = m_things[sprite];
if (!m_sprites[state]->m_generatedCount)
return m_sprites[state]->m_rowY;
+
int extra;
- if (m_sprites[state]->frameSync()) {
+ if (m_sprites[state]->frameSync())
extra = m_startTimes[sprite];
- } else {
- if (!m_duration[sprite])
- return state;
- int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow / m_sprites[state]->m_frames;
- extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
- }
+ else if (!m_duration[sprite])
+ return m_sprites[state]->m_rowY;
+ else
+ extra = pseudospriteProgress(sprite, state);
+ if (m_sprites[state]->reverse())
+ extra = (m_sprites[state]->m_generatedCount - 1) - extra;
+
+
return m_sprites[state]->m_rowY + m_sprites[state]->m_frameHeight * extra;
}
+int QQuickSpriteEngine::spriteX(int sprite)
+{
+ int state = m_things[sprite];
+ if (!m_sprites[state]->m_generatedCount)
+ return m_sprites[state]->m_rowStartX;
+
+ int extra;
+ if (m_sprites[state]->frameSync())
+ extra = m_startTimes[sprite];
+ else if (!m_duration[sprite])
+ return m_sprites[state]->m_rowStartX;
+ else
+ extra = pseudospriteProgress(sprite, state);
+ if (m_sprites[state]->reverse())
+ extra = (m_sprites[state]->m_generatedCount - 1) - extra;
+
+ if (extra)
+ return 0;
+ return m_sprites[state]->m_rowStartX;
+}
+
+QQuickSprite* QQuickSpriteEngine::sprite(int sprite)
+{
+ return m_sprites[m_things[sprite]];
+}
+
int QQuickSpriteEngine::spriteWidth(int sprite)
{
int state = m_things[sprite];
@@ -470,7 +522,7 @@ void QQuickSpriteEngine::advance(int idx) //Reimplemented to recognize and handl
> int(m_timeOffset + (m_addAdvance ? m_advanceTime.elapsed() : 0))) {
//only a pseduostate ended
emit stateChanged(idx);
- addToUpdateList(m_timeOffset + spriteDuration(idx), idx);
+ addToUpdateList(spriteStart(idx) + spriteDuration(idx) + (m_addAdvance ? m_advanceTime.elapsed() : 0), idx);
return;
}
int nextIdx = nextState(m_things[idx],idx);
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index 6adab97430..cb954f26ff 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -264,12 +264,12 @@ public:
return QDeclarativeListProperty<QQuickSprite>(this, m_sprites);
}
-
+ QQuickSprite* sprite(int sprite=0);
int spriteState(int sprite=0);
int spriteStart(int sprite=0);
int spriteFrames(int sprite=0);
int spriteDuration(int sprite=0);//Full duration, not per frame
- int spriteX(int /* sprite */ = 0) { return 0; }//Currently all rows are 0 aligned, if we get more space efficient we might change this
+ int spriteX(int sprite=0);
int spriteY(int sprite=0);
int spriteWidth(int sprite=0);
int spriteHeight(int sprite=0);
@@ -281,6 +281,7 @@ public:
virtual void restart(int index=0);
virtual void advance(int index=0);
private:
+ int pseudospriteProgress(int,int,int*rd=0);
QList<QQuickSprite*> m_sprites;
};
diff --git a/src/quick/items/qquickspriteimage.cpp b/src/quick/items/qquickspriteimage.cpp
index 1819decf10..e34944b970 100644
--- a/src/quick/items/qquickspriteimage.cpp
+++ b/src/quick/items/qquickspriteimage.cpp
@@ -452,6 +452,8 @@ void QQuickSpriteImage::prepareNextFrame()
frameAt = m_curFrame;
progress = 0;
}
+ if (m_spriteEngine->sprite()->reverse())
+ frameAt = (m_spriteEngine->spriteFrames() - 1) - frameAt;
qreal y = m_spriteEngine->spriteY() / m_sheetSize.height();
qreal w = m_spriteEngine->spriteWidth() / m_sheetSize.width();
qreal h = m_spriteEngine->spriteHeight() / m_sheetSize.height();