[Scummvm-cvs-logs] CVS: scummvm/saga animation.cpp,1.29,1.30 animation.h,1.14,1.15 ihnm_introproc.cpp,1.32,1.33 ite_introproc.cpp,1.35,1.36 saga.h,1.56,1.57 scene.cpp,1.62,1.63 script.h,1.35,1.36 sfuncs.cpp,1.53,1.54

Eugene Sandulenko sev at users.sourceforge.net
Mon Dec 27 19:45:00 CET 2004


Update of /cvsroot/scummvm/scummvm/saga
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10227

Modified Files:
	animation.cpp animation.h ihnm_introproc.cpp ite_introproc.cpp 
	saga.h scene.cpp script.h sfuncs.cpp 
Log Message:
o Fixed animation playback
o Implemented almost all animation opcodes


Index: animation.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/animation.cpp,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- animation.cpp	22 Dec 2004 19:34:41 -0000	1.29
+++ animation.cpp	28 Dec 2004 03:44:00 -0000	1.30
@@ -30,7 +30,6 @@
 #include "saga/render.h"
 
 #include "saga/animation.h"
-#include "saga/stream.h"
 
 namespace Saga {
 
@@ -56,7 +55,8 @@
 }
 
 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 @@
 	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 @@
 		}
 
 		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 @@
 	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 @@
 	}
 
 	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 @@
 		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 @@
 			anim->cur_frame_len = nextf_len;
 		}
 		anim->current_frame++;
-	}
+		anim->completed++;
 
-	anim->play_flag = 1;
+		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;
 
-	if (anim->current_frame > anim->n_frames) {
+			if (anim->current_frame == -1)
+				anim->playing = false;
+		}
+
+	} 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 @@
 		}
 	}
 
+	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 @@
 	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 @@
 	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;
-			}
-
-			magic = *(anim_resource + offset);
-			if (magic == SAGA_FRAME_START) {
-				*n_frames = x;
-				return SUCCESS;
-			}
-		}
-
-		return FAILURE;
-	}
+	ah.nframes = readS.readByte() - 1;
+	ah.loopframe = readS.readByte() - 1;
+	ah.start = readS.readUint16BE(); //FIXME: check on Mac
 
-	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 @@
 	}
 
 	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 @@
 	// 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 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

Index: animation.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/animation.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- animation.h	22 Dec 2004 19:34:41 -0000	1.14
+++ animation.h	28 Dec 2004 03:44:07 -0000	1.15
@@ -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 @@
 	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 @@
 
 	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 @@
 
 	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;

Index: ihnm_introproc.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/ihnm_introproc.cpp,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- ihnm_introproc.cpp	22 Dec 2004 13:09:47 -0000	1.32
+++ ihnm_introproc.cpp	28 Dec 2004 03:44:07 -0000	1.33
@@ -193,7 +193,7 @@
 
 		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 @@
 
 	switch (param) {
 	case SCENE_BEGIN:
-		_vm->_anim->setFlag(0, ANIM_LOOP);
+		_vm->_anim->setCycles(0, -1);
 		_vm->_anim->play(0, 0);
 
 		// More music

Index: ite_introproc.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/ite_introproc.cpp,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- ite_introproc.cpp	22 Dec 2004 21:04:50 -0000	1.35
+++ ite_introproc.cpp	28 Dec 2004 03:44:07 -0000	1.36
@@ -657,7 +657,7 @@
 		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 @@
 		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

Index: saga.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/saga.h,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -d -r1.56 -r1.57
--- saga.h	25 Dec 2004 16:55:13 -0000	1.56
+++ saga.h	28 Dec 2004 03:44:07 -0000	1.57
@@ -78,7 +78,8 @@
 };
 
 enum scriptTimings {
-	kScriptTimeTicksPerSecond = (728L/10L)
+	kScriptTimeTicksPerSecond = (728L/10L),
+	kRepeatSpeed = 40   // 25 frames/sec
 };
 
 enum Directions {

Index: scene.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/scene.cpp,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -d -r1.62 -r1.63
--- scene.cpp	24 Dec 2004 20:44:39 -0000	1.62
+++ scene.cpp	28 Dec 2004 03:44:07 -0000	1.63
@@ -972,10 +972,6 @@
 		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;

Index: script.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/script.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- script.h	25 Dec 2004 11:17:03 -0000	1.35
+++ script.h	28 Dec 2004 03:44:07 -0000	1.36
@@ -307,8 +307,8 @@
 	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 @@
 	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);

Index: sfuncs.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/sfuncs.cpp,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- sfuncs.cpp	25 Dec 2004 11:17:03 -0000	1.53
+++ sfuncs.cpp	28 Dec 2004 03:44:07 -0000	1.54
@@ -54,8 +54,8 @@
 		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 @@
 		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 @@
 }
 
 // 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 @@
 }
 
 // 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 @@
 
 // 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();
-
-	frame_count = getSWord(frame_parm);
-	anim_id = getSWord(anim_id_parm);
+int Script::sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS) {
+	int animId = getSWord(thread->pop());
+	int cycles = getSWord(thread->pop());
+	int speed = getSWord(thread->pop());
 
-	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;
 }
 





More information about the Scummvm-git-logs mailing list