diff options
author | Eugene Sandulenko | 2004-12-28 03:44:07 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2004-12-28 03:44:07 +0000 |
commit | 03ed4dd4df23b8c6962419df7212dd863ead6664 (patch) | |
tree | 4a9fc0d96cedb4c4e1afe8a0d0130620908466f1 /saga | |
parent | 48e70acbaa96a8bf6fe4147a21596f2be7524794 (diff) | |
download | scummvm-rg350-03ed4dd4df23b8c6962419df7212dd863ead6664.tar.gz scummvm-rg350-03ed4dd4df23b8c6962419df7212dd863ead6664.tar.bz2 scummvm-rg350-03ed4dd4df23b8c6962419df7212dd863ead6664.zip |
o Fixed animation playback
o Implemented almost all animation opcodes
svn-id: r16352
Diffstat (limited to 'saga')
-rw-r--r-- | saga/animation.cpp | 207 | ||||
-rw-r--r-- | saga/animation.h | 34 | ||||
-rw-r--r-- | saga/ihnm_introproc.cpp | 4 | ||||
-rw-r--r-- | saga/ite_introproc.cpp | 4 | ||||
-rw-r--r-- | saga/saga.h | 3 | ||||
-rw-r--r-- | saga/scene.cpp | 4 | ||||
-rw-r--r-- | saga/script.h | 8 | ||||
-rw-r--r-- | saga/sfuncs.cpp | 65 |
8 files changed, 153 insertions, 176 deletions
diff --git a/saga/animation.cpp b/saga/animation.cpp index c3cb9a2054..599df2c92d 100644 --- a/saga/animation.cpp +++ b/saga/animation.cpp @@ -30,7 +30,6 @@ #include "saga/render.h" #include "saga/animation.h" -#include "saga/stream.h" namespace Saga { @@ -56,7 +55,8 @@ Anim::~Anim(void) { } int Anim::load(const byte *anim_resdata, size_t anim_resdata_len, uint16 *anim_id_p) { - ANIMATION *new_anim; + ANIMATION *new_anim; + ANIMATION_HEADER ah; uint16 anim_id = 0; uint16 i; @@ -88,12 +88,13 @@ int Anim::load(const byte *anim_resdata, size_t anim_resdata_len, uint16 *anim_i new_anim->resdata = anim_resdata; new_anim->resdata_len = anim_resdata_len; - if (_vm->_gameType == GType_ITE) { - if (getNumFrames(anim_resdata, anim_resdata_len, &new_anim->n_frames) != SUCCESS) { - warning("Anim::load Couldn't get animation frame count"); - return FAILURE; - } + MemoryReadStreamEndian headerReadS(anim_resdata, anim_resdata_len, IS_BIG_ENDIAN); + + readAnimHeader(headerReadS, ah); + new_anim->n_frames = ah.nframes; + new_anim->loopframe = ah.loopframe; + if (_vm->_gameType == GType_ITE) { // Cache frame offsets new_anim->frame_offsets = (size_t *)malloc(new_anim->n_frames * sizeof *new_anim->frame_offsets); if (new_anim->frame_offsets == NULL) { @@ -102,24 +103,22 @@ int Anim::load(const byte *anim_resdata, size_t anim_resdata_len, uint16 *anim_i } for (i = 0; i < new_anim->n_frames; i++) { - getFrameOffset(anim_resdata, anim_resdata_len, i + 1, &new_anim->frame_offsets[i]); + getFrameOffset(anim_resdata, anim_resdata_len, i, &new_anim->frame_offsets[i]); } } else { new_anim->cur_frame_p = anim_resdata + SAGA_FRAME_HEADER_LEN; // ? len - may vary new_anim->cur_frame_len = anim_resdata_len - SAGA_FRAME_HEADER_LEN; - getNumFrames(anim_resdata, anim_resdata_len, &new_anim->n_frames); } // Set animation data - new_anim->current_frame = 1; - new_anim->end_frame = new_anim->n_frames; - new_anim->stop_frame = new_anim->end_frame; + new_anim->current_frame = 0; + new_anim->completed = 0; + new_anim->cycles = new_anim->n_frames; new_anim->frame_time = DEFAULT_FRAME_TIME; new_anim->flags = 0; - new_anim->play_flag = 0; - new_anim->link_flag = 0; - new_anim->link_id = 0; + new_anim->link_id = -1; + new_anim->playing = false; _anim_tbl[anim_id] = new_anim; @@ -130,7 +129,7 @@ int Anim::load(const byte *anim_resdata, size_t anim_resdata_len, uint16 *anim_i return SUCCESS; } -int Anim::link(uint16 anim_id1, uint16 anim_id2) { +int Anim::link(int16 anim_id1, int16 anim_id2) { ANIMATION *anim1; ANIMATION *anim2; @@ -139,21 +138,33 @@ int Anim::link(uint16 anim_id1, uint16 anim_id2) { } anim1 = _anim_tbl[anim_id1]; + + anim1->link_id = anim_id2; + + if (anim_id2 == -1) + return SUCCESS; + anim2 = _anim_tbl[anim_id2]; if ((anim1 == NULL) || (anim2 == NULL)) { return FAILURE; } - anim1->link_id = anim_id2; - anim1->link_flag = 1; - anim2->frame_time = anim1->frame_time; return SUCCESS; } -int Anim::play(uint16 anim_id, int vector_time) { +void Anim::setCycles(uint animId, int cycles) { + if (animId >= _anim_count) { + warning("Anim::setStopFrame(): wrong animation number (%d)", animId); + return; + } + + _anim_tbl[animId]->cycles = cycles; +} + +int Anim::play(uint16 anim_id, int vector_time, bool playing) { EVENT event; ANIMATION *anim; ANIMATION *link_anim; @@ -185,30 +196,34 @@ int Anim::play(uint16 anim_id, int vector_time) { return FAILURE; } + if (playing) + anim->playing = true; + if (anim->flags & ANIM_PAUSE) return SUCCESS; - if (anim->play_flag) { + if (anim->completed < anim->cycles) { frame = anim->current_frame; if (_vm->_gameType == GType_ITE) { - result = ITE_DecodeFrame(anim->resdata, anim->resdata_len, anim->frame_offsets[frame - 1], display_buf, + // FIXME: if start > 0, then this works incorrectly + result = ITE_DecodeFrame(anim->resdata, anim->resdata_len, anim->frame_offsets[frame], display_buf, disp_info.logical_w * disp_info.logical_h); if (result != SUCCESS) { - warning("ANIM::play: Error decoding frame %u", anim->current_frame); - anim->play_flag = 0; + warning("Anim::play: Error decoding frame %u", anim->current_frame); + anim->playing = false; return FAILURE; } } else { if (anim->cur_frame_p == NULL) { - warning("ANIM::play: Frames exhausted"); + warning("Anim::play: Frames exhausted"); return FAILURE; } result = IHNM_DecodeFrame(display_buf, disp_info.logical_w * disp_info.logical_h, 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->play_flag = 0; + warning("Anim::play: Error decoding frame %u", anim->current_frame); + anim->playing = false; return FAILURE; } @@ -216,35 +231,39 @@ int Anim::play(uint16 anim_id, int vector_time) { anim->cur_frame_len = nextf_len; } anim->current_frame++; - } + anim->completed++; + + if (anim->current_frame >= anim->n_frames) { + anim->current_frame = anim->loopframe; + + // FIXME: HACK. probably needs more testing for IHNM + anim->cur_frame_p = anim->resdata + SAGA_FRAME_HEADER_LEN; + anim->cur_frame_len = anim->resdata_len - SAGA_FRAME_HEADER_LEN; - anim->play_flag = 1; + if (anim->current_frame == -1) + anim->playing = false; + } - if (anim->current_frame > anim->n_frames) { + } else { // Animation done playing - if (anim->link_flag) { + if (anim->link_id != -1) { // If this animation has a link, follow it - anim->play_flag = 0; - anim->current_frame = 1; + anim->current_frame = 0; + anim->playing = false; link_anim_id = anim->link_id; link_anim = _anim_tbl[link_anim_id]; if (link_anim != NULL) { - link_anim->current_frame = 1; - link_anim->play_flag = 1; + link_anim->current_frame = 0; + link_anim->playing = true; } anim_id = link_anim_id; - } else if (anim->flags & ANIM_LOOP) { - // Loop animation - anim->current_frame = 1; - anim->cur_frame_p = anim->resdata + SAGA_FRAME_HEADER_LEN; - anim->cur_frame_len = anim->resdata_len - SAGA_FRAME_HEADER_LEN; } else { // No link, stop playing - anim->current_frame = anim->n_frames; - anim->play_flag = 0; + anim->current_frame = anim->n_frames - 1; + anim->playing = false; if (anim->flags & ANIM_ENDSCENE) { // This animation ends the scene @@ -258,6 +277,18 @@ int Anim::play(uint16 anim_id, int vector_time) { } } + if (!anim->playing && 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; + } + anim_id = link_anim_id; + } + event.type = ONESHOT_EVENT; event.code = ANIM_EVENT; event.op = EVENT_FRAME; @@ -269,6 +300,16 @@ int Anim::play(uint16 anim_id, int vector_time) { return SUCCESS; } +void Anim::stop(uint16 animId) { + if (animId >= _anim_count) { + warning("Anim::stop(): wrong animation number (%d)", animId); + return; + } + + _anim_tbl[animId]->playing = false; + _anim_tbl[animId]->flags |= ANIM_PAUSE; +} + int Anim::reset() { uint16 i; @@ -357,54 +398,20 @@ int Anim::freeId(uint16 anim_id) { return SUCCESS; } -// The actual number of frames present in an animation resource is -// sometimes less than number present in the .nframes member of the -// animation header. For this reason, the function attempts to find -// the last valid frame number, which it returns via 'n_frames' -int Anim::getNumFrames(const byte *anim_resource, size_t anim_resource_len, uint16 *n_frames) { - ANIMATION_HEADER ah; - - size_t offset; - int magic; - - int x; - - if (!_initialized) { - return FAILURE; - } - - - MemoryReadStreamEndian readS(anim_resource, anim_resource_len, IS_BIG_ENDIAN); - +void Anim::readAnimHeader(MemoryReadStreamEndian &readS, ANIMATION_HEADER &ah) { ah.magic = readS.readUint16LE(); // cause ALWAYS LE ah.screen_w = readS.readUint16(); ah.screen_h = readS.readUint16(); ah.unknown06 = readS.readByte(); ah.unknown07 = readS.readByte(); - ah.nframes = readS.readByte(); - - if (_vm->_gameType == GType_IHNM) { - *n_frames = ah.nframes; - } - - if (ah.magic == 68) { - for (x = ah.nframes; x > 0; x--) { - if (getFrameOffset(anim_resource, anim_resource_len, x, &offset) != SUCCESS) { - return FAILURE; - } + ah.nframes = readS.readByte() - 1; + ah.loopframe = readS.readByte() - 1; + ah.start = readS.readUint16BE(); //FIXME: check on Mac - magic = *(anim_resource + offset); - if (magic == SAGA_FRAME_START) { - *n_frames = x; - return SUCCESS; - } - } - - return FAILURE; - } - - return FAILURE; + if (ah.start != 65535 && ah.start != 0) + error("Anim::readAnimHeader(): found different start: %d. Fix Anim::play()", ah.start); + ah.start += readS.pos(); } int Anim::ITE_DecodeFrame(const byte *resdata, size_t resdata_len, size_t frame_offset, byte *buf, size_t buf_len) { @@ -437,16 +444,8 @@ int Anim::ITE_DecodeFrame(const byte *resdata, size_t resdata_len, size_t frame_ } MemoryReadStreamEndian headerReadS(resdata, resdata_len, IS_BIG_ENDIAN); - // Read animation header - ah.magic = headerReadS.readUint16LE(); - ah.screen_w = headerReadS.readUint16(); - ah.screen_h = headerReadS.readUint16(); - ah.unknown06 = headerReadS.readByte(); - ah.unknown07 = headerReadS.readByte(); - ah.nframes = headerReadS.readByte(); - ah.flags = headerReadS.readByte(); - ah.unknown10 = headerReadS.readByte(); - ah.unknown11 = headerReadS.readByte(); + + readAnimHeader(headerReadS, ah); screen_w = ah.screen_w; screen_h = ah.screen_h; @@ -462,7 +461,7 @@ int Anim::ITE_DecodeFrame(const byte *resdata, size_t resdata_len, size_t frame_ // Check for frame magic byte magic = readS.readByte(); if (magic != SAGA_FRAME_START) { - warning("ITE_DecodeFrame: Invalid frame offset"); + warning("ITE_DecodeFrame: Invalid frame offset %x", frame_offset); return FAILURE; } @@ -828,33 +827,19 @@ int Anim::getFrameOffset(const byte *resdata, size_t resdata_len, uint16 find_fr int i; - if (!_initialized) { - return FAILURE; - } - - MemoryReadStreamEndian readS(resdata, resdata_len, IS_BIG_ENDIAN); - // Read animation header - ah.magic = readS.readUint16LE(); - ah.screen_w = readS.readUint16(); - ah.screen_h = readS.readUint16(); - ah.unknown06 = readS.readByte(); - ah.unknown07 = readS.readByte(); - ah.nframes = readS.readByte(); - ah.flags = readS.readByte(); - ah.unknown10 = readS.readByte(); - ah.unknown11 = readS.readByte(); + readAnimHeader(readS, ah); num_frames = ah.nframes; - if ((find_frame < 1) || (find_frame > num_frames)) { + if (find_frame >= num_frames) { return FAILURE; } readS._bigEndian = !IS_BIG_ENDIAN; // RLE has inversion BE<>LE - for (current_frame = 1; current_frame < find_frame; current_frame++) { + for (current_frame = 0; current_frame < find_frame; current_frame++) { magic = readS.readByte(); if (magic != SAGA_FRAME_START) { // Frame sync failure. Magic Number not found diff --git a/saga/animation.h b/saga/animation.h index c800534fd0..d2eace7e1b 100644 --- a/saga/animation.h +++ b/saga/animation.h @@ -26,6 +26,8 @@ #ifndef SAGA_ANIMATION_H_ #define SAGA_ANIMATION_H_ +#include "saga/stream.h" + namespace Saga { #define MAX_ANIMATIONS 7 @@ -52,15 +54,13 @@ struct ANIMATION_HEADER { uint16 screen_w; uint16 screen_h; - uint16 unknown06; - uint16 unknown07; - - uint16 nframes; - uint16 flags; + byte unknown06; + byte unknown07; - uint16 unknown10; - uint16 unknown11; + byte nframes; + byte loopframe; + uint16 start; }; struct FRAME_HEADER { @@ -82,16 +82,16 @@ struct ANIMATION { uint16 n_frames; size_t *frame_offsets; - uint16 current_frame; - uint16 end_frame; - uint16 stop_frame; + int16 current_frame; + uint16 completed; + uint16 cycles; + int16 loopframe; const byte *cur_frame_p; size_t cur_frame_len; int frame_time; - uint16 play_flag; - int link_flag; - uint16 link_id; + bool playing; + int16 link_id; uint16 flags; }; @@ -108,20 +108,22 @@ public: int load(const byte *anim_resdata, size_t anim_resdata_len, uint16 *anim_id_p); int freeId(uint16 anim_id); - int play(uint16 anim_id, int vector_time); - int link(uint16 anim_id1, uint16 anim_id2); + int play(uint16 anim_id, int vector_time, bool playing = true); + int link(int16 anim_id1, int16 anim_id2); int setFlag(uint16 anim_id, uint16 flag); int clearFlag(uint16 anim_id, uint16 flag); int setFrameTime(uint16 anim_id, int time); int reset(void); void animInfo(void); + void setCycles(uint animId, int cycles); + void stop(uint16 animId); private: - int getNumFrames(const byte *anim_resource, size_t anim_resource_len, uint16 *n_frames); int ITE_DecodeFrame(const byte *anim_resource, size_t anim_resource_len, size_t frame_offset, byte *buf, size_t buf_len); int IHNM_DecodeFrame(byte *decode_buf, size_t decode_buf_len, const byte *thisf_p, size_t thisf_len, const byte **nextf_p, size_t *nextf_len); int getFrameOffset(const byte *anim_resource, size_t anim_resource_len, uint16 find_frame, size_t *frame_offset); + void readAnimHeader(MemoryReadStreamEndian &readS, ANIMATION_HEADER &ah); SagaEngine *_vm; bool _initialized; diff --git a/saga/ihnm_introproc.cpp b/saga/ihnm_introproc.cpp index 3a157b6c4a..82e9361ddb 100644 --- a/saga/ihnm_introproc.cpp +++ b/saga/ihnm_introproc.cpp @@ -193,7 +193,7 @@ int Scene::IHNMIntroMovieProc2(int param, SCENE_INFO *scene_info) { q_event = _vm->_events->chain(q_event, &event); - _vm->_anim->setFlag(0, ANIM_LOOP); + _vm->_anim->setCycles(0, -1); _vm->_anim->play(0, IHNM_PALFADE_TIME * 2); // Queue end of scene after looping animation for a while @@ -301,7 +301,7 @@ int Scene::IHNMHateProc(int param, SCENE_INFO *scene_info) { switch (param) { case SCENE_BEGIN: - _vm->_anim->setFlag(0, ANIM_LOOP); + _vm->_anim->setCycles(0, -1); _vm->_anim->play(0, 0); // More music diff --git a/saga/ite_introproc.cpp b/saga/ite_introproc.cpp index 8af18ac39f..c92ad9bb0e 100644 --- a/saga/ite_introproc.cpp +++ b/saga/ite_introproc.cpp @@ -657,7 +657,7 @@ int Scene::ITEIntroValleyProc(int param, SCENE_INFO *scene_info) { debug(0, "Beginning animation playback."); // Begin title screen background animation - _vm->_anim->setFlag(0, ANIM_LOOP); + _vm->_anim->setCycles(0, -1); _vm->_anim->play(0, PALETTE_FADE_DURATION); // Begin ITE title theme music @@ -938,7 +938,7 @@ int Scene::ITEIntroFairePathProc(int param, SCENE_INFO *scene_info) { event_delay = DISSOLVE_DURATION; // Begin title screen background animation - _vm->_anim->setFlag(0, ANIM_LOOP); + _vm->_anim->setCycles(0, -1); _vm->_anim->play(0, event_delay); // Queue game credits list diff --git a/saga/saga.h b/saga/saga.h index 217df20d5f..77c93cdb86 100644 --- a/saga/saga.h +++ b/saga/saga.h @@ -78,7 +78,8 @@ enum SAGAGameType { }; enum scriptTimings { - kScriptTimeTicksPerSecond = (728L/10L) + kScriptTimeTicksPerSecond = (728L/10L), + kRepeatSpeed = 40 // 25 frames/sec }; enum Directions { diff --git a/saga/scene.cpp b/saga/scene.cpp index b159fd1304..ccfc96c092 100644 --- a/saga/scene.cpp +++ b/saga/scene.cpp @@ -972,10 +972,6 @@ int Scene::defaultScene(int param, SCENE_INFO *scene_info) { event.op = EVENT_SHOW; _vm->_events->chain(q_event, &event); - // Start scene animations - _vm->_anim->setFlag(0, ANIM_LOOP); - _vm->_anim->play(0, 0); - // Start the scene main script if (_desc.sceneScriptNum > 0) { event.type = ONESHOT_EVENT; diff --git a/saga/script.h b/saga/script.h index ef9ba36a45..c7b90e9422 100644 --- a/saga/script.h +++ b/saga/script.h @@ -307,8 +307,8 @@ private: int sfScriptWalkTo(SCRIPTFUNC_PARAMS); int SF_doAction(SCRIPTFUNC_PARAMS); int sfSetActorFacing(SCRIPTFUNC_PARAMS); - int SF_startBgdAnim(SCRIPTFUNC_PARAMS); - int SF_stopBgdAnim(SCRIPTFUNC_PARAMS); + int sfStartBgdAnim(SCRIPTFUNC_PARAMS); + int sfStopBgdAnim(SCRIPTFUNC_PARAMS); int SF_freezeInterface(SCRIPTFUNC_PARAMS); int SF_dialogMode(SCRIPTFUNC_PARAMS); int SF_killActorThreads(SCRIPTFUNC_PARAMS); @@ -321,10 +321,10 @@ private: int SF_getNumber(SCRIPTFUNC_PARAMS); int SF_openDoor(SCRIPTFUNC_PARAMS); int SF_closeDoor(SCRIPTFUNC_PARAMS); - int SF_setBgdAnimSpeed(SCRIPTFUNC_PARAMS); + int sfSetBgdAnimSpeed(SCRIPTFUNC_PARAMS); int SF_cycleColors(SCRIPTFUNC_PARAMS); int SF_centerActor(SCRIPTFUNC_PARAMS); - int SF_startAnim(SCRIPTFUNC_PARAMS); + int sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS); int SF_actorWalkToAsync(SCRIPTFUNC_PARAMS); int SF_enableZone(SCRIPTFUNC_PARAMS); int sfSetActorState(SCRIPTFUNC_PARAMS); diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp index 4eb1efc5f5..c240f633d3 100644 --- a/saga/sfuncs.cpp +++ b/saga/sfuncs.cpp @@ -54,8 +54,8 @@ void Script::setupScriptFuncList(void) { OPCODE(sfScriptWalkTo), OPCODE(SF_doAction), OPCODE(sfSetActorFacing), - OPCODE(SF_startBgdAnim), - OPCODE(SF_stopBgdAnim), + OPCODE(sfStartBgdAnim), + OPCODE(sfStopBgdAnim), OPCODE(SF_freezeInterface), OPCODE(SF_dialogMode), OPCODE(SF_killActorThreads), @@ -68,10 +68,10 @@ void Script::setupScriptFuncList(void) { OPCODE(SF_getNumber), OPCODE(SF_openDoor), OPCODE(SF_closeDoor), - OPCODE(SF_setBgdAnimSpeed), + OPCODE(sfSetBgdAnimSpeed), OPCODE(SF_cycleColors), OPCODE(SF_centerActor), - OPCODE(SF_startAnim), + OPCODE(sfStartBgdAnimSpeed), OPCODE(SF_actorWalkToAsync), OPCODE(SF_enableZone), OPCODE(sfSetActorState), @@ -251,19 +251,24 @@ int Script::sfSetActorFacing(SCRIPTFUNC_PARAMS) { } // Script function #9 (0x09) -int Script::SF_startBgdAnim(SCRIPTFUNC_PARAMS) { - ScriptDataWord param1 = thread->pop(); - ScriptDataWord param2 = thread->pop(); +int Script::sfStartBgdAnim(SCRIPTFUNC_PARAMS) { + int animId = getSWord(thread->pop()); + int cycles = getSWord(thread->pop()); - debug(1, "stub: SF_startBgdAnim(%d, %d)", param1, param2); + _vm->_anim->setCycles(animId, cycles); + _vm->_anim->play(animId, kRepeatSpeed); + + debug(1, "sfStartBgdAnim(%d, %d)", animId, cycles); return SUCCESS; } // Script function #10 (0x0A) -int Script::SF_stopBgdAnim(SCRIPTFUNC_PARAMS) { - ScriptDataWord param = thread->pop(); +int Script::sfStopBgdAnim(SCRIPTFUNC_PARAMS) { + ScriptDataWord animId = thread->pop(); - debug(1, "stub: SF_stopBgdAnim(%d)", param); + _vm->_anim->stop(animId); + + debug(1, "sfStopBgdAnim(%d)", animId); return SUCCESS; } @@ -417,11 +422,13 @@ int Script::SF_closeDoor(SCRIPTFUNC_PARAMS) { } // Script function #23 (0x17) -int Script::SF_setBgdAnimSpeed(SCRIPTFUNC_PARAMS) { - ScriptDataWord param1 = thread->pop(); - ScriptDataWord param2 = thread->pop(); +int Script::sfSetBgdAnimSpeed(SCRIPTFUNC_PARAMS) { + int animId = getSWord(thread->pop()); + int speed = getSWord(thread->pop()); + + _vm->_anim->setFrameTime(animId, ticksToMSec(speed)); + debug(1, "sfSetBgdAnimSpeed(%d, %d)", animId, speed); - debug(1, "stub: SF_setBgdAnimSpeed(%d, %d)", param1, param2); return SUCCESS; } @@ -444,29 +451,15 @@ int Script::SF_centerActor(SCRIPTFUNC_PARAMS) { // Script function #26 (0x1A) nonblocking // Starts the specified animation -// Param1: ? -// Param2: frames of animation to play or -1 to loop -// Param3: animation id -int Script::SF_startAnim(SCRIPTFUNC_PARAMS) { -// FIXME: implementation is wrong. Should link animation - ScriptDataWord timer_parm; - ScriptDataWord frame_parm; - ScriptDataWord anim_id_parm; - int frame_count; - int anim_id; - - anim_id_parm = thread->pop(); - frame_parm = thread->pop(); - timer_parm = thread->pop(); +int Script::sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS) { + int animId = getSWord(thread->pop()); + int cycles = getSWord(thread->pop()); + int speed = getSWord(thread->pop()); - frame_count = getSWord(frame_parm); - anim_id = getSWord(anim_id_parm); - - if (_vm->_anim->play(anim_id, 0) != SUCCESS) { - _vm->_console->DebugPrintf(S_WARN_PREFIX "SF.26: Anim::play() failed. Anim id: %u\n", anim_id); - return FAILURE; - } + _vm->_anim->setCycles(animId, cycles); + _vm->_anim->play(animId, ticksToMSec(speed)); + debug(1, "sfStartBgdAnimSpeed(%d, %d, %d)", animId, cycles, speed); return SUCCESS; } |