aboutsummaryrefslogtreecommitdiff
path: root/saga
diff options
context:
space:
mode:
Diffstat (limited to 'saga')
-rw-r--r--saga/animation.cpp207
-rw-r--r--saga/animation.h34
-rw-r--r--saga/ihnm_introproc.cpp4
-rw-r--r--saga/ite_introproc.cpp4
-rw-r--r--saga/saga.h3
-rw-r--r--saga/scene.cpp4
-rw-r--r--saga/script.h8
-rw-r--r--saga/sfuncs.cpp65
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;
}