[Scummvm-cvs-logs] CVS: scummvm/kyra codecs.cpp,1.6,1.7 cpsimage.cpp,1.1,1.2 kyra.cpp,1.7,1.8 kyra.h,1.3,1.4 module.mk,1.4,1.5 palette.cpp,1.2,1.3 resource.cpp,1.5,1.6 resource.h,1.3,1.4 script.cpp,1.6,1.7 script.h,1.2,1.3 script_v1.cpp,1.4,1.5 wsamovie.cpp,1.2,1.3 wsamovie.h,1.1,1.2

James Brown ender at users.sourceforge.net
Thu Nov 11 05:36:00 CET 2004


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

Modified Files:
	codecs.cpp cpsimage.cpp kyra.cpp kyra.h module.mk palette.cpp 
	resource.cpp resource.h script.cpp script.h script_v1.cpp 
	wsamovie.cpp wsamovie.h 
Log Message:
Bring kyra up-to-date with patch 1051358


Index: codecs.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/codecs.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- codecs.cpp	30 Oct 2004 21:54:18 -0000	1.6
+++ codecs.cpp	11 Nov 2004 13:35:21 -0000	1.7
@@ -84,9 +84,13 @@
 					copyp = (const uint8*)&image_out[READ_LE_UINT16(readp)];
 					readp += 2;
 
-					memcpy(writep, copyp, count);
-					writep += count;
-					copyp += count;
+					// FIXME: Using memmove sometimes segfaults 
+					// (reproducably for Ender), which suggests something Bad here
+					//memmove(writep, copyp, count);
+					//writep += count;
+					//copyp += count;
+					while (count--)
+						*writep++ = *copyp++;
 				} else if (count == 0x3e) {
 					//command 3 (11111110 c c v): fill
 

Index: cpsimage.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/cpsimage.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cpsimage.cpp	15 Oct 2004 06:06:47 -0000	1.1
+++ cpsimage.cpp	11 Nov 2004 13:35:21 -0000	1.2
@@ -51,6 +51,7 @@
 		if (!buffer) {
 			error("resource created without data");
 		}
+		_ownPalette = 0;
 		Common::MemoryReadStream bufferstream(buffer, size);
 		
 		// reads in the Header
@@ -61,11 +62,15 @@
 		
 		// lets check a bit
 		if(_cpsHeader._pal == 0x3000000) {
-			warning("CPS images with a palette aren't supported");
-			
-			// skip 768 bytes
 			// if this was a compressed palette you should have strange graphics
-			bufferstream.seek(bufferstream.pos() + 768);
+			
+			uint8* palbuffer = new uint8[768];
+			assert(palbuffer);
+			
+			bufferstream.read(palbuffer, 768 * sizeof(uint8));
+			
+			_ownPalette = new Palette(palbuffer, 768);
+			assert(palbuffer);
 		}
 		
 		_image = new uint8[_cpsHeader._imagesize];
@@ -104,16 +109,15 @@
 	}
 	
 	void CPSImage::drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y) {
+		uint8* src = _image;
+		uint8* dst = &plane[y * planepitch + x];
+		uint32 copysize = planepitch - x;
+		
+		if (copysize > _width)
+			copysize = _width;
+		
 		if (_transparency == -1) {
 			// 'fast' blitting
-			
-			uint8* src = _image;
-			uint8* dst = &plane[y * planepitch + x];
-			uint32 copysize = planepitch - x;
-			
-			if (copysize > _width)
-				copysize = _width;
-			
 			for (uint16 y_ = 0; y_ < _height && y + y_ < planeheight; ++y_) {
 				memcpy(dst, src, copysize * sizeof(uint8));
 				dst += planepitch;
@@ -122,11 +126,9 @@
 			
 		} else {
 			// oh no! we have transparency so we have a very slow copy :/
-			uint8* src = _image;
-			uint8* dst = &plane[y * planepitch + x];
 			
 			for (uint16 yadd = 0; yadd < _height; ++yadd) {
-				for (uint16 xadd = 0; xadd < _width; ++xadd) {
+				for (uint16 xadd = 0; xadd < copysize; ++xadd) {
 					if (*src == _transparency) {
 						++dst;
 						++src;
@@ -135,23 +137,26 @@
 					}
 				}
 				
-				dst += planepitch - _width;
+				src += _width - copysize;
+				dst += planepitch - copysize;
 			}
 		}
 	}
 	
 	void CPSImage::drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y,
 								uint16 srcx, uint16 srcy, uint16 srcwidth, uint16 srcheight) {
+		uint8* src = &_image[srcy * _width + srcx];
+		uint8* dst = &plane[y * planepitch + x];
+		uint32 copysize = planepitch - x;
+		
+		if (srcwidth > _width)
+			srcwidth = _width;
+		
+		if (copysize > srcwidth)
+			copysize = srcwidth;
+		
 		if (_transparency == -1) {
 			// 'fast' blitting
-			
-			uint8* src = &_image[srcy * _width + srcx];
-			uint8* dst = &plane[y * planepitch + x];
-			uint32 copysize = planepitch - x;
-			
-			if (copysize > srcwidth)
-				copysize = srcwidth;
-			
 			for (uint16 y_ = 0; y_ < srcheight && y + y_ < planeheight; ++y_) {
 				memcpy(dst, src, copysize * sizeof(uint8));
 				dst += planepitch;
@@ -160,12 +165,9 @@
 			
 		} else {
 			// oh no! we have transparency so we have a very slow copy :/
-			// blit it without transparency
-			uint8* src = &_image[srcy * _width + srcx];
-			uint8* dst = &plane[y * planepitch + x];
 			
-			for (uint16 yadd = 0; yadd < _height; ++yadd) {
-				for (uint16 xadd = 0; xadd < _width; ++xadd) {
+			for (uint16 yadd = 0; yadd < srcheight; ++yadd) {
+				for (uint16 xadd = 0; xadd < copysize; ++xadd) {
 					if (*src == _transparency) {
 						++dst;
 						++src;
@@ -174,8 +176,8 @@
 					}
 				}
 				
-				dst += planepitch - _width;
-				src += _width - srcwidth;
+				dst += planepitch - copysize;
+				src += _width - copysize;
 			}
 		}
 	}

Index: kyra.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- kyra.cpp	10 Nov 2004 18:45:30 -0000	1.7
+++ kyra.cpp	11 Nov 2004 13:35:21 -0000	1.8
@@ -28,10 +28,13 @@
 #include "sound/mixer.h"
 #include "common/file.h"
 #include "common/config-manager.h"
+#include "sound/mididrv.h"
 
 #include "kyra.h"
 #include "resource.h"
 #include "script.h"
+#include "wsamovie.h"
+#include "sound.h"
 
 struct KyraGameSettings {
 	const char *name;
@@ -44,10 +47,13 @@
 	}
 };
 
-static const KyraGameSettings kyra_settings[] = { 
-	{"kyra1cd", "Legend of Kyrandia (CD)",	GF_TALKIE & GF_KYRA1,  "CHAPTER1.VRM"},
-	{"kyra1", "Legend of Kyrandia (Floppy)", GF_FLOPPY & GF_KYRA1, "INTRO.SND"},
-	{ 0, 0, 0, 0}
+static const KyraGameSettings kyra_settings[] = {
+	{"kyra1", "Legend of Kyrandia (Floppy)", GF_FLOPPY | GF_KYRA1, "INTRO.SND"},
+	{"kyra1cd", "Legend of Kyrandia (CD)",  GF_TALKIE | GF_KYRA1,  "CHAPTER1.VRM"},
+	{"kyra2", "Hand of Fate (Floppy)", GF_FLOPPY | GF_KYRA2, 0 },
+	{"kyra2cd", "Hand of Fate (CD)", GF_TALKIE | GF_KYRA2, "AUDIO.PAK"},
+	{"kyra3", "Malcom's Revenge", GF_TALKIE | GF_KYRA3, "K3INTRO0.VQA"},
+	{0, 0, 0, 0}
 };
 
 GameList Engine_KYRA_gameList() {
@@ -99,10 +105,40 @@
 
 	_mixer->setVolume(ConfMan.getInt("sfx_volume") * ConfMan.getInt("master_volume") / 255);
 
+	// gets the game
+	if (detector->_game.features & GF_KYRA1) {
+		if (detector->_game.features & GF_FLOPPY)
+			_game = KYRA1;
+		else
+			_game = KYRA1CD;
+	} else if (detector->_game.features & GF_KYRA2) {
+		if (detector->_game.features & GF_FLOPPY)
+			_game = KYRA2;
+		else
+			_game = KYRA2CD;
+	} else if (detector->_game.features & GF_KYRA3) {
+		_game = KYRA3;
+	} else {
+		error("unknown game");
+	}
+	
+	MidiDriver *driver = GameDetector::createMidi(GameDetector::detectMusicDriver(MDT_NATIVE | MDT_PREFER_NATIVE));
+	if (driver) {
+		if (ConfMan.getBool("native_mt32"))
+			driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
+		_midiDriver = new MusicPlayer(driver, this);
+		assert(_midiDriver);
+		_midiDriver->hasNativeMT32(ConfMan.getBool("native_mt32"));
+		_midiDriver->setVolume(255);
+	} else {
+		warning("Couldn't create MIDI driver... No music!");
+		_midiDriver = NULL;
+	};
+	
 	// Initialize backen
 	syst->initSize(320, 200);
-	_screen = new uint8[320 * 200];
-	memset(_screen, 0, 320 * 200);
+	_screen = new uint8[320*200];
+	memset(_screen, 0, sizeof(uint8) * 320 * 200);
 
 	_resMgr = new Resourcemanager(this);
 	assert(_resMgr);
@@ -110,15 +146,23 @@
 	setCurrentPalette(_resMgr->loadPalette("PALETTE.COL"));
 
 	// loads the 2 cursors
-	_mouse = _resMgr->loadImage("MOUSE.CPS");	//startup.pak
+	_mouse = _resMgr->loadImage("MOUSE.CPS");
 	_items = _resMgr->loadImage("ITEMS.CPS");
 
 	// loads the Font
 	_font = _resMgr->loadFont("8FAT.FNT");
-
-	// loads out scripts
+	
 	_npcScript = _resMgr->loadScript("_NPC.EMC");
-	_currentScript = _resMgr->loadScript("_STARTUP.EMC");
+
+	// loads the scripts (only Kyrandia 1)
+	if (_game == KYRA1 || _game == KYRA1CD) {
+		_currentScript = _resMgr->loadScript("_STARTUP.EMC");
+	} else {
+		error("game start files not known");
+	}
+	
+	assert(_npcScript);
+	assert(_currentScript);
 }
 
 KyraEngine::~KyraEngine() {
@@ -138,7 +182,7 @@
 void KyraEngine::go() {
 	warning("Kyrandia Engine ::go()");
 	// starts the init script
-	if (!_currentScript->startScript(kSetupScene)) {
+	/*if (!_currentScript->startScript(kSetupScene)) {
 		error("couldn't init '_STARTUP.EMC' script");
 	}
 
@@ -148,25 +192,67 @@
 		} else {
 			warning("init script returned: %d", _currentScript->state());
 		}
-	}
+	}*/
+	
+	Movie* movie = _resMgr->loadMovie("MAL-KAL.WSA");
+	assert(movie);
+	CPSImage* image = _resMgr->loadImage("GEMCUT.CPS");
+	assert(image);
+
+	int16 currentFrame = 0;
+	uint32 lastFrameChange = 0;
+
+	image->transparency(0);
+	image->drawToPlane(_screen, 320, 200, 0, 0, 0, 0, 320, 136);
+	movie->setImageBackground(_screen, 320, 200);
+	movie->position(16, 58);
+
+	setCurrentPalette(_resMgr->loadPalette("MAL-KAL.COL"));
 
+	uint8* _buffer = new uint8[320 * 200];
+	assert(_buffer);
+	memcpy(_buffer, _screen, 320 * 200);
+	movie->renderFrame(_buffer, 320, 200, movie->countFrames() - 1);
+
+	if (_midiDriver) {
+		_midiDriver->playMusic("KYRA2A.XMI");
+		_midiDriver->playTrack(3);
+	}
+	
 	while(true) {
 		OSystem::Event event;
 		//if (_debugger->isAttached())
 		//	_debugger->onFrame();
+		
+		memcpy(_screen, _buffer, 320 * 200);
+		if (lastFrameChange + movie->frameChange() < _system->getMillis()) {
+			lastFrameChange = _system->getMillis();
+			++currentFrame;
 
+			if (currentFrame >= (int16)movie->countFrames()) {
+				currentFrame = 0;
+			}
+		}
+		
+		movie->renderFrame(_screen, 320, 200, currentFrame);
+		_font->drawStringToPlane("This is only a test!", _screen, 320, 200, 75, 179, 136);
+		_font->drawStringToPlane("Nothing scripted!", _screen, 320, 200, 85, 189, 136);
 		updateScreen();
 		while (g_system->pollEvent(event)) {
 			switch (event.event_code) {
-			case OSystem::EVENT_QUIT:
-				g_system->quit();
-				break;
-			default:
-				break;
+				case OSystem::EVENT_QUIT:
+					g_system->quit();
+					break;
+				default:
+					break;
 			}
 		}
 		_system->delayMillis(10);
 	}
+	
+	delete movie;
+	delete image;
+	delete [] _buffer;
 }
 
 void KyraEngine::shutdown() {
@@ -179,12 +265,15 @@
 }
 
 void KyraEngine::setCurrentPalette(Palette* pal, bool delNextTime) {
-//	if (_delPalNextTime)
-//		delete _currentPal;
+	if (!pal)
+		return;
 
-//	_delPalNextTime = delNextTime;
+//        if (_delPalNextTime)
+//                delete _currentPal;
 
-//	_currentPal = pal;
+//        _delPalNextTime = delNextTime;
+
+//        _currentPal = pal;
 
 	if (pal->getData()) {
 		_system->setPalette(pal->getData(), 0, 256);

Index: kyra.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- kyra.h	16 Oct 2004 22:28:29 -0000	1.3
+++ kyra.h	11 Nov 2004 13:35:21 -0000	1.4
@@ -8,7 +8,7 @@
 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
  * GNU General Public License for more details.
 
  * You should have received a copy of the GNU General Public License
@@ -31,7 +31,17 @@
 	GF_FLOPPY	= 1 << 0,
 	GF_TALKIE	= 1 << 1,
 	GF_KYRA1	= 1 << 2,
-	GF_KYRA2	= 1 << 3
+	GF_KYRA2	= 1 << 3,
+	GF_KYRA3	= 1 << 4,
+	GF_AUDIOCD	= 1 << 5	// FM-Towns versions seems to use audio CD
+};
+
+enum {
+	KYRA1 = 0,
+	KYRA1CD = 1,
+	KYRA2 = 2,
+	KYRA2CD = 3,
+	KYRA3 = 4
 };
 
 namespace Kyra {
@@ -40,6 +50,7 @@
 	class Font;
 	class Palette;
 	class VMContext;
+	class MusicPlayer;
 
 class KyraEngine : public Engine {
 public:
@@ -51,13 +62,17 @@
 	void setCurrentPalette(Palette* pal, bool delNextTime = true);
 
 	Resourcemanager* resManager(void) { return _resMgr; }
-//	MidiDriver* midiDriver(void) { return _midiDriver; }
+	MusicPlayer* midiDriver(void) { return _midiDriver; }
+	
+	uint8 game(void) { return _game; }
 
 protected:
 	void go();
 	void shutdown();
 	Resourcemanager* _resMgr;
+	MusicPlayer* _midiDriver;
 	uint8 *_screen;
+	uint8 _game;
 
 	Font* _font;
 	CPSImage* _mouse;

Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/module.mk,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- module.mk	6 Nov 2004 09:26:36 -0000	1.4
+++ module.mk	11 Nov 2004 13:35:21 -0000	1.5
@@ -9,6 +9,7 @@
 	kyra/resource.o \
 	kyra/script_v1.o \
 	kyra/script.o \
+	kyra/sound.o \
 	kyra/wsamovie.o
 
 MODULE_DIRS += \

Index: palette.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/palette.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- palette.cpp	16 Oct 2004 22:28:29 -0000	1.2
+++ palette.cpp	11 Nov 2004 13:35:21 -0000	1.3
@@ -21,7 +21,7 @@
 
 #include "stdafx.h"
 #include "resource.h"
-	
+
 #include "common/stream.h"
 #include "codecs.h"
 
@@ -52,7 +52,7 @@
 			}
 			
 			delete [] data;
-			data = _palette;			
+			data = _palette;
 		}
 		
 		// hmm.. common/system.h Docu is wrong or SDL Backend has a bug :)

Index: resource.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/resource.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- resource.cpp	10 Nov 2004 18:09:14 -0000	1.5
+++ resource.cpp	11 Nov 2004 13:35:21 -0000	1.6
@@ -34,21 +34,48 @@
 		
 		// ugly a hardcoded list
 		// TODO: use the FS Backend to get all .PAK Files and load them
-		static const char* kyraFilelist[] = {
+		// or any other thing to get all files
+		static const char* kyra1Filelist[] = {
 			"A_E.PAK", "DAT.PAK", "F_L.PAK", "MAP_5.PAK", "MSC.PAK", "M_S.PAK",
 			"S_Z.PAK", "WSA1.PAK", "WSA2.PAK", "WSA3.PAK", "WSA4.PAK", "WSA5.PAK",
-			"WSA6.PAK", "startup.pak", "intro1.pak", 0
+			"WSA6.PAK", 0
 		};
 		
-		for (uint32 tmp = 0; kyraFilelist[tmp]; ++tmp)	{
+		static const char* kyra1CDFilelist[] = {
+			"ADL.PAK", "BRINS.PAK", "CLIFF.PAK", "ENTER.PAK", "FORESTA.PAK", "GEM.PAK", "INTRO1.PAK",
+			"LEPHOLE.PAK", "OAKS.PAK", "SPELL.PAK", "WILLOW.PAK", "ALCHEMY.PAK", "BROKEN.PAK", "COL.PAK",
+			"EXTHEAL.PAK", "FORESTB.PAK", "GEMCUT.PAK", "INTRO2.PAK", "LIBRARY.PAK", "PLATEAU.PAK", "SPRING.PAK",
+			"WISE.PAK", "ALGAE.PAK", "BURN.PAK", "DARMS.PAK", "EXTPOT.PAK", "FORESTC.PAK", "GENCAVB.PAK",
+			"INTRO3.PAK", "MISC.PAK", "PLTCAVE.PAK", "SQUARE.PAK", "XEDGE.PAK", "ALTAR.PAK", "CASTLE.PAK",
+			"DEAD.PAK", "EXTSPEL.PAK", "FOUNTN.PAK", "GENHALL.PAK", "INTRO4.PAK", "MIX.PAK", "POTION.PAK",
+			"STARTUP.PAK", "XEDGEB.PAK", "ARCH.PAK", "CATACOM.PAK", "DNSTAIR.PAK", "FALLS.PAK", "FOYER.PAK",
+			"GEN_CAV.PAK", "KITCHEN.PAK", "MOONCAV.PAK", "RUBY.PAK", "STUMP.PAK", "XEDGEC.PAK", "BALCONY.PAK",
+			"CAVE.PAK", "DRAGON.PAK", "FESTSTH.PAK", "FSOUTH.PAK", "GLADE.PAK", "KYRAGEM.PAK", "NCLIFF.PAK",
+			"SICKWIL.PAK", "TEMPLE.PAK", "XMI.PAK", "BELROOM.PAK",  "CAVEB.PAK", "EDGE.PAK", "FGOWEST.PAK",
+			"FSOUTHB.PAK", "GRAVE.PAK", "LAGOON.PAK", "NCLIFFB.PAK", "SND.PAK", "TRUNK.PAK", "ZROCK.PAK",
+			"BONKBG.PAK", "CGATE.PAK", "EDGEB.PAK", "FINALE.PAK", "FWSTSTH.PAK", "GRTHALL.PAK", "LANDING.PAK",
+			"NWCLIFB.PAK", "SONG.PAK", "UPSTAIR.PAK", "BRIDGE.PAK", "CHASM.PAK", "EMCAV.PAK", "FNORTH.PAK",
+			"GATECV.PAK", "HEALER.PAK", "LAVA.PAK", "NWCLIFF.PAK", "SORROW.PAK", "WELL.PAK", 0
+		};
+		
+		const char** usedFilelist = 0;
+		
+		if (_engine->game() == KYRA1)
+			usedFilelist = kyra1Filelist;
+		else if (_engine->game() == KYRA1CD)
+			usedFilelist = kyra1CDFilelist;
+		else
+			error("no filelist found for this game");
+
+		for (uint32 tmp = 0; usedFilelist[tmp]; ++tmp) {
 			// prefetch file
-			PAKFile* file = new PAKFile(kyraFilelist[tmp]);
+			PAKFile* file = new PAKFile(usedFilelist[tmp]);
 			assert(file);			
 
-			if (file->isOpen() && file->isValid())		
+			if (file->isOpen() && file->isValid())
 				_pakfiles.push_back(file);
 			else
-				warning("couldn't load file '%s' correctly", kyraFilelist[tmp]);
+				debug("couldn't load file '%s' correctly", usedFilelist[tmp]);
 		}
 	}
 	
@@ -63,11 +90,8 @@
 	
 	uint8* Resourcemanager::fileData(const char* file, uint32* size) {
 		uint8* buffer = 0;
-		
-		debug("looking for file '%s'", file);
-		
 		File file_;
-		
+
 		// test to open it in the main dir
 		if (file_.open(file)) {
 		
@@ -83,37 +107,39 @@
 		} else {
 			// opens the file in a PAK File
 			Common::List<PAKFile*>::iterator start = _pakfiles.begin();
-			
+
 			for (;start != _pakfiles.end(); ++start) {
 				*size = (*start)->getFileSize(file);
-				
-				if (!*size)
+
+				if (!(*size))
 					continue;
-					
+
 				buffer = new uint8[*size];
 				assert(buffer);
-				
+
 				// creates a copy of the file
 				memcpy(buffer, (*start)->getFile(file), *size);
-				
+
 				break;
 			}
 			
 		}
 		
 		if (!buffer || !(*size)) {
-			warning("couldn't find file '%s'", file);
+			return 0;
 		}
 		
 		return buffer;
 	}
 	
-	Palette* Resourcemanager::loadPalette(const char* file) {
+	Palette* Resourcemanager::loadPalette(const char* file)	{
 		uint32 size = 0;
 		uint8* buffer = 0;
 		buffer = fileData(file, &size);
-		if (!buffer)
+		if (!buffer) {
+			warning("ResMgr: Failed loading palette %s", file);
 			return 0;
+		}
 		return new Palette(buffer, size);
 	}
 	
@@ -140,9 +166,12 @@
 		uint32 size = 0;
 		uint8* buffer = 0;
 		buffer = fileData(file, &size);
-		if (!buffer)
+		if (!buffer || !size)
 			return 0;
-		return new WSAMovieV1(buffer, size);
+		if (_engine->game() == KYRA1 || _engine->game() == KYRA1CD)
+			return new WSAMovieV1(buffer, size, _engine->game());
+		else
+			return new WSAMovieV2(buffer, size);
 	}
 
 	VMContext* Resourcemanager::loadScript(const char* file) {
@@ -154,13 +183,13 @@
 ///////////////////////////////////////////
 // Pak file manager
 	#define PAKFile_Iterate Common::List<PakChunk*>::iterator start=_files.begin();start != _files.end(); ++start
-	PAKFile::PAKFile(const Common::String& file) {
+	PAKFile::PAKFile(/*const Common::String &path, */const Common::String& file) {
 		File pakfile;
 		_buffer = 0;
 		_open = false;
 
-		if (!pakfile.open(file.c_str())) {
-			warning("PAKFile couldn't open: '%s'", file.c_str());
+		if (!pakfile.open(file.c_str())){ /*, File::kFileReadMode, path.c_str())) {*/
+			printf("pakfile couldn't open %s\n", file.c_str());
 			return;
 		}
 
@@ -184,18 +213,25 @@
 			// saves the name
 			chunk->_name = reinterpret_cast<const char*>(_buffer + pos);
 			pos += strlen(chunk->_name) + 1;
-			if(!chunk->_name)
+			if(!(*chunk->_name))
 				break;
 
 			endoffset = READ_LE_UINT32(_buffer + pos);
 			pos += 4;
+			
+			if (endoffset == 0) {
+				endoffset = filesize;
+			}
 
 			chunk->_data = _buffer + startoffset;
 			chunk->_size = endoffset - startoffset;
 
-			startoffset = endoffset;
-
 			_files.push_back(chunk);
+			
+			if (endoffset == filesize)
+				break;
+
+			startoffset = endoffset;
 		}
 		_open = true;
 	}
@@ -212,7 +248,7 @@
 	}
 
 	const uint8* PAKFile::getFile(const char* file) {
-		for (PAKFile_Iterate) { 
+		for (PAKFile_Iterate) {
 			if (!scumm_stricmp((*start)->_name, file))
 				return (*start)->_data;
 		}

Index: resource.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/resource.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- resource.h	10 Nov 2004 18:09:14 -0000	1.3
+++ resource.h	11 Nov 2004 13:35:21 -0000	1.4
@@ -114,7 +114,7 @@
 		bool hasPalette(void) { return (_ownPalette != 0); }
 
 		// if col == -1 then no transparany
-		void setTransparencyColor(int16 col) { _transparency = col; }
+		void transparency(int16 col) { _transparency = col; }
 
 		void drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y);
 		void drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y,

Index: script.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/script.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- script.cpp	10 Nov 2004 18:45:31 -0000	1.6
+++ script.cpp	11 Nov 2004 13:35:21 -0000	1.7
@@ -25,6 +25,7 @@
 #include "resource.h"
 
 #include "common/stream.h"
+#include "common/util.h"
 
 #define COMMAND(x) { &VMContext::x, #x }
 #define OPCODE(x) { &VMContext::x, #x }
@@ -54,7 +55,7 @@
 			// 0x0C
 			COMMAND(c1_addToSP),
 			COMMAND(c1_subFromSP),
-			COMMAND(c1_execOpcode),			
+			COMMAND(c1_execOpcode),
 			COMMAND(c1_ifNotGoTo),
 			// 0x10
 			COMMAND(c1_negate),
@@ -82,7 +83,7 @@
 			// 0x0C
 			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
-			COMMAND(o1_unknownOpcode),			
+			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
 			// 0x10
 			COMMAND(o1_unknownOpcode),
@@ -107,7 +108,7 @@
 			// 0x20
 			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
-			COMMAND(o1_unknownOpcode),			
+			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
 			// 0x24
 			COMMAND(o1_unknownOpcode),
@@ -132,7 +133,7 @@
 			// 0x34
 			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
-			COMMAND(o1_unknownOpcode),			
+			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
 			// 0x38
 			COMMAND(o1_unknownOpcode),
@@ -157,7 +158,7 @@
 			// 0x48
 			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
-			COMMAND(o1_unknownOpcode),			
+			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
 			// 0x4C
 			COMMAND(o1_unknownOpcode),
@@ -182,7 +183,7 @@
 			// 0x5C
 			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
-			COMMAND(o1_unknownOpcode),			
+			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
 			// 0x60
 			COMMAND(o1_unknownOpcode),
@@ -207,7 +208,7 @@
 			// 0x70
 			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
-			COMMAND(o1_unknownOpcode),			
+			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
 			// 0x74
 			COMMAND(o1_unknownOpcode),
@@ -232,7 +233,7 @@
 			// 0x84
 			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
-			COMMAND(o1_unknownOpcode),			
+			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
 			// 0x88
 			COMMAND(o1_unknownOpcode),
@@ -262,7 +263,7 @@
 			// 0x9C
 			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
-			COMMAND(o1_unknownOpcode),			
+			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
 			// 0xA0
 			COMMAND(o1_unknownOpcode),
@@ -287,7 +288,7 @@
 			// 0xB0
 			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
-			COMMAND(o1_unknownOpcode),			
+			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
 			// 0xB4
 			COMMAND(o1_unknownOpcode),
@@ -312,7 +313,7 @@
 			// 0xC4
 			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
-			COMMAND(o1_unknownOpcode),			
+			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
 			// 0xC8
 			COMMAND(o1_unknownOpcode),
@@ -337,7 +338,7 @@
 			// 0xD8
 			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
-			COMMAND(o1_unknownOpcode),			
+			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
 			// 0xDC
 			COMMAND(o1_unknownOpcode),
@@ -362,7 +363,7 @@
 			// 0xEC
 			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
-			COMMAND(o1_unknownOpcode),			
+			COMMAND(o1_unknownOpcode),
 			COMMAND(o1_unknownOpcode),
 			// 0xF0
 			COMMAND(o1_unknownOpcode),
@@ -398,8 +399,8 @@
 			_scriptFileSize = 0;
 		}
 		
-		debug("--------------");
-		
+		memset(_stack, 0, sizeof(int32) * ARRAYSIZE(_stack));
+
 		// loads the new file
 		_scriptFile = _engine->resManager()->fileData(file, &_scriptFileSize);
 		
@@ -415,32 +416,27 @@
 		while(true) {
 			if (script.eof()) {
 				break;
-			}		
+			}
 			// lets read only the first 4 chars
 			script.read(chunkName, sizeof(uint8) * 4);
 			chunkName[4] = '\0';
-			debug("chunk name(4 chars): '%s'", chunkName);
-			
+
 			// check name of chunk
 			if (!scumm_stricmp((const char *)chunkName, "FORM")) {			
 				// FreeKyra swaps the size I only read it in BigEndian :)
 				_chunks[kForm]._size = script.readUint32BE();	
-				debug("_chunks[kForm]._size = %d", _chunks[kForm]._size);				
+				debug("_chunks[kForm]._size = %d", _chunks[kForm]._size);
 			} else if (!scumm_stricmp((const char *)chunkName, "TEXT")) {
 				uint32 text_size = script.readUint32BE();
 				text_size += text_size % 2 != 0 ? 1 : 0;
 				
 				_chunks[kText]._data = _scriptFile + script.pos();
 				_chunks[kText]._size = READ_BE_UINT16(_chunks[kText]._data) >> 1;
-				_chunks[kText]._additional = _chunks[kText]._data + (_chunks[kText]._size << 1);				
-				debug("_chunks[kText]._size = %d, real chunk size = %d", _chunks[kText]._size, text_size);	
-				
+				_chunks[kText]._additional = _chunks[kText]._data + (_chunks[kText]._size << 1);
 				script.seek(script.pos() + text_size);
 			} else if (!scumm_stricmp((const char *)chunkName, "DATA")) {
 				_chunks[kData]._size = script.readUint32BE();
-				_chunks[kData]._data = _scriptFile + script.pos();				
-				debug("_chunks[kData]._size = %d", _chunks[kData]._size);
-				
+				_chunks[kData]._data = _scriptFile + script.pos();
 				// mostly it will be the end of the file because all files should end with a 'DATA' chunk
 				script.seek(script.pos() + _chunks[kData]._size);
 			} else {
@@ -451,25 +447,20 @@
 				
 				if (!scumm_stricmp((const char *)chunkName, "EMC2ORDR")) {
 					_chunks[kEmc2Ordr]._size = script.readUint32BE() >> 1;
-					_chunks[kEmc2Ordr]._data = _scriptFile + script.pos();					
-					debug("_chunks[kEmc2Ordr]._size = %d, real chunk size = %d", _chunks[kEmc2Ordr]._size, _chunks[kEmc2Ordr]._size * 2);
-					
+					_chunks[kEmc2Ordr]._data = _scriptFile + script.pos();
 					script.seek(script.pos() + _chunks[kEmc2Ordr]._size * 2);
 				} else {
 					// any unkown chunk or problems with seeking through the file
-					error("unknown chunk");
+					error("unknown chunk(%s)", chunkName);
 				}
 			}
 		}
-		
-		// so file loaded
-		debug("--------------");
 	}
 	
 	int32 VMContext::param(int32 index) {
-		if (_stackPos - index + 1 >= 16 || _stackPos - index + 1 < 0)
+		if (_stackPos - index - 1 >= ARRAYSIZE(_stack) || _stackPos - index - 1 < 0)
 			return -0xFFFF;
-		return _stack[_stackPos - index + 1];
+		return _stack[_stackPos - index - 1];
 	}
 	
 	const char* VMContext::stringAtIndex(int32 index) {
@@ -485,11 +476,28 @@
 			return false;
 		}
 			
-		_instructionPos = (READ_BE_UINT16(&_chunks[kEmc2Ordr]._data[func]) << 1) + 2;
+		_instructionPos = READ_BE_UINT16(&_chunks[kEmc2Ordr]._data[func]) << 1;
 		_stackPos = 0;
 		_tempPos = 0;
 		_delay = 0;
 		_scriptState = kScriptRunning;
+		
+		uint32 pos = 0xFFFFFFFE;
+
+		// get start of next script
+		for (uint32 tmp = 0; tmp < _chunks[kEmc2Ordr]._size; ++tmp) {
+			if ((uint32)((READ_BE_UINT16(&_chunks[kEmc2Ordr]._data[tmp]) << 1)) > (uint32)_instructionPos &&
+				(uint32)((READ_BE_UINT16(&_chunks[kEmc2Ordr]._data[tmp]) << 1)) < pos) {
+				pos = ((READ_BE_UINT16(&_chunks[kEmc2Ordr]._data[tmp]) << 1));
+			}
+		}
+
+		if (pos > _scriptFileSize) {
+			pos = _scriptFileSize;
+		}
+		
+		_nextScriptPos = pos;
+
 		return true;
 	}
 	
@@ -505,6 +513,9 @@
 				debug("_instructionPos( = %d) > _chunks[kData]._size( = %d)", _instructionPos, _chunks[kData]._size);
 				_error = true;
 				break;
+			} else if(_instructionPos >= _nextScriptPos) {
+				_scriptState = kScriptStopped;
+				break;
 			}
 
 			_currentCommand = *(script_start + _instructionPos++);
@@ -525,9 +536,12 @@
 				_instructionPos += 2;
 			} else {
 				debug("unknown way of getting the command");
+				// next thing
+				continue;
 			}
 			
 			_currentCommand &= 0x1f;
+
 			if (_currentCommand < _numCommands) {
 				CommandProc currentProc = _commands[_currentCommand].proc;
 				(this->*currentProc)();

Index: script.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/script.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- script.h	10 Nov 2004 18:45:31 -0000	1.2
+++ script.h	11 Nov 2004 13:35:21 -0000	1.3
@@ -71,14 +71,15 @@
 		uint32 _delay;
 		
 		int32 _registers[32]; // registers of the interpreter
-		int32 _stack[32]; // our stack
+		int32 _stack[64]; // our stack
 		
 		// TODO: check for 'under'flow
-		int32 popStack(void) { return _stack[_stackPos--]; }
+		int32 popStack(void) { return _stack[--_stackPos]; }
 		int32& topStack(void) { return _stack[_stackPos]; }
 		
 		uint32 _returnValue;
 		
+		int32 _nextScriptPos;
 		int32 _instructionPos;
 		int32 _stackPos;
 		int32 _tempPos;
@@ -131,7 +132,7 @@
  		void c1_goToLine(void);			// 0x00
  		void c1_setReturn(void);		// 0x01
  		void c1_pushRetRec(void);		// 0x02
- 		void c1_push(void);				// 0x03 & 0x04
+ 		void c1_push(void);			// 0x03 & 0x04
  		void c1_pushVar(void);			// 0x05
  		void c1_pushFrameNeg(void);		// 0x06
  		void c1_pushFramePos(void);		// 0x07
@@ -148,7 +149,7 @@
 		void c1_unknownCommand(void);
   
 		// the opcode procs
-		void o1_0x68(void);				// 0x68
+		void o1_0x68(void);			// 0x68
 		void o1_unknownOpcode(void);
 	};
 } // end of namespace Kyra

Index: script_v1.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/script_v1.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- script_v1.cpp	10 Nov 2004 18:45:32 -0000	1.4
+++ script_v1.cpp	11 Nov 2004 13:35:21 -0000	1.5
@@ -237,6 +237,7 @@
 	}
 
 	void VMContext::o1_0x68(void) {
-		debug("o1_0x68 was called with param0: '%d' and param1: '%d'", param(0), param(1));
+		debug("o1_0x68 was called with param0: '%d'", param(0));
+		_error = true;
 	}
 } // end of namespace Kyra

Index: wsamovie.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/wsamovie.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- wsamovie.cpp	15 Oct 2004 19:48:07 -0000	1.2
+++ wsamovie.cpp	11 Nov 2004 13:35:21 -0000	1.3
@@ -18,25 +18,67 @@
  * $Header$
  *
  */
-
+ 
 #include "stdafx.h"
 #include "wsamovie.h"
 #include "codecs.h"
 
 #include "common/stream.h"
 
+#ifdef DUMP_FILES
+#include <stdio.h>
+#endif
+
 namespace Kyra {
-	WSAMovieV1::WSAMovieV1(uint8* data, uint32 size) {
+	WSAMovieV1::WSAMovieV1(uint8* data, uint32 size, uint8 gameid) {
 		if (!data) {
 			error("resource created without data");
 		}
 
+		_background = 0;
+		_currentFrame = 0;
+		_ownPalette = 0;
+		_offsetTable = 0;
+		_prefetchedFrame = 0xFFFE;
 		_buffer = data;
 
 		// I like these Streams .... =)
 		Common::MemoryReadStream datastream(data, size);
 		
 		datastream.read(&_wsaHeader, sizeof(_wsaHeader));
+
+#ifdef DUMP_FILES
+		FILE* wsaheader = fopen("dumps/wsaheader.txt", "w+");
+		
+		if (wsaheader) {
+			for (uint32 pos = 0; pos < sizeof(_wsaHeader); ++pos)
+				fprintf(wsaheader, "%d pos. byte: %d\n", pos + 1, ((uint8*)&_wsaHeader)[pos]);
+			fprintf(wsaheader, "\n");
+			for (uint32 pos = 0; pos < sizeof(_wsaHeader) / 2; ++pos)
+				fprintf(wsaheader, "%d pos. word: %d\n", pos + 1, ((uint16*)&_wsaHeader)[pos]);
+			fprintf(wsaheader, "\n");
+			for (uint32 pos = 0; pos < sizeof(_wsaHeader) / 4; ++pos)
+				fprintf(wsaheader, "%d pos. dword: %d\n", pos + 1, ((uint32*)&_wsaHeader)[pos]);
+		}
+		fclose(wsaheader);
+#endif
+
+		if (gameid == KYRA1CD) {
+			uint16 tmp = _wsaHeader._delta;
+			_wsaHeader._delta = _wsaHeader._type;
+			_wsaHeader._type = tmp;
+			
+			// skip 2 bytes
+			datastream.readUint16LE();
+		}
+		
+		debug("_wsaHeader._numFrames = %d", _wsaHeader._numFrames);
+		debug("_wsaHeader._width = %d", _wsaHeader._width);
+		debug("_wsaHeader._height = %d", _wsaHeader._height);
+		debug("_wsaHeader._xPos = %d", _wsaHeader._xPos);
+		debug("_wsaHeader._yPos = %d", _wsaHeader._yPos);
+		debug("_wsaHeader._delta = %d", _wsaHeader._delta);
+		debug("_wsaHeader._type = %d", _wsaHeader._type);
 		
 		// check for version
 		if (_wsaHeader._type) {
@@ -55,27 +97,34 @@
 			offsetAdd = 768 /* 0x300 */;
 		}
 		
-		_frameCount = _wsaHeader._numFrames;
+		// last frame seems every time to be a empty one
+		_frameCount = _wsaHeader._numFrames - 1;
 		_offsetTable = new uint32[_wsaHeader._numFrames + 2];
-		assert(!_offsetTable);
+		assert(_offsetTable);
 		
 		// loads the offset table
-		for (uint32 tmp = 0; tmp < _wsaHeader._numFrames; ++tmp) {
+		for (uint32 tmp = 0; tmp < (uint32)_wsaHeader._numFrames + 2; ++tmp) {
 			_offsetTable[tmp] = datastream.readUint32LE() + offsetAdd;
 		}
 		
 		if (offsetAdd) {
 			uint8* palbuffer = new uint8[offsetAdd];
-			assert(!palbuffer);
+			assert(palbuffer);
+			
+			datastream.read(palbuffer, offsetAdd);
 			
 			_ownPalette = new Palette(palbuffer, offsetAdd);
-			assert(!_ownPalette);
-		}		
+			assert(_ownPalette);
+		}
+
+		// FIXME: Confirm the default value here?
+		_transparency = -1;
 	}
 	
 	WSAMovieV1::~WSAMovieV1() {
 		delete [] _buffer;
 		delete [] _offsetTable;
+		delete [] _currentFrame;
 		delete _ownPalette;
 	}
 	
@@ -89,21 +138,215 @@
 			if (!_currentFrame) {
 				_currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height];
 				assert(_currentFrame);
+				memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height);
 			}
 			
+			if (frame >= _wsaHeader._numFrames)
+				return 0;
+				
 			uint8* frameData = 0;
-			uint8 image40[64000]; // I think this will crash on Plam OS :)
+			static uint8 image40[64000]; // I think this will crash on Plam OS :)
+			memset(image40, 0, ARRAYSIZE(image40));
 			
 			if (frame == _prefetchedFrame + 1) {
-				frameData = _buffer + _offsetTable[frame] + (hasPalette() ? 768 : 0);
+				frameData = _buffer + _offsetTable[frame];
 				Compression::decode80(frameData, image40);
 				Compression::decode40(image40, _currentFrame);
 			} else {
-				memset(_currentFrame, 0, _wsaHeader._width * _wsaHeader._height);
+				if (_background) {
+					setImageBackground(_background, _backWidth, _backHeight);
+				} else {
+					memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height);
+				}
+
+				for (uint32 i = 0; i <= frame; ++i)
+				{
+					frameData = _buffer + _offsetTable[i];
+					Compression::decode80(frameData, image40);
+					Compression::decode40(image40, _currentFrame);
+				}
+			}
+			
+			_prefetchedFrame = frame;
+			return _currentFrame;
+		}
+		
+		return 0;
+	}
+	
+	void WSAMovieV1::renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame) {
+		if (!loadFrame(frame, 0, 0))
+			return;
+
+		uint8* src = _currentFrame;
+		uint8* dst = &plane[_wsaHeader._yPos * planepitch + _wsaHeader._xPos];
+		uint32 copysize = planepitch - _wsaHeader._xPos;
+		
+		if (copysize > _wsaHeader._width)
+			copysize = _wsaHeader._width;
+			
+		if (_transparency == -1) {
+			for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < planeheight; ++y_) {
+				memcpy(dst, src, copysize * sizeof(uint8));
+				dst += planepitch;
+				src += _wsaHeader._width;
+			}
+		} else {
+			for (uint16 yadd = 0; yadd < _wsaHeader._height; ++yadd) {
+				for (uint16 xadd = 0; xadd < copysize; ++xadd) {
+					if (*src == _transparency) {
+						++dst;
+						++src;
+					} else {
+						*dst++ = *src++;
+					}
+				}
 				
-				for (uint32 i = 0; i <= frame; i++)
+				src += _wsaHeader._width - copysize;
+				dst += planepitch - copysize;
+			}
+		}
+	}
+	
+	void WSAMovieV1::setImageBackground(uint8* plane, uint16 planepitch, uint16 height) {
+		assert(plane);
+		
+		_background = plane;
+		_backWidth = planepitch; _backHeight = height;
+
+		if (!_currentFrame) {
+			_currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height];
+			assert(_currentFrame);
+		}
+		
+		memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height);
+		
+		uint8* src = &plane[_wsaHeader._yPos * planepitch + _wsaHeader._xPos];
+		uint8* dst = _currentFrame;
+		uint32 copysize = planepitch - _wsaHeader._xPos;
+		
+		if (copysize > _wsaHeader._width)
+			copysize = _wsaHeader._width;
+		
+		// now copy the rect of the plane
+		for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < height; ++y_) {
+			memcpy(dst, src, copysize * sizeof(uint8));
+			dst += _wsaHeader._width;
+			src += planepitch;
+		}
+		
+		for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < height; ++y_) {
+			for (uint16 x = 0; x < _wsaHeader._width; ++x) {
+				_currentFrame[y_ * _wsaHeader._width + x] ^= 0;
+			}
+		}
+		
+		_prefetchedFrame = 0xFFFE;
+	}
+	
+	// Kyrandia 2+ Movies
+	WSAMovieV2::WSAMovieV2(uint8* data, uint32 size) {
+		if (!data) {
+			error("resource created without data");
+		}
+		
+		_background = 0;
+		_currentFrame = 0;
+		_ownPalette = 0;
+		_offsetTable = 0;
+		_prefetchedFrame = 0xFFFE;
+		_looping = false;
+		_buffer = data;
+
+		// I like these Streams .... =)
+		Common::MemoryReadStream datastream(data, size);
+		
+		datastream.read(&_wsaHeader, sizeof(_wsaHeader));
+		
+		// check for version
+		if (!_wsaHeader._type) {
+			error("loading a WSA version 1 with the WSA version 2 loader");
+		}
+		
+		uint16 offsetAdd = 0;
+		
+		// checks now for own palette
+		if (_wsaHeader._type % 2) {
+			// don't now if this will work right, because a few lines before we use
+			// _wsaHeader._type for detect the version of the WSA movie,
+			// but this code was from FreeKyra Tools so I think it will work
+			
+			// if this is a packed palette we have a problem :)
+			offsetAdd = 768 /* 0x300 */;
+		}
+		
+		_offsetTable = new uint32[_wsaHeader._numFrames + 2];
+		assert(_offsetTable);
+		
+		// loads the offset table
+		for (uint32 tmp = 0; tmp < (uint32)_wsaHeader._numFrames + 2; ++tmp) {
+			_offsetTable[tmp] = datastream.readUint32LE() + offsetAdd;
+		}
+		
+		if (offsetAdd) {
+			uint8* palbuffer = new uint8[offsetAdd];
+			assert(palbuffer);
+			
+			datastream.read(palbuffer, offsetAdd);
+			
+			_ownPalette = new Palette(palbuffer, offsetAdd);
+			assert(_ownPalette);
+		}
+		
+		if (_offsetTable[_wsaHeader._numFrames + 1] - offsetAdd) {
+			++_wsaHeader._numFrames;
+			_looping = true;
+		}
+		
+		_frameCount = _wsaHeader._numFrames;
+	}
+	
+	WSAMovieV2::~WSAMovieV2() {
+		delete [] _buffer;
+		delete [] _offsetTable;
+		delete [] _currentFrame;
+		delete _ownPalette;
+	}
+	
+	const uint8* WSAMovieV2::loadFrame(uint16 frame, uint16* width, uint16* height) {
+		if (width) *width = _wsaHeader._width;
+		if (height) *height = _wsaHeader._height;
+			
+		if (frame == _prefetchedFrame) {
+			return _currentFrame;
+		} else {
+			if (!_currentFrame) {
+				_currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height];
+				assert(_currentFrame);
+				memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height);
+			}
+			
+			if (frame >= _wsaHeader._numFrames)
+				return 0;
+				
+			uint8* frameData = 0;
+			static uint8 image40[64000]; // I think this will crash on Plam OS :)
+			memset(image40, 0, ARRAYSIZE(image40));
+			
+			if (frame == _prefetchedFrame + 1) {
+				frameData = _buffer + _offsetTable[frame];
+				Compression::decode80(frameData, image40);
+				Compression::decode40(image40, _currentFrame);
+			} else {
+				if (_background) {
+					setImageBackground(_background, _backWidth, _backHeight);
+				} else {
+					memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height);
+				}
+				
+				for (uint32 i = 0; i <= frame; ++i)
 				{
-					frameData = _buffer + _offsetTable[i] + (hasPalette() ? 768 : 0);
+					frameData = _buffer + _offsetTable[i];
 					Compression::decode80(frameData, image40);
 					Compression::decode40(image40, _currentFrame);
 				}
@@ -115,5 +358,75 @@
 		
 		return 0;
 	}
+	
+	void WSAMovieV2::renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame) {
+		if (!loadFrame(frame, 0, 0))
+			return;
+			
+		uint8* src = _currentFrame;
+		uint8* dst = &plane[_wsaHeader._yPos * planepitch + _wsaHeader._xPos];
+		uint32 copysize = planepitch - _wsaHeader._xPos;
+		
+		if (copysize > _wsaHeader._width)
+			copysize = _wsaHeader._width;
+			
+		if (_transparency == -1) {
+			for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < planeheight; ++y_) {
+				memcpy(dst, src, copysize * sizeof(uint8));
+				dst += planepitch;
+				src += _wsaHeader._width;
+			}
+		} else {
+			for (uint16 yadd = 0; yadd < _wsaHeader._height; ++yadd) {
+				for (uint16 xadd = 0; xadd < copysize; ++xadd) {
+					if (*src == _transparency) {
+						++dst;
+						++src;
+					} else {
+						*dst++ = *src++;
+					}
+				}
+				
+				src += _wsaHeader._width - copysize;
+				dst += planepitch - copysize;
+			}
+		}
+	}
+	
+	void WSAMovieV2::setImageBackground(uint8* plane, uint16 planepitch, uint16 height) {
+		assert(plane);
+		
+		_background = plane;
+		_backWidth = planepitch; _backHeight = height;
+		
+		if (!_currentFrame) {
+			_currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height];
+			assert(_currentFrame);
+		}
+		
+		memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height);
+		
+		uint8* src = &plane[_wsaHeader._yPos * planepitch + _wsaHeader._xPos];
+		uint8* dst = _currentFrame;
+		uint32 copysize = planepitch - _wsaHeader._xPos;
+		
+		if (copysize > _wsaHeader._width)
+			copysize = _wsaHeader._width;
+		
+		// now copy the rect of the plane
+		for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < height; ++y_) {
+			memcpy(dst, src, copysize * sizeof(uint8));
+			dst += _wsaHeader._width;
+			src += planepitch;
+		}
+		
+		for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < height; ++y_) {
+			for (uint16 x = 0; x < _wsaHeader._width; ++x) {
+				_currentFrame[y_ * _wsaHeader._width + x] ^= 0;
+			}
+		}
+		
+		_prefetchedFrame = 0xFFFE;
+	}
 } // end of namespace Kyra
 

Index: wsamovie.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/wsamovie.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- wsamovie.h	15 Oct 2004 06:06:47 -0000	1.1
+++ wsamovie.h	11 Nov 2004 13:35:21 -0000	1.2
@@ -31,30 +31,42 @@
 	
 	public:
 	
-		virtual ~Movie() {}
+		virtual ~Movie() { _transparency = -1; _ownPalette = 0; _frameCount = 0; }
 		
+		virtual void renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame) = 0;
 		virtual const uint8* loadFrame(uint16 frame, uint16* width = 0, uint16* height = 0) = 0;
 		virtual uint16 countFrames(void) { return _frameCount; }
 		
+		// could be deleted(not imdiantly maybe it's needed sometime)
+		virtual void transparency(int16 color) { _transparency = color; }
+		virtual void position(uint16 x, uint16 y) = 0;
+		
 		virtual bool hasPalette(void) { return (_ownPalette != 0); }
 		virtual Palette* palette(void) { return _ownPalette; }
+		
+		virtual bool looping(void) { return false; }
+		virtual uint32 frameChange(void) { return 100; }		
+		virtual void setImageBackground(uint8* plane, uint16 planepitch, uint16 height) {};
 	
 	protected:
+		int16 _transparency;
 		uint16 _frameCount;
 		Palette* _ownPalette;
 	};
 	
 	// movie format for Kyrandia 1
-	// there is also a new WSA Format for Kyrandia 2
-	// which i will implement in future
 	class WSAMovieV1 : public Movie {
 	
 	public:
 	
-		WSAMovieV1(uint8* data, uint32 size);
+		WSAMovieV1(uint8* data, uint32 size, uint8 gameid);
 		~WSAMovieV1();
 		
+		void renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame);
 		const uint8* loadFrame(uint16 frame, uint16* width, uint16* height);
+		void setImageBackground(uint8* plane, uint16 planepitch, uint16 height);
+		
+		void position(uint16 x, uint16 y) { _wsaHeader._xPos = x; _wsaHeader._yPos = y; }
 	protected:
 	
 		uint8* _buffer;
@@ -62,19 +74,60 @@
 #pragma START_PACK_STRUCTS	
 		struct WSAHeader {
 			uint16 _numFrames; // All right
+			uint16 _width; // All right
+			uint16 _height; // All right
+			uint8 _xPos; // is wrong
+			uint8 _yPos; // is wrong
+			uint16 _delta; // should be right
+			uint16 _type; // should be right
+		} GCC_PACK _wsaHeader;
+#pragma END_PACK_STRUCTS
+
+		uint32* _offsetTable;
+		
+		uint8* _currentFrame;
+		uint16 _prefetchedFrame;
+		
+		uint8* _background; // only a pointer to the screen
+		uint16 _backWidth, _backHeight;
+	};
+	
+	// movie format for Kyrandia 2+
+	class WSAMovieV2 : public Movie {
+	
+	public:
+		WSAMovieV2(uint8* data, uint32 size);
+		~WSAMovieV2();
+	
+		void renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame);
+		const uint8* loadFrame(uint16 frame, uint16* width, uint16* height);
+		void setImageBackground(uint8* plane, uint16 planepitch, uint16 height);
+		
+		void position(uint16 x, uint16 y) { _wsaHeader._xPos = x; _wsaHeader._yPos = y; }
+		bool looping(void) { return _looping; }
+	protected:
+	
+		uint8* _buffer;
+		
+		struct WSAHeader {
+			uint16 _numFrames; // All right
 			uint16 _width; // should be right
 			uint16 _height; // should be right
-			uint8 _xPos; // could be wrong
-			uint8 _yPos; // could be wrong
+			uint16 _xPos; // could be wrong
+			uint16 _yPos; // could be wrong
 			uint16 _delta; // could be wrong
 			uint16 _type; // should be right
 		} GCC_PACK _wsaHeader;
-#pragma END_PACK_STRUCTS
-
+		
 		uint32* _offsetTable;
 		
 		uint8* _currentFrame;
 		uint16 _prefetchedFrame;
+		
+		uint8* _background; // only a pointer to the screen
+		uint16 _backWidth, _backHeight;
+		
+		bool _looping;
 	};
 } // end of namespace Kyra
 





More information about the Scummvm-git-logs mailing list