aboutsummaryrefslogtreecommitdiff
path: root/queen
diff options
context:
space:
mode:
authorGregory Montoir2003-10-15 16:31:51 +0000
committerGregory Montoir2003-10-15 16:31:51 +0000
commit57a2b4c453f197becf94a64c80e08c366d0ec717 (patch)
tree4e82953daab101fbfdbecb8817a13255b16ef88b /queen
parentde410e62f2f6ebde22948e2d31f444abeec7279a (diff)
downloadscummvm-rg350-57a2b4c453f197becf94a64c80e08c366d0ec717.tar.gz
scummvm-rg350-57a2b4c453f197becf94a64c80e08c366d0ec717.tar.bz2
scummvm-rg350-57a2b4c453f197becf94a64c80e08c366d0ec717.zip
preliminary GRAPHIC_ANIM support
svn-id: r10814
Diffstat (limited to 'queen')
-rw-r--r--queen/graphics.cpp15
-rw-r--r--queen/graphics.h6
-rw-r--r--queen/logic.cpp203
-rw-r--r--queen/logic.h5
-rw-r--r--queen/structs.h18
5 files changed, 181 insertions, 66 deletions
diff --git a/queen/graphics.cpp b/queen/graphics.cpp
index a405c59ee3..a4fe8150ea 100644
--- a/queen/graphics.cpp
+++ b/queen/graphics.cpp
@@ -387,15 +387,15 @@ void Graphics::bobSetupControl() {
}
-void Graphics::bobAnimString(uint32 bobnum, uint16* animBuf) {
+void Graphics::bobAnimString(uint32 bobnum, const AnimFrame *animBuf) {
BobSlot *pbs = &_bobs[bobnum];
pbs->active = true;
pbs->animating = true;
pbs->anim.string.buffer = animBuf;
pbs->anim.string.curPos = animBuf;
- pbs->frameNum = animBuf[0];
- pbs->anim.speed = animBuf[1] / 4;
+ pbs->frameNum = animBuf->frame;
+ pbs->anim.speed = animBuf->speed / 4;
}
@@ -501,16 +501,17 @@ void BobSlot::animOneStep() {
if (anim.string.buffer != NULL) {
--anim.speed;
if(anim.speed == 0) {
- anim.string.curPos += 2;
- uint16 nextFrame = anim.string.curPos[0];
+ // jump to next entry
+ ++anim.string.curPos;
+ uint16 nextFrame = anim.string.curPos->frame;
if (nextFrame == 0) {
anim.string.curPos = anim.string.buffer;
- frameNum = anim.string.curPos[0];
+ frameNum = anim.string.curPos->frame;
}
else {
frameNum = nextFrame;
}
- anim.speed = anim.string.curPos[1] / 4;
+ anim.speed = anim.string.curPos->speed / 4;
// FIXME: handle that when QueenSound class is ready
// play memory sfx and move on to next frame
diff --git a/queen/graphics.h b/queen/graphics.h
index 152a662826..91c909deb5 100644
--- a/queen/graphics.h
+++ b/queen/graphics.h
@@ -64,8 +64,8 @@ struct BobSlot {
//! string based animation
struct {
- uint16* buffer;
- uint16* curPos;
+ const AnimFrame *buffer;
+ const AnimFrame *curPos;
} string;
//! normal moving animation
@@ -123,7 +123,7 @@ public:
void bankErase(uint32 bankslot); // erase()
void bobSetupControl();
- void bobAnimString(uint32 bobnum, uint16* animBuf); // stringanim()
+ void bobAnimString(uint32 bobnum, const AnimFrame *buf); // stringanim()
void bobAnimNormal(uint32 bobnum, uint16 firstFrame, uint16 lastFrame, uint16 speed, bool rebound, bool xflip); // makeanim()
void bobMove(uint32 bobnum, uint16 endx, uint16 endy, int16 speed); // movebob()
void bobDraw(uint32 bobnum, uint16 x, uint16 y, uint16 scale, bool xflip, const Box& box); // bob()
diff --git a/queen/logic.cpp b/queen/logic.cpp
index 4880170224..a339ca5688 100644
--- a/queen/logic.cpp
+++ b/queen/logic.cpp
@@ -725,7 +725,7 @@ void Logic::roomErase() {
_personFrames[i] = 0;
}
for (i = 1; i <= 16; ++i) {
- _newAnim[i][0] = 0;
+ _newAnim[i][0].frame = 0;
}
uint16 cur = _roomData[_oldRoom] + 1;
@@ -889,9 +889,28 @@ void Logic::roomSetupObjects() {
rebound = true;
}
if (pgd->firstFrame < 0) {
- // FIXME: need GRAPHIC_ANIM stuff
- // see queen.c l.1251-1296
- warning("Logic::roomSetupObjects() - Object number %d not handled", pod->image);
+ // FIXME: if(TEMPA[1]<0) bobs[CURRBOB].xflip=1;
+ curBob = 5 + _numFurnitureAnimated;
+ AnimFrame *paf = NULL;
+ if (pod->name > 0) {
+ paf = _newAnim[curBob + numObjectAnimated];
+ }
+ BobSlot *pbs = _graphics->bob(curBob + numObjectAnimated);
+ int16 f = animFindAll(pgd, curImage + 1, paf);
+ curImage += pgd->lastFrame;
+ if (paf != NULL) {
+ if (f < 0) {
+ pbs->xflip = true;
+ }
+ pbs->active = true;
+ pbs->x = pgd->x;
+ pbs->y = pgd->y;
+ _graphics->bobAnimString(curBob + numObjectAnimated, paf);
+ }
+ else {
+ pbs->animating = false;
+ }
+ ++numObjectAnimated;
}
else if (lastFrame != 0) {
// animated objects
@@ -1022,50 +1041,65 @@ uint16 Logic::roomRefreshObject(uint16 obj) {
curImage = findFrame(obj);
int image = pod->image;
- if (pod->image > 5000)
+ if (image > 5000) {
image -= 5000;
-
-
- GraphicData *pgd = &_graphicData[image];
- bool rebound = false;
- int16 lastFrame = pgd->lastFrame;
- if (lastFrame < 0) {
- lastFrame = -lastFrame;
- rebound = true;
+ }
+
+ GraphicData *pgd = &_graphicData[image];
+ bool rebound = false;
+ int16 lastFrame = pgd->lastFrame;
+ if (lastFrame < 0) {
+ lastFrame = -lastFrame;
+ rebound = true;
+ }
+ if (pgd->firstFrame < 0) {
+ AnimFrame *paf = NULL;
+ if (pod->name != 0) {
+ paf = _newAnim[curBob];
}
- if (pgd->firstFrame) {
- // FIXME: need GRAPHIC_ANIM stuff
- // see queen.c l.944-981
- warning("Logic::roomRefreshObject() - Object number %d not handled", obj);
+ int16 f = animFindAll(pgd, curImage, paf);
+ curImage += pgd->lastFrame - 1;
+ if (f < 0) {
+ pbs->xflip = true;
}
- else if (lastFrame != 0) {
- // turn on an animated bob
- _graphics->bankUnpack(pgd->firstFrame, 2, 15);
- pbs->animating = false;
- uint16 firstFrame = curImage;
- --curImage;
- uint16 j;
- for (j = pgd->firstFrame; j <= lastFrame; ++j) {
- ++curImage;
- _graphics->bankUnpack(j, curImage, 15);
- }
+ if (paf != NULL) {
pbs->active = true;
pbs->x = pgd->x;
pbs->y = pgd->y;
- pbs->frameNum = firstFrame;
- if (pgd->speed > 0) {
- _graphics->bobAnimNormal(curBob, firstFrame, curImage, pgd->speed / 4, rebound, false);
- }
+ _graphics->bobAnimString(curBob, _newAnim[curBob]);
}
else {
- // frame 2 is used as a buffer frame to prevent BOB flickering
- _graphics->bankUnpack(pgd->firstFrame, 2, 15);
- _graphics->bankUnpack(pgd->firstFrame, curImage, 15);
- pbs->active = true;
- pbs->x = pgd->x;
- pbs->y = pgd->y;
- pbs->frameNum = curImage;
+ pbs->animating = false;
+ }
+ }
+ else if (lastFrame != 0) {
+ // turn on an animated bob
+ _graphics->bankUnpack(pgd->firstFrame, 2, 15);
+ pbs->animating = false;
+ uint16 firstImage = curImage;
+ --curImage;
+ uint16 j;
+ for (j = pgd->firstFrame; j <= lastFrame; ++j) {
+ ++curImage;
+ _graphics->bankUnpack(j, curImage, 15);
+ }
+ pbs->active = true;
+ pbs->x = pgd->x;
+ pbs->y = pgd->y;
+ pbs->frameNum = firstImage;
+ if (pgd->speed > 0) {
+ _graphics->bobAnimNormal(curBob, firstImage, curImage, pgd->speed / 4, rebound, false);
}
+ }
+ else {
+ // frame 2 is used as a buffer frame to prevent BOB flickering
+ _graphics->bankUnpack(pgd->firstFrame, 2, 15);
+ _graphics->bankUnpack(pgd->firstFrame, curImage, 15);
+ pbs->active = true;
+ pbs->x = pgd->x;
+ pbs->y = pgd->y;
+ pbs->frameNum = curImage;
+ }
return curImage;
}
@@ -1289,7 +1323,7 @@ uint16 Logic::personAllocate(uint16 noun, uint16 curImage) {
uint16 Logic::animCreate(uint16 curImage, const Person *person) {
- uint16 *animFrames = _newAnim[person->actor->bobNum];
+ AnimFrame *animFrames = _newAnim[person->actor->bobNum];
uint16 allocatedFrames[256];
memset(allocatedFrames, 0, sizeof(allocatedFrames));
@@ -1298,8 +1332,8 @@ uint16 Logic::animCreate(uint16 curImage, const Person *person) {
uint16 f1, f2;
do {
sscanf(p, "%3hu,%3hu", &f1, &f2);
- animFrames[frame + 0] = f1;
- animFrames[frame + 1] = f2;
+ animFrames[frame].frame = f1;
+ animFrames[frame].speed = f2;
if (f1 > 500) {
// SFX
@@ -1310,7 +1344,7 @@ uint16 Logic::animCreate(uint16 curImage, const Person *person) {
}
p += 8;
- frame += 2;
+ ++frame;
} while(f1 != 0);
// ajust frame numbers
@@ -1322,13 +1356,13 @@ uint16 Logic::animCreate(uint16 curImage, const Person *person) {
++n;
}
}
- for (i = 0; animFrames[i] != 0; i += 2) {
- uint16 frameNum = animFrames[i];
+ for (i = 0; animFrames[i].frame != 0; ++i) {
+ uint16 frameNum = animFrames[i].frame;
if (frameNum > 500) {
- animFrames[i] = curImage + allocatedFrames[frameNum - 500] + 500;
+ animFrames[i].frame = curImage + allocatedFrames[frameNum - 500] + 500;
}
else {
- animFrames[i] = curImage + allocatedFrames[frameNum];
+ animFrames[i].frame = curImage + allocatedFrames[frameNum];
}
}
@@ -1348,13 +1382,86 @@ uint16 Logic::animCreate(uint16 curImage, const Person *person) {
void Logic::animErase(uint16 bobNum) {
- _newAnim[bobNum][0] = 0;
+ _newAnim[bobNum][0].frame = 0;
BobSlot *pbs = _graphics->bob(bobNum);
pbs->animating = false;
pbs->anim.string.buffer = NULL;
}
+int16 Logic::animFindAll(const GraphicData *gd, uint16 firstImage, AnimFrame *paf) {
+
+ int16 tempFrames[20];
+ memset(tempFrames, 0, sizeof(tempFrames));
+ uint16 numTempFrames = 0;
+ uint16 i, j;
+ for (i = 1; i <= _numGraphicAnim; ++i) {
+ const GraphicAnim *pga = &_graphicAnim[i];
+ if (pga->keyFrame == gd->firstFrame) {
+ int16 frame = pga->frame;
+ if (frame > 500) { // SFX
+ frame -= 500;
+ }
+ bool foundMatchingFrame = false;
+ for (j = 0; j < numTempFrames; ++j) {
+ if (tempFrames[j] == frame) {
+ foundMatchingFrame = true;
+ break;
+ }
+ }
+ if (!foundMatchingFrame) {
+ assert(numTempFrames < 20);
+ tempFrames[numTempFrames] = frame;
+ ++numTempFrames;
+ }
+ }
+ }
+
+ // sort found frames ascending
+ bool swap = true;
+ while (swap) {
+ swap = false;
+ for (i = 0; i < numTempFrames - 1; ++i) {
+ if (tempFrames[i] > tempFrames[i + 1]) {
+ SWAP(tempFrames[i], tempFrames[i + 1]);
+ swap = true;
+ }
+ }
+ }
+
+ // queen.c l.962-980 / l.1269-1294
+ for (i = 0; i < gd->lastFrame; ++i) {
+ _graphics->bankUnpack(ABS(tempFrames[i]), firstImage + i, 15);
+ }
+ if (paf != NULL) {
+ uint16 frameNr = 0;
+ for (i = 1; i <= _numGraphicAnim; ++i) {
+ const GraphicAnim *pga = &_graphicAnim[i];
+ if (pga->keyFrame == gd->firstFrame) {
+ for (j = 1; j <= gd->lastFrame; ++j) {
+ int16 f = pga->frame;
+ if (f > 500) {
+ f -= 500;
+ }
+ if (f == tempFrames[j - 1]) {
+ frameNr = j + firstImage - 1;
+ }
+ if (pga->frame > 500) {
+ frameNr += 500;
+ }
+ }
+ paf->frame = frameNr;
+ paf->speed = pga->speed;
+ ++paf;
+ }
+ }
+ paf->frame = 0;
+ paf->speed = 0;
+ }
+ return tempFrames[0];
+}
+
+
StateDirection Logic::findStateDirection(uint16 state) {
// FIXME: may be we should return a DIR_* constant instead
diff --git a/queen/logic.h b/queen/logic.h
index f7cae8b61c..de2647074a 100644
--- a/queen/logic.h
+++ b/queen/logic.h
@@ -124,6 +124,7 @@ public:
uint16 animCreate(uint16 curImage, const Person *person); // CREATE_ANIM
void animErase(uint16 bobNum);
+ int16 animFindAll(const GraphicData *gd, uint16 firstImage, AnimFrame *paf); // FIND_GRAPHIC_ANIMS
StateDirection findStateDirection(uint16 state); // == FIND_STATE(state, "DIR");
StateTalk findStateTalk (uint16 state); // == FIND_STATE(state, "TALK");
@@ -221,8 +222,8 @@ protected:
uint16 _numFrames; // FRAMES
uint16 _personFrames[4];
- //! contains the animation frames (max 60) to use for a bob (whose number must be < 17)
- uint16 _newAnim[17][60];
+ //! contains the animation frames (max 30) to use for a bob (whose number must be < 17)
+ AnimFrame _newAnim[17][30];
Resource *_resource;
Graphics *_graphics;
diff --git a/queen/structs.h b/queen/structs.h
index dc314dff1d..90c1a62dfe 100644
--- a/queen/structs.h
+++ b/queen/structs.h
@@ -421,18 +421,24 @@ struct FurnitureData {
struct GraphicAnim {
- int16 frame1;
- int16 frame2;
- int16 frame3;
+ int16 keyFrame;
+ int16 frame;
+ uint16 speed;
void readFrom(byte *&ptr) {
- frame1 = (int16)READ_BE_UINT16(ptr); ptr += 2;
- frame2 = (int16)READ_BE_UINT16(ptr); ptr += 2;
- frame3 = (int16)READ_BE_UINT16(ptr); ptr += 2;
+ keyFrame = (int16)READ_BE_UINT16(ptr); ptr += 2;
+ frame = (int16)READ_BE_UINT16(ptr); ptr += 2;
+ speed = READ_BE_UINT16(ptr); ptr += 2;
}
};
+struct AnimFrame {
+ uint16 frame;
+ uint16 speed;
+};
+
+
struct Person {
//! actor settings to use
const ActorData *actor; // P_ROOM, P_BNUM, P_GAMES, P_VALUE, P_COLOR, P_STAND, P_X, P_Y