diff options
-rw-r--r-- | saga/animation.cpp | 46 | ||||
-rw-r--r-- | saga/animation.h | 7 | ||||
-rw-r--r-- | saga/events.cpp | 2 | ||||
-rw-r--r-- | saga/script.h | 4 | ||||
-rw-r--r-- | saga/sfuncs.cpp | 24 |
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; } |