aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2004-12-28 04:09:10 +0000
committerEugene Sandulenko2004-12-28 04:09:10 +0000
commit864b1f88c0477c65ab40612a77930f998f23c2c0 (patch)
treebccd9d8327fbe5a5b44de468d979f23066534631
parent03ed4dd4df23b8c6962419df7212dd863ead6664 (diff)
downloadscummvm-rg350-864b1f88c0477c65ab40612a77930f998f23c2c0.tar.gz
scummvm-rg350-864b1f88c0477c65ab40612a77930f998f23c2c0.tar.bz2
scummvm-rg350-864b1f88c0477c65ab40612a77930f998f23c2c0.zip
Implement rest of animation-related opcodes.
svn-id: r16353
-rw-r--r--saga/animation.cpp46
-rw-r--r--saga/animation.h7
-rw-r--r--saga/events.cpp2
-rw-r--r--saga/script.h4
-rw-r--r--saga/sfuncs.cpp24
5 files changed, 54 insertions, 29 deletions
diff --git a/saga/animation.cpp b/saga/animation.cpp
index 599df2c92d..902dadb3ef 100644
--- a/saga/animation.cpp
+++ b/saga/animation.cpp
@@ -118,7 +118,7 @@ int Anim::load(const byte *anim_resdata, size_t anim_resdata_len, uint16 *anim_i
new_anim->frame_time = DEFAULT_FRAME_TIME;
new_anim->flags = 0;
new_anim->link_id = -1;
- new_anim->playing = false;
+ new_anim->state = ANIM_PAUSE;
_anim_tbl[anim_id] = new_anim;
@@ -197,9 +197,9 @@ int Anim::play(uint16 anim_id, int vector_time, bool playing) {
}
if (playing)
- anim->playing = true;
+ anim->state = ANIM_PLAYING;
- if (anim->flags & ANIM_PAUSE)
+ if (anim->state == ANIM_PAUSE)
return SUCCESS;
if (anim->completed < anim->cycles) {
@@ -210,7 +210,7 @@ int Anim::play(uint16 anim_id, int vector_time, bool playing) {
disp_info.logical_w * disp_info.logical_h);
if (result != SUCCESS) {
warning("Anim::play: Error decoding frame %u", anim->current_frame);
- anim->playing = false;
+ anim->state = ANIM_PAUSE;
return FAILURE;
}
} else {
@@ -223,7 +223,7 @@ int Anim::play(uint16 anim_id, int vector_time, bool playing) {
anim->cur_frame_p, anim->cur_frame_len, &nextf_p, &nextf_len);
if (result != SUCCESS) {
warning("Anim::play: Error decoding frame %u", anim->current_frame);
- anim->playing = false;
+ anim->state = ANIM_PAUSE;
return FAILURE;
}
@@ -240,8 +240,8 @@ int Anim::play(uint16 anim_id, int vector_time, bool playing) {
anim->cur_frame_p = anim->resdata + SAGA_FRAME_HEADER_LEN;
anim->cur_frame_len = anim->resdata_len - SAGA_FRAME_HEADER_LEN;
- if (anim->current_frame == -1)
- anim->playing = false;
+ if (anim->flags & ANIM_STOPPING || anim->current_frame == -1)
+ anim->state = ANIM_PAUSE;
}
} else {
@@ -249,21 +249,21 @@ int Anim::play(uint16 anim_id, int vector_time, bool playing) {
if (anim->link_id != -1) {
// If this animation has a link, follow it
anim->current_frame = 0;
- anim->playing = false;
+ anim->state = ANIM_PAUSE;
link_anim_id = anim->link_id;
link_anim = _anim_tbl[link_anim_id];
if (link_anim != NULL) {
link_anim->current_frame = 0;
- link_anim->playing = true;
+ link_anim->state = ANIM_PLAYING;
}
anim_id = link_anim_id;
} else {
// No link, stop playing
anim->current_frame = anim->n_frames - 1;
- anim->playing = false;
+ anim->state = ANIM_PAUSE;
if (anim->flags & ANIM_ENDSCENE) {
// This animation ends the scene
@@ -277,14 +277,14 @@ int Anim::play(uint16 anim_id, int vector_time, bool playing) {
}
}
- if (!anim->playing && anim->link_id != -1) {
+ if (anim->state == ANIM_PAUSE && anim->link_id != -1) {
// If this animation has a link, follow it
link_anim_id = anim->link_id;
link_anim = _anim_tbl[link_anim_id];
if (link_anim != NULL) {
link_anim->current_frame = 0;
- link_anim->playing = true;
+ link_anim->state = ANIM_PLAYING;
}
anim_id = link_anim_id;
}
@@ -306,8 +306,26 @@ void Anim::stop(uint16 animId) {
return;
}
- _anim_tbl[animId]->playing = false;
- _anim_tbl[animId]->flags |= ANIM_PAUSE;
+ _anim_tbl[animId]->state = ANIM_PAUSE;
+}
+
+void Anim::finish(uint16 animId) {
+ if (animId >= _anim_count) {
+ warning("Anim::finish(): wrong animation number (%d)", animId);
+ return;
+ }
+
+ _anim_tbl[animId]->state = ANIM_STOPPING;
+}
+
+void Anim::resume(uint16 animId, int cycles) {
+ if (animId >= _anim_count) {
+ warning("Anim::resume(): wrong animation number (%d)", animId);
+ return;
+ }
+
+ _anim_tbl[animId]->cycles += cycles;
+ play(animId, 0, true);
}
int Anim::reset() {
diff --git a/saga/animation.h b/saga/animation.h
index d2eace7e1b..cc259571c6 100644
--- a/saga/animation.h
+++ b/saga/animation.h
@@ -90,14 +90,15 @@ struct ANIMATION {
size_t cur_frame_len;
int frame_time;
- bool playing;
+ int state;
int16 link_id;
uint16 flags;
};
enum ANIM_FLAGS {
- ANIM_LOOP = 0x01,
+ ANIM_PLAYING = 0x01,
ANIM_PAUSE = 0x02,
+ ANIM_STOPPING = 0x04,
ANIM_ENDSCENE = 0x80 // When animation ends, dispatch scene end event
};
@@ -117,6 +118,8 @@ public:
void animInfo(void);
void setCycles(uint animId, int cycles);
void stop(uint16 animId);
+ void finish(uint16 animId);
+ void resume(uint16 animId, int cycles);
private:
int ITE_DecodeFrame(const byte *anim_resource, size_t anim_resource_len, size_t frame_offset, byte *buf, size_t buf_len);
diff --git a/saga/events.cpp b/saga/events.cpp
index 0e95f03751..1c9313f40d 100644
--- a/saga/events.cpp
+++ b/saga/events.cpp
@@ -327,7 +327,7 @@ int Events::handleOneShot(EVENT *event) {
case ANIM_EVENT:
switch (event->op) {
case EVENT_FRAME:
- _vm->_anim->play(event->param, event->time);
+ _vm->_anim->play(event->param, event->time, false);
break;
case EVENT_SETFLAG:
_vm->_anim->setFlag(event->param, event->param2);
diff --git a/saga/script.h b/saga/script.h
index c7b90e9422..4183dfc3f4 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -331,7 +331,7 @@ private:
int scriptMoveTo(SCRIPTFUNC_PARAMS);
int SF_sceneEq(SCRIPTFUNC_PARAMS);
int SF_dropObject(SCRIPTFUNC_PARAMS);
- int SF_finishBgdAnim(SCRIPTFUNC_PARAMS);
+ int sfFinishBgdAnim(SCRIPTFUNC_PARAMS);
int sfSwapActors(SCRIPTFUNC_PARAMS);
int sfSimulSpeech(SCRIPTFUNC_PARAMS);
int SF_actorWalk(SCRIPTFUNC_PARAMS);
@@ -349,7 +349,7 @@ private:
int SF_placard(SCRIPTFUNC_PARAMS);
int SF_placardOff(SCRIPTFUNC_PARAMS);
int SF_setProtagState(SCRIPTFUNC_PARAMS);
- int SF_resumeBgdAnim(SCRIPTFUNC_PARAMS);
+ int sfResumeBgdAnim(SCRIPTFUNC_PARAMS);
int SF_throwActor(SCRIPTFUNC_PARAMS);
int SF_waitWalk(SCRIPTFUNC_PARAMS);
int SF_sceneID(SCRIPTFUNC_PARAMS);
diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp
index c240f633d3..4c8b3ffc5a 100644
--- a/saga/sfuncs.cpp
+++ b/saga/sfuncs.cpp
@@ -78,7 +78,7 @@ void Script::setupScriptFuncList(void) {
OPCODE(scriptMoveTo),
OPCODE(SF_sceneEq),
OPCODE(SF_dropObject),
- OPCODE(SF_finishBgdAnim),
+ OPCODE(sfFinishBgdAnim),
OPCODE(sfSwapActors),
OPCODE(sfSimulSpeech),
OPCODE(SF_actorWalk),
@@ -96,7 +96,7 @@ void Script::setupScriptFuncList(void) {
OPCODE(SF_placard),
OPCODE(SF_placardOff),
OPCODE(SF_setProtagState),
- OPCODE(SF_resumeBgdAnim),
+ OPCODE(sfResumeBgdAnim),
OPCODE(SF_throwActor),
OPCODE(SF_waitWalk),
OPCODE(SF_sceneID),
@@ -264,7 +264,7 @@ int Script::sfStartBgdAnim(SCRIPTFUNC_PARAMS) {
// Script function #10 (0x0A)
int Script::sfStopBgdAnim(SCRIPTFUNC_PARAMS) {
- ScriptDataWord animId = thread->pop();
+ ScriptDataWord animId = getSWord(thread->pop());
_vm->_anim->stop(animId);
@@ -578,10 +578,12 @@ int Script::SF_dropObject(SCRIPTFUNC_PARAMS) {
}
// Script function #33 (0x21)
-int Script::SF_finishBgdAnim(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param = thread->pop();
+int Script::sfFinishBgdAnim(SCRIPTFUNC_PARAMS) {
+ ScriptDataWord animId = getSWord(thread->pop());
+
+ _vm->_anim->finish(animId);
- debug(1, "stub: SF_finishBgdAnim(%d)", param);
+ debug(1, "sfFinishBgdAnim(%d)", animId);
return SUCCESS;
}
@@ -926,11 +928,13 @@ int Script::SF_setProtagState(SCRIPTFUNC_PARAMS) {
}
// Script function #51 (0x33)
-int Script::SF_resumeBgdAnim(SCRIPTFUNC_PARAMS) {
- for (int i = 0; i < nArgs; i++)
- thread->pop();
+int Script::sfResumeBgdAnim(SCRIPTFUNC_PARAMS) {
+ int animId = getSWord(thread->pop());
+ int cycles = getSWord(thread->pop());
+
+ _vm->_anim->resume(animId, cycles);
+ debug(1, "sfResumeBgdAnimSpeed(%d, %d)", animId, cycles);
- debug(1, "stub: SF_resumeBgdAnim(), %d args", nArgs);
return SUCCESS;
}