diff options
40 files changed, 5194 insertions, 5058 deletions
@@ -779,7 +779,7 @@ site, please see the section on reporting bugs.        original game.    The Legend of Kyrandia: -    - No music or sound effects in the Amiga and Macintosh floppy versions. +    - No music or sound effects in the Macintosh floppy versions.      - Macintosh CD is using included DOS music and sound effects.      - PC-9821 version lacks support for sound effects. diff --git a/backends/fs/psp/psp-stream.cpp b/backends/fs/psp/psp-stream.cpp deleted file mode 100644 index fac4067f46..0000000000 --- a/backends/fs/psp/psp-stream.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * 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 - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ -#ifdef __PSP__ - -#include "backends/fs/psp/psp-stream.h" -#include "backends/platform/psp/trace.h" -#include <errno.h> - -PSPIoStream::PSPIoStream(const Common::String &path, bool writeMode) -: StdioStream((void *)1), _path(path), _writeMode(writeMode) { - -	assert(!path.empty()); - -	_handle = (void *)0;		// Need to do this since base class asserts not 0. - -	PowerMan.registerSuspend(this);	 // Register with the powermanager to be suspended - -} - -PSPIoStream::~PSPIoStream() { -	PowerMan.unregisterSuspend(this); // Unregister with powermanager to be suspended -								 // Must do this before fclose() or resume() will reopen. - -	fclose((FILE *)_handle); -} - -// Function to open the file pointed to by the path. -// -// -void * PSPIoStream::open() { -	if (PowerMan.beginCriticalSection()==PowerManager::Blocked) { -		// No need to open. Just return the _handle resume() already opened. -		PSPDebugTrace("Suspended in PSPIoStream::open\n"); -	} else { -		_handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb"); 	// open -	} -	 -	PowerMan.endCriticalSection(); - -	return _handle; -} - -bool PSPIoStream::err() const { -	bool ret; - -	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) -		PSPDebugTrace("Suspended in PSPIoStream::err()\n"); - -	ret = ferror((FILE *)_handle) != 0; - -	PowerMan.endCriticalSection(); - -	return ret; -} - -void PSPIoStream::clearErr() { -	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) -		PSPDebugTrace("Suspended in PSPIoStream::clearErr()\n"); - -	clearerr((FILE *)_handle); - -	PowerMan.endCriticalSection(); -} - -bool PSPIoStream::eos() const { -	bool ret; - -	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) -		PSPDebugTrace("Suspended in PSPIoStream::eos()\n"); - -	ret = feof((FILE *)_handle) != 0; - -	PowerMan.endCriticalSection(); - -	return ret; -} - -int32 PSPIoStream::pos() const { -	int32 ret; - -	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) -		PSPDebugTrace("Suspended in PSPIoStream::pos()\n"); - -	ret = ftell((FILE *)_handle); - -	PowerMan.endCriticalSection(); - -	return ret; -} - - -int32 PSPIoStream::size() const { -	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) -		PSPDebugTrace("Suspended in PSPIoStream::size()\n"); - -	int32 oldPos = ftell((FILE *)_handle); -	fseek((FILE *)_handle, 0, SEEK_END); -	int32 length = ftell((FILE *)_handle); -	fseek((FILE *)_handle, oldPos, SEEK_SET); - -	PowerMan.endCriticalSection(); - -	return length; -} - -bool PSPIoStream::seek(int32 offs, int whence) { -	int ret = 0; - -	// Check if we can access the file -	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) -		PSPDebugTrace("Suspended in PSPIoStream::seek()\n"); - -	ret = fseek((FILE *)_handle, offs, whence); - -	PowerMan.endCriticalSection(); - -	return ret == 0; -} - -uint32 PSPIoStream::read(void *ptr, uint32 len) { -	int ret = 0; - -	// Check if we can access the file -	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) -		PSPDebugTrace("Suspended in PSPIoStream::read()\n"); - -	ret = fread((byte *)ptr, 1, len, (FILE *)_handle); -	 -	PowerMan.endCriticalSection(); -	 -	return ret; -} - -uint32 PSPIoStream::write(const void *ptr, uint32 len) { -	int ret = 0; - -	// Check if we can access the file -	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) -		PSPDebugTrace("Suspended in PSPIoStream::read()\n"); - -	ret = fwrite(ptr, 1, len, (FILE *)_handle); - -	PowerMan.endCriticalSection(); - -	return ret; -} - -bool PSPIoStream::flush() { -	int ret = 0; - -	// Check if we can access the file -	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) -		PSPDebugTrace("Suspended in PSPIoStream::read()\n"); - -	ret = fflush((FILE *)_handle); - -	PowerMan.endCriticalSection(); - -	return ret == 0; -} - -// For the PSP, since we're building in suspend support, we moved opening -// the actual file to an open function since we need an actual PSPIoStream object to suspend. -// -PSPIoStream *PSPIoStream::makeFromPath(const Common::String &path, bool writeMode) { -	PSPIoStream *stream = new PSPIoStream(path, writeMode); - -	if (stream->open() > 0) { -		return stream; -	} else { -		delete stream; -		return 0; -	} -} - -/* - *  Function to suspend the IO stream (called by PowerManager) - */ -int PSPIoStream::suspend() { -	if (_handle > 0) { -		_pos = ftell((FILE *)_handle);	// Save our position -		fclose((FILE *)_handle);		// close our file descriptor -		_handle = 0;					// Set handle to null -	} - -	return 0; -} - -/* - *  Function to resume the IO stream (called by Power Manager) - */ -int PSPIoStream::resume() { -	int ret = 0; - -	// We reopen our file descriptor -	_handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb"); -	if (_handle <= 0) { -		PSPDebugTrace("PSPIoStream::resume(): Couldn't reopen file %s\n", _path.c_str()); -		ret = -1;; -	} - -	// Resume our previous position -	if(_handle > 0) fseek((FILE *)_handle, _pos, SEEK_SET); - -	return ret; -} - -#endif /* __PSP__ */ diff --git a/backends/fs/psp/psp-stream.h b/backends/fs/psp/psp-stream.h deleted file mode 100644 index 0363c92416..0000000000 --- a/backends/fs/psp/psp-stream.h +++ /dev/null @@ -1,70 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * 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 - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef PSPSTREAM_H_ -#define PSPSTREAM_H_ - -#include "backends/fs/stdiostream.h" -#include "backends/platform/psp/powerman.h" -#include "common/list.h" - -/* - *  Class to handle special suspend/resume needs of PSP IO Streams - */ -class PSPIoStream : public StdioStream, public Suspendable { -protected: -	Common::String _path;			/* Need to maintain for reopening after suspend */ -	bool _writeMode;				/* "" */ -	unsigned int _pos;				/* "" */ - -public: -	/** -	 * Given a path, invoke fopen on that path and wrap the result in a -	 * PSPIoStream instance. -	 */ -	static PSPIoStream *makeFromPath(const Common::String &path, bool writeMode); - -	PSPIoStream(const Common::String &path, bool writeMode); -	virtual ~PSPIoStream(); - -	void * open();		// open the file pointed to by the file path - -	bool err() const; -	void clearErr(); -	bool eos() const; - -	virtual uint32 write(const void *dataPtr, uint32 dataSize); -	virtual bool flush(); - -	virtual int32 pos() const; -	virtual int32 size() const; -	virtual bool seek(int32 offs, int whence = SEEK_SET); -	virtual uint32 read(void *dataPtr, uint32 dataSize); - -	int suspend();		/* Suspendable interface (power manager) */ -	int resume();		/* " " */ -}; - -#endif /* PSPSTREAM_H_ */ diff --git a/backends/platform/psp/powerman.cpp b/backends/platform/psp/powerman.cpp deleted file mode 100644 index c553669fc3..0000000000 --- a/backends/platform/psp/powerman.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * 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 - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "./powerman.h" -#include "./trace.h" - -DECLARE_SINGLETON(PowerManager); - - /******************************************* -* -*	Constructor -* -********************************************/  -PowerManager::PowerManager() { -	_flagMutex = NULL;					/* Init mutex handle */ -	_listMutex = NULL;					/* Init mutex handle */ -	_condSuspendable = NULL;			/* Init condition variable */ -	_condPM = NULL; -	 -	_condSuspendable = SDL_CreateCond(); -	if (_condSuspendable <= 0) { -		PSPDebugTrace("PowerManager::PowerManager(): Couldn't create condSuspendable\n"); -	} -	 -	_condPM = SDL_CreateCond(); -	if (_condPM <= 0) { -		PSPDebugTrace("PowerManager::PowerManager(): Couldn't create condPM\n"); -	} - -	_flagMutex = SDL_CreateMutex(); -	if (_flagMutex <= 0) { -		PSPDebugTrace("PowerManager::PowerManager(): Couldn't create flagMutex\n"); -	} - -	_listMutex = SDL_CreateMutex(); -	if (_listMutex <= 0) { -		PSPDebugTrace("PowerManager::PowerManager(): Couldn't create listMutex\n"); -	} - -	_suspendFlag = false; -	_criticalCounter = 0; - } -  -/******************************************* -* -*	Function to register to be notified when suspend/resume time comes -* -********************************************/  -int PowerManager::registerSuspend(Suspendable *item) { -	// Register in list -	PSPDebugTrace("In registerSuspend\n"); - -	if (SDL_mutexP(_listMutex) != 0) { -		PSPDebugTrace("PowerManager::registerSuspend(): Couldn't lock _listMutex %d\n", _listMutex); -	} - -	_suspendList.push_front(item); - -	if (SDL_mutexV(_listMutex) != 0) { -		PSPDebugTrace("PowerManager::registerSuspend(): Couldn't unlock _listMutex %d\n", _listMutex); -	} - -	PSPDebugTrace("Out of registerSuspend\n"); - -	return 0; -} - -/******************************************* -* -*	Function to unregister to be notified when suspend/resume time comes -* -********************************************/   -int PowerManager::unregisterSuspend(Suspendable *item) { - -	PSPDebugTrace("In unregisterSuspend\n"); - -	 // Unregister from stream list -	if (SDL_mutexP(_listMutex) != 0) { -		PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex); -	} - -	_suspendList.remove(item); - -	if (SDL_mutexV(_listMutex) != 0) { -		PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex); -	} - -	PSPDebugTrace("Out of unregisterSuspend\n"); - -	return 0; - } -  - /******************************************* -* -*	Destructor -* -********************************************/  - PowerManager::~PowerManager() { -	SDL_DestroyCond(_condSuspendable); -	_condSuspendable = 0; -	 -	SDL_DestroyCond(_condPM); -	_condPM = 0; - -	SDL_DestroyMutex(_flagMutex); -	_flagMutex = 0; - -	SDL_DestroyMutex(_listMutex); -	_listMutex = 0; - } -  -  - /******************************************* -* -*	Function to be called by threads wanting to block on the PSP entering suspend -* -********************************************/   - int PowerManager::blockOnSuspend()  { -	return beginCriticalSection(true); -} - - /* -  * Function to block on a suspend, then start a non-suspendable critical section -  */ -int PowerManager::beginCriticalSection(bool justBlock) { -	int ret = PowerManager::NotBlocked; - -	if (SDL_mutexP(_flagMutex) != 0) { -		PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't lock flagMutex %d\n", _flagMutex); -		ret = PowerManager::Error; -	} - -	// Check the access flag -	if (_suspendFlag == true) { -		PSPDebugTrace("Blocking!!\n"); -		ret = PowerManager::Blocked; - -		// If it's true, we wait for a signal to continue -		if( SDL_CondWait(_condSuspendable, _flagMutex) != 0) { -			PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't wait on cond %d\n", _condSuspendable); -		} - -		PSPDebugTrace("We got blocked!!\n"); -	} -	 -	// Now put the pm to sleep -	if (justBlock == false) -		_criticalCounter++; - -	if (SDL_mutexV(_flagMutex) != 0) { -		PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex %d\n", _flagMutex); -		ret = PowerManager::Error; -	} - -	return ret; -} - -int PowerManager::endCriticalSection() { -	int ret = 0; - -	if (SDL_mutexP(_flagMutex) != 0) { -		PSPDebugTrace("PowerManager::endCriticalSection(): Couldn't lock flagMutex %d\n", _flagMutex); -		ret = PowerManager::Error; -	} - -	// We're done with our critical section -	_criticalCounter--; -	 -	if (_criticalCounter <= 0) { -		if(_suspendFlag == true) PSPDebugTrace("Waking up the PM and suspendFlag is true\n"); - -		SDL_CondBroadcast(_condPM); - -		if (_criticalCounter < 0) { -			PSPDebugTrace("PowerManager::endCriticalSection(): Error! Critical counter is %d\n", _criticalCounter); -		} -	} - -	if (SDL_mutexV(_flagMutex) != 0) { -		PSPDebugTrace("PowerManager::endCriticalSection(): Couldn't unlock flagMutex %d\n", _flagMutex); -		ret = PowerManager::Error; -	} - -	return ret; -} - - /******************************************* -* -*	Callback function to be called to put every Suspendable to suspend -* -********************************************/   -int PowerManager::suspend() { -	int ret = 0; - -	// First we set the suspend flag to true -	if (SDL_mutexP(_flagMutex) != 0) { -		PSPDebugTrace("PowerManager::suspend(): Couldn't lock flagMutex %d\n", _flagMutex); -		ret = -1; -	} - -	_suspendFlag = true; -	 -	if (_criticalCounter > 0) -		SDL_CondWait(_condPM, _flagMutex); - -	if (SDL_mutexV(_flagMutex) != 0) { -		PSPDebugTrace("PowerManager::suspend(): Couldn't unlock flagMutex %d\n", _flagMutex); -		ret = -1; -	} - -	// Loop over list, calling suspend() -	if (SDL_mutexP(_listMutex) != 0) { -		PSPDebugTrace("PowerManager::suspend(): Couldn't lock listMutex %d\n", _listMutex); -		ret = -1; -	} - -	Common::List<Suspendable *>::iterator i = _suspendList.begin(); - -	for (; i != _suspendList.end(); i++) { -		(*i)->suspend(); -	} - -	if (SDL_mutexV(_listMutex) != 0) { -		PSPDebugTrace("PowerManager::suspend(): Couldn't unlock listMutex %d\n", _listMutex); -		ret = -1; -	} - -	return ret; -} - -/******************************************* -* -*	Callback function to resume every Suspendable -* -********************************************/   -int PowerManager::resume() { -	int ret = 0; - -	// First we notify our Suspendables. Loop over list, calling resume() -	if (SDL_mutexP(_listMutex) != 0) { -		PSPDebugTrace("PowerManager::resume(): Couldn't lock listMutex %d\n", _listMutex); -		ret = -1; -	} - -	Common::List<Suspendable *>::iterator i = _suspendList.begin(); - -	for (; i != _suspendList.end(); i++) { -		(*i)->resume(); -	} - -	if (SDL_mutexV(_listMutex) != 0) { -		PSPDebugTrace("PowerManager::resume(): Couldn't unlock listMutex %d\n", _listMutex); -		ret = -1; -	} - -	// Now we set the suspend flag to false -	if (SDL_mutexP(_flagMutex) != 0) { -		PSPDebugTrace("PowerManager::resume(): Couldn't lock flagMutex %d\n", _flagMutex); -		ret = -1; -	} -	_suspendFlag = false; - -	// Signal the other threads to wake up -	if (SDL_CondBroadcast(_condSuspendable) != 0) { -		PSPDebugTrace("PowerManager::resume(): Couldn't broadcast condition %d\n", _condSuspendable); -		ret = -1; -	} - -	if (SDL_mutexV(_flagMutex) != 0) { -		PSPDebugTrace("PowerManager::resume(): Couldn't unlock flagMutex %d\n", _flagMutex); -		ret = -1; -	} - -	return ret; -} diff --git a/backends/platform/psp/powerman.h b/backends/platform/psp/powerman.h deleted file mode 100644 index 0a5f7a2361..0000000000 --- a/backends/platform/psp/powerman.h +++ /dev/null @@ -1,87 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * 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 - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef POWERMAN_H -#define POWERMAN_H -  -#include <SDL/SDL_thread.h> -#include <SDL/SDL_mutex.h> -#include "common/singleton.h" -#include "common/list.h" -  - /* -  *  Implement this class (interface) if you want to use PowerManager's suspend callback functionality -  * -  */ - class Suspendable { - public: -	virtual ~Suspendable() {} -	virtual int suspend() = 0; -	virtual int resume() = 0; - }; -  - /******************************************************************************************************  - * - *  This class will call a Suspendable when the PSP goes to suspend/resumes. It also provides the ability to block - *  a thread when the PSP is going to suspend/suspending, and to wake it up when the PSP is resumed.  - *	This ability is very useful for managing the PSPIoStream class, but may be found useful by other classes as well. - * - *******************************************************************************************************/ - class PowerManager: public Common::Singleton<PowerManager> { -private: -	friend class Common::Singleton<PowerManager>; -	PowerManager(); -	~PowerManager(); - -	Common::List<Suspendable *> _suspendList;		/* list to register in */ - -	bool _suspendFlag;								/* protected variable */ -	SDL_mutex *_flagMutex;							/* mutex to access access flag */ -	SDL_mutex *_listMutex;							/* mutex to access Suspendable list */ -	SDL_cond *_condSuspendable;						/* signal to synchronize accessing threads */ -	SDL_cond *_condPM;								/* signal to wake up the PM from a critical section */ -	int _criticalCounter;							/* Counter of how many threads are in a critical section */ - -public: -	int blockOnSuspend();								/* block if suspending */ -	int beginCriticalSection(bool justBlock = false);	/* Use a critical section to block (if suspend was already pressed) */ -	int endCriticalSection();							/* and to prevent the PSP from suspending in a particular section */ -	int registerSuspend(Suspendable *item);			/* register to be called to suspend/resume */ -	int unregisterSuspend(Suspendable *item);		/* remove from suspend/resume list */ -	int suspend();									/* callback to have all items in list suspend */ -	int resume();									/* callback to have all items in list resume */ -	 -	enum { -		Error = -1, -		NotBlocked = 0, -		Blocked = 1		 -	}; -		 - }; -  - // For easy access -#define PowerMan	PowerManager::instance() - - #endif /* POWERMAN_H */ diff --git a/common/scummsys.h b/common/scummsys.h index a9c5fb3266..dc87f7103a 100644 --- a/common/scummsys.h +++ b/common/scummsys.h @@ -44,16 +44,6 @@  		#ifdef _MSC_VER  		#pragma once -		#pragma warning( disable : 4068 ) // turn off "unknown pragma" warning -		#pragma	warning( disable : 4103 ) // turn off "alignement changed after including header" warning. We use pack-start.h file -		#pragma warning( disable : 4244 ) // turn off "conversion type" warning -		#pragma warning( disable : 4250 ) // turn off "inherits via dominance" warning -		#pragma warning( disable : 4351 ) // turn off "new behavior ... will be default initialized" warning -		#pragma warning( disable : 4355 ) // turn off "base member init" warning -		#pragma warning( disable : 4510 ) // turn off "default constructor could not be generated" -		#pragma warning( disable : 4610 ) // turn off "struct can never be instantiated - user defined constructor required" -		#pragma warning( disable : 4701 ) // turn off "potentially uninitialized variables" warning -		#pragma warning( disable : 4800 ) // turn off "forcing value to bool 'true' or 'false' (performance warning)"  		// vsnprintf is already defined in Visual Studio 2008  		#if (_MSC_VER < 1500) diff --git a/dists/msvc9/kyra.vcproj b/dists/msvc9/kyra.vcproj index 98b2609718..053007fae4 100644 --- a/dists/msvc9/kyra.vcproj +++ b/dists/msvc9/kyra.vcproj @@ -100,6 +100,7 @@  		<File RelativePath="..\..\engines\kyra\sound.cpp" />  		<File RelativePath="..\..\engines\kyra\sound.h" />  		<File RelativePath="..\..\engines\kyra\sound_adlib.cpp" /> +		<File RelativePath="..\..\engines\kyra\sound_amiga.cpp" />  		<File RelativePath="..\..\engines\kyra\sound_digital.cpp" />  		<File RelativePath="..\..\engines\kyra\sound_intern.h" />  		<File RelativePath="..\..\engines\kyra\sound_lok.cpp" /> diff --git a/dists/msvc9/scumm.vcproj b/dists/msvc9/scumm.vcproj index a428fbceee..e261319fdb 100644 --- a/dists/msvc9/scumm.vcproj +++ b/dists/msvc9/scumm.vcproj @@ -152,6 +152,8 @@  		<File RelativePath="..\..\engines\scumm\player_v2cms.cpp" />  		<File RelativePath="..\..\engines\scumm\player_v3a.cpp" />  		<File RelativePath="..\..\engines\scumm\player_v3a.h" /> +		<File RelativePath="..\..\engines\scumm\player_v4a.cpp" /> +		<File RelativePath="..\..\engines\scumm\player_v4a.h" />  		<File RelativePath="..\..\engines\scumm\resource.cpp" />  		<File RelativePath="..\..\engines\scumm\resource.h" />  		<File RelativePath="..\..\engines\scumm\resource_v2.cpp" /> diff --git a/dists/msvc9/scummvm.vcproj b/dists/msvc9/scummvm.vcproj index 68820f16cf..1dd95998dd 100644 --- a/dists/msvc9/scummvm.vcproj +++ b/dists/msvc9/scummvm.vcproj @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="windows-1252"?>  <VisualStudioProject  	ProjectType="Visual C++" -	Version="9.00" +	Version="9,00"  	Name="scummvm"  	ProjectGUID="{8434CB15-D08F-427D-9E6D-581AE5B28440}"  	RootNamespace="scummvm" @@ -9,212 +9,877 @@  	TargetFrameworkVersion="131072"  	>  	<Platforms> -		<Platform Name="Win32" /> +		<Platform +			Name="Win32" +		/>  	</Platforms> +	<ToolFiles> +	</ToolFiles>  	<Configurations> -		<Configuration Name="Debug|Win32" ConfigurationType="1" InheritedPropertySheets=".\ScummVM_Debug.vsprops"> -			<Tool	Name="VCLinkerTool" OutputFile="$(OutDir)/scummvm.exe" +		<Configuration +			Name="Debug|Win32" +			ConfigurationType="1" +			InheritedPropertySheets=".\ScummVM_Debug.vsprops" +			> +			<Tool +				Name="VCPreBuildEventTool" +			/> +			<Tool +				Name="VCCustomBuildTool" +			/> +			<Tool +				Name="VCXMLDataGeneratorTool" +			/> +			<Tool +				Name="VCWebServiceProxyGeneratorTool" +			/> +			<Tool +				Name="VCMIDLTool" +			/> +			<Tool +				Name="VCCLCompilerTool" +			/> +			<Tool +				Name="VCManagedResourceCompilerTool" +			/> +			<Tool +				Name="VCResourceCompilerTool" +			/> +			<Tool +				Name="VCPreLinkEventTool" +			/> +			<Tool +				Name="VCLinkerTool"  				AdditionalDependencies="winmm.lib sdl.lib zlib.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib $(OutDir)/*.lib" +				OutputFile="$(OutDir)/scummvm.exe" +			/> +			<Tool +				Name="VCALinkTool" +			/> +			<Tool +				Name="VCManifestTool" +			/> +			<Tool +				Name="VCXDCMakeTool" +			/> +			<Tool +				Name="VCBscMakeTool" +			/> +			<Tool +				Name="VCFxCopTool" +			/> +			<Tool +				Name="VCAppVerifierTool" +			/> +			<Tool +				Name="VCPostBuildEventTool"  			/>  		</Configuration> -		<Configuration Name="Release|Win32" ConfigurationType="1" InheritedPropertySheets=".\ScummVM_Release.vsprops"> -			<Tool Name="VCLinkerTool" OutputFile="$(OutDir)/scummvm.exe" +		<Configuration +			Name="Release|Win32" +			ConfigurationType="1" +			InheritedPropertySheets=".\ScummVM_Release.vsprops" +			> +			<Tool +				Name="VCPreBuildEventTool" +			/> +			<Tool +				Name="VCCustomBuildTool" +			/> +			<Tool +				Name="VCXMLDataGeneratorTool" +			/> +			<Tool +				Name="VCWebServiceProxyGeneratorTool" +			/> +			<Tool +				Name="VCMIDLTool" +			/> +			<Tool +				Name="VCCLCompilerTool" +			/> +			<Tool +				Name="VCManagedResourceCompilerTool" +			/> +			<Tool +				Name="VCResourceCompilerTool" +			/> +			<Tool +				Name="VCPreLinkEventTool" +			/> +			<Tool +				Name="VCLinkerTool"  				AdditionalDependencies="winmm.lib sdl.lib zlib.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib $(OutDir)/*.lib" +				OutputFile="$(OutDir)/scummvm.exe" +			/> +			<Tool +				Name="VCALinkTool" +			/> +			<Tool +				Name="VCManifestTool" +			/> +			<Tool +				Name="VCXDCMakeTool" +			/> +			<Tool +				Name="VCBscMakeTool" +			/> +			<Tool +				Name="VCFxCopTool" +			/> +			<Tool +				Name="VCAppVerifierTool" +			/> +			<Tool +				Name="VCPostBuildEventTool"  			/>  		</Configuration>  	</Configurations> +	<References> +	</References>  	<Files> -		<Filter	Name="base"> -			<File RelativePath="..\..\base\commandLine.cpp" /> -			<File RelativePath="..\..\base\commandLine.h" /> -			<File RelativePath="..\..\base\internal_version.h" /> -			<File RelativePath="..\..\base\main.cpp" /> -			<File RelativePath="..\..\base\main.h" /> -			<File RelativePath="..\..\base\plugins.cpp" /> -			<File RelativePath="..\..\base\plugins.h" /> -			<File RelativePath="..\..\base\version.cpp" /> -			<File RelativePath="..\..\base\version.h" /> +		<Filter +			Name="base" +			> +			<File +				RelativePath="..\..\base\commandLine.cpp" +				> +			</File> +			<File +				RelativePath="..\..\base\commandLine.h" +				> +			</File> +			<File +				RelativePath="..\..\base\internal_version.h" +				> +			</File> +			<File +				RelativePath="..\..\base\main.cpp" +				> +			</File> +			<File +				RelativePath="..\..\base\main.h" +				> +			</File> +			<File +				RelativePath="..\..\base\plugins.cpp" +				> +			</File> +			<File +				RelativePath="..\..\base\plugins.h" +				> +			</File> +			<File +				RelativePath="..\..\base\version.cpp" +				> +			</File> +			<File +				RelativePath="..\..\base\version.h" +				> +			</File>  		</Filter> -		<Filter	Name="common"> -			<File RelativePath="..\..\common\algorithm.h" /> -			<File RelativePath="..\..\common\archive.cpp" /> -			<File RelativePath="..\..\common\archive.h" /> -			<File RelativePath="..\..\common\array.h" /> -			<File RelativePath="..\..\common\config-file.cpp" /> -			<File RelativePath="..\..\common\config-file.h" /> -			<File RelativePath="..\..\common\config-manager.cpp" /> -			<File RelativePath="..\..\common\config-manager.h" /> -			<File RelativePath="..\..\common\debug.cpp" /> -			<File RelativePath="..\..\common\debug.h" /> -			<File RelativePath="..\..\common\endian.h" /> -			<File RelativePath="..\..\common\error.h" /> -			<File RelativePath="..\..\common\EventDispatcher.cpp" /> -			<File RelativePath="..\..\common\EventRecorder.cpp" /> -			<File RelativePath="..\..\common\EventRecorder.h" /> -			<File RelativePath="..\..\common\events.h" /> -			<File RelativePath="..\..\common\file.cpp" /> -			<File RelativePath="..\..\common\file.h" /> -			<File RelativePath="..\..\common\frac.h" /> -			<File RelativePath="..\..\common\fs.cpp" /> -			<File RelativePath="..\..\common\fs.h" /> -			<File RelativePath="..\..\common\func.h" /> -			<File RelativePath="..\..\common\hash-str.h" /> -			<File RelativePath="..\..\common\hashmap.cpp" /> -			<File RelativePath="..\..\common\hashmap.h" /> -			<File RelativePath="..\..\common\iff_container.h" /> -			<File RelativePath="..\..\common\keyboard.h" /> -			<File RelativePath="..\..\common\list.h" /> -			<File RelativePath="..\..\common\list_intern.h" /> -			<File RelativePath="..\..\common\md5.cpp" /> -			<File RelativePath="..\..\common\md5.h" /> -			<File RelativePath="..\..\common\memorypool.cpp" /> -			<File RelativePath="..\..\common\memorypool.h" /> -			<File RelativePath="..\..\common\mutex.cpp" /> -			<File RelativePath="..\..\common\mutex.h" /> -			<File RelativePath="..\..\common\noncopyable.h" /> -			<File RelativePath="..\..\common\pack-end.h" /> -			<File RelativePath="..\..\common\pack-start.h" /> -			<File RelativePath="..\..\common\ptr.h" /> -			<File RelativePath="..\..\common\queue.h" /> -			<File RelativePath="..\..\common\rect.h" /> -			<File RelativePath="..\..\common\savefile.h" /> -			<File RelativePath="..\..\common\scummsys.h" /> -			<File RelativePath="..\..\common\serializer.h" /> -			<File RelativePath="..\..\common\singleton.h" /> -			<File RelativePath="..\..\common\stack.h" /> -			<File RelativePath="..\..\common\str.cpp" /> -			<File RelativePath="..\..\common\str.h" /> -			<File RelativePath="..\..\common\stream.cpp" /> -			<File RelativePath="..\..\common\stream.h" /> -			<File RelativePath="..\..\common\system.cpp" /> -			<File RelativePath="..\..\common\system.h" /> -			<File RelativePath="..\..\common\timer.h" /> -			<File RelativePath="..\..\common\unarj.cpp" /> -			<File RelativePath="..\..\common\unarj.h" /> -			<File RelativePath="..\..\common\unzip.cpp" /> -			<File RelativePath="..\..\common\unzip.h" /> -			<File RelativePath="..\..\common\util.cpp" /> -			<File RelativePath="..\..\common\util.h" /> -			<File RelativePath="..\..\common\xmlparser.cpp" /> -			<File RelativePath="..\..\common\xmlparser.h" /> -			<File RelativePath="..\..\common\zlib.cpp" /> -			<File RelativePath="..\..\common\zlib.h" /> +		<Filter +			Name="common" +			> +			<File +				RelativePath="..\..\common\algorithm.h" +				> +			</File> +			<File +				RelativePath="..\..\common\archive.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\archive.h" +				> +			</File> +			<File +				RelativePath="..\..\common\array.h" +				> +			</File> +			<File +				RelativePath="..\..\common\config-file.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\config-file.h" +				> +			</File> +			<File +				RelativePath="..\..\common\config-manager.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\config-manager.h" +				> +			</File> +			<File +				RelativePath="..\..\common\debug.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\debug.h" +				> +			</File> +			<File +				RelativePath="..\..\common\endian.h" +				> +			</File> +			<File +				RelativePath="..\..\common\error.h" +				> +			</File> +			<File +				RelativePath="..\..\common\EventDispatcher.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\EventRecorder.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\EventRecorder.h" +				> +			</File> +			<File +				RelativePath="..\..\common\events.h" +				> +			</File> +			<File +				RelativePath="..\..\common\file.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\file.h" +				> +			</File> +			<File +				RelativePath="..\..\common\frac.h" +				> +			</File> +			<File +				RelativePath="..\..\common\fs.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\fs.h" +				> +			</File> +			<File +				RelativePath="..\..\common\func.h" +				> +			</File> +			<File +				RelativePath="..\..\common\hash-str.h" +				> +			</File> +			<File +				RelativePath="..\..\common\hashmap.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\hashmap.h" +				> +			</File> +			<File +				RelativePath="..\..\common\iff_container.h" +				> +			</File> +			<File +				RelativePath="..\..\common\keyboard.h" +				> +			</File> +			<File +				RelativePath="..\..\common\list.h" +				> +			</File> +			<File +				RelativePath="..\..\common\list_intern.h" +				> +			</File> +			<File +				RelativePath="..\..\common\md5.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\md5.h" +				> +			</File> +			<File +				RelativePath="..\..\common\memorypool.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\memorypool.h" +				> +			</File> +			<File +				RelativePath="..\..\common\mutex.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\mutex.h" +				> +			</File> +			<File +				RelativePath="..\..\common\noncopyable.h" +				> +			</File> +			<File +				RelativePath="..\..\common\pack-end.h" +				> +			</File> +			<File +				RelativePath="..\..\common\pack-start.h" +				> +			</File> +			<File +				RelativePath="..\..\common\ptr.h" +				> +			</File> +			<File +				RelativePath="..\..\common\queue.h" +				> +			</File> +			<File +				RelativePath="..\..\common\rect.h" +				> +			</File> +			<File +				RelativePath="..\..\common\savefile.h" +				> +			</File> +			<File +				RelativePath="..\..\common\scummsys.h" +				> +			</File> +			<File +				RelativePath="..\..\common\serializer.h" +				> +			</File> +			<File +				RelativePath="..\..\common\singleton.h" +				> +			</File> +			<File +				RelativePath="..\..\common\stack.h" +				> +			</File> +			<File +				RelativePath="..\..\common\str.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\str.h" +				> +			</File> +			<File +				RelativePath="..\..\common\stream.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\stream.h" +				> +			</File> +			<File +				RelativePath="..\..\common\system.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\system.h" +				> +			</File> +			<File +				RelativePath="..\..\common\timer.h" +				> +			</File> +			<File +				RelativePath="..\..\common\unarj.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\unarj.h" +				> +			</File> +			<File +				RelativePath="..\..\common\unzip.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\unzip.h" +				> +			</File> +			<File +				RelativePath="..\..\common\util.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\util.h" +				> +			</File> +			<File +				RelativePath="..\..\common\xmlparser.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\xmlparser.h" +				> +			</File> +			<File +				RelativePath="..\..\common\zlib.cpp" +				> +			</File> +			<File +				RelativePath="..\..\common\zlib.h" +				> +			</File>  		</Filter> -		<Filter	Name="sound"> -			<File RelativePath="..\..\sound\adpcm.cpp" /> -			<File RelativePath="..\..\sound\adpcm.h" /> -			<File RelativePath="..\..\sound\aiff.cpp" /> -			<File RelativePath="..\..\sound\aiff.h" /> -			<File RelativePath="..\..\sound\audiocd.cpp" /> -			<File RelativePath="..\..\sound\audiocd.h" /> -			<File RelativePath="..\..\sound\audiostream.cpp" /> -			<File RelativePath="..\..\sound\audiostream.h" /> -			<File RelativePath="..\..\sound\flac.cpp" /> -			<File RelativePath="..\..\sound\flac.h" /> -			<File RelativePath="..\..\sound\fmopl.cpp" /> -			<File RelativePath="..\..\sound\fmopl.h" /> -			<File RelativePath="..\..\sound\iff_sound.cpp" /> -			<File RelativePath="..\..\sound\iff_sound.h" /> -			<File RelativePath="..\..\sound\mididrv.cpp" /> -			<File RelativePath="..\..\sound\mididrv.h" /> -			<File RelativePath="..\..\sound\midiparser.cpp" /> -			<File RelativePath="..\..\sound\midiparser.h" /> -			<File RelativePath="..\..\sound\midiparser_smf.cpp" /> -			<File RelativePath="..\..\sound\midiparser_xmidi.cpp" /> -			<File RelativePath="..\..\sound\mixer.cpp" /> -			<File RelativePath="..\..\sound\mixer.h" /> -			<File RelativePath="..\..\sound\mixer_intern.h" /> -			<File RelativePath="..\..\sound\mp3.cpp" /> -			<File RelativePath="..\..\sound\mp3.h" /> -			<File RelativePath="..\..\sound\mpu401.cpp" /> -			<File RelativePath="..\..\sound\mpu401.h" /> -			<File RelativePath="..\..\sound\musicplugin.cpp" /> -			<File RelativePath="..\..\sound\musicplugin.h" /> -			<File RelativePath="..\..\sound\null.cpp" /> -			<File RelativePath="..\..\sound\rate.cpp" /> -			<File RelativePath="..\..\sound\rate.h" /> -			<File RelativePath="..\..\sound\shorten.cpp" /> -			<File RelativePath="..\..\sound\shorten.h" /> -			<File RelativePath="..\..\sound\timestamp.cpp" /> -			<File RelativePath="..\..\sound\timestamp.h" /> -			<File RelativePath="..\..\sound\vag.cpp" /> -			<File RelativePath="..\..\sound\vag.h" /> -			<File RelativePath="..\..\sound\voc.cpp" /> -			<File RelativePath="..\..\sound\voc.h" /> -			<File RelativePath="..\..\sound\vorbis.cpp" /> -			<File RelativePath="..\..\sound\vorbis.h" /> -			<File RelativePath="..\..\sound\wave.cpp" /> -			<File RelativePath="..\..\sound\wave.h" /> -			<Filter Name="softhsynth"> -				<File	RelativePath="..\..\sound\softsynth\adlib.cpp" /> -				<File RelativePath="..\..\sound\softsynth\emumidi.h" /> -				<File RelativePath="..\..\sound\softsynth\fluidsynth.cpp" /> -				<File RelativePath="..\..\sound\softsynth\mt32.cpp" /> -				<File RelativePath="..\..\sound\softsynth\pcspk.cpp" /> -				<File RelativePath="..\..\sound\softsynth\pcspk.h" /> -				<File RelativePath="..\..\sound\softsynth\ym2612.cpp" /> -				<File RelativePath="..\..\sound\softsynth\ym2612.h" /> -				<Filter	Name="mt32"> -					<File RelativePath="..\..\sound\softsynth\mt32\freeverb.cpp" /> -					<File RelativePath="..\..\sound\softsynth\mt32\freeverb.h" /> -					<File RelativePath="..\..\sound\softsynth\mt32\i386.cpp" /> -					<File RelativePath="..\..\sound\softsynth\mt32\i386.h" /> -					<File RelativePath="..\..\sound\softsynth\mt32\mt32_file.cpp" /> -					<File RelativePath="..\..\sound\softsynth\mt32\mt32_file.h" /> -					<File RelativePath="..\..\sound\softsynth\mt32\mt32emu.h" /> -					<File RelativePath="..\..\sound\softsynth\mt32\part.cpp" /> -					<File RelativePath="..\..\sound\softsynth\mt32\part.h" /> -					<File RelativePath="..\..\sound\softsynth\mt32\partial.cpp" /> -					<File RelativePath="..\..\sound\softsynth\mt32\partial.h" /> -					<File RelativePath="..\..\sound\softsynth\mt32\partialManager.cpp" /> -					<File RelativePath="..\..\sound\softsynth\mt32\partialManager.h" /> -					<File RelativePath="..\..\sound\softsynth\mt32\structures.h" /> -					<File RelativePath="..\..\sound\softsynth\mt32\synth.cpp" /> -					<File RelativePath="..\..\sound\softsynth\mt32\synth.h" /> -					<File RelativePath="..\..\sound\softsynth\mt32\tables.cpp" /> -					<File RelativePath="..\..\sound\softsynth\mt32\tables.h" /> +		<Filter +			Name="sound" +			> +			<File +				RelativePath="..\..\sound\adpcm.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\adpcm.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\aiff.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\aiff.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\audiocd.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\audiocd.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\audiostream.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\audiostream.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\flac.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\flac.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\fmopl.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\fmopl.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\iff_sound.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\iff_sound.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\mididrv.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\mididrv.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\midiparser.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\midiparser.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\midiparser_smf.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\midiparser_xmidi.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\mixer.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\mixer.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\mixer_intern.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\mp3.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\mp3.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\mpu401.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\mpu401.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\musicplugin.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\musicplugin.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\null.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\rate.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\rate.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\shorten.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\shorten.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\timestamp.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\timestamp.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\vag.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\vag.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\voc.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\voc.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\vorbis.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\vorbis.h" +				> +			</File> +			<File +				RelativePath="..\..\sound\wave.cpp" +				> +			</File> +			<File +				RelativePath="..\..\sound\wave.h" +				> +			</File> +			<Filter +				Name="softhsynth" +				> +				<File +					RelativePath="..\..\sound\softsynth\adlib.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\softsynth\emumidi.h" +					> +				</File> +				<File +					RelativePath="..\..\sound\softsynth\fluidsynth.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\softsynth\mt32.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\softsynth\pcspk.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\softsynth\pcspk.h" +					> +				</File> +				<File +					RelativePath="..\..\sound\softsynth\ym2612.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\softsynth\ym2612.h" +					> +				</File> +				<Filter +					Name="mt32" +					> +					<File +						RelativePath="..\..\sound\softsynth\mt32\freeverb.cpp" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\freeverb.h" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\i386.cpp" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\i386.h" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\mt32_file.cpp" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\mt32_file.h" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\mt32emu.h" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\part.cpp" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\part.h" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\partial.cpp" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\partial.h" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\partialManager.cpp" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\partialManager.h" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\structures.h" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\synth.cpp" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\synth.h" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\tables.cpp" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\mt32\tables.h" +						> +					</File>  				</Filter> -				<Filter Name="opl"> -					<File RelativePath="..\..\sound\softsynth\opl\dosbox.cpp" /> -					<File RelativePath="..\..\sound\softsynth\opl\dosbox.h" /> -					<File RelativePath="..\..\sound\softsynth\opl\mame.cpp" /> -					<File RelativePath="..\..\sound\softsynth\opl\mame.h" /> -					<File RelativePath="..\..\sound\softsynth\opl\opl_impl.h" /> -					<File RelativePath="..\..\sound\softsynth\opl\opl_inc.h" /> +				<Filter +					Name="opl" +					> +					<File +						RelativePath="..\..\sound\softsynth\opl\dosbox.cpp" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\opl\dosbox.h" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\opl\mame.cpp" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\opl\mame.h" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\opl\opl_impl.h" +						> +					</File> +					<File +						RelativePath="..\..\sound\softsynth\opl\opl_inc.h" +						> +					</File>  				</Filter>  			</Filter> -			<Filter Name="mods"> -				<File RelativePath="..\..\sound\mods\infogrames.cpp" /> -				<File RelativePath="..\..\sound\mods\infogrames.h" /> -				<File RelativePath="..\..\sound\mods\module.cpp" /> -				<File RelativePath="..\..\sound\mods\module.h" /> -				<File RelativePath="..\..\sound\mods\paula.cpp" /> -				<File RelativePath="..\..\sound\mods\paula.h" /> -				<File RelativePath="..\..\sound\mods\protracker.cpp" /> -				<File RelativePath="..\..\sound\mods\protracker.h" /> -				<File RelativePath="..\..\sound\mods\rjp1.cpp" /> -				<File RelativePath="..\..\sound\mods\rjp1.h" /> -				<File RelativePath="..\..\sound\mods\soundfx.cpp" /> -				<File RelativePath="..\..\sound\mods\soundfx.h" /> +			<Filter +				Name="mods" +				> +				<File +					RelativePath="..\..\sound\mods\infogrames.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\infogrames.h" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\maxtrax.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\maxtrax.h" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\module.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\module.h" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\paula.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\paula.h" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\protracker.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\protracker.h" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\rjp1.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\rjp1.h" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\soundfx.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\soundfx.h" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\tfmx.cpp" +					> +				</File> +				<File +					RelativePath="..\..\sound\mods\tfmx.h" +					> +				</File>  			</Filter>  		</Filter> -		<Filter Name="txt"> -			<File RelativePath="..\..\COPYING" /> -			<File RelativePath="..\..\NEWS" /> -			<File RelativePath="..\..\README" /> -			<File RelativePath="..\..\TODO" /> +		<Filter +			Name="txt" +			> +			<File +				RelativePath="..\..\COPYING" +				> +			</File> +			<File +				RelativePath="..\..\NEWS" +				> +			</File> +			<File +				RelativePath="..\..\README" +				> +			</File> +			<File +				RelativePath="..\..\TODO" +				> +			</File>  		</Filter> -		<Filter Name="rsc"> -			<File RelativePath="..\..\icons\scummvm.ico" /> -			<File RelativePath="..\..\dists\scummvm.rc" /> +		<Filter +			Name="rsc" +			> +			<File +				RelativePath="..\..\icons\scummvm.ico" +				> +			</File> +			<File +				RelativePath="..\..\dists\scummvm.rc" +				> +			</File>  		</Filter> -		<Filter Name="backends"> -			<File RelativePath="..\..\backends\base-backend.cpp" /> -			<File RelativePath="..\..\backends\base-backend.h" /> -			<Filter Name="sdl"> -				<File RelativePath="..\..\backends\platform\sdl\events.cpp" /> -				<File RelativePath="..\..\backends\platform\sdl\graphics.cpp" /> -				<File RelativePath="..\..\backends\platform\sdl\hardwarekeys.cpp" /> +		<Filter +			Name="backends" +			> +			<File +				RelativePath="..\..\backends\base-backend.cpp" +				> +			</File> +			<File +				RelativePath="..\..\backends\base-backend.h" +				> +			</File> +			<Filter +				Name="sdl" +				> +				<File +					RelativePath="..\..\backends\platform\sdl\events.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\platform\sdl\graphics.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\platform\sdl\hardwarekeys.cpp" +					> +				</File>  				<File  					RelativePath="..\..\backends\platform\sdl\main.cpp"  					> @@ -237,156 +902,558 @@  						/>  					</FileConfiguration>  				</File> -				<File RelativePath="..\..\backends\platform\sdl\sdl.cpp" /> -				<File RelativePath="..\..\backends\platform\sdl\sdl.h" /> +				<File +					RelativePath="..\..\backends\platform\sdl\sdl.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\platform\sdl\sdl.h" +					> +				</File>  			</Filter> -			<Filter Name="fs"> -				<File RelativePath="..\..\backends\fs\abstract-fs.cpp" /> -				<File RelativePath="..\..\backends\fs\abstract-fs.h" /> -				<File RelativePath="..\..\backends\fs\fs-factory.h" /> -				<File RelativePath="..\..\backends\fs\stdiostream.cpp" /> -				<File RelativePath="..\..\backends\fs\stdiostream.h" /> -				<Filter Name="windows"> -					<File RelativePath="..\..\backends\fs\windows\windows-fs-factory.cpp" /> -					<File RelativePath="..\..\backends\fs\windows\windows-fs-factory.h" /> +			<Filter +				Name="fs" +				> +				<File +					RelativePath="..\..\backends\fs\abstract-fs.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\fs\abstract-fs.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\fs\fs-factory.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\fs\stdiostream.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\fs\stdiostream.h" +					> +				</File> +				<Filter +					Name="windows" +					> +					<File +						RelativePath="..\..\backends\fs\windows\windows-fs-factory.cpp" +						> +					</File> +					<File +						RelativePath="..\..\backends\fs\windows\windows-fs-factory.h" +						> +					</File>  				</Filter>  			</Filter> -			<Filter Name="midi"> -				<File RelativePath="..\..\backends\midi\windows.cpp" /> +			<Filter +				Name="midi" +				> +				<File +					RelativePath="..\..\backends\midi\windows.cpp" +					> +				</File>  			</Filter> -			<Filter Name="timer"> -				<File RelativePath="..\..\backends\timer\default\default-timer.cpp" /> -				<File RelativePath="..\..\backends\timer\default\default-timer.h" /> +			<Filter +				Name="timer" +				> +				<File +					RelativePath="..\..\backends\timer\default\default-timer.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\timer\default\default-timer.h" +					> +				</File>  			</Filter> -			<Filter Name="saves"> -				<File RelativePath="..\..\backends\saves\default\default-saves.cpp" /> -				<File RelativePath="..\..\backends\saves\default\default-saves.h" /> -				<File RelativePath="..\..\backends\saves\savefile.cpp" /> +			<Filter +				Name="saves" +				> +				<File +					RelativePath="..\..\backends\saves\default\default-saves.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\saves\default\default-saves.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\saves\savefile.cpp" +					> +				</File>  			</Filter> -			<Filter Name="events"> -				<Filter Name="default"> -					<File RelativePath="..\..\backends\events\default\default-events.cpp" /> -					<File RelativePath="..\..\backends\events\default\default-events.h" /> +			<Filter +				Name="events" +				> +				<Filter +					Name="default" +					> +					<File +						RelativePath="..\..\backends\events\default\default-events.cpp" +						> +					</File> +					<File +						RelativePath="..\..\backends\events\default\default-events.h" +						> +					</File>  				</Filter>  			</Filter> -			<Filter Name="keymapper"> -				<File RelativePath="..\..\backends\keymapper\action.cpp" /> -				<File RelativePath="..\..\backends\keymapper\action.h" /> -				<File RelativePath="..\..\backends\keymapper\hardware-key.h" /> -				<File RelativePath="..\..\backends\keymapper\keymap.cpp" /> -				<File RelativePath="..\..\backends\keymapper\keymap.h" /> -				<File RelativePath="..\..\backends\keymapper\keymapper.cpp" /> -				<File RelativePath="..\..\backends\keymapper\keymapper.h" /> -				<File RelativePath="..\..\backends\keymapper\remap-dialog.cpp" /> -				<File RelativePath="..\..\backends\keymapper\remap-dialog.h" /> -				<File RelativePath="..\..\backends\keymapper\types.h" /> +			<Filter +				Name="keymapper" +				> +				<File +					RelativePath="..\..\backends\keymapper\action.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\keymapper\action.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\keymapper\hardware-key.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\keymapper\keymap.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\keymapper\keymap.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\keymapper\keymapper.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\keymapper\keymapper.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\keymapper\remap-dialog.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\keymapper\remap-dialog.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\keymapper\types.h" +					> +				</File>  			</Filter> -			<Filter Name="vkeybd"> -				<File RelativePath="..\..\backends\vkeybd\image-map.cpp" /> -				<File RelativePath="..\..\backends\vkeybd\image-map.h" /> -				<File RelativePath="..\..\backends\vkeybd\keycode-descriptions.h" /> -				<File RelativePath="..\..\backends\vkeybd\polygon.cpp" /> -				<File RelativePath="..\..\backends\vkeybd\polygon.h" /> -				<File RelativePath="..\..\backends\vkeybd\virtual-keyboard-gui.cpp" /> -				<File RelativePath="..\..\backends\vkeybd\virtual-keyboard-gui.h" /> -				<File RelativePath="..\..\backends\vkeybd\virtual-keyboard-parser.cpp" /> -				<File RelativePath="..\..\backends\vkeybd\virtual-keyboard-parser.h" /> -				<File RelativePath="..\..\backends\vkeybd\virtual-keyboard.cpp" /> -				<File RelativePath="..\..\backends\vkeybd\virtual-keyboard.h" /> +			<Filter +				Name="vkeybd" +				> +				<File +					RelativePath="..\..\backends\vkeybd\image-map.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\vkeybd\image-map.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\vkeybd\keycode-descriptions.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\vkeybd\polygon.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\vkeybd\polygon.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\vkeybd\virtual-keyboard-gui.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\vkeybd\virtual-keyboard-gui.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\vkeybd\virtual-keyboard-parser.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\vkeybd\virtual-keyboard-parser.h" +					> +				</File> +				<File +					RelativePath="..\..\backends\vkeybd\virtual-keyboard.cpp" +					> +				</File> +				<File +					RelativePath="..\..\backends\vkeybd\virtual-keyboard.h" +					> +				</File>  			</Filter>  		</Filter> -		<Filter Name="gui"> -			<File RelativePath="..\..\gui\about.cpp" /> -			<File RelativePath="..\..\gui\about.h" /> -			<File RelativePath="..\..\gui\browser.cpp" /> -			<File RelativePath="..\..\gui\browser.h" /> -			<File RelativePath="..\..\gui\chooser.cpp" /> -			<File RelativePath="..\..\gui\chooser.h" /> -			<File RelativePath="..\..\gui\console.cpp" /> -			<File RelativePath="..\..\gui\console.h" /> -			<File RelativePath="..\..\gui\credits.h" /> -			<File RelativePath="..\..\gui\debugger.cpp" /> -			<File RelativePath="..\..\gui\debugger.h" /> -			<File RelativePath="..\..\gui\dialog.cpp" /> -			<File RelativePath="..\..\gui\dialog.h" /> -			<File RelativePath="..\..\gui\editable.cpp" /> -			<File RelativePath="..\..\gui\editable.h" /> -			<File RelativePath="..\..\gui\EditTextWidget.cpp" /> -			<File RelativePath="..\..\gui\EditTextWidget.h" /> -			<File RelativePath="..\..\gui\GuiManager.cpp" /> -			<File RelativePath="..\..\gui\GuiManager.h" /> -			<File RelativePath="..\..\gui\Key.cpp" /> -			<File RelativePath="..\..\gui\Key.h" /> -			<File RelativePath="..\..\gui\launcher.cpp" /> -			<File RelativePath="..\..\gui\launcher.h" /> -			<File RelativePath="..\..\gui\ListWidget.cpp" /> -			<File RelativePath="..\..\gui\ListWidget.h" /> -			<File RelativePath="..\..\gui\massadd.cpp" /> -			<File RelativePath="..\..\gui\massadd.h" /> -			<File RelativePath="..\..\gui\message.cpp" /> -			<File RelativePath="..\..\gui\message.h" /> -			<File RelativePath="..\..\gui\object.cpp" /> -			<File RelativePath="..\..\gui\object.h" /> -			<File RelativePath="..\..\gui\options.cpp" /> -			<File RelativePath="..\..\gui\options.h" /> -			<File RelativePath="..\..\gui\PopUpWidget.cpp" /> -			<File RelativePath="..\..\gui\PopUpWidget.h" /> -			<File RelativePath="..\..\gui\saveload.cpp" /> -			<File RelativePath="..\..\gui\saveload.h" /> -			<File RelativePath="..\..\gui\ScrollBarWidget.cpp" /> -			<File RelativePath="..\..\gui\ScrollBarWidget.h" /> -			<File RelativePath="..\..\gui\TabWidget.cpp" /> -			<File RelativePath="..\..\gui\TabWidget.h" /> -			<File RelativePath="..\..\gui\themebrowser.cpp" /> -			<File RelativePath="..\..\gui\themebrowser.h" /> -			<File RelativePath="..\..\gui\ThemeEngine.cpp" /> -			<File RelativePath="..\..\gui\ThemeEngine.h" /> -			<File RelativePath="..\..\gui\ThemeEval.cpp" /> -			<File RelativePath="..\..\gui\ThemeLayout.cpp" /> -			<File RelativePath="..\..\gui\ThemeLayout.h" /> -			<File RelativePath="..\..\gui\ThemeParser.cpp" /> -			<File RelativePath="..\..\gui\ThemeParser.h" /> -			<File RelativePath="..\..\gui\widget.cpp" /> -			<File RelativePath="..\..\gui\widget.h" /> +		<Filter +			Name="gui" +			> +			<File +				RelativePath="..\..\gui\about.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\about.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\browser.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\browser.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\chooser.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\chooser.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\console.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\console.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\credits.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\debugger.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\debugger.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\dialog.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\dialog.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\editable.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\editable.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\EditTextWidget.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\EditTextWidget.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\GuiManager.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\GuiManager.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\Key.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\Key.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\launcher.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\launcher.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\ListWidget.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\ListWidget.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\massadd.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\massadd.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\message.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\message.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\object.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\object.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\options.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\options.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\PopUpWidget.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\PopUpWidget.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\saveload.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\saveload.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\ScrollBarWidget.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\ScrollBarWidget.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\TabWidget.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\TabWidget.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\themebrowser.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\themebrowser.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\ThemeEngine.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\ThemeEngine.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\ThemeEval.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\ThemeLayout.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\ThemeLayout.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\ThemeParser.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\ThemeParser.h" +				> +			</File> +			<File +				RelativePath="..\..\gui\widget.cpp" +				> +			</File> +			<File +				RelativePath="..\..\gui\widget.h" +				> +			</File>  		</Filter> -		<Filter Name="graphics"> -			<File RelativePath="..\..\graphics\colormasks.h" /> -			<File RelativePath="..\..\graphics\conversion.cpp" /> -			<File RelativePath="..\..\graphics\conversion.h" /> -			<File RelativePath="..\..\graphics\cursorman.cpp" /> -			<File RelativePath="..\..\graphics\cursorman.h" /> -			<File RelativePath="..\..\graphics\dither.cpp" /> -			<File RelativePath="..\..\graphics\dither.h" /> -			<File RelativePath="..\..\graphics\font.cpp" /> -			<File RelativePath="..\..\graphics\font.h" /> -			<File RelativePath="..\..\graphics\fontman.cpp" /> -			<File RelativePath="..\..\graphics\fontman.h" /> -			<File RelativePath="..\..\graphics\iff.cpp" /> -			<File RelativePath="..\..\graphics\iff.h" /> -			<File RelativePath="..\..\graphics\imagedec.cpp" /> -			<File RelativePath="..\..\graphics\imagedec.h" /> -			<File RelativePath="..\..\graphics\jpeg.cpp" /> -			<File RelativePath="..\..\graphics\jpeg.h" /> -			<File RelativePath="..\..\graphics\pixelformat.h" /> -			<File RelativePath="..\..\graphics\primitives.cpp" /> -			<File RelativePath="..\..\graphics\primitives.h" /> -			<File RelativePath="..\..\graphics\scaler.cpp" /> -			<File RelativePath="..\..\graphics\scaler.h" /> -			<File RelativePath="..\..\graphics\sjis.cpp" /> -			<File RelativePath="..\..\graphics\sjis.h" /> -			<File RelativePath="..\..\graphics\surface.cpp" /> -			<File RelativePath="..\..\graphics\surface.h" /> -			<File RelativePath="..\..\graphics\thumbnail.cpp" /> -			<File RelativePath="..\..\graphics\thumbnail.h" /> -			<File RelativePath="..\..\graphics\VectorRenderer.cpp" /> -			<File RelativePath="..\..\graphics\VectorRenderer.h" /> -			<File RelativePath="..\..\graphics\VectorRendererSpec.cpp" /> -			<File RelativePath="..\..\graphics\VectorRendererSpec.h" /> -			<Filter Name="scaler"> -				<File RelativePath="..\..\graphics\scaler\2xsai.cpp" /> -				<File RelativePath="..\..\graphics\scaler\aspect.cpp" /> -				<File RelativePath="..\..\graphics\scaler\hq2x.cpp" /> -				<File RelativePath="..\..\graphics\scaler\hq2x.h" /> +		<Filter +			Name="graphics" +			> +			<File +				RelativePath="..\..\graphics\colormasks.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\conversion.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\conversion.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\cursorman.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\cursorman.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\dither.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\dither.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\font.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\font.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\fontman.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\fontman.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\iff.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\iff.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\imagedec.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\imagedec.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\jpeg.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\jpeg.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\pixelformat.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\primitives.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\primitives.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\scaler.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\scaler.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\sjis.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\sjis.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\surface.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\surface.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\thumbnail.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\thumbnail.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\VectorRenderer.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\VectorRenderer.h" +				> +			</File> +			<File +				RelativePath="..\..\graphics\VectorRendererSpec.cpp" +				> +			</File> +			<File +				RelativePath="..\..\graphics\VectorRendererSpec.h" +				> +			</File> +			<Filter +				Name="scaler" +				> +				<File +					RelativePath="..\..\graphics\scaler\2xsai.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\scaler\aspect.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\scaler\hq2x.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\scaler\hq2x.h" +					> +				</File>  				<File  					RelativePath="..\..\graphics\scaler\hq2x_i386.asm"  					> @@ -409,8 +1476,14 @@  						/>  					</FileConfiguration>  				</File> -				<File RelativePath="..\..\graphics\scaler\hq3x.cpp" /> -				<File RelativePath="..\..\graphics\scaler\hq3x.h" /> +				<File +					RelativePath="..\..\graphics\scaler\hq3x.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\scaler\hq3x.h" +					> +				</File>  				<File  					RelativePath="..\..\graphics\scaler\hq3x_i386.asm"  					> @@ -433,51 +1506,169 @@  						/>  					</FileConfiguration>  				</File> -				<File RelativePath="..\..\graphics\scaler\intern.h" /> -				<File RelativePath="..\..\graphics\scaler\scale2x.cpp" /> -				<File RelativePath="..\..\graphics\scaler\scale2x.h" /> -				<File RelativePath="..\..\graphics\scaler\scale3x.cpp" /> -				<File RelativePath="..\..\graphics\scaler\scale3x.h" /> -				<File RelativePath="..\..\graphics\scaler\scalebit.cpp" /> -				<File RelativePath="..\..\graphics\scaler\scalebit.h" /> -				<File RelativePath="..\..\graphics\scaler\thumbnail_intern.cpp" /> +				<File +					RelativePath="..\..\graphics\scaler\intern.h" +					> +				</File> +				<File +					RelativePath="..\..\graphics\scaler\scale2x.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\scaler\scale2x.h" +					> +				</File> +				<File +					RelativePath="..\..\graphics\scaler\scale3x.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\scaler\scale3x.h" +					> +				</File> +				<File +					RelativePath="..\..\graphics\scaler\scalebit.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\scaler\scalebit.h" +					> +				</File> +				<File +					RelativePath="..\..\graphics\scaler\thumbnail_intern.cpp" +					> +				</File>  			</Filter> -			<Filter Name="fonts"> -				<File RelativePath="..\..\graphics\fonts\consolefont.cpp" /> -				<File RelativePath="..\..\graphics\fonts\newfont.cpp" /> -				<File RelativePath="..\..\graphics\fonts\newfont_big.cpp" /> -				<File RelativePath="..\..\graphics\fonts\scummfont.cpp" /> +			<Filter +				Name="fonts" +				> +				<File +					RelativePath="..\..\graphics\fonts\consolefont.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\fonts\newfont.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\fonts\newfont_big.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\fonts\scummfont.cpp" +					> +				</File>  			</Filter> -			<Filter Name="video"> -				<File RelativePath="..\..\graphics\video\dxa_decoder.cpp" /> -				<File RelativePath="..\..\graphics\video\dxa_decoder.h" /> -				<File RelativePath="..\..\graphics\video\flic_decoder.cpp" /> -				<File RelativePath="..\..\graphics\video\flic_decoder.h" /> -				<File RelativePath="..\..\graphics\video\mpeg_player.cpp" /> -				<File RelativePath="..\..\graphics\video\mpeg_player.h" /> -				<File RelativePath="..\..\graphics\video\smk_decoder.cpp" /> -				<File RelativePath="..\..\graphics\video\smk_decoder.h" /> -				<File RelativePath="..\..\graphics\video\video_player.cpp" /> -				<File RelativePath="..\..\graphics\video\video_player.h" /> -				<Filter Name="coktelvideo"> -					<File RelativePath="..\..\graphics\video\coktelvideo\coktelvideo.cpp" /> -					<File RelativePath="..\..\graphics\video\coktelvideo\coktelvideo.h" /> -					<File RelativePath="..\..\graphics\video\coktelvideo\indeo3.cpp" /> -					<File RelativePath="..\..\graphics\video\coktelvideo\indeo3.h" /> -					<File RelativePath="..\..\graphics\video\coktelvideo\indeo3data.h" /> +			<Filter +				Name="video" +				> +				<File +					RelativePath="..\..\graphics\video\dxa_decoder.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\video\dxa_decoder.h" +					> +				</File> +				<File +					RelativePath="..\..\graphics\video\flic_decoder.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\video\flic_decoder.h" +					> +				</File> +				<File +					RelativePath="..\..\graphics\video\mpeg_player.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\video\mpeg_player.h" +					> +				</File> +				<File +					RelativePath="..\..\graphics\video\smk_decoder.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\video\smk_decoder.h" +					> +				</File> +				<File +					RelativePath="..\..\graphics\video\video_player.cpp" +					> +				</File> +				<File +					RelativePath="..\..\graphics\video\video_player.h" +					> +				</File> +				<Filter +					Name="coktelvideo" +					> +					<File +						RelativePath="..\..\graphics\video\coktelvideo\coktelvideo.cpp" +						> +					</File> +					<File +						RelativePath="..\..\graphics\video\coktelvideo\coktelvideo.h" +						> +					</File> +					<File +						RelativePath="..\..\graphics\video\coktelvideo\indeo3.cpp" +						> +					</File> +					<File +						RelativePath="..\..\graphics\video\coktelvideo\indeo3.h" +						> +					</File> +					<File +						RelativePath="..\..\graphics\video\coktelvideo\indeo3data.h" +						> +					</File>  				</Filter>  			</Filter>  		</Filter> -		<Filter Name="engines"> -			<File RelativePath="..\..\engines\advancedDetector.cpp" /> -			<File RelativePath="..\..\engines\advancedDetector.h" /> -			<File RelativePath="..\..\engines\dialogs.cpp" /> -			<File RelativePath="..\..\engines\dialogs.h" /> -			<File RelativePath="..\..\engines\engine.cpp" /> -			<File RelativePath="..\..\engines\engine.h" /> -			<File RelativePath="..\..\engines\game.cpp" /> -			<File RelativePath="..\..\engines\game.h" /> -			<File RelativePath="..\..\engines\metaengine.h" /> +		<Filter +			Name="engines" +			> +			<File +				RelativePath="..\..\engines\advancedDetector.cpp" +				> +			</File> +			<File +				RelativePath="..\..\engines\advancedDetector.h" +				> +			</File> +			<File +				RelativePath="..\..\engines\dialogs.cpp" +				> +			</File> +			<File +				RelativePath="..\..\engines\dialogs.h" +				> +			</File> +			<File +				RelativePath="..\..\engines\engine.cpp" +				> +			</File> +			<File +				RelativePath="..\..\engines\engine.h" +				> +			</File> +			<File +				RelativePath="..\..\engines\game.cpp" +				> +			</File> +			<File +				RelativePath="..\..\engines\game.h" +				> +			</File> +			<File +				RelativePath="..\..\engines\metaengine.h" +				> +			</File>  		</Filter>  	</Files> +	<Globals> +	</Globals>  </VisualStudioProject> diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp index 36f134d9e4..fc19b2fb65 100644 --- a/engines/kyra/kyra_lok.cpp +++ b/engines/kyra/kyra_lok.cpp @@ -183,8 +183,13 @@ Common::Error KyraEngine_LoK::init() {  	_sound->setSoundList(&_soundData[kMusicIntro]); -	_trackMap = _dosTrackMap; -	_trackMapSize = _dosTrackMapSize; +	if (_flags.platform == Common::kPlatformAmiga) { +		_trackMap = _amigaTrackMap; +		_trackMapSize = _amigaTrackMapSize; +	} else { +		_trackMap = _dosTrackMap; +		_trackMapSize = _dosTrackMapSize; +	}  	if (!_sound->init())  		error("Couldn't init sound"); diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h index e7cc92c5e1..5d20cb0652 100644 --- a/engines/kyra/kyra_lok.h +++ b/engines/kyra/kyra_lok.h @@ -507,6 +507,9 @@ protected:  	static const int8 _dosTrackMap[];  	static const int _dosTrackMapSize; +	static const int8 _amigaTrackMap[]; +	static const int _amigaTrackMapSize; +  	// TODO: get rid of all variables having pointers to the static resources if possible  	// i.e. let them directly use the _staticres functions  	void initStaticResource(); diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index d8e91b138d..cf2b360d79 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -50,7 +50,10 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags)  	_emc = 0;  	_debugger = 0; -	_gameSpeed = 60; +	if (_flags.platform == Common::kPlatformAmiga) +		_gameSpeed = 50; +	else +		_gameSpeed = 60;  	_tickLength = (uint8)(1000.0 / _gameSpeed);  	_trackMap = 0; @@ -114,6 +117,8 @@ Common::Error KyraEngine_v1::init() {  				_sound = new SoundPC98(this, _mixer);  			else  				_sound = new SoundTownsPC98_v2(this, _mixer); +		} else if (_flags.platform == Common::kPlatformAmiga) { +			_sound = new SoundAmiga(this, _mixer);  		} else if (midiDriver == MD_ADLIB) {  			_sound = new SoundAdlibPC(this, _mixer);  		} else { diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index 7b0c0dfb68..b484fa345f 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -50,6 +50,7 @@ MODULE_OBJS := \  	sequences_hof.o \  	sequences_mr.o \  	sound_adlib.o \ +	sound_amiga.o \  	sound_digital.o \  	sound_midi.o \  	sound_pcspk.o \ diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp index 38d1b90e7a..4086d06c00 100644 --- a/engines/kyra/seqplayer.cpp +++ b/engines/kyra/seqplayer.cpp @@ -414,8 +414,6 @@ void SeqPlayer::s1_fillRect() {  void SeqPlayer::s1_playEffect() {  	uint8 track = *_seqData++; -	if (_vm->gameFlags().platform == Common::kPlatformAmiga) -		return;  	_vm->delay(3 * _vm->tickLength());  	_sound->playSoundEffect(track);  } @@ -423,9 +421,6 @@ void SeqPlayer::s1_playEffect() {  void SeqPlayer::s1_playTrack() {  	uint8 msg = *_seqData++; -	if (_vm->gameFlags().platform == Common::kPlatformAmiga) -		return; -  	if (msg == 1) {  		_sound->beginFadeOut();  	} else { diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp index d13dc2d291..16c9b75f3a 100644 --- a/engines/kyra/sequences_lok.cpp +++ b/engines/kyra/sequences_lok.cpp @@ -110,7 +110,7 @@ void KyraEngine_LoK::seq_intro() {  	_seq->setCopyViewOffs(true);  	_screen->setFont(Screen::FID_8_FNT); -	if (_flags.platform != Common::kPlatformFMTowns && _flags.platform != Common::kPlatformPC98) +	if (_flags.platform != Common::kPlatformFMTowns && _flags.platform != Common::kPlatformPC98 && _flags.platform != Common::kPlatformAmiga)  		snd_playTheme(0, 2);  	_text->setTalkCoords(144); @@ -994,6 +994,14 @@ int KyraEngine_LoK::seq_playEnd() {  		snd_playWanderScoreViaMap(50, 1);  		setupPanPages(); +		if (_flags.platform == Common::kPlatformAmiga) { +			_sound->loadSoundFile(kMusicFinale); + +			// The original started song 0 directly here. Since our player +			// uses 0, 1 for stop and fade we start song 0 with 2 +			_sound->playTrack(2); +		} +  		_finalA = createWSAMovie();  		assert(_finalA);  		_finalA->open("finala.wsa", 1, 0); diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp index 91945d91ee..781516282e 100644 --- a/engines/kyra/sound.cpp +++ b/engines/kyra/sound.cpp @@ -215,6 +215,13 @@ void KyraEngine_v1::snd_playWanderScoreViaMap(int command, int restart) {  				_sound->playTrack(command);  			}  		} +	} else if (_flags.platform == Common::kPlatformAmiga) { +		if (_curMusicTheme != 1) +			snd_playTheme(1, -1); + +		assert(command < _trackMapSize); +		if (_trackMap[_lastMusicCommand] != _trackMap[command]) +			_sound->playTrack(_trackMap[command]);  	}  	_lastMusicCommand = command; diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h index 263cd586f7..2f24a264f1 100644 --- a/engines/kyra/sound.h +++ b/engines/kyra/sound.h @@ -55,7 +55,8 @@ public:  		kMidiGM,  		kTowns,  		kPC98, -		kPCSpkr +		kPCSpkr, +		kAmiga  	};  	virtual kType getMusicType() const = 0; diff --git a/engines/kyra/sound_amiga.cpp b/engines/kyra/sound_amiga.cpp new file mode 100644 index 0000000000..0b64e67525 --- /dev/null +++ b/engines/kyra/sound_amiga.cpp @@ -0,0 +1,239 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/system.h" +#include "common/mutex.h" +#include "kyra/resource.h" +#include "kyra/sound_intern.h" + +#include "sound/mixer.h" +#include "sound/mods/maxtrax.h" +#include "sound/audiostream.h" + +namespace { + +FORCEINLINE uint8 sfxTableGetNote(const byte* address) { +	return (uint8)address[0]; +} +FORCEINLINE uint8 sfxTableGetPatch(const byte* address) { +	return (uint8)address[1]; +} +FORCEINLINE uint16 sfxTableGetDuration(const byte* address) { +	return READ_BE_UINT16(&address[4]); +} +FORCEINLINE int8 sfxTableGetVolume(const byte* address) { +	return (int8)address[6]; +} +FORCEINLINE int8 sfxTableGetPan(const byte* address) { +	return (int8)address[7]; +} + +} // end of namespace + +namespace Kyra { + +SoundAmiga::SoundAmiga(KyraEngine_v1 *vm, Audio::Mixer *mixer) +	: Sound(vm, mixer), +	  _driver(0), +	  _musicHandle(), +	  _fileLoaded(kFileNone), +	  _tableSfxIntro(), +	  _tableSfxGame() { +} + +SoundAmiga::~SoundAmiga() { +	_mixer->stopHandle(_musicHandle); +	delete _driver; +} + +extern const byte LoKAmigaSfxIntro[]; +extern const byte LoKAmigaSfxGame[]; + +bool SoundAmiga::init() { +	_driver = new Audio::MaxTrax(_mixer->getOutputRate(), true); +	_tableSfxIntro = LoKAmigaSfxIntro; +	_tableSfxGame = LoKAmigaSfxGame; + +	return _driver != 0 && _tableSfxIntro && _tableSfxGame; +} + +void SoundAmiga::loadSoundFile(uint file) { +	debugC(5, kDebugLevelSound, "SoundAmiga::loadSoundFile(%d)", file); + +	static const char *const tableFilenames[3][2] = { +		{ "introscr.mx",  "introinst.mx" }, +		{ "kyramusic.mx", 0 }, +		{ "finalescr.mx", "introinst.mx" } +	}; +	assert(file < ARRAYSIZE(tableFilenames)); +	if (_fileLoaded == (FileType)file) +		return; +	const char* scoreName = tableFilenames[file][0]; +	const char* sampleName = tableFilenames[file][1]; +	bool loaded = false; + +	Common::SeekableReadStream *scoreIn = _vm->resource()->createReadStream(scoreName); +	if (sampleName) { +		Common::SeekableReadStream *sampleIn = _vm->resource()->createReadStream(sampleName); +		if (scoreIn && sampleIn) { +			_fileLoaded = kFileNone; +			loaded = _driver->load(*scoreIn, true, false); +			loaded = loaded && _driver->load(*sampleIn, false, true); +		} else +			warning("SoundAmiga: missing atleast one of those music files: %s, %s", scoreName, sampleName); +		delete sampleIn; +	} else { +		if (scoreIn) { +			_fileLoaded = kFileNone; +			loaded = _driver->load(*scoreIn); +		} else +			warning("SoundAmiga: missing music file: %s", scoreName); +	} +	delete scoreIn; + +	if (loaded) +		_fileLoaded = (FileType)file; +} + +void SoundAmiga::playTrack(uint8 track) { +	debugC(5, kDebugLevelSound, "SoundAmiga::playTrack(%d)", track); + +	static const byte tempoIntro[] = { 0x46, 0x55, 0x3C, 0x41 }; +	static const byte tempoFinal[] = { 0x78, 0x50 }; +	static const byte tempoIngame[] = { +		0x64, 0x64, 0x64, 0x64, 0x64, 0x73, 0x4B, 0x64, +		0x64, 0x64, 0x55, 0x9C, 0x6E, 0x91, 0x78, 0x84, +		0x32, 0x64, 0x64, 0x6E, 0x3C, 0xD8, 0xAF +	}; +	static const byte loopIngame[] = { +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +		0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, +		0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00 +	}; + +	int score = -1; +	bool loop = false; +	byte volume = 0x40; +	byte tempo = 0; + + +	switch (_fileLoaded) { +	case kFileIntro: +		if (track >= 2 && track < ARRAYSIZE(tempoIntro) + 2) { +			score = track - 2; +			tempo = tempoIntro[score]; +		} +		break; + +	case kFileGame: +		if (track >= 11 && track < ARRAYSIZE(tempoIngame) + 11) { +			score = track - 11; +			loop = loopIngame[score] != 0; +			tempo = tempoIngame[score]; +		} +		break; + +	case kFileFinal: +		// score 0 gets started immediately after loading the music-files with different tempo. +		// we need to define a track-value for the fake call of this function +		if (track >= 2 && track < ARRAYSIZE(tempoFinal) + 2) { +			score = track - 2; +			loop = true; +			tempo = tempoFinal[score]; +		} +		break; + +	default: +		return; +	} + +	if (score >= 0) { +		if (_musicEnabled && _driver->playSong(score, loop)) { +			_driver->setVolume(volume); +			_driver->setTempo(tempo << 4); +			if (!_mixer->isSoundHandleActive(_musicHandle)) +				_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_musicHandle, _driver, -1, Audio::Mixer::kMaxChannelVolume, 0, false); +		} +	} else if (track == 0) +		_driver->stopMusic(); +	else if (track == 1) +		beginFadeOut(); +} + +void SoundAmiga::haltTrack() { +	debugC(5, kDebugLevelSound, "SoundAmiga::haltTrack()"); +	_driver->stopMusic(); +} + +void SoundAmiga::beginFadeOut() { +	debugC(5, kDebugLevelSound, "SoundAmiga::beginFadeOut()"); +	for (int i = 0x3F; i >= 0; --i) { +		_driver->setVolume((byte)i); +		_vm->delay(_vm->tickLength()); +	} + +	_driver->stopMusic(); +	_vm->delay(_vm->tickLength()); +	_driver->setVolume(0x40); +} + +void SoundAmiga::playSoundEffect(uint8 track) { +	debugC(5, kDebugLevelSound, "SoundAmiga::playSoundEffect(%d)", track); +	const byte* tableEntry = 0; +	bool pan = false; + +	switch (_fileLoaded) { +	case kFileFinal: +	case kFileIntro: +		// We only allow playing of sound effects, which are included in the table. +		if (track < 40) { +			tableEntry = &_tableSfxIntro[track * 8]; +			pan = (sfxTableGetPan(tableEntry) != 0); +		} +		break; + +	case kFileGame: +		if (0x61 <= track && track <= 0x63) +			playTrack(track - 0x4F); + +		assert(track < 120); +		if (sfxTableGetNote(&_tableSfxGame[track * 8])) {  +			tableEntry = &_tableSfxGame[track * 8]; +			pan = (sfxTableGetPan(tableEntry) != 0) && (sfxTableGetPan(tableEntry) != 2); +		} +		break; +	default: +		; +	} + +	if (_sfxEnabled && tableEntry) { +		const bool success = _driver->playNote(sfxTableGetNote(tableEntry), sfxTableGetPatch(tableEntry), sfxTableGetDuration(tableEntry), sfxTableGetVolume(tableEntry), pan); +		if (success && !_mixer->isSoundHandleActive(_musicHandle)) +			_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_musicHandle, _driver, -1, Audio::Mixer::kMaxChannelVolume, 0, false); +	} +} + +} // end of namespace Kyra + diff --git a/engines/kyra/sound_intern.h b/engines/kyra/sound_intern.h index 975672b76a..b85b8a2e30 100644 --- a/engines/kyra/sound_intern.h +++ b/engines/kyra/sound_intern.h @@ -37,6 +37,7 @@  namespace Audio {  class PCSpeaker; +class MaxTrax;  } // end of namespace Audio  namespace Kyra { @@ -284,7 +285,34 @@ private:  	static const uint8 _noteTable2[];  }; +class SoundAmiga : public Sound { +public: +	SoundAmiga(KyraEngine_v1 *vm, Audio::Mixer *mixer); +	~SoundAmiga(); + +	virtual kType getMusicType() const { return kAmiga; } //FIXME + +	bool init(); + +	void process() {} +	void loadSoundFile(uint file); +	void loadSoundFile(Common::String) {} + +	void playTrack(uint8 track); +	void haltTrack(); +	void beginFadeOut(); + +	int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx) { return -1; } +	void playSoundEffect(uint8); + +protected: +	Audio::MaxTrax *_driver; +	Audio::SoundHandle _musicHandle; +	enum FileType { kFileNone = -1, kFileIntro = 0, kFileGame = 1, kFileFinal = 2 } _fileLoaded; +	const byte *_tableSfxIntro; +	const byte *_tableSfxGame; +}; +  } // end of namespace Kyra  #endif - diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 4f3824479d..be73df47f7 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -2356,6 +2356,18 @@ const int8 KyraEngine_LoK::_dosTrackMap[] = {  const int KyraEngine_LoK::_dosTrackMapSize = ARRAYSIZE(KyraEngine_LoK::_dosTrackMap); +const int8 KyraEngine_LoK::_amigaTrackMap[] = { +	 0,  1, 32, 26, 31, 30, 33, 33, +	32, 17, 27, 32, 25, 29, 25, 24, +	23, 26, 26, 30, 28, 21, 21, 15, +	 3, 15, 23, 25, 33, 21, 30, 22, +	15,  3, 33, 11, 12, 13, 14, 22, +	22, 22,  3,  3,  3, 23,  3,  3, +	23,  3,  3,  3,  3,  3,  3, 33 +}; + +const int KyraEngine_LoK::_amigaTrackMapSize = ARRAYSIZE(KyraEngine_LoK::_amigaTrackMap); +  // kyra engine v2 static data  const int GUI_v2::_sliderBarsPosition[] = { @@ -3378,4 +3390,172 @@ const int LoLEngine::_outroMonsterScaleTableY[] = {  #endif // ENABLE_LOL +// TODO: fileoffset = 0x32D5C, len = 40 * 8 +extern const byte LoKAmigaSfxIntro[] = { +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x6E, 0x00, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x6E, 0x00, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x6E, 0x00, +	0x3C, 0x13, 0x00, 0x00, 0x1B, 0x91, 0x6E, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x16, 0x00, 0x00, 0x26, 0x77, 0x6E, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x17, 0x00, 0x00, 0x11, 0x98, 0x6E, 0x00, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x6E, 0x00, +	0x3C, 0x18, 0x00, 0x00, 0x22, 0xD1, 0x6E, 0x00, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x6E, 0x00, +	0x45, 0x03, 0x00, 0x00, 0x02, 0x24, 0x6E, 0x00, +	0x3C, 0x16, 0x00, 0x00, 0x26, 0x77, 0x6E, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +// TODO: fileoffset = 0x2C55E, len = 120 * 8 +extern const byte LoKAmigaSfxGame[] = { +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x13, 0x00, 0x00, 0x01, 0x56, 0x78, 0x02, +	0x3C, 0x14, 0x00, 0x00, 0x27, 0x2C, 0x78, 0x02, +	0x3C, 0x15, 0x00, 0x00, 0x1B, 0x91, 0x78, 0x02, +	0x3C, 0x16, 0x00, 0x00, 0x1E, 0x97, 0x78, 0x02, +	0x3C, 0x17, 0x00, 0x00, 0x12, 0x2B, 0x78, 0x02, +	0x3C, 0x16, 0x00, 0x00, 0x1E, 0x97, 0x78, 0x02, +	0x45, 0x03, 0x00, 0x00, 0x02, 0x24, 0x78, 0x02, +	0x3C, 0x16, 0x00, 0x00, 0x1E, 0x97, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x78, 0x02, +	0x2C, 0x04, 0x00, 0x00, 0x09, 0x10, 0x78, 0x02, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x78, 0x02, +	0x3C, 0x1A, 0x00, 0x00, 0x3A, 0xEB, 0x78, 0x02, +	0x25, 0x1B, 0x00, 0x00, 0x13, 0x8B, 0x78, 0x02, +	0x18, 0x03, 0x00, 0x00, 0x0F, 0x52, 0x78, 0x02, +	0x3E, 0x1C, 0x00, 0x00, 0x06, 0x22, 0x78, 0x02, +	0x3B, 0x1C, 0x00, 0x00, 0x07, 0x54, 0x78, 0x02, +	0x16, 0x03, 0x00, 0x00, 0x20, 0x6F, 0x78, 0x02, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x78, 0x02, +	0x3C, 0x1D, 0x00, 0x00, 0x09, 0xEA, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x14, 0x00, 0x00, 0x27, 0x2C, 0x78, 0x02, +	0x3C, 0x1E, 0x00, 0x00, 0x03, 0x6E, 0x78, 0x02, +	0x3C, 0x17, 0x00, 0x00, 0x12, 0x2B, 0x78, 0x02, +	0x4E, 0x0B, 0x00, 0x00, 0x09, 0x91, 0x78, 0x02, +	0x47, 0x1B, 0x00, 0x00, 0x02, 0xBC, 0x78, 0x02, +	0x4C, 0x1B, 0x00, 0x00, 0x02, 0x11, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x13, 0x00, 0x00, 0x01, 0x56, 0x78, 0x02, +	0x3C, 0x13, 0x00, 0x00, 0x01, 0x56, 0x78, 0x02, +	0x3C, 0x1F, 0x00, 0x00, 0x0E, 0x9E, 0x78, 0x02, +	0x3C, 0x20, 0x00, 0x00, 0x01, 0x0C, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x78, 0x02, +	0x3C, 0x21, 0x00, 0x00, 0x0F, 0x7C, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x2A, 0x0B, 0x00, 0x00, 0x4C, 0x47, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x1B, 0x00, 0x00, 0x05, 0x28, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x2C, 0x04, 0x00, 0x00, 0x09, 0x10, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x22, 0x00, 0x00, 0x0A, 0xEE, 0x78, 0x02, +	0x3C, 0x16, 0x00, 0x00, 0x1E, 0x97, 0x78, 0x02, +	0x3C, 0x15, 0x00, 0x00, 0x1B, 0x91, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x14, 0x00, 0x00, 0x27, 0x2C, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x22, 0x00, 0x00, 0x0A, 0xEE, 0x78, 0x02, +	0x3C, 0x14, 0x00, 0x00, 0x27, 0x2C, 0x78, 0x02, +	0x32, 0x23, 0x00, 0x00, 0x14, 0x19, 0x9C, 0x02, +	0x3C, 0x19, 0x00, 0x00, 0x17, 0x1C, 0x78, 0x02, +	0x3C, 0x14, 0x00, 0x00, 0x27, 0x2C, 0x78, 0x02, +	0x3E, 0x1C, 0x00, 0x00, 0x06, 0x22, 0x78, 0x02, +	0x43, 0x13, 0x00, 0x00, 0x02, 0x01, 0x78, 0x02, +	0x3C, 0x24, 0x00, 0x00, 0x12, 0x43, 0x5A, 0x02, +	0x3E, 0x20, 0x00, 0x00, 0x00, 0xEE, 0x78, 0x02, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x78, 0x02, +	0x29, 0x04, 0x00, 0x00, 0x19, 0xEA, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x20, 0x00, 0x00, 0x01, 0x0C, 0x78, 0x02, +	0x3C, 0x25, 0x00, 0x00, 0x30, 0xB6, 0x78, 0x02, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x16, 0x00, 0x00, 0x1E, 0x97, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x1A, 0x00, 0x00, 0x3A, 0xEB, 0x78, 0x02, +	0x1B, 0x04, 0x00, 0x00, 0x39, 0xF3, 0x78, 0x02, +	0x30, 0x23, 0x00, 0x00, 0x16, 0x99, 0x50, 0x02, +	0x3C, 0x15, 0x00, 0x00, 0x1B, 0x91, 0x78, 0x02, +	0x29, 0x06, 0x00, 0x00, 0x19, 0xEA, 0x50, 0x02, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x78, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x1A, 0x00, 0x00, 0x3A, 0xEB, 0x78, 0x02, +	0x3C, 0x19, 0x00, 0x00, 0x25, 0x2C, 0x78, 0x02, +	0x3C, 0x26, 0x00, 0x00, 0x07, 0x13, 0x78, 0x02, +	0x3C, 0x26, 0x00, 0x00, 0x07, 0x13, 0x78, 0x02, +	0x3C, 0x14, 0x00, 0x00, 0x27, 0x2C, 0x78, 0x02, +	0x30, 0x23, 0x00, 0x00, 0x16, 0x99, 0x50, 0x02, +	0x30, 0x23, 0x00, 0x00, 0x16, 0x99, 0x50, 0x02, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3C, 0x13, 0x00, 0x00, 0x01, 0x56, 0x78, 0x02 +}; +  } // End of namespace Kyra diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h deleted file mode 100644 index f935bdff0d..0000000000 --- a/engines/sci/detection_tables.h +++ /dev/null @@ -1,2918 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * 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 - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -namespace Sci { - -#define FANMADE_L(name, resMapMd5, resMapSize, resMd5, resSize, lang) \ -	{{"sci-fanmade", name, { \ -		{"resource.map", 0, resMapMd5, resMapSize}, \ -		{"resource.001", 0, resMd5, resSize}, \ -		{NULL, 0, NULL, 0}}, lang, Common::kPlatformPC, 0, GUIO_NOSPEECH}, \ -		0 \ -	} - -#define FANMADE(name, resMapMd5, resMapSize, resMd5, resSize) FANMADE_L(name, resMapMd5, resMapSize, resMd5, resSize, Common::EN_ANY) - -using Common::GUIO_NONE; -using Common::GUIO_NOSPEECH; - -// Game descriptions -static const struct SciGameDescription SciGameDescriptions[] = { -	// Astro Chicken - English DOS -	// SCI interpreter version 0.000.453 -	{{"astrochicken", "", { -		{"resource.map", 0, "f3d1be7752d30ba60614533d531e2e98", 474}, -		{"resource.001", 0, "6fd05926c2199af0af6f72f90d0d7260", 126895}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Castle of Dr. Brain - English Amiga (from www.back2roots.org) -	// Executable scanning reports "1.005.000" -	// SCI interpreter version 1.000.510 -	{{"castlebrain", "", { -		{"resource.map", 0, "9f9fb826aa7e944b95eadbf568244a68", 2766}, -		{"resource.000", 0, "0efa8409c43d42b32642f96652d3230d", 314773}, -		{"resource.001", 0, "3fb02ce493f6eacdcc3713851024f80e", 559540}, -		{"resource.002", 0, "d226d7d3b4f77c4a566913fc310487fc", 792380}, -		{"resource.003", 0, "d226d7d3b4f77c4a566913fc310487fc", 464348}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Castle of Dr. Brain - German Amiga (from www.back2roots.org) -	// Executable scanning reports "1.005.001" -	// SCI interpreter version 1.000.510 -	{{"castlebrain", "", { -		{"resource.map", 0, "8e60424682db52a982bcc3535a7e86f3", 2796}, -		{"resource.000", 0, "0efa8409c43d42b32642f96652d3230d", 332468}, -		{"resource.001", 0, "4e0836fadc324316c1a418125709ba45", 569057}, -		{"resource.002", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 826309}, -		{"resource.003", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 493638}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Castle of Dr. Brain - English DOS Non-Interactive Demo -	// SCI interpreter version 1.000.005 -	{{"castlebrain", "Demo", { -		{"resource.map", 0, "467bb5e3224bb54640c3280032aebff5", 633}, -		{"resource.000", 0, "9780f040d58182994e22d2e34fab85b0", 67367}, -		{"resource.001", 0, "2af49dbd8f2e1db4ab09f9310dc91259", 570553}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Castle of Dr. Brain - English DOS Floppy (from jvprat) -	// Executable scanning reports "1.000.044", Floppy label reports "1.0, 10.30.91", VERSION file reports "1.000" -	// SCI interpreter version 1.000.510 -	{{"castlebrain", "", { -		{"resource.map", 0, "1302ceb141d44b05a42723791b2d84c6", 2739}, -		{"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 346731}, -		{"resource.001", 0, "d2f5a1be74ed963fa849a76892be5290", 794832}, -		{"resource.002", 0, "c0c29c51af66d65cb53f49e785a2d978", 1280907}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Castle of Dr. Brain - English DOS Floppy 1.1 -	{{"castlebrain", "", { -		{"resource.map", 0, "f77728304c70017c54793eb6ca648174", 2745}, -		{"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 347071}, -		{"resource.001", 0, "13e81e1839cd7b216d2bb5615c1ca160", 796776}, -		{"resource.002", 0, "930e416bec196b9703a331d81b3d66f2", 1283812}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Castle of Dr. Brain - Spanish DOS -	// SCI interpreter version 1.000.510 -	{{"castlebrain", "", { -		{"resource.map", 0, "5738c163e014bbe046474de009020b82", 2727}, -		{"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 1197694}, -		{"resource.001", 0, "735be4e58957180cfc807d5e18fdffcd", 1433302}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Christmas Card 1988 - English DOS -	// SCI interpreter version 0.000.294 -	{{"christmas1988", "", { -		{"resource.map", 0, "39485580d34a72997f3d5b3aba4d24f1", 426}, -		{"resource.001", 0, "11391434f41c834090d7a1e9488ce936", 129739}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Christmas Card 1990: The Seasoned Professional - English DOS (16 Colors) -	// SCI interpreter version 1.000.172 -	{{"christmas1990", "16 Colors", { -		{"resource.map", 0, "8f656714a05b94423ac6eb10ee8797d0", 600}, -		{"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 272629}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Christmas Card 1990: The Seasoned Professional - English DOS (256 Colors) -	// SCI interpreter version 1.000.174 -	{{"christmas1990", "256 Colors", { -		{"resource.map", 0, "44b8f45b841b9b5e17e939a35e443988", 600}, -		{"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 335362}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Christmas Card 1992 - English DOS -	// SCI interpreter version 1.001.055 -	{{"christmas1992", "", { -		{"resource.map", 0, "f1f8c8a8443f523422af70b4ec85b71c", 318}, -		{"resource.000", 0, "62fb9256f8e7e6e65a6875efdb7939ac", 203396}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Codename: Iceman - English Amiga (from www.back2roots.org) -	// Executable scanning reports "1.002.031" -	// SCI interpreter version 0.000.685 -	{{"iceman", "", { -		{"resource.map", 0, "035829b391709a4e542d7c7b224625f6", 6000}, -		{"resource.000", 0, "b1bccd827453d4cb834bfd5b45bef63c", 73682}, -		{"resource.001", 0, "ede5a0e1e2a80fb629dae72c72f33d37", 293145}, -		{"resource.002", 0, "36670a917550757d57df84c96cf9e6d9", 469387}, -		{"resource.003", 0, "d97a96f1ab91b41cf46a02cc89b0a04e", 619219}, -		{"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 713382}, -		{"resource.005", 0, "605b67a9ef199a9bb015745e7c004cf4", 478384}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Codename: Iceman - English DOS Non-Interactive Demo -	// Executable scanning reports "0.000.685" -	{{"iceman", "Demo", { -		{"resource.map", 0, "782974f29d8a824782d2d4aea39964e3", 1056}, -		{"resource.001", 0, "d4b75e280d1c3a97cfef1b0bebff387c", 573647}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Codename: Iceman - English DOS (from jvprat) -	// Executable scanning reports "0.000.685", Floppy label reports "1.033, 6.8.90", VERSION file reports "1.033" -	// SCI interpreter version 0.000.685 -	{{"iceman", "", { -		{"resource.map", 0, "a18f3cef4481a81d3415fb87a754343e", 5700}, -		{"resource.000", 0, "b1bccd827453d4cb834bfd5b45bef63c", 26989}, -		{"resource.001", 0, "32b351072fccf76fc82234d73d28c08b", 438872}, -		{"resource.002", 0, "36670a917550757d57df84c96cf9e6d9", 566549}, -		{"resource.003", 0, "d97a96f1ab91b41cf46a02cc89b0a04e", 624303}, -		{"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 670883}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Codename: Iceman - English DOS (from FRG) -	// SCI interpreter version 0.000.668 -	{{"iceman", "", { -		{"resource.map", 0, "554b44b79b0e9a7fc59f66dda0daac02", 5670}, -		{"resource.000", 0, "b1bccd827453d4cb834bfd5b45bef63c", 26974}, -		{"resource.001", 0, "005bd332d4b0f9d8e99d3b905223a332", 438501}, -		{"resource.002", 0, "250b859381ebf2bf8922bd99683b0cc1", 566464}, -		{"resource.003", 0, "dc7c5280e7acfaffe6ef2a6c963c5f94", 622118}, -		{"resource.004", 0, "64f342463f6f35ba71b3509ef696ae3f", 669188}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Conquests of Camelot - English Amiga (from www.back2roots.org) -	// Executable scanning reports "1.002.030" -	// SCI interpreter version 0.000.685 -	{{"camelot", "", { -		{"resource.map", 0, "51aba42f8e63b219755d4372ea424509", 6654}, -		{"resource.000", 0, "dfadf0b4c9fb44ce55570149856c302d", 128100}, -		{"resource.001", 0, "67391de361b9347f123ac0899b4b91f7", 300376}, -		{"resource.002", 0, "8c7f12b2c38d225d4c7121b30ea1b4d2", 605334}, -		{"resource.003", 0, "82a73e7572e7ee627429bb5111ff82ca", 672392}, -		{"resource.004", 0, "6821dc97cf643ba521a4e840dda3c58b", 647410}, -		{"resource.005", 0, "c6e551bdc24f0acc193159038d4ca767", 605882}, -		{"resource.006", 0, "8f880a536908ab496bbc552f7f5c3738", 585255}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Conquests of Camelot - English DOS Non-Interactive Demo -	// SCI interpreter version 0.000.668 -	{{"camelot", "Demo", { -		{"resource.map", 0, "f4cd75c15be75e04cdca3acda2c0b0ea", 468}, -		{"resource.001", 0, "4930708722f34bfbaa4945fb08f55f61", 232523}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Conquests of Camelot - English DOS (from jvprat) -	// Executable scanning reports "0.000.685", Floppy label reports "1.001, 0.000.685", VERSION file reports "1.001.000" -	// SCI interpreter version 0.000.685 -	{{"camelot", "", { -		{"resource.map", 0, "95eca3991906dfd7ed26d193df07596f", 7278}, -		{"resource.001", 0, "8e1a3a8c588007404b532b8dfacc1460", 596774}, -		{"resource.002", 0, "8e1a3a8c588007404b532b8dfacc1460", 722250}, -		{"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 723712}, -		{"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 729143}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Conquests of Camelot - English DOS -	// SCI interpreter version 0.000.685 -	{{"camelot", "", { -		{"resource.map", 0, "86bffb2a393b7a5d8de45e735091f037", 9504}, -		{"resource.001", 0, "8e1a3a8c588007404b532b8dfacc1460", 212461}, -		{"resource.002", 0, "8e1a3a8c588007404b532b8dfacc1460", 317865}, -		{"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 359145}, -		{"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 345180}, -		{"resource.005", 0, "8e1a3a8c588007404b532b8dfacc1460", 345734}, -		{"resource.006", 0, "8e1a3a8c588007404b532b8dfacc1460", 332446}, -		{"resource.007", 0, "8e1a3a8c588007404b532b8dfacc1460", 358182}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Conquests of the Longbow - English Amiga (from www.back2roots.org) -	// Executable scanning reports "1.005.001" -	// SCI interpreter version 1.000.510 -	{{"longbow", "", { -		{"resource.map", 0, "6204f3d00c0f6c0f5f95a29a4190f2f9", 6048}, -		{"resource.000", 0, "8d11c744b4a51e7a8ceac687a46f08ca", 830333}, -		{"resource.001", 0, "76caf8593e065a98c8ab4a6e2c7dbafc", 839008}, -		{"resource.002", 0, "eb312373045906b54a3181bebaf6651a", 733145}, -		{"resource.003", 0, "7fe3b3372d7fdda60045807e9c8e4867", 824554}, -		{"resource.004", 0, "d1038c75d85a6650d48e07d174a6a913", 838175}, -		{"resource.005", 0, "1c3804e56b114028c5873a35c2f06d13", 653002}, -		{"resource.006", 0, "f9487732289a4f4966b4e34eea413325", 842817}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Conquests of the Longbow - English DOS -	// SCI interpreter version 1.000.510 -	{{"longbow", "", { -		{"resource.map", 0, "36d3b81ff75b67dd4d27b7f5d3166503", 6261}, -		{"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 1096767}, -		{"resource.001", 0, "d4c299213f8d799da1492680d12d0fb3", 1133226}, -		{"resource.002", 0, "7f6ce331219d58d5087731e4475ab4f1", 1128555}, -		{"resource.003", 0, "21ebe6b39b57a73fc449f67f013765aa", 972635}, -		{"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1064637}, -		{"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1154950}, -		{"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1042966}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Conquests of the Longbow - English DOS Floppy (from jvprat) -	// Executable scanning reports "1.000.168", Floppy label reports "1.1, 1.13.92", VERSION file reports "1.1" -	// SCI interpreter version 1.000.510 -	{{"longbow", "", { -		{"resource.map", 0, "247f955865572569342751de47e861ab", 6027}, -		{"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 1297120}, -		{"resource.001", 0, "1e6084a19f7a6c50af88d3a9b32c411e", 1366155}, -		{"resource.002", 0, "7f6ce331219d58d5087731e4475ab4f1", 1234743}, -		{"resource.003", 0, "1867136d01ece57b531032d466910522", 823686}, -		{"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1261462}, -		{"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284720}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Conquests of the Longbow - English DOS -	// SCI interpreter version 1.000.510 -	{{"longbow", "", { -		{"resource.map", 0, "737c6f83a1ee601727ff026898f19fa1", 6045}, -		{"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 1296607}, -		{"resource.001", 0, "1e6084a19f7a6c50af88d3a9b32c411e", 1379267}, -		{"resource.002", 0, "7f6ce331219d58d5087731e4475ab4f1", 1234140}, -		{"resource.003", 0, "1867136d01ece57b531032d466910522", 823610}, -		{"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1260237}, -		{"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284609}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Conquests of the Longbow EGA - English DOS -	// SCI interpreter version 1.000.510 -	{{"longbow", "EGA", { -	      {"resource.map", 0, "7676ec9f08967d7a9a7724f5170456e0", 6261}, -	      {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 718161}, -	      {"resource.001", 0, "3c3735caa34fa3f261a9552831bb43ed", 705680}, -	      {"resource.002", 0, "7025b87e735b1df3f0e9488a621f4333", 700633}, -	      {"resource.003", 0, "eaca7933e8e56bea22b42f7fd5d7a8a7", 686510}, -	      {"resource.004", 0, "b7bb35c027bb424ecefcd122768e5e60", 705631}, -	      {"resource.005", 0, "58942b1aa6d6ffeb66e9f8897fd4435f", 469243}, -	      {"resource.006", 0, "8c767b3939add63d11274065e46aad04", 713158}, -	      {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -	      0, -	}, - -	// Conquests of the Longbow - English DOS Non-Interactive Demo -	// SCI interpreter version 1.000.510 -	{{"longbow", "Demo", { -		{"resource.map", 0, "cbc5cb73341de1bff1b1e20a640af220", 588}, -		{"resource.001", 0, "f05a20cc07eee85da8e999d0ac0f596b", 869916}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Conquests of the Longbow - German DOS (suplied by markcoolio in bug report #2727681) -	// SCI interpreter version 1.000.510 -	{{"longbow", "", { -		{"resource.map", 0, "7376b7a07f8bd3a8ab8d67595d3f5b51", 6285}, -		{"resource.000", 0, "ee39f92e006142424cf9209329e727c6", 977281}, -		{"resource.001", 0, "d4c299213f8d799da1492680d12d0fb3", 1167657}, -		{"resource.002", 0, "7f6ce331219d58d5087731e4475ab4f1", 1172521}, -		{"resource.003", 0, "a204de2a083a7770ff455a838210a678", 1165249}, -		{"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1101869}, -		{"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1176914}, -		{"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1123585}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Eco Quest - English DOS Non-Interactive Demo (from FRG) -	// Executable scanning reports "x.yyy.zzz" -	// SCI interpreter version 1.001.069 (just a guess) -	{{"ecoquest", "Demo", { -		{"resource.map", 0, "c819e171359b7c95f4c13b846d5c034e", 873}, -		{"resource.001", 0, "baf9393a9bfa73098adb501e5bc5487b", 657518}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Eco Quest - English DOS CD 1.1 -	// SCI interpreter version 1.001.064 -	{{"ecoquest", "CD", { -		{"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804}, -		{"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Eco Quest - English DOS Floppy -	// SCI interpreter version 1.000.510 -	{{"ecoquest", "Floppy", { -		{"resource.map", 0, "704367225929a88aad281ac72844ddac", 4053}, -		{"resource.000", 0, "241b98d3903f6a5b872baa19b80aef3b", 1099239}, -		{"resource.001", 0, "96d4435d24c01f1c1675e46457604c5f", 1413719}, -		{"resource.002", 0, "28fe9b4f0567e71feb198bc9f3a2c605", 1241816}, -		{"resource.003", 0, "f3146df0ad4297f5ce35aa8c4753bf6c", 586832}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Eco Quest - English DOS Floppy -	// SCI interpreter version 1.000.510 -	{{"ecoquest", "Floppy", { -		{"resource.map", 0, "f77baec05fae76707205f5be6534a7f3", 4059}, -		{"resource.000", 0, "241b98d3903f6a5b872baa19b80aef3b", 858490}, -		{"resource.001", 0, "2fed7451bca81b0c891eed1a956f2263", 1212161}, -		{"resource.002", 0, "323b3b12f43d53f27d259beb225f0aa7", 1129316}, -		{"resource.003", 0, "83ac03e4bddb2c1ac2d36d2a587d0536", 1145616}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Eco Quest - German DOS Floppy (supplied by markcoolio in bug report #2723744) -	// SCI interpreter version 1.000.510 -	{{"ecoquest", "Floppy", { -		{"resource.map", 0, "7a9b43bf27dc000ac8559ecbe824b659", 4395}, -		{"resource.000", 0, "99b73d40403a51c7e60d01df0d6cd34a", 998227}, -		{"resource.001", 0, "2fed7451bca81b0c891eed1a956f2263", 1212060}, -		{"resource.002", 0, "02d7d0411f7903aacb3bc8b0f8ca8a9a", 1202581}, -		{"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1175835}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Eco Quest - Spanish DOS Floppy (from jvprat) -	// Executable scanning reports "1.ECO.013", VERSION file reports "1.000, 11.12.92" -	// SCI interpreter version 1.000.510 -	{{"ecoquest", "Floppy", { -		{"resource.map", 0, "82e6b1e3bdb2f064b18380009df7b345", 4395}, -		{"resource.000", 0, "0b12a91c935e385308af8d17811deded", 1004085}, -		{"resource.001", 0, "2fed7451bca81b0c891eed1a956f2263", 1212060}, -		{"resource.002", 0, "2d21a1d2dcbffa551552e3e0725d2284", 1186033}, -		{"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1174993}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Eco Quest - French DOS Floppy (from Strangerke) -	// SCI interpreter version 1.ECO.013 -	{{"ecoquest", "Floppy", { -		{"resource.map", 0, "67742945cd59b896d9f22a549f605217", 4407}, -		{"resource.000", 0, "0b12a91c935e385308af8d17811deded", 973723}, -		{"resource.001", 0, "fc7fba54b6bb88fd7e9c229636599aa9", 1205841}, -		{"resource.002", 0, "b836c6ee9de67d814ac5d1b05f5b9858", 1173872}, -		{"resource.003", 0, "f8f767f9d6351432621c6e54c1b2ba8c", 1141520}, -		{NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Eco Quest 2 - English DOS Non-Interactive Demo -	// SCI interpreter version 1.001.055 -	{{"ecoquest2", "Demo", { -		{"resource.map", 0, "607cfa0d8a03b7d348c06ee727e3d939", 1321}, -		{"resource.000", 0, "dd6f614c43c029f063e93cd243af90a4", 525992}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Eco Quest 2 - English DOS Floppy (supplied by markcoolio in bug report #2723761) -	// SCI interpreter version 1.001.065 -	{{"ecoquest2", "Floppy", { -		{"resource.map", 0, "28fb7b6abb9fc1cb8882d7c2e701b63f", 5658}, -		{"resource.000", 0, "cc1d17e5637528dbe4a812699e1cbfc6", 4208192}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Eco Quest 2 - French DOS Floppy (from Strangerke) -	// SCI interpreter version 1.001.081 -	{{"ecoquest2", "Floppy", { -		{"resource.map", 0, "c22ab8b33c339c138b6b1697b77b9e79", 5588}, -		{"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4231946}, -		{NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Freddy Pharkas - English DOS demo (from FRG) -	// SCI interpreter version 1.001.069 -	{{"freddypharkas", "Demo", { -		{"resource.map", 0, "97aa9fcfe84c9993a64debd28c32393a", 1909}, -		{"resource.000", 0, "5ea8e7a3ea10cce6efd5c106dc62fd8c", 867724}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Freddy Pharkas - English CD (from FRG) -	// SCI interpreter version 1.001.132 -	{{"freddypharkas", "CD", { -		{"resource.map", 0, "d46b282f228a67ba13bd4b4009e95f8f", 6058}, -		{"resource.000", 0, "ee3c64ffff0ba9fb08bea2624631c598", 5490246}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Freddy Pharkas - English DOS Floppy (updated information from markcoolio in bug reports #2723773 and #2724720) -	// Executable scanning reports "1.cfs.081" -	// SCI interpreter version 1.001.132 (just a guess) -	{{"freddypharkas", "Floppy", { -		{"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, -		{"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, -		{"resource.msg", 0, "554f65315d851184f6e38211489fdd8f", -1}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Freddy Pharkas - German DOS Floppy (from Tobis87, updated information from markcoolio in bug reports #2723772 and #2724720) -	// Executable scanning reports "1.cfs.081" -	// SCI interpreter version 1.001.132 (just a guess) -	{{"freddypharkas", "", { -		{"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, -		{"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, -		{"resource.msg", 0, "304b5a5781800affd2235152a5794fa8", -1}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Freddy Pharkas - Spanish DOS (from jvprat) -	// Executable scanning reports "1.cfs.081", VERSION file reports "1.000, March 30, 1995" -	// SCI interpreter version 1.001.132 (just a guess) -	{{"freddypharkas", "CD", { -		{"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, -		{"resource.000", 0, "fed4808fdb72486908ac7ad0044b14d8", 1456640}, -		{"resource.001", 0, "15298fac241b5360763bfb68add1db07", 1456640}, -		{"resource.002", 0, "419dbd5366f702b4123dedbbb0cffaae", 1456640}, -		{"resource.003", 0, "05acdc256c742e79c50b9fe7ec2cc898", 863310}, -		{"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Freddy Pharkas - Spanish DOS (from jvprat) -	// Executable scanning reports "1.cfs.081", VERSION file reports "1.000, March 30, 1995" -	// SCI interpreter version 1.001.132 (just a guess) -	{{"freddypharkas", "Floppy", { -		{"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, -		{"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, -		{"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Freddy Pharkas - English DOS CD Demo -	// SCI interpreter version 1.001.095 -	{{"freddypharkas", "CD Demo", { -		{"resource.map", 0, "a62a7eae85dd1e6b07f39662b278437e", 1918}, -		{"resource.000", 0, "4962a3c4dd44e36e78ea4a7a374c2220", 957382}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NONE}, -		0 -	}, - -	// Fun Seeker's Guide - English DOS -	// SCI interpreter version 0.000.506 -	{{"funseeker", "", { -		{"resource.map", 0, "7ee6859ef74314f6d91938c3595348a9", 282}, -		{"resource.001", 0, "f1e680095424e31f7fae1255d36bacba", 40692}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Gabriel Knight - English DOS CD Demo -	// SCI interpreter version 1.001.092 -	{{"gk1", "CD Demo", { -		{"resource.map", 0, "39645952ae0ed8072c7e838f31b75464", 2490}, -		{"resource.000", 0, "eb3ed7477ca4110813fe1fcf35928561", 1718450}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NONE}, -		0 -	}, - -#ifdef ENABLE_SCI32 -	// Gabriel Knight - English DOS Floppy -	// SCI interpreter version 2.000.000 -	{{"gk1", "", { -		{"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10783}, -		{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Gabriel Knight - English DOS Floppy (supplied my markcoolio in bug report #2723777) -	// SCI interpreter version 2.000.000 -	{{"gk1", "", { -		{"resource.map", 0, "65e8c14092e4c9b3b3538b7602c8c5ec", 10783}, -		{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Gabriel Knight - German DOS Floppy (supplied my markcoolio in bug report #2723775) -	// SCI interpreter version 2.000.000 -	{{"gk1", "", { -		{"resource.map", 0, "ad6508b0296b25c07b1f58828dc33696", 10789}, -		{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13077029}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Gabriel Knight - English DOS CD (from jvprat) -	// Executable scanning reports "2.000.000", VERSION file reports "01.100.000" -	{{"gk1", "CD", { -		{"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996}, -		{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Gabriel Knight - German DOS CD (from Tobis87) -	// SCI interpreter version 2.000.000 -	{{"gk1", "CD", { -		{"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392}, -		{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Gabriel Knight - Spanish DOS CD (from jvprat) -	// Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995" -	{{"gk1", "CD", { -		{"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404}, -		{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Gabriel Knight 2 - English Windows Non-Interactive Demo -	// Executable scanning reports "2.100.002" -	{{"gk2", "Demo", { -		{"resource.map", 0, "e0effce11c4908f4b91838741716c83d", 1351}, -		{"resource.000", 0, "d04cfc7f04b6f74d13025378be49ec2b", 4640330}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, -	// Gabriel Knight 2 - English DOS (from jvprat) -	// Executable scanning reports "2.100.002", VERSION file reports "1.1" -	{{"gk2", "", { -		{"resmap.001", 0, "1b8bf6a23b37ed67358eb825fc687260", 2776}, -		{"ressci.001", 0, "24463ae235b1afbbc4ff5e2ed1b8e3b2", 50496082}, -		{"resmap.002", 0, "2028230674bb54cd24370e0745e7a9f4", 1975}, -		{"ressci.002", 0, "f0edc1dcd704bd99e598c5a742dc7150", 42015676}, -		{"resmap.003", 0, "51f3372a2133c406719dafad86369be3", 1687}, -		{"ressci.003", 0, "86cb3f3d176994e7f8a9ad663a4b907e", 35313750}, -		{"resmap.004", 0, "0f6e48f3e84e867f7d4a5215fcff8d5c", 2719}, -		{"ressci.004", 0, "4f30aa6e6f895132402c8652f9e1d741", 58317316}, -		{"resmap.005", 0, "2dac0e232262b4a51271fd28559b3e70", 2065}, -		{"ressci.005", 0, "14b62d4a3bddee57a03cb1495a798a0f", 38075705}, -		{"resmap.006", 0, "ce9359037277b7d7976da185c2fa0aad", 2977}, -		{"ressci.006", 0, "8e44e03890205a7be12f45aaba9644b4", 60659424}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, -#endif // ENABLE_SCI32 - -	// Hoyle 1 - English DOS (supplied by wibble92 in bug report #2644547) -	// SCI interpreter version 0.000.530 -	{{"hoyle1", "", { -		{"resource.map", 0, "9de9aa6d23569b3c8bf798503cf1216a", 7818}, -		{"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 162783}, -		{"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 342309}, -		{"resource.003", 0, "e0dd44069a62a463fd124974b915f10d", 328912}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Hoyle 1 - English DOS (supplied by merkur in bug report #2719227) -	// SCI interpreter version 0.000.530 -	{{"hoyle1", "", { -		{"resource.map", 0, "1034a218943d12f1f36e753fa10c95b8", 4386}, -		{"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518308}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -#if 0 // TODO: unknown if these files are corrupt -	// Hoyle 1 - English Amiga (from www.back2roots.org) -	// SCI interpreter version 0.000.519 - FIXME: some have 0.000.530, others x.yyy.zzz -	{{"hoyle1", "", { -		{"resource.map", 0, "2a72b1aba65fa6e339370eb86d8601d1", 5166}, -		{"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 218755}, -		{"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 439502}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, -#endif - -	// Hoyle 2 - English DOS -	// SCI interpreter version 0.000.572 -	{{"hoyle2", "", { -		{"resource.map", 0, "4f894d203f64aa23d9ff64d30ae36926", 2100}, -		{"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 98138}, -		{"resource.002", 0, "8f2dd70abe01112eca464cda818b5eb6", 196631}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Hoyle 2 - English Amiga (from www.back2roots.org) -	// Executable scanning reports "1.002.032" -	// SCI interpreter version 0.000.685 -	{{"hoyle2", "", { -		{"resource.map", 0, "62ed48d20c580e5a98f102f7cd93706a", 1356}, -		{"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 222704}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -#if 0 // TODO: unknown if these files are corrupt -	// Hoyle 3 - English Amiga (from www.back2roots.org) -	// Executable scanning reports "1.005.000" -	// SCI interpreter version 1.000.510 -	{{"hoyle3", "", { -		{"resource.map", 0, "f1f158e428398cb87fc41fb4aa8c2119", 2088}, -		{"resource.000", 0, "595b6039ea1356e7f96a52c58eedcf22", 355791}, -		{"resource.001", 0, "143df8aef214a2db34c2d48190742012", 632273}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, -#endif - -	// Hoyle 3 - English DOS Non-Interactive Demo -	// Executable scanning reports "x.yyy.zzz" -	// SCI interpreter version 1.000.510 (just a guess) -	{{"hoyle3", "Demo", { -		{"resource.map", 0, "0d06cacc87dc21a08cd017e73036f905", 735}, -		{"resource.001", 0, "24db2bccda0a3c43ac4a7b5edb116c7e", 797678}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Hoyle 3 - English DOS Floppy (from jvprat) -	// Executable scanning reports "x.yyy.zzz", Floppy label reports "1.0, 11.2.91", VERSION file reports "1.000" -	// SCI interpreter version 1.000.510 (just a guess) -	{{"hoyle3", "", { -		{"resource.map", 0, "7216a2972f9c595c45ab314941628e43", 2247}, -		{"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 541845}, -		{"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 845795}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Hoyle 4 - English DOS Demo -	// SCI interpreter version 1.001.200 (just a guess) -	{{"hoyle4", "Demo", { -		{"resource.map", 0, "662087cb383e52e3cc4ae7ecb10e20aa", 938}, -		{"resource.000", 0, "24c10844792c54d476d272213cbac300", 675252}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -#if 0 -	// Jones in the Fast Lane - English DOS -	// SCI interpreter version 1.000.172 -	{{"jones", "", { -		{"resource.map", 0, "65cbe19b36fffc71c8e7b2686bd49ad7", 1800}, -		{"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 313476}, -		{"resource.002", 0, "b86daa3ba2784d1502da881eedb80d9b", 719747}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, -#endif - -	// King's Quest 1 SCI Remake - English Amiga (from www.back2roots.org) -	// Executable scanning reports "1.003.007" -	// SCI interpreter version 0.001.010 -	{{"kq1sci", "SCI Remake", { -		{"resource.map", 0, "37ed1a05eb719629eba15059c2eb6cbe", 6798}, -		{"resource.001", 0, "9ae2a13708d691cd42f9129173c4b39d", 266621}, -		{"resource.002", 0, "9ae2a13708d691cd42f9129173c4b39d", 795123}, -		{"resource.003", 0, "9ae2a13708d691cd42f9129173c4b39d", 763224}, -		{"resource.004", 0, "9ae2a13708d691cd42f9129173c4b39d", 820443}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 1 SCI Remake - English DOS Non-Interactive Demo -	// Executable scanning reports "S.old.010" -	{{"kq1sci", "SCI Remake Demo", { -		{"resource.map", 0, "59b13619078bd47011421468959ee5d4", 954}, -		{"resource.001", 0, "4cfb9040db152868f7cb6a1e8151c910", 296555}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 1 SCI Remake - English DOS (from the King's Quest Collection) -	// Executable scanning reports "S.old.010", VERSION file reports "1.000.051" -	// SCI interpreter version 0.000.999 -	{{"kq1sci", "SCI Remake", { -		{"resource.map", 0, "7fe9399a0bec84ca5727309778d27f07", 5790}, -		{"resource.001", 0, "fed9e0072ffd511d248674e60dee2099", 555439}, -		{"resource.002", 0, "fed9e0072ffd511d248674e60dee2099", 714062}, -		{"resource.003", 0, "fed9e0072ffd511d248674e60dee2099", 717478}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 4 - English Amiga (from www.back2roots.org) -	// Executable scanning reports "1.002.032" -	// SCI interpreter version 0.000.685 -	{{"kq4sci", "", { -		{"resource.map", 0, "f88dd267fb9504d40a04d599c048d42b", 6354}, -		{"resource.000", 0, "77615c595388acf3d1df8e107bfb6b52", 138523}, -		{"resource.001", 0, "52c2231765eced34faa7f7bcff69df83", 44751}, -		{"resource.002", 0, "fb351106ec865fad9af5d78bd6b8e3cb", 663629}, -		{"resource.003", 0, "fd16c9c223f7dc5b65f06447615224ff", 683016}, -		{"resource.004", 0, "3fac034c7d130e055d05bc43a1f8d5f8", 549993}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 4 - English DOS Non-Interactive Demo -	// Executable scanning reports "0.000.494" -	{{"kq4sci", "Demo", { -		{"resource.map", 0, "992ac7cc31d3717fe53818a9bb6d1dae", 594}, -		{"resource.001", 0, "143e1c14f15ad0fbfc714f648a65f661", 205330}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// King's Quest 4 - English DOS (from the King's Quest Collection) -	// Executable scanning reports "0.000.502" -	// SCI interpreter version 0.000.502 -	{{"kq4sci", "", { -		{"resource.map", 0, "3164a39790b599c954ecf716d0b32be8", 7476}, -		{"resource.001", 0, "77615c595388acf3d1df8e107bfb6b52", 452523}, -		{"resource.002", 0, "77615c595388acf3d1df8e107bfb6b52", 536573}, -		{"resource.003", 0, "77615c595388acf3d1df8e107bfb6b52", 707591}, -		{"resource.004", 0, "77615c595388acf3d1df8e107bfb6b52", 479562}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// King's Quest 4 - English DOS -	// SCI interpreter version 0.000.274 -	{{"kq4sci", "", { -		{"resource.map", 0, "adbe267662a5915d3c89c9075ec8cf3e", 9474}, -		{"resource.001", 0, "851a62d00972dc4002f472cc0d84e71d", 188239}, -		{"resource.002", 0, "851a62d00972dc4002f472cc0d84e71d", 329895}, -		{"resource.003", 0, "851a62d00972dc4002f472cc0d84e71d", 355385}, -		{"resource.004", 0, "851a62d00972dc4002f472cc0d84e71d", 322951}, -		{"resource.005", 0, "851a62d00972dc4002f472cc0d84e71d", 321593}, -		{"resource.006", 0, "851a62d00972dc4002f472cc0d84e71d", 333777}, -		{"resource.007", 0, "851a62d00972dc4002f472cc0d84e71d", 341038}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// King's Quest 4 - English DOS -	// SCI interpreter version 0.000.253 -	{{"kq4sci", "", { -		{"resource.map", 0, "381d9dcb69c626f0a60631dbfec1d13a", 9474}, -		{"resource.001", 0, "0c8566848a76eea19a6d6220914030a7", 191559}, -		{"resource.002", 0, "0c8566848a76eea19a6d6220914030a7", 333345}, -		{"resource.003", 0, "0c8566848a76eea19a6d6220914030a7", 358513}, -		{"resource.004", 0, "0c8566848a76eea19a6d6220914030a7", 326297}, -		{"resource.005", 0, "0c8566848a76eea19a6d6220914030a7", 325102}, -		{"resource.006", 0, "0c8566848a76eea19a6d6220914030a7", 337288}, -		{"resource.007", 0, "0c8566848a76eea19a6d6220914030a7", 343882}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// King's Quest 5 - English Amiga (from www.back2roots.org) -	// Executable scanning reports "1.004.018" -	// SCI interpreter version 1.000.060 -	{{"kq5", "", { -		{"resource.map", 0, "fcbcca058e1157221ffc27251cd59bc3", 8040}, -		{"resource.000", 0, "c595ca99e7fa9b2cabcf69cfab0caf67", 344909}, -		{"resource.001", 0, "964a3be90d810a99baf72ea70c09f935", 836477}, -		{"resource.002", 0, "d10f3e8ff2cd95a798b21cd08797b694", 814730}, -		{"resource.003", 0, "f72fdd994d9ba03a8360d639f256344e", 804882}, -		{"resource.004", 0, "a5b80f95c66b3a032348989408eec287", 747914}, -		{"resource.005", 0, "31a5487f4d942e6354d5be49d59707c9", 834146}, -		{"resource.006", 0, "26c0c25399b6715fec03fc3e12544fe3", 823048}, -		{"resource.007", 0, "b914b5901e786327213e779725d30dd1", 778772}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 5 - German Amiga -	// Executable scanning reports "1.004.024" -	// SCI interpreter version 1.000.060 -	{{"kq5", "", { -		{"resource.map", 0, "bfbffd923cd64b24498e54f797aa6e41", 8250}, -		{"resource.000", 0, "79479b5e4e5b0085d8eea1c7ff0f9f5a", 306893}, -		{"resource.001", 0, "7840aadc82977c7b4f504a7e4a12829f", 720376}, -		{"resource.002", 0, "d547167d4204170b44de8e1d63506215", 792586}, -		{"resource.003", 0, "9cbb0712816097cbc9d0c1f987717c7f", 646446}, -		{"resource.004", 0, "319712573661bd122390cdfbafb000fd", 831842}, -		{"resource.005", 0, "5aa3d59968b569cd509dde00d4eb8751", 754201}, -		{"resource.006", 0, "56546b20db11a4836f900efa6d3a3e74", 672099}, -		{"resource.007", 0, "56546b20db11a4836f900efa6d3a3e74", 794194}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 5 - Italian Amiga -	// Executable scanning reports "1.004.024" -	// SCI interpreter version 1.000.060 -	{{"kq5", "", { -		{"resource.map", 0, "12e2f80c0269932411716dad06d2b229", 8250}, -		{"resource.000", 0, "c598ff615a61bc0e418761283409f128", 305879}, -		{"resource.001", 0, "17e63cfe78632fe07222e13a26dc0fb2", 720023}, -		{"resource.002", 0, "abb340a53e4873a7c3bacfb16c0b779d", 792432}, -		{"resource.003", 0, "aced8ce0be07eef77c0e7cff8cc4e476", 646088}, -		{"resource.004", 0, "13fc1f1679f7f226ba52ffffe2e65f38", 831805}, -		{"resource.005", 0, "de3c5c09e350fded36ca354998c2194d", 754784}, -		{"resource.006", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 672527}, -		{"resource.007", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 794259}, -		{NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 5 - English DOS CD (from the King's Quest Collection) -	// Executable scanning reports "x.yyy.zzz", VERSION file reports "1.000.052" -	// SCI interpreter version 1.000.784 -	{{"kq5", "CD", { -		{"resource.map", 0, "f68ba690e5920725dcf9328001b90e33", 13122}, -		{"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368}, -		{"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// King's Quest 5 - English DOS Floppy -	// SCI interpreter version 1.000.060 -	{{"kq5", "", { -		{"resource.map", 0, "d6172c27b453350e158815fbae23f41e", 8004}, -		{"resource.000", 0, "a591bd4b879fc832b8095c0b3befe9e2", 276351}, -		{"resource.001", 0, "3f28c72dc7531aaccf8e972c7ee50d14", 1022087}, -		{"resource.002", 0, "3e56ba5bf5e8637c619b57f6b6cacbb4", 1307211}, -		{"resource.003", 0, "5d5d498f33ca7cde0d5b058630b36ad3", 1347875}, -		{"resource.004", 0, "944a996f9cc90dabde9f51ed7dd52366", 1239689}, -		{"resource.005", 0, "b6c43441cb78a9b484efc8e614aac092", 1287999}, -		{"resource.006", 0, "672ede1136e9e401658538e51bd5dc22", 1172619}, -		{"resource.007", 0, "2f48faf27666b58c276dda20f91f4a93", 1240456}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 5 - German DOS Floppy (supplied by markcoolio in bug report #2727101) -	// SCI interpreter version 1.000.060 -	{{"kq5", "", { -		{"resource.map", 0, "bff44f0c326a71b1757c793a02b502d6", 8283}, -		{"resource.000", 0, "d7ed18ec4a5de02a9a57830aa65a600d", 336826}, -		{"resource.001", 0, "b1e5ec6a17be7e75ddb955f6f73191e4", 1136919}, -		{"resource.002", 0, "04a88122db44610a4af019a579ec5ff6", 1340813}, -		{"resource.003", 0, "215bb35acefae75fc80757c717166d7e", 1323916}, -		{"resource.004", 0, "fecdec847e3bd8e3b0f9827900aa95fd", 1331811}, -		{"resource.005", 0, "9c429782d102739f6bbb81e8b953b0cb", 1267525}, -		{"resource.006", 0, "d1a75fdc01840664d00366cff6919366", 1208972}, -		{"resource.007", 0, "c07494f0cce7c05210893938786a955b", 1337361}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 5 - French DOS Floppy (from the King's Quest Collector's Edition 1994) -	// Supplied by aroenai in bug report #2812611 -	// VERSION file reports "1.000", SCI interpreter version 1.000.784 -	{{"kq5", "", { -		{"resource.map", 0, "eb7853832f3bb10900b13b421a0bbe7f", 8283}, -		{"resource.000", 0, "f063775b279208c14a83eda47073be90", 332806}, -		{"resource.001", 0, "3e6add38564250fd1a5bb10593007530", 1136827}, -		{"resource.002", 0, "d9a97a9cf6c79bbe8f19378f6dea45d5", 1343738}, -		{"resource.003", 0, "bef90d755076c110e67ee3e635503f82", 1324811}, -		{"resource.004", 0, "c14dbafcfbe00855ac6b2f2701058047", 1332216}, -		{"resource.005", 0, "f4b31cafc5defac75125c5f7b7f9a31a", 1268334}, -		{"resource.006", 0, "f7dc85307632ef657ceb1651204f6f51", 1210081}, -		{"resource.007", 0, "7db4d0a1d8d547c0019cb7d2a6acbdd4", 1338473}, -		{NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 5 - Italian DOS Floppy (from glorifindel) -	// SCI interpreter version 1.000.060 -	{{"kq5", "", { -		{"resource.map", 0, "d55c9e83894a0885e37cd79bacf86384", 8283}, -		{"resource.000", 0, "c99bbb11ace4aaacdc98b588a2ecea06", 332246}, -		{"resource.001", 0, "42b98457b1a7282daa27afd89eef53f4", 1136389}, -		{"resource.002", 0, "8cdc160f9dfc84aed7caa6c66fa31000", 1340730}, -		{"resource.003", 0, "d0cb52dc41488c018359aa79a6527f51", 1323676}, -		{"resource.004", 0, "e5c57060adf2b5c6fc24142acba023da", 1331097}, -		{"resource.005", 0, "f4e441f284560eaa8022102315656a7d", 1267757}, -		{"resource.006", 0, "8eeabd92af71e766e323db2100879102", 1209325}, -		{"resource.007", 0, "dc10c107e0923b902326a040b9c166b9", 1337859}, -		{NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 5 - Polish DOS Floppy (supplied by jacek909 in bug report #2725722) -	// SCI interpreter version 1.000.060 -	{{"kq5", "", { -		{"resource.map", 0, "70010c20138541f89013bb5e1b30f16a", 7998}, -		{"resource.000", 0, "a591bd4b879fc832b8095c0b3befe9e2", 276398}, -		{"resource.001", 0, "c0f48d4a7ebeaa6aa074fc98d77423e9", 1018560}, -		{"resource.002", 0, "7f188a95acdb60bbe32a8379ba299393", 1307048}, -		{"resource.003", 0, "0860785af59518b94d54718dddcd6907", 1348500}, -		{"resource.004", 0, "c4745dd1e261c22daa6477961d08bf6c", 1239887}, -		{"resource.005", 0, "6556ff8e7c4d1acf6a78aea154daa76c", 1287869}, -		{"resource.006", 0, "da82e4beb744731d0a151f1d4922fafa", 1170456}, -		{"resource.007", 0, "431def14ca29cdb5e6a5e84d3f38f679", 1240176}, -		{NULL, 0, NULL, 0}}, Common::PL_POL, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 6 - English DOS Non-Interactive Demo -	// Executable scanning reports "1.001.055", VERSION file reports "1.000.000" -	// SCI interpreter version 1.001.055 -	{{"kq6", "Demo", { -		{"resource.map", 0, "f75727c00a6d884234fa2a43c951943a", 706}, -		{"resource.000", 0, "535b1b920441ec73f42eaa4ccfd47b89", 264116}, -		{"resource.msg", 0, "54d1fdc936f98c81f9e4c19e04fb1510", 8260}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 6 - English DOS Floppy -	// SCI interpreter version 1.001.054 -	{{"kq6", "", { -		{"resource.map", 0, "a362063318eebe7d6423b1d9dc6213e1", 8703}, -		{"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324}, -		{"resource.msg", 0, "3cf5de44de36191f109d425b8450efc8", 258590}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 6 - German DOS Floppy (supplied by markcoolio in bug report #2727156) -	// SCI interpreter version 1.001.054 -	{{"kq6", "", { -		{"resource.map", 0, "a362063318eebe7d6423b1d9dc6213e1", 8703}, -		{"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324}, -		{"resource.msg", 0, "756297b2155db9e43f621c6f6fb763c3", 282822}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 6 - English Windows CD (from the King's Quest Collection) -	// Executable scanning reports "1.cfs.158", VERSION file reports "1.034 9/11/94 - KQ6 version 1.000.00G" -	// SCI interpreter version 1.001.054 -	{{"kq6", "CD", { -		{"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215}, -		{"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// King's Quest 6 - Spanish DOS CD (from jvprat) -	// Executable scanning reports "1.cfs.158", VERSION file reports "1.000.000, July 5, 1994" -	// SCI interpreter version 1.001.055 -	{{"kq6", "CD", { -		{"resource.map", 0, "a73a5ab04b8f60c4b75b946a4dccea5a", 8953}, -		{"resource.000", 0, "4da3ad5868a775549a7cc4f72770a58e", 8537260}, -		{"resource.msg", 0, "41eed2d3893e1ca6c3695deba4e9d2e8", 267102}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -#ifdef ENABLE_SCI32 -	// King's Quest 7 - English DOS (from the King's Quest Collection) -	// Executable scanning reports "2.100.002", VERSION file reports "1.4" -	{{"kq7", "", { -		{"resource.map", 0, "2be9ab94429c721af8e05c507e048a15", 18697}, -		{"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 203882535}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 7 - English DOS (from FRG) -	// SCI interpreter version 2.100.002 -	{{"kq7", "", { -		{"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709}, -		{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 7 - German Windows (supplied by markcoolio in bug report #2727402) -	// SCI interpreter version 2.100.002 -	{{"kq7", "", { -		{"resource.map", 0, "838b9ff132bd6962026fee832e8a7ddb", 18697}, -		{"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 206626576}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 7 - Spanish DOS (from jvprat) -	// Executable scanning reports "2.100.002", VERSION file reports "2.00" -	{{"kq7", "", { -		{"resource.map", 0, "0b62693cbe87e3aaca3e8655a437f27f", 18709}, -		{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// King's Quest 7 - English DOS Non-Interactive Demo -	// SCI interpreter version 2.100.002 -	{{"kq7", "Demo", { -		{"resource.map", 0, "b44f774108d63faa1d021101221c5a54", 1690}, -		{"resource.000", 0, "d9659d2cf0c269c6a9dc776707f5bea0", 2433827}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, -#endif // ENABLE_SCI32 - -	// Laura Bow - English Amiga -	// Executable scanning reports "1.002.030" -	// SCI interpreter version 0.000.685 -	{{"laurabow", "", { -		{"resource.map", 0, "731ab85e138f8cef1a7f4d1f36dfd375", 7422}, -		{"resource.000", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 126317}, -		{"resource.001", 0, "42fe895e9eb60e103025fd9ca737a849", 264763}, -		{"resource.002", 0, "6f1ebd3692ce76644e0e06a38b7b56b5", 677436}, -		{"resource.003", 0, "2ab23f64306b18c28302c8ec2964c5d6", 605134}, -		{"resource.004", 0, "aa553977f7e5804081de293800d3bcce", 695067}, -		{"resource.005", 0, "bfd870d51dc97729f0914095f58e6957", 676881}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Laura Bow - English Atari ST (from jvprat) -	// Executable scanning reports "1.002.030", Floppy label reports "1.000.062, 9.23.90" -	// SCI interpreter version 0.000.685 -	{{"laurabow", "", { -		{"resource.map", 0, "9f90878e6e1b8c96e692203f068ce2b1", 8478}, -		{"resource.001", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 515964}, -		{"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 721149}, -		{"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667365}, -		{"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683737}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Laura Bow - English DOS Non-Interactive Demo -	// Executable scanning reports "x.yyy.zzz" -	{{"laurabow", "Demo", { -		{"resource.map", 0, "e625726268ff4e123ada11f31f0249f3", 768}, -		{"resource.001", 0, "0c8912290af0890f8d95faeb4ddb2d68", 333031}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Laura Bow - English DOS 3.5" Floppy (from "The Roberta Williams Anthology"/1996) -	// SCI interpreter version 0.000.631 -	{{"laurabow", "", { -		{"resource.map", 0, "4e511f47d9893fa529d6621a93fa0030", 8478}, -		{"resource.001", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 515788}, -		{"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 721381}, -		{"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667468}, -		{"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683807}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Laura Bow - English DOS (from FRG) -	// SCI interpreter version 0.000.631 (or 0.000.685?) -	{{"laurabow", "", { -		{"resource.map", 0, "b1905f6aa68ff65a057b080b1eae954c", 12030}, -		{"resource.001", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 108032}, -		{"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 354680}, -		{"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 361815}, -		{"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 339714}, -		{"resource.005", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 327465}, -		{"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390}, -		{"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Laura Bow - German DOS (from Tobis87) -	// SCI interpreter version 0.000.631 (or 0.000.685?) -	{{"laurabow", "", { -		{"resource.map", 0, "b1905f6aa68ff65a057b080b1eae954c", 12030}, -		{"resource.001", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 108032}, -		{"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 354680}, -		{"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 361815}, -		{"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 339714}, -		{"resource.005", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 327465}, -		{"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390}, -		{"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Laura Bow 2 - English DOS Non-Interactive Demo (from FRG) -	// Executable scanning reports "x.yyy.zzz" -	// SCI interpreter version 1.001.069 (just a guess) -	{{"laurabow2", "Demo", { -		{"resource.map", 0, "24dffc5db1d88c7999f13e8767ed7346", 855}, -		{"resource.000", 0, "2b2b1b4f7584f9b38fd13f6ab95634d1", 781912}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Laura Bow 2 - English DOS Floppy -	// Executable scanning reports "2.000.274" -	// SCI interpreter version 1.001.069 (just a guess) -	{{"laurabow2", "", { -		{"resource.map", 0, "610bfd9a852004222f0faaf5fc9e630a", 6489}, -		{"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5035964}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Laura Bow 2 - English DOS CD (from "The Roberta Williams Antology"/1996) -	// Executable scanning reports "1.001.072", VERSION file reports "1.1" (from jvprat) -	// SCI interpreter version 1.001.069 (just a guess) -	{{"laurabow2", "CD", { -		{"resource.map", 0, "a70945e61ba7ac7bfea6b7bd72c6aec5", 7274}, -		{"resource.000", 0, "82578b8d5a7e09c4c58891ca49fae35b", 5598672}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Laura Bow 2 v1.1 - German DOS Floppy (from Tobis87, updated info from  markcoolio in bug report #2723787, updated info from #2797962)) -	// Executable scanning reports "2.000.274" -	{{"laurabow2", "", { -		{"resource.map", 0, "3b6dfbcda210bbc3f23fd1927113bf98", 6483}, -		{"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, -		{"resource.msg", 0, "795c928cd00dfec9fbc62ebcd12e1f65", 303185}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Laura Bow 2 - Spanish DOS CD (from jvprat) -	// Executable scanning reports "2.000.274", VERSION file reports "1.000.000, May 10, 1994" -	{{"laurabow2", "CD", { -		{"resource.map", 0, "3b6dfbcda210bbc3f23fd1927113bf98", 6483}, -		{"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, -		{"resource.msg", 0, "71f1f0cd9f082da2e750c793a8ed9d84", 286141}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Larry 1 EGA Remake - English DOS (from spookypeanut) -	// SCI interpreter version 0.000.510 (or 0.000.577?) -	{{"lsl1sci", "EGA Remake", { -		{"resource.map", 0, "abc0dc50c55de5b9723bb6de193f8756", 3282}, -		{"resource.000", 0, "d3bceaebef3f7be941c2038b3565161e", 451366}, -		{"resource.001", 0, "38936d3c68b6f79d3ffb13955713fed7", 591352}, -		{"resource.002", 0, "24c958bc922b07f91e25e8c93aa01fcf", 491230}, -		{"resource.003", 0, "685cd6c1e05a695ab1e0db826337ee2a", 553279}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Larry 1 VGA Remake - English Amiga (from www.back2roots.org) -	// Executable scanning reports "1.004.024" -	// SCI interpreter version 1.000.784 -	{{"lsl1sci", "VGA Remake", { -		{"resource.map", 0, "7d115a9e27dc8ac71e8d5ef33d589bd5", 3366}, -		{"resource.000", 0, "e67fd129d5810fc7ad8ea509d891cc00", 363073}, -		{"resource.001", 0, "24ed6dc01b1e7fbc66c3d63a5994549a", 750465}, -		{"resource.002", 0, "5790ac0505f7ca98d4567132b875eb1e", 681041}, -		{"resource.003", 0, "4a34c3367c2fe7eb380d741374da1989", 572251}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 1 VGA Remake - English DOS (from spookypeanut) -	// Executable scanning reports "1.000.577", VERSION file reports "2.1" -	{{"lsl1sci", "VGA Remake", { -		{"resource.map", 0, "6d04d26466337a1a64b8c6c0eb65c9a9", 3222}, -		{"resource.000", 0, "d3bceaebef3f7be941c2038b3565161e", 922406}, -		{"resource.001", 0, "ec20246209d7b19f38989261e5c8f5b8", 1111226}, -		{"resource.002", 0, "85d6935ef77e6b0e16bc307640a0d913", 1088312}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 1 VGA Remake - English DOS (from FRG) -	// SCI interpreter version 1.000.510 -	{{"lsl1sci", "VGA Remake", { -		{"resource.map", 0, "8606b083b011a0cc4a1fbfc2198a0a77", 3198}, -		{"resource.000", 0, "d3bceaebef3f7be941c2038b3565161e", 918242}, -		{"resource.001", 0, "d34cadb11e1aefbb497cf91bc1d3baa7", 1114688}, -		{"resource.002", 0, "85b030bb66d5342b0a068f1208c431a8", 1078443}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 1 VGA Remake - English DOS Non-Interactive Demo -	// SCI interpreter version 1.000.084 -	{{"lsl1sci", "VGA Remake Demo", { -		{"resource.map", 0, "434e1f6c39d71647b34f0ee57b2bbd68", 444}, -		{"resource.001", 0, "0c0768215c562d9dace4a5ca53696cf3", 359913}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 1 VGA Remake - Spanish DOS (from the Leisure Suit Larry Collection) -	// Executable scanning reports "1.SQ4.057", VERSION file reports "1.000" -	// This version is known to be corrupted -	// SCI interpreter version 1.000.510 -	{{"lsl1sci", "VGA Remake", { -		{"resource.map", 0, "4fbe5c25878d51d7b2a68b710de4491b", 3327}, -		{"resource.000", 0, "5e501a9bf8c753bf4c96158042422f00", 839172}, -		{"resource.001", 0, "112648995dbc194037f1e4ed2e195910", 1063341}, -		{"resource.002", 0, "3fe2a3aec0ed53c7d6db1845a67e3aa2", 1095908}, -		{"resource.003", 0, "ac175df0ea9a2cba57f0248651856d27", 376556}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 1 VGA Remake - Russian DOS -	// Executable scanning reports "1.000.510", VERSION file reports "2.0" -	// SCI interpreter version 1.000.510 -	{{"lsl1sci", "VGA Remake", { -		{"resource.map", 0, "b54413d35e206d21ae2b2bdb092bd13a", 3198}, -		{"resource.000", 0, "0d7b2afa666bd36d9535a15d3a837a66", 928566}, -		{"resource.001", 0, "bc8ca10c807515d959cbd91f9ba47735", 1123759}, -		{"resource.002", 0, "b7409ab32bc3bee2d6cce887cd33f2b6", 1092160}, -		{NULL, 0, NULL, 0}}, Common::RU_RUS, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 2 - English Amiga (from www.back2roots.org) -	// Executable scanning reports "x.yyy.zzz" -	// SCI interpreter version 0.000.572 -	{{"lsl2", "", { -		{"resource.map", 0, "e36ce0fc94d1678d15acbf12d84ec47d", 6612}, -		{"resource.001", 0, "a0d4a625311d307257da7fc43d00459d", 409124}, -		{"resource.002", 0, "a0d4a625311d307257da7fc43d00459d", 630106}, -		{"resource.003", 0, "a0d4a625311d307257da7fc43d00459d", 570356}, -		{"resource.004", 0, "a0d4a625311d307257da7fc43d00459d", 717844}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Larry 2 - English DOS Non-Interactive Demo -	// Executable scanning reports "x.yyy.zzz" -	// SCI interpreter version 0.000.409 -	{{"lsl2", "Demo", { -		{"resource.map", 0, "03dba704bb77da55a91ad27b5a3cac09", 528}, -		{"resource.001", 0, "9f5520f0297206928df0b0b36493cd33", 127532}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Larry 2 - English DOS -	// SCI interpreter version 0.000.409 -	{{"lsl2", "", { -		{"resource.map", 0, "42258cf767a8ebaa9e66b6151a80e601", 5628}, -		{"resource.001", 0, "4a24443a25e2b1492462a52809605dc2", 143847}, -		{"resource.002", 0, "4a24443a25e2b1492462a52809605dc2", 348331}, -		{"resource.003", 0, "4a24443a25e2b1492462a52809605dc2", 236550}, -		{"resource.004", 0, "4a24443a25e2b1492462a52809605dc2", 204861}, -		{"resource.005", 0, "4a24443a25e2b1492462a52809605dc2", 277732}, -		{"resource.006", 0, "4a24443a25e2b1492462a52809605dc2", 345683}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Larry 2 - English DOS -	// SCI interpreter version 0.000.343 -	{{"lsl2", "", { -		{"resource.map", 0, "6bd43c92eaf561f64818116eed683fcf", 5598}, -		{"resource.001", 0, "96033f57accfca903750413fd09193c8", 140526}, -		{"resource.002", 0, "96033f57accfca903750413fd09193c8", 348672}, -		{"resource.003", 0, "96033f57accfca903750413fd09193c8", 236676}, -		{"resource.004", 0, "96033f57accfca903750413fd09193c8", 204867}, -		{"resource.005", 0, "96033f57accfca903750413fd09193c8", 274953}, -		{"resource.006", 0, "96033f57accfca903750413fd09193c8", 345818}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Larry 3 - English Amiga (from www.back2roots.org) -	// Executable scanning reports "1.002.032" -	// SCI interpreter version 0.000.685 -	{{"lsl3", "", { -		{"resource.map", 0, "4a6da6322ce189431b5ffbac992bad3a", 5328}, -		{"resource.000", 0, "cdc2e21e297b10fe8fed6377af8c5698", 66523}, -		{"resource.001", 0, "6abbaf8c7e3b36dd868868ed187e8995", 71761}, -		{"resource.002", 0, "a883424fe6d594fec0cd5a79e7ad54c8", 476490}, -		{"resource.003", 0, "5c10e462c8cf589610773e4fe8bfd996", 527238}, -		{"resource.004", 0, "f408e59cbee1457f042e5773b8c53951", 651634}, -		{"resource.005", 0, "433911eb764089d493aed1f958a5615a", 524259}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 3 - English DOS -	// SCI interpreter version 0.000.572 -	{{"lsl3", "", { -		{"resource.map", 0, "0b6bd3e039682830a51c5755c06591db", 5916}, -		{"resource.001", 0, "f18441027154292836b973c655fa3175", 456722}, -		{"resource.002", 0, "f18441027154292836b973c655fa3175", 578024}, -		{"resource.003", 0, "f18441027154292836b973c655fa3175", 506807}, -		{"resource.004", 0, "f18441027154292836b973c655fa3175", 513651}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Larry 3 - English DOS -	// SCI interpreter version 0.000.572 -	{{"lsl3", "", { -		{"resource.map", 0, "0f429f5186f96d6c501838a1cb44bd43", 7452}, -		{"resource.001", 0, "f18441027154292836b973c655fa3175", 141381}, -		{"resource.002", 0, "f18441027154292836b973c655fa3175", 345171}, -		{"resource.003", 0, "f18441027154292836b973c655fa3175", 329214}, -		{"resource.004", 0, "f18441027154292836b973c655fa3175", 290173}, -		{"resource.005", 0, "f18441027154292836b973c655fa3175", 302946}, -		{"resource.006", 0, "f18441027154292836b973c655fa3175", 282465}, -		{"resource.007", 0, "f18441027154292836b973c655fa3175", 257174}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Larry 3 - English DOS Non-Interactive Demo -	// SCI interpreter version 0.000.530 -	{{"lsl3", "Demo", { -		{"resource.map", 0, "33a2384f395470af3d2180e37ad0322a", 1140}, -		{"resource.001", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 76525}, -		{"resource.002", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 268299}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Larry 3 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723832) -	// Executable scanning reports "S.old.123" -	// SCI interpreter version 0.000.572 (just a guess) -	{{"lsl3", "", { -		{"resource.map", 0, "4a77c8382e48a90c4168d3c144fc1b8f", 6480}, -		{"resource.001", 0, "3827a9b17b926e12dcc336860f50612a", 460488}, -		{"resource.002", 0, "3827a9b17b926e12dcc336860f50612a", 672403}, -		{"resource.003", 0, "3827a9b17b926e12dcc336860f50612a", 587036}, -		{"resource.004", 0, "3827a9b17b926e12dcc336860f50612a", 691932}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Larry 3 - French DOS (provided by richiefs in bug report #2670691) -	// Executable scanning reports "S.old.123" -	// SCI interpreter version 0.000.572 (just a guess) -	{{"lsl3", "", { -		{"resource.map", 0, "13541234d440c7988a13582468b0e4be", 6480}, -		{"resource.001", 0, "65f1bdaa20f6d0470e9d969f22473873", 457402}, -		{"resource.002", 0, "65f1bdaa20f6d0470e9d969f22473873", 671614}, -		{"resource.003", 0, "65f1bdaa20f6d0470e9d969f22473873", 586921}, -		{"resource.004", 0, "65f1bdaa20f6d0470e9d969f22473873", 690826}, -		{NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Larry 5 - English Amiga -	// Executable scanning reports "1.004.023" -	// SCI interpreter version 1.000.784 -	{{"lsl5", "", { -		{"resource.map", 0, "e36052ae0c8b14d6f074bcb0aee50a38", 6096}, -		{"resource.000", 0, "d8b58ce10de52aa16f8b2006838c4fcc", 310510}, -		{"resource.001", 0, "8caa8fbb50ea43f3efdfb66f1e68998b", 800646}, -		{"resource.002", 0, "abdaa299e00c908052d33cd82eb60e9b", 784576}, -		{"resource.003", 0, "810ad1d61638c27a780576cb09f18ed7", 805941}, -		{"resource.004", 0, "3ce5901f1bc171ac0274d99a4eeb9e57", 623022}, -		{"resource.005", 0, "f8b2d1137bb767e5d232056b99dd69eb", 623621}, -		{"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 715598}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 5 - German Amiga -	// Executable scanning reports "1.004.024" -	// SCI interpreter version 1.000.784 -	{{"lsl5", "", { -		{"resource.map", 0, "863326c2eb5160f0b0960e159e8bf954", 6372}, -		{"resource.000", 0, "5113d03db08e3da77a5b61294001331b", 357525}, -		{"resource.001", 0, "59eba83ad465b08d763b44f86afa86f6", 837566}, -		{"resource.002", 0, "59eba83ad465b08d763b44f86afa86f6", 622229}, -		{"resource.003", 0, "59eba83ad465b08d763b44f86afa86f6", 383690}, -		{"resource.004", 0, "59eba83ad465b08d763b44f86afa86f6", 654296}, -		{"resource.005", 0, "59eba83ad465b08d763b44f86afa86f6", 664717}, -		{"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 754966}, -		{"resource.007", 0, "59eba83ad465b08d763b44f86afa86f6", 683135}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 5 - English DOS Non-Interactive Demo (from FRG) -	// SCI interpreter version 1.000.181 -	{{"lsl5", "Demo", { -		{"resource.map", 0, "efe8d3f45ce4f6bd9a6643e0ac8d2a97", 504}, -		{"resource.001", 0, "8bd8d9c0b5f455ee1269d63ce86c50dd", 531380}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 5 - English DOS (from spookypeanut) -	// SCI interpreter version 1.000.510 -	{{"lsl5", "", { -		{"resource.map", 0, "be00ef895197754ae4eab021ca44cbcd", 6417}, -		{"resource.000", 0, "f671ab479df0c661b19cd16237692846", 726823}, -		{"resource.001", 0, "db4a1381d88028876a99303bfaaba893", 751296}, -		{"resource.002", 0, "d39d8db1a1e7806e7ccbfea3ef22df44", 1137646}, -		{"resource.003", 0, "13fd4942bb818f9acd2970d66fca6509", 768599}, -		{"resource.004", 0, "999f407c9f38f937d4b8c4230ff5bb38", 1024516}, -		{"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 1011944}, -		{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1024810}, -		{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 1030656}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 5 - German DOS (from Tobis87) -	// SCI interpreter version 1.000.510 (just a guess) -	{{"lsl5", "", { -		{"resource.map", 0, "c97297aa76d4dd2ed144c7b7769e2caf", 6867}, -		{"resource.000", 0, "4c00c14b8181ad47076a51d86097d97e", 759095}, -		{"resource.001", 0, "245c44f8ccd796732e61857e67b30079", 918742}, -		{"resource.002", 0, "e86aeb27711f4a673e06ec32cfc84125", 947382}, -		{"resource.003", 0, "74edc89d8c1cb346ca346081b927e4c6", 1006884}, -		{"resource.004", 0, "999f407c9f38f937d4b8c4230ff5bb38", 1023776}, -		{"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 959342}, -		{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1021774}, -		{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 993408}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 5 - French DOS (provided by richiefs in bug report #2670691) -	// Executable scanning reports "1.lsl5.019" -	// SCI interpreter version 1.000.510 (just a guess) -	{{"lsl5", "", { -		{"resource.map", 0, "499898e652dc41b51e368ae41acce41f", 7023}, -		{"resource.000", 0, "4c00c14b8181ad47076a51d86097d97e", 958096}, -		{"resource.001", 0, "245c44f8ccd796732e61857e67b30079", 1196765}, -		{"resource.002", 0, "e86aeb27711f4a673e06ec32cfc84125", 948898}, -		{"resource.003", 0, "74edc89d8c1cb346ca346081b927e4c6", 1006608}, -		{"resource.004", 0, "999f407c9f38f937d4b8c4230ff5bb38", 971293}, -		{"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 920524}, -		{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 946540}, -		{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 958842}, -		{NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 5 - Spanish DOS (from the Leisure Suit Larry Collection) -	// Executable scanning reports "1.ls5.006", VERSION file reports "1.000, 4/21/92" -	// SCI interpreter version 1.000.510 (just a guess) -	{{"lsl5", "", { -		{"resource.map", 0, "b6f7da7bf24e5a6b2946032cec3ea59c", 6861}, -		{"resource.000", 0, "4c00c14b8181ad47076a51d86097d97e", 765418}, -		{"resource.001", 0, "245c44f8ccd796732e61857e67b30079", 916028}, -		{"resource.002", 0, "e86aeb27711f4a673e06ec32cfc84125", 929645}, -		{"resource.003", 0, "74edc89d8c1cb346ca346081b927e4c6", 1005496}, -		{"resource.004", 0, "999f407c9f38f937d4b8c4230ff5bb38", 1021996}, -		{"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 958079}, -		{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1015136}, -		{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 987222}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 5 - Italian DOS Floppy (from glorifindel) -	// SCI interpreter version 1.000.510 (just a guess) -	{{"lsl5", "", { -		{"resource.map", 0, "a99776df795127f387cb35dae872d4e4", 5919}, -		{"resource.000", 0, "a8989a5a89e7d4f702b26b378c7a357a", 7001981}, -		{NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 6 - English DOS (from spookypeanut) -	// SCI interpreter version 1.001.113 -	{{"lsl6", "", { -		{"resource.map", 0, "bb8a39d9e2a77ba449a1e591109ad9a8", 6973}, -		{"resource.000", 0, "4462fe48c7452d98fddcec327a3e738d", 5789138}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 6 - English/German/French DOS CD - LORES -	// SCI interpreter version 1.001.115 -	{{"lsl6", "", { -		{"resource.map", 0, "0b91234b7112782962cb480b7791b6e2", 7263}, -		{"resource.000", 0, "57d5fe8bb9e044158514476ea7678eb0", 5754790}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Larry 6 - German DOS CD - LORES (provided by richiefs in bug report #2670691) -	// SCI interpreter version 1.001.115 -	{{"lsl6", "", { -		{"resource.map", 0, "bafe85f32738854135991d4324ad147e", 7268}, -		{"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5773160}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Larry 6 - French DOS CD - LORES (provided by richiefs in bug report #2670691) -	// SCI interpreter version 1.001.115 -	{{"lsl6", "", { -		{"resource.map", 0, "97797ea775baaf18a1907d357d3c0ea6", 7268}, -		{"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5776092}, -		{NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Larry 6 - Spanish DOS - LORES (from the Leisure Suit Larry Collection) -	// Executable scanning reports "1.001.113", VERSION file reports "1.000, 11.06.93, FIVE PATCHES ADDED TO DISK 6 ON 11-18-93" -	{{"lsl6", "", { -		{"resource.map", 0, "633bf8f42170b6271019917c8009989b", 6943}, -		{"resource.000", 0, "7884a8db9253e29e6b37a2651fd90ba3", 5733116}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Leisure Suit Larry's Casino - English DOS (from the Leisure Suit Larry Collection) -	// Executable scanning reports "1.001.029", VERSION file reports "1.000" -	{{"lslcasino", "", { -		{"resource.map", 0, "194f1578f2624db813c9072359ad1639", 783}, -		{"resource.001", 0, "3733433b517ec3d14a3331d9ab3842ae", 344830}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -#ifdef ENABLE_SCI32 -	// Larry 6 - English/German DOS CD - HIRES -	// SCI interpreter version 2.100.002 -	{{"lsl6", "", { -		{"resource.map", 0, "0c0804434ea62278dd15032b1947426c", 8872}, -		{"resource.000", 0, "9a9f4870504444cda863dd14d077a680", 18520872}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Larry 6 - German DOS CD - HIRES (provided by richiefs in bug report #2670691) -	// SCI interpreter version 2.100.002 -	{{"lsl6", "", { -		{"resource.map", 0, "badfdf446ffed569a310d2c63a249421", 8896}, -		{"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18534274}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Larry 6 - French DOS CD - HIRES (provided by richiefs in bug report #2670691) -	// SCI interpreter version 2.100.002 -	{{"lsl6", "", { -		{"resource.map", 0, "d184e9aa4f2d4b5670ddb3669db82cda", 8896}, -		{"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18538987}, -		{NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Larry 7 - English DOS CD (from spookypeanut) -	// SCI interpreter version 3.000.000 -	{{"lsl7", "", { -		{"resmap.000", 0, "eae93e1b1d1ccc58b4691c371281c95d", 8188}, -		{"ressci.000", 0, "89353723488219e25589165d73ed663e", 66965678}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Larry 7 - German DOS (from Tobis87) -	// SCI interpreter version 3.000.000 -	{{"lsl7", "", { -		{"resmap.000", 0, "c11e6bfcfc2f2d05da47e5a7df3e9b1a", 8188}, -		{"ressci.000", 0, "a8c6817bb94f332ff498a71c8b47f893", 66971724}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 7 - French DOS (provided by richiefs in bug report #2670691) -	// SCI interpreter version 3.000.000 -	{{"lsl7", "", { -		{"resmap.000", 0, "4407849fd52fe3efb0c30fba60cd5cd4", 8206}, -		{"ressci.000", 0, "dc37c3055fffbefb494ff22b145d377b", 66964472}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 7 - Italian DOS CD (from glorifindel) -	// SCI interpreter version 3.000.000 -	{{"lsl7", "", { -		{"resmap.000", 0, "9852a97141f789413f29bf956052acdb", 8212}, -		{"ressci.000", 0, "440b9fed89590abb4e4386ed6f948ee2", 67140181}, -		{NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Larry 7 - Spanish DOS (from the Leisure Suit Larry Collection) -	// Executable scanning reports "3.000.000", VERSION file reports "1.0s" -	{{"lsl7", "", { -		{"resmap.000", 0, "8f3d603e1acc834a5d598b30cdfc93f3", 8188}, -		{"ressci.000", 0, "32792f9bc1bf3633a88b382bb3f6e40d", 67071418}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Larry 7 - English DOS Demo (provided by richiefs in bug report #2670691) -	// SCI interpreter version 2.100.002 -	{{"lsl7", "Demo", { -		{"ressci.000", 0, "5cc6159688b2dc03790a67c90ccc67f9", 10195878}, -		{"resmap.000", 0, "6a2b2811eef82e87cde91cf1de845af8", 2695}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Lighthouse - English Windows Demo (from jvprat) -	// Executable scanning reports "2.100.002", VERSION file reports "1.00" -	{{"lighthouse", "Demo", { -		{"resource.map", 0, "543124606352bfa5e07696ddf2a669be", 64}, -		{"resource.000", 0, "5d7714416b612463d750fb9c5690c859", 28952}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Lighthouse - English Windows Demo -	// Executable scanning reports "3.000.000", VERSION file reports "1.00" -	{{"lighthouse", "Demo", { -		{"resmap.000", 0, "3bdee7a16926975a4729f75cf6b80a92", 1525}, -		{"ressci.000", 0, "3c585827fa4a82f4c04a56a0bc52ccee", 11494351}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Lighthouse - English DOS (from jvprat) -	// Executable scanning reports "3.000.000", VERSION file reports "1.1" -	{{"lighthouse", "", { -		{"resmap.001", 0, "47abc502c0b541b582db28f38dbc6a56", 7801}, -		{"ressci.001", 0, "14e922c47b92156377cb49e241691792", 99591924}, -		{"resmap.002", 0, "c68db5333f152fea6ca2dfc75cad8b34", 7573}, -		{"ressci.002", 0, "175468431a979b9f317c294ce3bc1430", 94628315}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Lighthouse - Spanish DOS (from jvprat) -	// Executable scanning reports "3.000.000", VERSION file reports "1.1" -	{{"lighthouse", "", { -		{"resmap.001", 0, "c5d49b2a8a4eafc92fd041a3a0f2da68", 7846}, -		{"ressci.001", 0, "18553177dbf83fb2cb6c8edcbb174183", 99543093}, -		{"resmap.002", 0, "e7dc85884a2417e2eff9de0c63dd65fa", 7630}, -		{"ressci.002", 0, "3c8d627c555b0e3e4f1d9955bc0f0df4", 94631127}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, -#endif // ENABLE_SCI32 - -	// Mixed-Up Fairy Tales v1.000 - English DOS Non-Interactive Demo -	{{"fairytales", "Demo", { -		{"resource.map", 0, "c2cf672c3f4251e7472d4542af3bf764", 933}, -		{"resource.000", 0, "8be56a3a88c065ee00c02c0e29199f3a", 14643}, -		{"resource.001", 0, "9e33566515b18bee7915db448063bba2", 871853}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Mixed-Up Fairy Tales v1.000 - English DOS (supplied by markcoolio in bug report #2723791) -	// Executable scanning reports "1.000.145" -	{{"fairytales", "", { -		{"resource.map", 0, "9ae5aecc1cb797b11ea5cf0caeea272c", 3261}, -		{"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 923685}, -		{"resource.001", 0, "49c8f7dcd9989e4491a93554bec325b0", 52324}, -		{"resource.002", 0, "6767f8c8585f617aaa91d442f41ae714", 1032989}, -		{"resource.003", 0, "b1288e0821ee358d1ffe877e5900c8ec", 1047565}, -		{"resource.004", 0, "f79daa70390d73746742ffcfc3dc4471", 937580}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Mixed-Up Fairy Tales - English DOS Floppy (from jvprat) -	// Executable scanning reports "1.000.145", Floppy label reports "1.0, 11.13.91", VERSION file reports "1.000" -	{{"fairytales", "", { -		{"resource.map", 0, "66105c02fa8f1785a3fd28957e41cb48", 3249}, -		{"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 984439}, -		{"resource.001", 0, "49c8f7dcd9989e4491a93554bec325b0", 238019}, -		{"resource.002", 0, "564f516d991032e781492592a4eaa275", 1414142}, -		{"resource.003", 0, "dd6cef0c592eadb7e6be9a25307c57a2", 1344719}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Mixed-Up Mother Goose - English Amiga (from www.back2roots.org) -	// Executable scanning reports "1.003.009" -	// SCI interpreter version 0.001.010 -	{{"mothergoose", "", { -		{"resource.map", 0, "4aa28ac93fae03cf854594da13d9229c", 2700}, -		{"resource.001", 0, "fb552ae550ca1dac19ed8f6a3767612d", 262885}, -		{"resource.002", 0, "fb552ae550ca1dac19ed8f6a3767612d", 817191}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Mixed-Up Mother Goose v2.000 - English DOS Floppy (supplied by markcoolio in bug report #2723795) -	// Executable scanning reports "1.001.031" -	{{"mothergoose", "", { -		{"resource.map", 0, "52aae15e493cafd1da7e1c9b657a5bb9", 7026}, -		{"resource.000", 0, "b7ecd8ae9e254e80310b5a668b276e6e", 2948975}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Mixed-Up Mother Goose - English DOS CD (from jvprat) -	// Executable scanning reports "x.yyy.zzz" -	// SCI interpreter version 0.000.999 (just a guess) -	{{"mothergoose", "CD", { -		{"resource.map", 0, "1c7f311b0a2c927b2fbe81ae341fb2f6", 5790}, -		{"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 4369438}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Mixed-Up Mother Goose - English Windows Interactive Demo -	// Executable scanning reports "x.yyy.zzz" -	{{"mothergoose", "Demo", { -		{"resource.map", 0, "87f9dc1cafc4d4fa835fb2f00cf3a6ef", 4560}, -		{"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 2070072}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -#ifdef ENABLE_SCI32 -	// Mixed-Up Mother Goose Deluxe - English Windows/DOS CD (supplied by markcoolio in bug report #2723810) -	// Executable scanning reports "2.100.002" -	{{"mothergoose", "", { -		{"resource.map", 0, "5159a1578c4306bfe070a3e4d8c2e1d3", 4741}, -		{"resource.000", 0, "1926925c95d82f0999590e93b02887c5", 15150768}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, -#endif // ENABLE_SCI32 - -	// Ms. Astro Chicken - English DOS -	// SCI interpreter version 1.000.679 -	{{"msastrochicken", "", { -		{"resource.map", 0, "5b457cbe5042f557e5b610148171f6c0", 1158}, -		{"resource.001", 0, "453ea81ef66a50cbe33ce06302afe47f", 229737}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -#ifdef ENABLE_SCI32 -	// Phantasmagoria - English DOS (from jvprat) -	// Executable scanning reports "2.100.002", VERSION file reports "1.100.000UK" -	{{"phantasmagoria", "", { -		{"resmap.001", 0, "416138651ea828219ca454cae18341a3", 11518}, -		{"ressci.001", 0, "3aae6559aa1df273bc542d5ac6330d75", 65844612}, -		{"resmap.002", 0, "de521d0c7ab32897e7fe58e421c816b7", 12058}, -		{"ressci.002", 0, "3aae6559aa1df273bc542d5ac6330d75", 71588691}, -		{"resmap.003", 0, "25df95bd7da3686f71a0af8784a2b8ca", 12334}, -		{"ressci.003", 0, "3aae6559aa1df273bc542d5ac6330d75", 73651084}, -		{"resmap.004", 0, "e108a3d35794f1721aeea3e62a3f8b3b", 12556}, -		{"ressci.004", 0, "3aae6559aa1df273bc542d5ac6330d75", 75811935}, -		{"resmap.005", 0, "390d81f9e14a3f3ee2ea477135f0288e", 12604}, -		{"ressci.005", 0, "3aae6559aa1df273bc542d5ac6330d75", 78814934}, -		{"resmap.006", 0, "8ea3c954606e80604680f9fe707f15d8", 12532}, -		{"ressci.006", 0, "3aae6559aa1df273bc542d5ac6330d75", 77901360}, -		{"resmap.007", 0, "afbd16ea77869a720afa1c5371de107d", 7972}, -		//{"ressci.007", 0, "3aae6559aa1df273bc542d5ac6330d75", 25859038}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Phantasmagoria 2 - English Windows (from jvprat) -	// Executable scanning reports "3.000.000", VERSION file reports "001.0.06" -	{{"phantasmagoria2", "", { -		{"resmap.001", 0, "0a961e135f4f7effb195158325856633", 1108}, -		{"ressci.001", 0, "53f457cddb0dffc056593905c4cbb989", 24379964}, -		{"resmap.002", 0, "5d3189fe3d4f286f83c5c8031fa3e9f7", 1126}, -		{"ressci.002", 0, "53f457cddb0dffc056593905c4cbb989", 34465805}, -		{"resmap.003", 0, "c92e3c840b827c236ab6671c03760c56", 1162}, -		{"ressci.003", 0, "53f457cddb0dffc056593905c4cbb989", 38606375}, -		{"resmap.004", 0, "8d5cfe19365f71370b87063686f39171", 1288}, -		{"ressci.004", 0, "53f457cddb0dffc056593905c4cbb989", 42447131}, -		{"resmap.005", 0, "8bd5ceeedcbe16dfe55d1b90dcd4be84", 1942}, -		{"ressci.005", 0, "05f9fe2bee749659acb3cd2c90252fc5", 67905112}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, -		0 -	}, -#endif // ENABLE_SCI32 - -	// Pepper's Adventure In Time 1.000 English -	// Executable scanning reports "1.001.072", VERSION file reports "1.000" -	{{"pepper", "", { -		{"resource.map", 0, "72726dc81c1b4c1110c486be77369bc8", 5179}, -		{"resource.000", 0, "670d0c53622429f4b11275caf7f8d292", 5459574}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Pepper - English DOS Non-Interactive Demo -	// Executable scanning reports "1.001.060", VERSION file reports "1.000" -	{{"pepper", "Demo", { -		{"resource.map", 0, "379bb4fb896630b14f2d91ed21e36ba1", 984}, -		{"resource.000", 0, "118f6c31a93ec7fd9a231c61125229e3", 645494}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Pepper - English DOS/Windows Interactive Demo -	// Executable scanning reports "1.001.069", VERSION file reports ".001" -	{{"pepper", "Demo", { -		{"resource.map", 0, "975e8df76106a5c13d12ab674f906a02", 2514}, -		{"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1698164}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Pepper - English DOS Interactive Demo -	// Executable scanning reports "1.001.072", VERSION file reports "1.000" -	{{"pepper", "Demo", { -		{"resource.map", 0, "9c9b7b900651a370dd3fb38d478b1798", 2524}, -		{"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1713544}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Police Quest 1 VGA Remake - English DOS (from the Police Quest Collection) -	// Executable scanning reports "1.001.029", VERSION file reports "2.000" -	{{"pq1sci", "VGA Remake", { -		{"resource.map", 0, "35efa814fb994b1cbdac9611e401da67", 5013}, -		{"resource.000", 0, "e0d5ddf34eda903a38f0837e2aa7145b", 6401433}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Police Quest 2 - English Amiga (from www.back2roots.org) -	// SCI interpreter version 0.000.685 (just a guess) -	{{"pq2", "", { -		{"resource.map", 0, "499de78ae72b7ce219f944c5e7ef0c5b", 3426}, -		{"resource.000", 0, "77f02def3094af804fd2371db25b7100", 250232}, -		{"resource.001", 0, "523db0c07f1da2a822c2c39ee0482544", 179334}, -		{"resource.002", 0, "499737c21a28ac026e11ab817100d610", 511099}, -		{"resource.003", 0, "e008f5d6e2a7c4d4a0da0173e4fa8f8b", 553970}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Police Quest 2 - English DOS Non-Interactive Demo -	// Executable scanning reports "0.000.413" -	{{"pq2", "Demo", { -		{"resource.map", 0, "8b77d0d4650c2052b356cece28294b58", 576}, -		{"resource.001", 0, "376ef6d6eaaeed66e1424bd219c4b9ab", 215398}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Police Quest 2 - English DOS (provided by richiefs in bug report #2670691) -	// SCI interpreter version 0.000.395 -	{{"pq2", "", { -		{"resource.map", 0, "9cff78c4be9e6a4848b6e9377569e3d9", 5700}, -		{"resource.001", 0, "77f02def3094af804fd2371db25b7100", 163291}, -		{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 329367}, -		{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 305819}, -		{"resource.004", 0, "77f02def3094af804fd2371db25b7100", 342149}, -		{"resource.005", 0, "77f02def3094af804fd2371db25b7100", 349899}, -		{"resource.006", 0, "77f02def3094af804fd2371db25b7100", 354991}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Police Quest 2 - English DOS (from the Police Quest Collection) -	// Executable scanning reports "0.000.490" -	{{"pq2", "", { -		{"resource.map", 0, "28a6f471c7900c2c92da40eecb615d9d", 4584}, -		{"resource.001", 0, "77f02def3094af804fd2371db25b7100", 509525}, -		{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 546000}, -		{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 591851}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Police Quest 2 - English DOS (from FRG) -	// SCI interpreter version 0.000.395 -	{{"pq2", "", { -		{"resource.map", 0, "fe019e9773623fcb7da810db9e64c8a9", 4548}, -		{"resource.001", 0, "77f02def3094af804fd2371db25b7100", 509760}, -		{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 542897}, -		{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 586857}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Police Quest 3 - English Amiga -	// Executable scanning reports "1.004.024" -	// SCI interpreter version 1.000.784 -	{{"pq3", "", { -		{"resource.map", 0, "29923fe1ef1f0909b57255d61c558e68", 5742}, -		{"resource.000", 0, "4908e4f4977e8e19c90c29b36a741ffe", 298541}, -		{"resource.001", 0, "0eb943ca807e2f69578821d490770d2c", 836567}, -		{"resource.002", 0, "f7044bb08a1fcbe5077791ed8d4996f0", 691207}, -		{"resource.003", 0, "630bfa65beb05f743552704ac2899dae", 759891}, -		{"resource.004", 0, "7b229fbdf30d670d0728cede3e984a7e", 838663}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Police Quest 3 - German Amiga -	// Executable scanning reports "1.004.024" -	// SCI interpreter version 1.000.784 -	{{"pq3", "", { -		{"resource.map", 0, "357304811fc2bbaa3443fc62d677fe06", 6282}, -		{"resource.000", 0, "49879e6ce7c19151ffa6af1a09763dc7", 324273}, -		{"resource.001", 0, "015e6119badb391ab5f4b36abedb5d4a", 718814}, -		{"resource.002", 0, "1ee419ba252fbed47fbce8399f56f8ad", 674823}, -		{"resource.003", 0, "87361c17fd863b58f98828de68770279", 682288}, -		{"resource.004", 0, "6258d5dd85898d8e218eb8113ebc9059", 722738}, -		{"resource.005", 0, "6258d5dd85898d8e218eb8113ebc9059", 704485}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Police Quest 3 - English DOS (from the Police Quest Collection) -	// Executable scanning reports "T.A00.178", VERSION file reports "1.00" -	// SCI interpreter version 1.000.510 -	{{"pq3", "", { -		{"resource.map", 0, "6457bf0c8ca865a42d9ff5827ab49b89", 5559}, -		{"resource.000", 0, "7659713720d61d9465a59091b7ee63ea", 737253}, -		{"resource.001", 0, "61c7c187d25a8346be0a092d5f037278", 1196787}, -		{"resource.002", 0, "c18e0d408e4f4f40365d42aa15931f67", 1153561}, -		{"resource.003", 0, "8791b9eef53edf77c2dac950142221d3", 1159791}, -		{"resource.004", 0, "1b91e891a3c60a941dac0eecdf83375b", 1143606}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Police Quest 3 - English DOS Non-Interactive Demo -	// Executable scanning reports "T.A00.052" -	// SCI interpreter version 1.000.510 -	{{"pq3", "Demo", { -		{"resource.map", 0, "ec8e58e7663ae5173853abf6c76b52bb", 867}, -		{"resource.000", 0, "277f97771f7a6d89677141f02da313d6", 65150}, -		{"resource.001", 0, "5c5a551b6c86cce2ee75becb90e0b586", 624411}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Police Quest 3 - German DOS (supplied by markcoolio in bug report #2723837) -	// Executable scanning reports "T.A00.178" -	// SCI interpreter version 1.000.510 -	{{"pq3", "", { -		{"resource.map", 0, "8a970edf98eba4c11bb1827aab1694d1", 5625}, -		{"resource.000", 0, "5ee460af3d70c06a745cc482b6c783ba", 865204}, -		{"resource.001", 0, "ff6182bf96c8f8af5bd8c11769c9cbf2", 1183456}, -		{"resource.002", 0, "cce99b96a578b62ff6cebdae8d122feb", 1179358}, -		{"resource.003", 0, "4836f460f4cfc8de61e2df4c45775504", 1180956}, -		{"resource.004", 0, "0c3eb84b9755852d9e795e0d5c9373c7", 1171760}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Police Quest 4 - English DOS Non-Interactive Demo (from FRG) -	// SCI interpreter version 1.001.096 -	{{"pq4", "Demo", { -		{"resource.map", 0, "be56f87a1c4a13062a30a362df860c2f", 1472}, -		{"resource.000", 0, "527d5684016e6816157cd15d9071b11b", 1121310}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -#ifdef ENABLE_SCI32 -	// Police Quest 4 - English DOS (from the Police Quest Collection) -	// Executable scanning reports "2.100.002", VERSION file reports "1.100.000" -	{{"pq4", "", { -		{"resource.map", 0, "379dfe80ed6bd16c47e4b950c4722eac", 11374}, -		{"resource.000", 0, "fd316a09b628b7032248139003369022", 18841068}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Police Quest 4 - English DOS -	// SCI interpreter version 2.000.000 (a guess?) -	{{"pq4", "", { -		{"resource.map", 0, "aed9643158ccf01b71f359db33137f82", 9895}, -		{"resource.000", 0, "da383857b3be1e4514daeba2524359e0", 15141432}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Police Quest 4 - German DOS (supplied by markcoolio in bug report #2723840) -	// SCI interpreter version 2.000.000 (a guess?) -	{{"pq4", "", { -		{"resource.map", 0, "2393ee728ab930b2762cb5889f9b5aff", 9256}, -		{"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730155}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Police Quest: SWAT - English DOS/Windows Demo (from jvprat) -	// Executable scanning reports "2.100.002", VERSION file reports "0.001.200" -	{{"pqswat", "Demo", { -		{"resource.map", 0, "8c96733ef94c21526792f7ca4e3f2120", 1648}, -		{"resource.000", 0, "d8892f1b8c56c8f7704325460f49b300", 3676175}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Police Quest: SWAT - English Windows (from the Police Quest Collection) -	// Executable scanning reports "2.100.002", VERSION file reports "1.0c" -	{{"pqswat", "", { -		{"resmap.001", 0, "de5ea1beb3d9490737aa5fd398fe9765", 6937}, -		{"ressci.001", 0, "7cd5414f54748f90904a46123a52472f", 29467363}, -		{"resmap.002", 0, "ff7a7e0f3dea2c73182b7ea84e3431cc", 6211}, -		{"ressci.002", 0, "e613357f3349c4bfa5a7b7b312be7f97", 25987989}, -		{"resmap.003", 0, "84303aa019fa75a0eb20ba502bc4ccae", 6601}, -		{"ressci.003", 0, "00a755e917c442ca8cf1a1bea689e6fb", 45073980}, -		{"resmap.004", 0, "4228038906f041623e65789500b22285", 6835}, -		{"ressci.004", 0, "b7e619e6ecf62fe65d5116a3a422e5f0", 46223872}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, -		0 -	}, -#endif // ENABLE_SCI32 - -	// Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy (supplied by merkur in bug report #2718784) -	// Executable scanning reports "0.000.566" -	{{"qfg1", "", { -		{"resource.map", 0, "c1dc4470fb947c067567252f62d6c1b6", 6474}, -		{"resource.000", 0, "481b034132106390cb5160fe61dd5f58", 80334}, -		{"resource.001", 0, "4d67acf52833ff45c7f753d6663532e8", 462727}, -		{"resource.002", 0, "439ba9b6dde216e6eb97ef3a9830fbe4", 646869}, -		{"resource.003", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 642203}, -		{"resource.004", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 641688}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by markcoolio in bug report #2723843) -	// Executable scanning reports "0.000.566" -	{{"qfg1", "", { -		{"resource.map", 0, "94bc3f2ae2dad12f1303606740d087ff", 6936}, -		{"resource.000", 0, "481b034132106390cb5160fe61dd5f58", 80334}, -		{"resource.001", 0, "4d67acf52833ff45c7f753d6663532e8", 95498}, -		{"resource.002", 0, "3e2a89d60d385caca5b3394049da4bc4", 271587}, -		{"resource.003", 0, "e56e9fd2f7d2c98774699f7a5087e524", 255998}, -		{"resource.004", 0, "d74cd4290bf60e1409117202e4ce8592", 266415}, -		{"resource.005", 0, "7288ed6d5da89b7a80b4af3897a7963a", 271185}, -		{"resource.006", 0, "69366c2a2f99917199fe1b60a4fee19d", 267852}, -		{"resource.007", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 272747}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Quest for Glory 1 - Japanese PC-98 5.25" Floppy -	// Executable scanning reports "S.old.201" -	{{"qfg1", "8 Colors", { -		{"resource.map", 0, "5cbeb95dd2a4b7cb242b415cc6ec1c47", 6444}, -		{"resource.001", 0, "a21451ef6fa8179bd4b22c4950004c44", 859959}, -		{"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1136968}, -		{"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 769897}, -		{NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 1 - Japanese PC-98 5.25" Floppy -	// Executable scanning reports "S.old.201" -	{{"qfg1", "16 Colors", { -		{"resource.map", 0, "3ecaba33bf77cb434067a0b8aee15097", 6444}, -		{"resource.001", 0, "a21451ef6fa8179bd4b22c4950004c44", 864754}, -		{"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1147121}, -		{"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 777575}, -		{NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 1 - English Amiga -	// Executable scanning reports "1.002.020" -	// SCI interpreter version 0.000.685 -	{{"qfg1", "", { -		{"resource.map", 0, "e65034832f0c9df1dc22128227b782d0", 6066}, -		{"resource.000", 0, "1c0255dea2d3cd71eee9f2db201eee3f", 111987}, -		{"resource.001", 0, "a270012fa74445d74c044d1b65a9ff8c", 143570}, -		{"resource.002", 0, "e64004e020fdf1813be52b639b08be89", 553201}, -		{"resource.003", 0, "16cd4414c37ae3bb6d6da33dce8e25e8", 654096}, -		{"resource.004", 0, "16cd4414c37ae3bb6d6da33dce8e25e8", 689124}, -		{"resource.005", 0, "5f3386ef2f2b1254e4a066f5d9027324", 609529}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 1 - English DOS -	// SCI interpreter version 0.000.629 -	{{"qfg1", "", { -		{"resource.map", 0, "74a108a7fb345bfc84f4113b6e5241bb", 6432}, -		{"resource.000", 0, "40332d3ebfc70a4b6a6a0443c2763287", 79181}, -		{"resource.001", 0, "917fcef303e9489597154727baaa9e07", 461422}, -		{"resource.002", 0, "05ddce5f437a516b89ede2438fac09d8", 635734}, -		{"resource.003", 0, "951299a82a8134ed12c5c18118d45c2f", 640483}, -		{"resource.004", 0, "951299a82a8134ed12c5c18118d45c2f", 644443}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 1 VGA Remake - English DOS -	// Executable scanning reports "2.000.411" -	{{"qfg1", "VGA Remake", { -		{"resource.map", 0, "a731fb6c9c0b282443f7027bc8694d4c", 8469}, -		{"resource.000", 0, "ecace1a2771846b1a8aa1afdd44111a0", 6570147}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 1 VGA Remake - English DOS Non-Interactive Demo (from FRG) -	// SCI interpreter version 1.001.029 -	{{"qfg1", "VGA Remake Demo", { -		{"resource.map", 0, "ac0257051c95a59c0cdc0be24d9b11fa", 729}, -		{"resource.000", 0, "ec6f5cf369054dd3e5392995e9975b9e", 768218}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 2 - English Amiga -	// Executable scanning reports "1.003.004" -	// SCI interpreter version 0.001.010 -	{{"qfg2", "", { -		{"resource.map", 0, "365ea1033ba26d227ec4007be88c59cc", 7596}, -		{"resource.000", 0, "810245be50fde5a67e3ea95e876e3e64", 233341}, -		{"resource.001", 0, "7a5fde9875211ed67a896fc0d91940c8", 127294}, -		{"resource.002", 0, "dcf6bc2c18660d7ad532fb61861eb721", 543644}, -		{"resource.003", 0, "dcf6bc2c18660d7ad532fb61861eb721", 565044}, -		{"resource.004", 0, "dcf6bc2c18660d7ad532fb61861eb721", 466630}, -		{"resource.005", 0, "a77d2576c842b2b06da57d4ac8fc51c0", 579975}, -		{"resource.006", 0, "ccf5dba33e5cab6d5872838c0f8db44c", 500039}, -		{"resource.007", 0, "4c9fc1587545879295cb9627f56a2cb8", 575056}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 2 - English (from FRG) -	// Executable scanning reports "1.000.072" -	{{"qfg2", "", { -		{"resource.map", 0, "bc79c5685c00edab3ad6df18691703bc", 6906}, -		{"resource.000", 0, "a17e374c4d33b81208c862bc0ffc1a38", 212119}, -		{"resource.001", 0, "e08d7887e30b12008c40f9570447711a", 867866}, -		{"resource.002", 0, "df137dc7869cab07e1149ba2333c815c", 790750}, -		{"resource.003", 0, "b192607c42f6960ecdf2ad2e4f90e9bc", 972804}, -		{"resource.004", 0, "cd2de58e27665d5853530de93fae7cd6", 983617}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 2 - English DOS -	// Executable scanning reports "1.000.072" -	{{"qfg2", "", { -		{"resource.map", 0, "be23af27e9557bf232efe213ac7f277c", 8166}, -		{"resource.000", 0, "a17e374c4d33b81208c862bc0ffc1a38", 212120}, -		{"resource.001", 0, "e08d7887e30b12008c40f9570447711a", 331973}, -		{"resource.002", 0, "df137dc7869cab07e1149ba2333c815c", 467505}, -		{"resource.003", 0, "df137dc7869cab07e1149ba2333c815c", 502560}, -		{"resource.004", 0, "df137dc7869cab07e1149ba2333c815c", 488541}, -		{"resource.005", 0, "df137dc7869cab07e1149ba2333c815c", 478688}, -		{"resource.006", 0, "b1944bd664ddbd2859cdaa0c4a0d6281", 507489}, -		{"resource.007", 0, "cd2de58e27665d5853530de93fae7cd6", 490794}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 2 - English DOS Non-Interactive Demo -	// Executable scanning reports "1.000.046" -	{{"qfg2", "Demo", { -		{"resource.map", 0, "e75eb86bdd517b3ef709058249986a87", 906}, -		{"resource.001", 0, "9b098f9e1008abe30e56c93b896494e6", 362123}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, -	 -	// Quest for Glory 3 - English DOS Non-Interactive Demo (from FRG) -	// Executable scanning reports "1.001.021", VERSION file reports "1.000, 0.001.059, 6.12.92" -	{{"qfg3", "Demo", { -		{"resource.map", 0, "fd71de9b588a45f085317caacf050e91", 687}, -		{"resource.000", 0, "b6c69bf6c18bf177492249fe81fc6a6d", 648702}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 3 - English DOS -	// SCI interpreter version 1.001.050 -	{{"qfg3", "", { -		{"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958}, -		{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 3 - German DOS (supplied by markcoolio in bug report #2723846) -	// Executable scanning reports "L.rry.083" -	{{"qfg3", "", { -		{"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958}, -		{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868042}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 3 - Spanish DOS CD (from jvprat) -	// Executable scanning reports "L.rry.083", VERSION file reports "1.000.000, June 30, 1994" -	{{"qfg3", "", { -		{"resource.map", 0, "10809197c33a5e62819311d8a2f73f85", 5978}, -		{"resource.000", 0, "ba7ac86155e4c531e46cd73c86daa80a", 5884098}, -		{"resource.msg", 0, "a63974730d294dec0bea10057c36e506", 256014}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Quest for Glory 4 - English DOS Non-Interactive Demo (from FRG) -	// SCI interpreter version 1.001.069 (just a guess) -	{{"qfg4", "Demo", { -		{"resource.map", 0, "1ba7c7ae1efb315326d45cb931569b1b", 922}, -		{"resource.000", 0, "41ba03f0b188b029132daa3ece0d3e14", 623154}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -#ifdef ENABLE_SCI32 -	// Quest for Glory 4 1.1 Floppy - English DOS (supplied by markcool in bug report #2723852) -	// SCI interpreter version 2.000.000 (a guess?) -	{{"qfg4", "", { -		{"resource.map", 0, "685bdb1ed47bbbb0e5e25db392da83ce", 9301}, -		{"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11004993}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 4 1.1 Floppy - German DOS (supplied by markcool in bug report #2723850) -	// SCI interpreter version 2.000.000 (a guess?) -	{{"qfg4", "", { -		{"resource.map", 0, "9e0abba8746f40565bc7eb5720522ecd", 9301}, -		{"resource.000", 0, "57f22cdc54eeb35fce1f26b31b5c3ee1", 11076197}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Quest for Glory 4 - English DOS/Windows (from jvprat) -	// Executable scanning reports "2.100.002", VERSION file reports "1.0" -	{{"qfg4", "", { -		{"resource.map", 0, "aba367f2102e81782d961b14fbe3d630", 10246}, -		{"resource.000", 0, "263dce4aa34c49d3ad29bec889007b1c", 11571394}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -#if 0 -	// NOTE: This version looks to be exactly the same as the English one -	// Perhaps it's the English one? - -	// Quest for Glory 4 - German DOS/Windows (from PCJoker 2/98) -	{{"qfg4", "", { -		{"resource.map", 0, "aba367f2102e81782d961b14fbe3d630", 10246}, -		{"resource.000", 0, "263dce4aa34c49d3ad29bec889007b1c", 11571394}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, -#endif - -	// Quest for Glory 4 - German DOS/Windows Disk V1.1 (from PCJoker 2/89) -	// SCI interpreter version 2.000.000 (a guess?) -	{{"qfg4", "", { -		{"resource.map", 0, "9e0abba8746f40565bc7eb5720522ecd", 9301}, -		{"resource.000", 0, "57f22cdc54eeb35fce1f26b31b5c3ee1", 11076197}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, -#endif - -	// Slater & Charlie go camping -	{{"slater", "", { -		{"resource.000", 0, "1846b57fe84774be72f7c50ab3c90df0", 2256126}, -		{"resource.map", 0, "21f85414124dc23e54544a5536dc35cd", 4044}, -		{"resource.msg", 0, "c44f51fb955eae266fecf360ebcd5ad2", 1132}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -#ifdef ENABLE_SCI32 -	// RAMA - English DOS/Windows Demo -	// Executable scanning reports "2.100.002", VERSION file reports "000.000.008" -	{{"rama", "Demo", { -		{"resmap.001", 0, "775304e9b2a545156be4d94209550094", 1393}, -		{"ressci.001", 0, "259437fd75fdf51e8207fda8c01fa4fd", 2334384}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// RAMA - English Windows (from jvprat) -	// Executable scanning reports "3.000.000", VERSION file reports "1.100.000" -	{{"rama", "", { -		{"resmap.001", 0, "3bac72a1910a563f8f92cf5b77c8b7f2", 8338}, -		{"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70588050}, -		{"resmap.002", 0, "83c2aa4653a985ab4b49ff60532ed08f", 12082}, -		{"ressci.002", 0, "2a68edd064e5e4937b5e9c74b38f2082", 128562138}, -		{"resmap.003", 0, "31ef4c0621711585d031f0ae81707251", 1636}, -		{"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6860492}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// RAMA - Italian Windows CD (from glorifindel) -	// SCI interpreter version 3.000.000 (a guess?) -	{{"rama", "", { -		{"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70611091}, -		{"resmap.001", 0, "70ba2ff04a2b7fb2c52420ba7fbd47c2", 8338}, -		{NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformWindows, 0, GUIO_NONE}, -		0 -	}, - -	// Shivers - English Windows (from jvprat) -	// Executable scanning reports "2.100.002", VERSION file reports "1.02" -	{{"shivers", "", { -		{"resmap.000", 0, "f2ead37749ed8f6535a2445a7d05a0cc", 46525}, -		{"ressci.000", 0, "4294c6d7510935f2e0a52e302073c951", 262654836}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Shivers - German Windows (from Tobis87) -	{{"shivers", "", { -		{"resmap.000", 0, "f483d0a1f78334c18052e92785c3086e", 46537}, -		{"ressci.000", 0, "6751b144671e2deed919eb9d284b07eb", 262390692}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Shivers - English Windows Demo -	// Executable scanning reports "2.100.002" -	{{"shivers", "Demo", { -		{"resmap.000", 0, "d9e0bc5eddefcbe47f528760085d8927", 1186}, -		{"ressci.000", 0, "3a93c6340b54e07e65d0e5583354d186", 10505469}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Shivers2 - English Windows Demo -	// Executable scanning reports "3.000.000" -	{{"shivers2", "Demo", { -		{"resmap.000", 0, "d8659188b84beaef076bd869837cd530", 634}, -		{"ressci.000", 0, "7fbac0807a044c9543e8ac376d200e59", 4925003}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, -#endif // ENABLE_SCI32 - -	// Slater & Charlie Go Camping - English DOS Demo -	// Executable scanning reports "1.cfs.081", VERSION file reports "1.000" -	{{"slater", "Demo", { -		{"resource.map", 0, "61b4f74039399e5aa1e737b16d0fc023", 1409}, -		{"resource.msg", 0, "1aeafe2b495de288d002109650b66614", 1364}, -		{"resource.000", 0, "8e10d4f05c1fd9f883384fa38a898489", 377394}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 1 VGA Remake - English Amiga (from www.back2roots.org) -	// SCI interpreter version 1.000.510 (just a guess) -	{{"sq1sci", "VGA Remake", { -		{"resource.map", 0, "106484b372af1d4cbf866472cc2813dc", 6396}, -		{"resource.000", 0, "cc9d6ace343661ae51ec8bd6e6b00a8c", 340944}, -		{"resource.001", 0, "59efcfa2268d2f8608f544e2674d8151", 761721}, -		{"resource.002", 0, "f00ef883128bf5fc2fbb888cdd7adf25", 814461}, -		{"resource.003", 0, "2588c1c2ca8b9bed0e3411948c0856a9", 839302}, -		{"resource.004", 0, "b25a1539c71701f7715f738c5037e9a6", 775515}, -		{"resource.005", 0, "640ffe1a9acde392cc33cc1b1a528328", 806324}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 1 VGA Remake - English DOS (from the Space Quest Collection) -	// Executable scanning reports "T.A00.081", VERSION file reports "2.000" -	// SCI interpreter version 1.000.510 (just a guess) -	{{"sq1sci", "VGA Remake", { -		{"resource.map", 0, "38a74d8f555a2da9ca4f21d14e3c1d33", 5913}, -		{"resource.000", 0, "e9d866534f8c84de82e25f2631ff258c", 1016436}, -		{"resource.001", 0, "a89b7b52064c75b1985b289edc2f5c69", 1038757}, -		{"resource.002", 0, "a9e847c687529481f3a22b9bf01f45f7", 1169831}, -		{"resource.003", 0, "c47600e50c6fc591957ae0c5020ee7b8", 1213262}, -		{"resource.004", 0, "e19ea4ad131472f9238590f2e1d40289", 1203051}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 1 VGA Remake - English Non-Interactive Demo (from FRG) -	// SCI interpreter version 1.000.181 -	{{"sq1sci", "VGA Remake Demo", { -		{"resource.map", 0, "5af709ac5e0e923e0b8174f49978c30e", 636}, -		{"resource.001", 0, "fd99ea43f57576ded7c86036996346cf", 507642}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 1 VGA Remake - Spanish DOS Floppy (from jvprat) -	// Executable scanning reports "T.A00.081", VERSION file reports "2.000" -	// SCI interpreter version 1.000.510 (just a guess) -	{{"sq1sci", "VGA Remake", { -		{"resource.map", 0, "cee2a67fa7f8f1f520f398110ca1c37e", 6111}, -		{"resource.000", 0, "945081a73211e0c40e62f709edcd8d1d", 970657}, -		{"resource.001", 0, "94692dc84c85c93bb8850f58aebf3cfc", 1085687}, -		{"resource.002", 0, "fc9ad3357e4cedec1611ad2b67b193a9", 1175465}, -		{"resource.003", 0, "8c22700a02991b763f512f837636b3ca", 1211307}, -		{"resource.004", 0, "9b78228ad4f9f335fedf74f1812dcfca", 513325}, -		{"resource.005", 0, "7d4ebcb745c0bf8fc42e4013f52ecd49", 1101812}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 3 - English Amiga (from www.back2roots.org) -	// SCI interpreter version 0.000.453 (just a guess) -	{{"sq3", "", { -		{"resource.map", 0, "bad41385acde6d677a8d55a7b20437e3", 5868}, -		{"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 171636}, -		{"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 754432}, -		{"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 746496}, -		{"resource.004", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 761984}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Space Quest 3 - German Amiga -	// Executable scanning reports "1.004.006" -	// SCI interpreter version 0.000.453 (just a guess) -	{{"sq3", "", { -		{"resource.map", 0, "44f53185fdf3f44f946e9cac3ca6588b", 6348}, -		{"resource.001", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 238664}, -		{"resource.002", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 642014}, -		{"resource.003", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 712374}, -		{"resource.004", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 545053}, -		{"resource.005", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 687507}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 3 - English DOS Non-Interactive Demo -	// SCI interpreter version 0.000.453 -	{{"sq3", "Demo", { -		{"resource.map", 0, "ec66ac2b1ce58b2575ba00b65058de1a", 612}, -		{"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 180245}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Space Quest 3 - English DOS (provided by richiefs in bug report #2670691) -	// SCI interpreter version 0.000.453 -	{{"sq3", "", { -		{"resource.map", 0, "fee82d211c3918a90ce3b476d3dbb245", 5484}, -		{"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 485158}, -		{"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 720244}, -		{"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 688367}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Space Quest 3 - English DOS (from the Space Quest Collection) -	// Executable scanning reports "0.000.685", VERSION file reports "1.018" -	{{"sq3", "", { -		{"resource.map", 0, "55e91aeef1705bce2a9b79172682f36d", 5730}, -		{"resource.001", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 490247}, -		{"resource.002", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 715777}, -		{"resource.003", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 703370}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 3 - German DOS (from Tobis87) -	// SCI interpreter version 0.000.453 (?) -	{{"sq3", "", { -		{"resource.map", 0, "4965c78b5eff50d5e4148ce114594ba8", 7584}, -		{"resource.001", 0, "9107c2aa5398e28b5c5406df13491f85", 117869}, -		{"resource.002", 0, "9107c2aa5398e28b5c5406df13491f85", 336101}, -		{"resource.003", 0, "9107c2aa5398e28b5c5406df13491f85", 350391}, -		{"resource.004", 0, "9107c2aa5398e28b5c5406df13491f85", 349750}, -		{"resource.005", 0, "9107c2aa5398e28b5c5406df13491f85", 322107}, -		{"resource.006", 0, "9107c2aa5398e28b5c5406df13491f85", 320643}, -		{"resource.007", 0, "9107c2aa5398e28b5c5406df13491f85", 344287}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		GF_FOR_SCI0_BEFORE_629 -	}, - -	// Space Quest 3 v1.052 - German DOS (supplied by markcoolio in bug report #2723860) -	// Executable scanning reports "S.old.114" -	{{"sq3", "", { -		{"resource.map", 0, "f0dd735098c254f584878649c6f08dbc", 5154}, -		{"resource.001", 0, "9107c2aa5398e28b5c5406df13491f85", 567245}, -		{"resource.002", 0, "9107c2aa5398e28b5c5406df13491f85", 596768}, -		{"resource.003", 0, "9107c2aa5398e28b5c5406df13491f85", 693573}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 4 - English Amiga -	// Executable scanning reports "1.004.024" -	// SCI interpreter version 1.000.200 -	{{"sq4", "", { -		{"resource.map", 0, "d87ae90031e7fd04f32a27db054f5c9c", 6174}, -		{"resource.000", 0, "19671ac620a0a4720a1937c20c2e24a1", 323309}, -		{"resource.001", 0, "abca51a4c896df550f095a2db71dce46", 805915}, -		{"resource.002", 0, "5667852471ba5b7f5b9a770eabd07df2", 796615}, -		{"resource.003", 0, "6ec43464f6a17e612636e2928fd9471c", 803868}, -		{"resource.004", 0, "1887ed88bb34ae7238650e8f77f26315", 798226}, -		{"resource.005", 0, "3540d1cc84d674cf4b2c898b88a3b563", 790296}, -		{"resource.006", 0, "ade814bc4d56244c156d9e9bcfebbc11", 664085}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 4 - German Amiga (from www.back2roots.org) -	// SCI interpreter version 1.000.200 (just a guess) -	{{"sq4", "", { -		{"resource.map", 0, "79641c0d43408e33c251a1d494d2575e", 6252}, -		{"resource.000", 0, "feff51c52146b3a31d4793c718279e13", 345170}, -		{"resource.001", 0, "ab33060bfebe32450c0b8d9a3a066efc", 822470}, -		{"resource.002", 0, "f79fd6a62da082addb205ed6cef99629", 810458}, -		{"resource.003", 0, "f4c21da916f450d4b893b4cba6120866", 815854}, -		{"resource.004", 0, "99c6a017da5e769a3b427ca52c8a564f", 824601}, -		{"resource.005", 0, "10ee1709e6559c724676d058199b75b5", 818745}, -		{"resource.006", 0, "67fb188b191d88efe8414af6ea297b93", 672675}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 4 - English DOS -	// Executable scanning reports "1.000.753" -	// SCI interpreter version 1.000.200 (just a guess) -	{{"sq4", "", { -		{"resource.map", 0, "a18088c8aceb06025dbc945f29e02935", 5124}, -		{"resource.000", 0, "e1f46832cd2458796028e054a0466031", 5502009}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 4 - English DOS -	// Executable scanning reports "1.000.753" -	// SCI interpreter version 1.000.200 (just a guess) -	{{"sq4", "", { -		{"resource.map", 0, "71ccf4f82ac4efb588731acfb7bf2603", 5646}, -		{"resource.000", 0, "e1f46832cd2458796028e054a0466031", 933928}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 4 1.052 - English DOS Floppy (supplied by markcoolio in bug report #2723865) -	// Executable scanning reports "1.000.753" -	// SCI interpreter version 1.000.200 (just a guess) -	{{"sq4", "", { -		{"resource.map", 0, "98852d6379622001efd0b50ae93c9a30", 5928}, -		{"resource.000", 0, "e1f46832cd2458796028e054a0466031", 173330}, -		{"resource.001", 0, "cc2f89e6057e05b040566b3699df7288", 1247215}, -		{"resource.002", 0, "9c342cd76b421369406d6fafd7b1a285", 1218373}, -		{"resource.003", 0, "96fa33d89d838bc3f671c5b953e7a896", 1240130}, -		{"resource.004", 0, "ff9c87da3bc53473fdee8b9d3edbc93c", 1200631}, -		{"resource.005", 0, "e33019ac19f755ae33fbf49b4fc9066c", 1053294}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 4 - German DOS (from Tobis87) -	// SCI interpreter version 1.000.200 (just a guess) -	{{"sq4", "", { -		{"resource.map", 0, "71715e775e3791178d606cfe6c7e1fb9", 6339}, -		{"resource.000", 0, "5f6a1fff40584ee807efd547899b1ba5", 206032}, -		{"resource.001", 0, "e924cf86a72ada7736043f045cce345f", 1065442}, -		{"resource.002", 0, "e18d731c3fba51333a7f402e454714a5", 858402}, -		{"resource.003", 0, "7c2e7508af1a6af877d921e476f70b5e", 1172738}, -		{"resource.004", 0, "b8d6efbd3235329bfe844c794097b2c9", 1064761}, -		{"resource.005", 0, "47ee647b5b12232d27e63cc627c25899", 1156765}, -		{"resource.006", 0, "dfb023e4e2a1e7a00fa18f9ede72a91b", 924059}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 4 - Italian DOS Floppy (from glorifindel) -	// SCI interpreter version 1.000.200 (just a guess) -	{{"sq4", "", { -		{"resource.map", 0, "e753dfa96d68dd95f84f6cd80479a35e", 6135}, -		{"resource.000", 0, "2ac39ff61e369b79f3d7a4ad514f8e29", 203170}, -		{"resource.001", 0, "99a6df6d366b3f061271ff3450ac0d32", 1286269}, -		{"resource.002", 0, "a6a8d7a24dbb7a266a26b084e7275e89", 1241124}, -		{"resource.003", 0, "5289000399d503b59da9e23129256f1a", 1325546}, -		{"resource.004", 0, "4277c61bed40a50dadc4b5a344520af2", 1251000}, -		{"resource.005", 0, "5f885abd335978e2fd4e5f886d7676c8", 1102880}, -		{NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 4 - Japanese PC-98 5.25" Floppy -	// SCI interpreter version 1.000.1068 -	{{"sq4", "", { -		{"resource.map", 0, "ca7bba01019222b6f3e54e9051067a99", 5283}, -		{"resource.000", 0, "161d719f38ed98d33f058a8cf3dc09c3", 952909}, -		{"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088}, -		{"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249}, -		{NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 4 - Japanese PC-98 5.25" Floppy -	// SCI interpreter version 1.000.1068 -	{{"sq4", "", { -		{"resource.map", 0, "ca7bba01019222b6f3e54e9051067a99", 5283}, -		{"resource.000", 0, "161d719f38ed98d33f058a8cf3dc09c3", 952909}, -		{"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088}, -		{"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 4 - English DOS CD (from the Space Quest Collection) -	// Executable scanning reports "1.001.064", VERSION file reports "1.0" -	{{"sq4", "CD", { -		{"resource.map", 0, "ed90a8e3ccc53af6633ff6ab58392bae", 7054}, -		{"resource.000", 0, "63247e3901ab8963d4eece73747832e0", 5157378}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Space Quest 4 - Spanish DOS CD (from jvprat) -	// Executable scanning reports "1.SQ4.057", VERSION file reports "1.000" -	// SCI interpreter version 1.000.200 (just a guess) -	{{"sq4", "", { -		{"resource.map", 0, "51bcb305568ec19713f8b79727f10071", 6159}, -		{"resource.000", 0, "8000a55aebc50a68b7cce07a8c33758c", 204315}, -		{"resource.001", 0, "99a6df6d366b3f061271ff3450ac0d32", 1269094}, -		{"resource.002", 0, "a6a8d7a24dbb7a266a26b084e7275e89", 1240998}, -		{"resource.003", 0, "42a307941edeb1a3be31daeb2e4be90b", 1319306}, -		{"resource.004", 0, "776fba81c110d1908776232cbe190e20", 1253752}, -		{"resource.005", 0, "55fae26c2a92f16ef72c1e216e827c0f", 1098328}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Space Quest 4 - Spanish DOS Floppy (from jvprat) -	// Executable scanning reports "1.SQ4.056", VERSION file reports "1.000" -	// SCI interpreter version 1.000.200 (just a guess) -	{{"sq4", "", { -		{"resource.map", 0, "41543ae71036046fef69df29a838ee05", 5589}, -		{"resource.000", 0, "2ac39ff61e369b79f3d7a4ad514f8e29", 242470}, -		{"resource.001", 0, "567608beb69d9dffdb42a8f39cb11a5e", 994323}, -		{"resource.002", 0, "74c62fa2146ff3b3b2ea2b3fb95b9af9", 1140801}, -		{"resource.003", 0, "42a307941edeb1a3be31daeb2e4be90b", 1088408}, -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 4 1.000 - German DOS Floppy (supplied by markcoolio in bug report #2723862) -	// Executable scanning reports "1.SQ4.030" -	// SCI interpreter version 1.000.200 (just a guess) -	{{"sq4", "", { -		{"resource.map", 0, "8f08b97ca093f370c56d99715b015554", 6153}, -		{"resource.000", 0, "5f6a1fff40584ee807efd547899b1ba5", 206032}, -		{"resource.001", 0, "99a6df6d366b3f061271ff3450ac0d32", 1270577}, -		{"resource.002", 0, "a6a8d7a24dbb7a266a26b084e7275e89", 1242817}, -		{"resource.003", 0, "47ee647b5b12232d27e63cc627c25899", 1321146}, -		{"resource.004", 0, "c06350184a490c10eb4585fff0aa3192", 1254368}, -		{"resource.005", 0, "b8d6efbd3235329bfe844c794097b2c9", 1098717}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 5 - English DOS (from the Space Quest Collection) -	// Executable scanning reports "1.001.068", VERSION file reports "1.04" -	{{"sq5", "", { -		{"resource.map", 0, "66317c12ac6e818d1f7c17e83c1d9819", 6143}, -		{"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486}, -		{"resource.msg", 0, "bb8ad78793c26bdb3f77498b1d6515a9", 125988}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 5 - English DOS -	// SCI interpreter version 1.001.067 -	{{"sq5", "", { -		{"resource.map", 0, "8bde0a9adb9a3e9aaa861826874c9834", 6473}, -		{"resource.000", 0, "f4a48705764544d7cc64a7bb22a610df", 6025184}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 5 v1.04 - German DOS (from Tobis87, updated information by markcool from bug reports #2723935 and #2724762) -	// SCI interpreter version 1.001.068 -	{{"sq5", "", { -		{"resource.map", 0, "66317c12ac6e818d1f7c17e83c1d9819", 6143}, -		{"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486}, -		{"resource.msg", 0, "7c71cfc36153cfe07b450423a51f7e68", 146282}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 5 - Italian DOS Floppy (from glorifindel) -	// SCI interpreter version 1.001.068 (just a guess) -	{{"sq5", "", { -		{"resource.000", 0, "5040026519f37199f3616fb1d4704dff", 6047170}, -		{"resource.map", 0, "5b09168baa2f6e2e22787429b2d72f54", 6492}, -		{NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -#ifdef ENABLE_SCI32 -	// Space Quest 6 - English DOS/Win3.11 CD (from the Space Quest Collection) -	// Executable scanning reports "2.100.002", VERSION file reports "1.0" -	{{"sq6", "", { -		{"resource.map", 0, "6dddfa3a8f3a3a513ec9dfdfae955005", 10528}, -		{"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Space Quest 6 - English DOS/Win3.11 CD ver 1.11 (from FRG) -	// SCI interpreter version 2.100.002 (just a guess) -	{{"sq6", "", { -		{"resource.map", 0, "e0615d6e4e10e37ae42e6a2a95aaf145", 10528}, -		{"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// Space Quest 6 - English DOS/Win3.11 Interactive Demo (from FRG) -	// SCI interpreter version 2.100.002 (just a guess) -	{{"sq6", "Demo", { -		{"resource.map", 0, "368f07b07433db3f819fa3fa0e5efee5", 2572}, -		{"resource.000", 0, "ab12724e078dea34b624e0d2a38dcd7c", 2272050}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Space Quest 6 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723884) -	// SCI interpreter version 2.100.002 (just a guess) -	{{"sq6", "", { -		{"resource.map", 0, "664d797415484f85c90b1b45aedc7686", 10534}, -		{"resource.000", 0, "ba87ba91e5bdabb4169dd0df75777722", 40933685}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, -#endif // ENABLE_SCI32 - -	// The Island of Dr. Brain - English DOS CD (from jvprat) -	// Executable scanning reports "1.001.053", VERSION file reports "1.0 10.27.92" -	{{"islandbrain", "", { -		{"resource.map", 0, "2388efef8430b041b0f3b00b9050e4a2", 3281}, -		{"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 2103560}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, -		0 -	}, - -	// The Island of Dr. Brain - English DOS (from Quietust) -	// Executable scanning reports "1.001.053", VERSION file reports "1.1 2.3.93" -	{{"islandbrain", "", { -		{"resource.map", 0, "3c07da06bdd1689f9d07af78fb94d0ec", 3101}, -		{"resource.000", 0, "ecc686e0034fb4d41de077ac7167b3cf", 1947866}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// The Island of Dr. Brain - English DOS Non-Interactive Demo -	// SCI interpreter version 1.001.053 (just a guess) -	{{"islandbrain", "Demo", { -		{"resource.map", 0, "a8e5ca8ed1996974afa59f4c45e06195", 986}, -		{"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 586560}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -#ifdef ENABLE_SCI32 -	// Torin's Passage - English Windows Interactive Demo -	// SCI interpreter version 2.100.002 (just a guess) -	{{"torin", "Demo", { -		{"resmap.000", 0, "9a3e172cde9963d0a969f26469318cec", 3403}, -		{"ressci.000", 0, "db3e290481c35c3224e9602e71e4a1f1", 5073868}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, -		0 -	}, - -	// Torin's Passage - English Windows -	// SCI interpreter version 2.100.002 (just a guess) -	{{"torin", "", { -		{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, -		{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, -		{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Torin's Passage - Spanish Windows (from jvprat) -	// Executable scanning reports "2.100.002", VERSION file reports "1.0" -	{{"torin", "", { -		{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, -		{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, -		// TODO: depend on one of the patches? -		{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Torin's Passage - French Windows -	// SCI interpreter version 2.100.002 (just a guess) -	{{"torin", "", { -		{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, -		{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, -		{NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Torin's Passage - German Windows -	// SCI interpreter version 2.100.002 (just a guess) -	{{"torin", "", { -		{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, -		{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, -		{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, -		0 -	}, - -	// Torin's Passage - Italian Windows CD (from glorifindel) -	// SCI interpreter version 2.100.002 (just a guess) -	{{"torin", "", { -		{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, -		{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, -		{NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformWindows, 0, GUIO_NONE}, -		0 -	}, -#endif // ENABLE_SCI32 - -	// SCI Fanmade Games -	FANMADE("Al Pond 2: Island Quest", "9625372e710d1a95d2027b48f9e325af", 1506, "a0f9aa65b9bf3d8703adff5a621f243c", 889843), -	FANMADE("Al Pond: Island Quest 2", "4cba6a5a4c8f66f21935ed78b0511a92", 870, "876587dc9a5ec569287a3dc4b29139d8", 613769), -	FANMADE("Another DG Game: I Want My C64 Back", "4a8ca7ca2abd18899ef856f47665e2e9", 588, "12ff558d20c72e42cc6adb408f34d6d8", 150513), -	FANMADE_L("Another DG Game: I Want My C64 Back", "13dc1d9ebc57daf8895412eee5e39fea", 576, "e2ad60b3a280171429db5c85f158f84a", 141697, Common::FR_FRA), -	FANMADE("Bluntman and Chronic (Politically Correct Version)", "c3ef9fa6c7c5fb840078bf28d87c7f8b", 1362, "441636a9f6f86710844868fded868ee7", 596688), -	FANMADE("Cascade Quest", "c94efc10d18c040b6e22a1dc6d3adfe1", 3468, "8ada33dfa945f81531e5508240b573de", 1432195), -	FANMADE("Curt Quest 1.0", "b0e555370380d218968a40a68eaaaffc", 1146, "c851182cdf6fc6a81b840f4d4875f1a0", 307165), -	FANMADE("Curt Quest 1.1", "54084c29346683296e45ef32d7ae74f3", 1128, "c851182cdf6fc6a81b840f4d4875f1a0", 302000), -	FANMADE("Demo Quest", "c89a0c9e0a4e4af0ecedb300a3b31dbf", 384, "a32f3495ba24764cba091119cc3f1e13", 160098), -	FANMADE("Dr. Jummybummy's Space Adventure 2", "6ae6cb7de423f51736d9487b4ca0c6da", 810, "26e5b563f578e104d79689f36568b7cf", 394670), -	FANMADE_L("Grostesteing: Plus Mechant que Jamais", "ec9a97ccb134f69249f6ea8b16c13d8e", 1500, "b869f5f11bfe2ab5f67f4f0c618f2ce1", 464657, Common::FR_FRA), // FIXME: Accent -	FANMADE("Jim Quest", "0af50be1d3f0cb77a09137709a76ef4f", 960, "9c042c136548b20d9183495668e03526", 496446), -	FANMADE("Knight's Quest Demo 1.0", "5e816edf993956752ed06fccfeeae6d9", 1260, "959321f88a22905fa1f8c6d897874744", 703836), -	FANMADE("LockerGnome Quest", "3eeff9130206cad0c4e1551e2b9dd2c5", 420, "ae05ca90806fd90cc43f147c82d3547c", 158906), -	FANMADE("New Year's Mystery", "efd1beb5120293725065c95959144f81", 714, "b3bd3c2372ed6efa28adb12403c4c31a", 305027), -	FANMADE("Osama", "db8f1710453cfbecf4214b2946970043", 390, "7afd75d4620dedf97a84ae8f0a7523cf", 123827), -	FANMADE("Quest for the Cheat", "a359d4cf27f98264b42b55c017671214", 882, "8a943029f73c4bc85d454b7f473455ba", 455209), -	FANMADE("SCI Companion Template", "ad54d4f504086cd597aa2348d0aa3b09", 354, "6798b7b601ce8154c1d1bc0f0edcdd18", 113061), -	FANMADE("SCI Studio Template 3.0", "ca0dc8d586e0a8670b7621cde090b532", 354, "58a48ee692a86c0575e6bd0b00a92b9a", 113097), -	FANMADE("SCI Quest", "9067e1f1e54436d2dbfce855524bc84a", 552, "ffa7d355cd9223f245289108a696bcd2", 149634), -	FANMADE("The Legend of the Lost Jewel", "ba1bca315e3818c5626eda51bcfbcccf", 636, "9b0736d69924af0cff32a0f78db96855", 300398), - -	// FIXME: The vga demo does not have a resource.000/001 file. -	//FANMADE_V("SCI VGA Demo", "00b1abd87bad356b90fcdfcb6132c26f", 8, "", 0, 0), - -	{AD_TABLE_END_MARKER, 0} -}; - -} // End of namespace Sci diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk index 58d8db91fc..51fbecdb0d 100644 --- a/engines/scumm/module.mk +++ b/engines/scumm/module.mk @@ -40,6 +40,7 @@ MODULE_OBJS := \  	player_v2a.o \  	player_v2cms.o \  	player_v3a.o \ +	player_v4a.o \  	resource_v2.o \  	resource_v3.o \  	resource_v4.o \ diff --git a/engines/scumm/music.h b/engines/scumm/music.h index c6555318a9..2fd7c50bce 100644 --- a/engines/scumm/music.h +++ b/engines/scumm/music.h @@ -81,12 +81,6 @@ public:  	 * @return the music timer  	 */  	virtual int  getMusicTimer() const { return 0; } - -	/** -	 * Terminate the music engine. Called just before the music engine -	 * is deleted. -	 */ -	virtual void terminate() {}  };  } // End of namespace Scumm diff --git a/engines/scumm/player_v4a.cpp b/engines/scumm/player_v4a.cpp new file mode 100644 index 0000000000..f441b3b364 --- /dev/null +++ b/engines/scumm/player_v4a.cpp @@ -0,0 +1,193 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "engines/engine.h" +#include "scumm/player_v4a.h" +#include "scumm/scumm.h" + +#include "common/file.h" + +namespace Scumm { + +Player_V4A::Player_V4A(ScummEngine *scumm, Audio::Mixer *mixer) +	: _vm(scumm), +	  _mixer(mixer), +	  _tfmxMusic(_mixer->getOutputRate(), true), +	  _tfmxSfx(_mixer->getOutputRate(), true), +	  _musicHandle(), +	  _sfxHandle(), +	  _musicId(), +	  _sfxSlots(), +	  _initState(0), +	  _signal(0) { + +	assert(scumm); +	assert(mixer); +	assert(_vm->_game.id == GID_MONKEY_VGA); +	_tfmxMusic.setSignalPtr(&_signal, 1); +} + +bool Player_V4A::init() { +	if (_vm->_game.id != GID_MONKEY_VGA) +		error("player_v4a - unknown game"); +	 +	Common::File fileMdat, fileSample; + +	if (fileMdat.open("music.dat") && fileSample.open("sample.dat")) { +		// explicitly request that no instance delets the resources automatically +		if (_tfmxMusic.load(fileMdat, fileSample, false)) { +			_tfmxSfx.setModuleData(_tfmxMusic); +			return true; +		} +	} else +		warning("player_v4a: couldnt load one of the music resources: music.dat, sample.dat"); +	 +	return false; +} + +Player_V4A::~Player_V4A() { +	_mixer->stopHandle(_musicHandle); +	_mixer->stopHandle(_sfxHandle); +	_tfmxMusic.freeResources(); +} + +void Player_V4A::setMusicVolume(int vol) { +	debug(5, "player_v4a: setMusicVolume %i", vol); +} + +void Player_V4A::stopAllSounds() { +	debug(5, "player_v4a: stopAllSounds"); +	if (_initState > 0) { +		_tfmxMusic.stopSong(); +		_signal = 0;		 +		_musicId = 0; + +		_tfmxSfx.stopSong(); +		clearSfxSlots(); +	} else +		_mixer->stopHandle(_musicHandle); +} + +void Player_V4A::stopSound(int nr) { +	debug(5, "player_v4a: stopSound %d", nr); +	if (nr == 0) +		return; +	if (nr == _musicId) { +		_musicId = 0; +		if (_initState > 0) +			_tfmxMusic.stopSong(); +		else +			_mixer->stopHandle(_musicHandle); +		_signal = 0; +	} else { +		const int chan = getSfxChan(nr); +		if (chan != -1) { +			setSfxSlot(chan, 0); +			_tfmxSfx.stopMacroEffect(chan); +		} +	} +} + +void Player_V4A::startSound(int nr) { +	static const int8 monkeyCommands[52] = { +		 -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8, +		 -9, -10, -11, -12, -13, -14,  18,  17, +		-17, -18, -19, -20, -21, -22, -23, -24, +		-25, -26, -27, -28, -29, -30, -31, -32, +		-33,  16, -35,   0,   1,   2,   3,   7, +		  8,  10,  11,   4,   5,  14,  15,  12, +		  6,  13,   9,  19 +	}; + +	const byte *ptr = _vm->getResourceAddress(rtSound, nr); +	assert(ptr); + +	const int val = ptr[9]; +	if (val < 0 || val >= ARRAYSIZE(monkeyCommands)) { +		warning("player_v4a: illegal Songnumber %i", val); +		return; +	} + +	if (!_initState) +		_initState = init() ? 1 : -1; + +	if (_initState < 0) +		return; + +	int index = monkeyCommands[val]; +	const byte type = ptr[6]; +	if (index < 0) {	// SoundFX +		index = -index - 1; +		debug(3, "player_v4a: play %d: custom %i - %02X", nr, index, type); + +		// start an empty Song so timing is setup +		if (_tfmxSfx.getSongIndex() < 0) +			_tfmxSfx.doSong(0x18); + +		const int chan = _tfmxSfx.doSfx((uint16)index); +		if (chan >= 0 && chan < ARRAYSIZE(_sfxSlots)) +			setSfxSlot(chan, nr, type); +		else +			warning("player_v4a: custom %i is not of required type", index); + +		// the Tfmx-player never "ends" the output by itself, so this should be threadsafe +		if (!_mixer->isSoundHandleActive(_sfxHandle)) +			_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, &_tfmxSfx, -1, Audio::Mixer::kMaxChannelVolume, 0, false); + +	} else {	// Song +		debug(3, "player_v4a: play %d: song %i - %02X", nr, index, type); +		if (ptr[6] != 0x7F) +			warning("player_v4a: Song has wrong type"); + +		_tfmxMusic.doSong(index); +		_signal = 2; + +		// the Tfmx-player never "ends" the output by itself, so this should be threadsafe  +		if (!_mixer->isSoundHandleActive(_musicHandle)) +			_mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, &_tfmxMusic, -1, Audio::Mixer::kMaxChannelVolume, 0, false); +		_musicId = nr; +	} +} + +int Player_V4A::getMusicTimer() const { +	// A workaround if the modplayer couldnt load the datafiles - just return a number big enough to pass all tests +	if (_initState < 0) +		return 2000; +	if (_musicId) { +		// The titlesong (and a few others) is running with ~70 ticks per second and the scale seems to be based on that.  +		// The Game itself doesnt get the timing from the Tfmx Player however, so we just use the elapsed time +		// 357 ~ 1000 * 25 * (1 / 70) +		return _mixer->getSoundElapsedTime(_musicHandle) / 357; +	} +	return 0; +} + +int Player_V4A::getSoundStatus(int nr) const { +	// For music the game queues a variable the Tfmx Player sets through a special command. +	// For sfx there seems to be no way to queue them, and the game doesnt try to. +	return (nr == _musicId) ? _signal : 0; +} + +} // End of namespace Scumm diff --git a/engines/scumm/player_v4a.h b/engines/scumm/player_v4a.h new file mode 100644 index 0000000000..5f5fae6b56 --- /dev/null +++ b/engines/scumm/player_v4a.h @@ -0,0 +1,98 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef SCUMM_PLAYER_V4A_H +#define SCUMM_PLAYER_V4A_H + +#include "common/scummsys.h" +#include "scumm/music.h" +#include "sound/mixer.h" +#include "sound/mods/tfmx.h" + +class Mixer; + +namespace Scumm { + +class ScummEngine; + +/** + * Scumm V4 Amiga sound/music driver. + */ +class Player_V4A : public MusicEngine { +public: +	Player_V4A(ScummEngine *scumm, Audio::Mixer *mixer); +	virtual ~Player_V4A(); + +	virtual void setMusicVolume(int vol); +	virtual void startSound(int sound); +	virtual void stopSound(int sound); +	virtual void stopAllSounds(); +	virtual int  getMusicTimer() const; +	virtual int  getSoundStatus(int sound) const; + +private: +	ScummEngine *const _vm; +	Audio::Mixer *const _mixer; + +	Audio::Tfmx _tfmxMusic; +	Audio::Tfmx _tfmxSfx; +	Audio::SoundHandle _musicHandle; +	Audio::SoundHandle _sfxHandle; + +	int _musicId; +	uint16 _signal; + +	struct SfxChan { +		int id; +//		byte type; +	} _sfxSlots[4]; + +	int8 _initState; // < 0: failed, 0: uninitialised, > 0: initialised   + +	int getSfxChan(int id) const { +		for (int i = 0; i < ARRAYSIZE(_sfxSlots); ++i) +			if (_sfxSlots[i].id == id) +				return i; +		return -1; +	} + +	void setSfxSlot(int channel, int id, byte type = 0) { +		_sfxSlots[channel].id = id; +//		_sfxSlots[channel].type = type; +	} + +	void clearSfxSlots() { +		for (int i = 0; i < ARRAYSIZE(_sfxSlots); ++i){ +			_sfxSlots[i].id = 0; +//			_sfxSlots[i].type = 0; +		} +	} + +	bool init(); +}; + +} // End of namespace Scumm + +#endif diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index af6b9278c6..587e2a8abe 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -56,6 +56,7 @@  #include "scumm/player_v2.h"  #include "scumm/player_v2a.h"  #include "scumm/player_v3a.h" +#include "scumm/player_v4a.h"  #include "scumm/he/resource_he.h"  #include "scumm/scumm_v0.h"  #include "scumm/scumm_v8.h" @@ -284,7 +285,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)  	_useTalkAnims = false;  	_defaultTalkDelay = 0;  	_musicType = MDT_NONE; -	_tempMusic = 0;  	_saveSound = 0;  	memset(_extraBoxFlags, 0, sizeof(_extraBoxFlags));  	memset(_scaleSlots, 0, sizeof(_scaleSlots)); @@ -554,10 +554,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)  ScummEngine::~ScummEngine() {  	Common::clearAllDebugChannels(); -	if (_musicEngine) { -		_musicEngine->terminate(); -		delete _musicEngine; -	} +	delete _musicEngine;  	_mixer->stopAll(); @@ -1296,7 +1293,6 @@ void ScummEngine::setupCostumeRenderer() {  void ScummEngine::resetScumm() {  	int i; -	_tempMusic = 0;  	debug(9, "resetScumm");  	if (_game.version == 0) { @@ -1698,7 +1694,7 @@ void ScummEngine::setupMusic(int midi) {  	} else if (_game.platform == Common::kPlatformPCEngine && _game.version == 3) {  		// TODO: Add support for music format  	} else if (_game.platform == Common::kPlatformAmiga && _game.version <= 4) { -		// TODO: Add support for music format +		_musicEngine = new Player_V4A(this, _mixer);  	} else if (_game.id == GID_MANIAC && _game.version == 1) {  		_musicEngine = new Player_V1(this, _mixer, midiDriver != MD_PCSPK);  	} else if (_game.version <= 2) { @@ -1909,17 +1905,6 @@ void ScummEngine::scummLoop(int delta) {  		if (_musicEngine) {  			// The music engine generates the timer data for us.  			VAR(VAR_MUSIC_TIMER) = _musicEngine->getMusicTimer(); -		} else { -			// Used for Money Island 1 (Amiga) -			// TODO: The music delay (given in milliseconds) might have to be tuned a little -			// to get it correct for all games. Without the ability to watch/listen to the -			// original games, I can't do that myself. -			const int MUSIC_DELAY = 350; -			_tempMusic += delta * 1000 / 60;	// Convert delta to milliseconds -			if (_tempMusic >= MUSIC_DELAY) { -				_tempMusic -= MUSIC_DELAY; -				VAR(VAR_MUSIC_TIMER) += 1; -			}  		}  	} diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index 6866b17668..940ea512d5 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -1139,7 +1139,6 @@ protected:  	bool _haveActorSpeechMsg;  	bool _useTalkAnims;  	uint16 _defaultTalkDelay; -	int _tempMusic;  	int _saveSound;  	bool _native_mt32;  	bool _enable_gs; diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index 524dbf70ea..82ed2a62e6 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -436,26 +436,6 @@ void Sound::playSound(int soundID) {  		if (_vm->_game.id == GID_MONKEY_VGA || _vm->_game.id == GID_MONKEY_EGA  			|| (_vm->_game.id == GID_MONKEY && _vm->_game.platform == Common::kPlatformMacintosh)) { -			// Sound is currently not supported at all in the amiga versions of these games -			if (_vm->_game.platform == Common::kPlatformAmiga) { -				int track = -1; -				if (soundID == 50) -					track = 17; -				else if (ptr[6] == 0x7F && ptr[7] == 0x00 && ptr[8] == 0x80) { -					static const char tracks[16] = {13,14,10,3,4,9,16,5,1,8,2,15,6,7,11,12}; -					if (ptr[9] == 0x0E) -						track = 18; -					else -						track = tracks[ptr[9] - 0x23]; -				} -				if (track != -1) { -					playCDTrack(track,((track < 5) || (track > 16)) ? 1 : -1,0,0); -					stopCDTimer(); -					_currentCDSound = soundID; -				} -				return; -			} -  			// Works around the fact that in some places in MonkeyEGA/VGA,  			// the music is never explicitly stopped.  			// Rather it seems that starting a new music is supposed to diff --git a/graphics/conversion.cpp b/graphics/conversion.cpp deleted file mode 100644 index df9d7c4d6d..0000000000 --- a/graphics/conversion.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * 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 - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - */ - -#include "graphics/conversion.h" - -namespace Graphics { - -// TODO: YUV to RGB conversion function - -// Function to blit a rect from one color format to another -bool crossBlit(byte *dst, const byte *src, int dstpitch, int srcpitch, -						int w, int h, const Graphics::PixelFormat &dstFmt, const Graphics::PixelFormat &srcFmt) { -	// Error out if conversion is impossible -	if ((srcFmt.bytesPerPixel == 1) || (dstFmt.bytesPerPixel == 1) -			 || (!srcFmt.bytesPerPixel) || (!dstFmt.bytesPerPixel) -			 || (srcFmt.bytesPerPixel > dstFmt.bytesPerPixel)) -		return false; - -	// Don't perform unnecessary conversion -	if (srcFmt == dstFmt) { -		if (dst == src)  -			return true; -		if (dstpitch == srcpitch && ((w * dstFmt.bytesPerPixel) == dstpitch)) { -			memcpy(dst,src,dstpitch * h); -			return true; -		} else { -			for (int i = 0; i < h; i++) { -				memcpy(dst,src,w * dstFmt.bytesPerPixel); -				dst += dstpitch; -				src += srcpitch; -			} -			return true; -		} -	} - -	// Faster, but larger, to provide optimized handling for each case. -	int srcDelta, dstDelta; -	srcDelta = (srcpitch - w * srcFmt.bytesPerPixel); -	dstDelta = (dstpitch - w * dstFmt.bytesPerPixel); - -	// TODO: optimized cases for dstDelta of 0 -	uint8 r, g, b, a; -	if (dstFmt.bytesPerPixel == 2) { -		uint16 color; -		for (int y = 0; y < h; y++) { -			for (int x = 0; x < w; x++, src += 2, dst += 2) { -				color = *(uint16 *) src; -				srcFmt.colorToARGB(color, a, r, g, b); -				color = dstFmt.ARGBToColor(a, r, g, b); -				*(uint16 *) dst = color; -			} -			src += srcDelta; -			dst += dstDelta; -		} -	} else if (dstFmt.bytesPerPixel == 3) { -		uint32 color; -		uint8 *col = (uint8 *) &color; -#ifdef SCUMM_BIG_ENDIAN -		col++; -#endif -		if (srcFmt.bytesPerPixel == 2) { -			for (int y = 0; y < h; y++) { -				for (int x = 0; x < w; x++, src += 2, dst += 3) { -					color = *(uint16 *) src; -					srcFmt.colorToARGB(color, a, r, g, b); -					color = dstFmt.ARGBToColor(a, r, g, b); -					memcpy(dst, col, 3); -				} -				src += srcDelta; -				dst += dstDelta; -			} -		} else { -			for (int y = 0; y < h; y++) { -				for (int x = 0; x < w; x++, src += 3, dst += 3) { -					memcpy(col, src, 3); -					srcFmt.colorToARGB(color, a, r, g, b); -					color = dstFmt.ARGBToColor(a, r, g, b); -					memcpy(dst, col, 3); -				} -				src += srcDelta; -				dst += dstDelta; -			} -		} -	} else if (dstFmt.bytesPerPixel == 4) { -		uint32 color; -		if (srcFmt.bytesPerPixel == 2) { -			for (int y = 0; y < h; y++) { -				for (int x = 0; x < w; x++, src += 2, dst += 4) { -					color = *(uint16 *) src; -					srcFmt.colorToARGB(color, a, r, g, b); -					color = dstFmt.ARGBToColor(a, r, g, b); -					*(uint32 *) dst = color; -				} -				src += srcDelta; -				dst += dstDelta; -			} -		} else if (srcFmt.bytesPerPixel == 3) { -			uint8 *col = (uint8 *)&color; -#ifdef SCUMM_BIG_ENDIAN -			col++; -#endif -			for (int y = 0; y < h; y++) { -				for (int x = 0; x < w; x++, src += 2, dst += 4) { -					memcpy(col, src, 3); -					srcFmt.colorToARGB(color, a, r, g, b); -					color = dstFmt.ARGBToColor(a, r, g, b); -					*(uint32 *) dst = color; -				} -				src += srcDelta; -				dst += dstDelta; -			} -		} else { -			for (int y = 0; y < h; y++) { -				for (int x = 0; x < w; x++, src += 4, dst += 4) { -					color = *(uint32 *) src; -					srcFmt.colorToARGB(color, a, r, g, b); -					color = dstFmt.ARGBToColor(a, r, g, b); -					*(uint32 *) dst = color; -				} -				src += srcDelta; -				dst += dstDelta; -			} -		} -	} else { -		return false; -	} -	return true; -} - -} // end of namespace Graphics diff --git a/graphics/conversion.h b/graphics/conversion.h deleted file mode 100644 index 77763eb3d4..0000000000 --- a/graphics/conversion.h +++ /dev/null @@ -1,76 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * 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 - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef GRAPHICS_CONVERSION_H -#define GRAPHICS_CONVERSION_H - -#include "common/util.h" -#include "graphics/pixelformat.h" - -namespace Graphics { - -/** Converting a color from YUV to RGB colorspace. */ -inline static void YUV2RGB(byte y, byte u, byte v, byte &r, byte &g, byte &b) { -	r = CLIP<int>(y + ((1357 * (v - 128)) >> 10), 0, 255); -	g = CLIP<int>(y - (( 691 * (v - 128)) >> 10) - ((333 * (u - 128)) >> 10), 0, 255); -	b = CLIP<int>(y + ((1715 * (u - 128)) >> 10), 0, 255); -} - -/** Converting a color from RGB to YUV colorspace. */ -inline static void RGB2YUV(byte r, byte g, byte b, byte &y, byte &u, byte &v) { -	y = CLIP<int>( ((r * 306) >> 10) + ((g * 601) >> 10) + ((b * 117) >> 10)      , 0, 255); -	u = CLIP<int>(-((r * 172) >> 10) - ((g * 340) >> 10) + ((b * 512) >> 10) + 128, 0, 255); -	v = CLIP<int>( ((r * 512) >> 10) - ((g * 429) >> 10) - ((b *  83) >> 10) + 128, 0, 255); -} - -// TODO: generic YUV to RGB blit - -/** - * Blits a rectangle from one graphical format to another. - * - * @param dstbuf	the buffer which will recieve the converted graphics data - * @param srcbuf	the buffer containing the original graphics data - * @param dstpitch	width in bytes of one full line of the dest buffer - * @param srcpitch	width in bytes of one full line of the source buffer - * @param w			the width of the graphics data - * @param h			the height of the graphics data - * @param dstFmt	the desired pixel format - * @param srcFmt	the original pixel format - * @return			true if conversion completes successfully, - *					false if there is an error. - * - * @note This implementation currently arbitrarily requires that the  - *		 destination's format have at least as high a bytedepth as  - *		 the source's. - * @note This can convert a rectangle in place, if the source and  - *		 destination format have the same bytedepth. - * - */ -bool crossBlit(byte *dst, const byte *src, int dstpitch, int srcpitch, -						int w, int h, const Graphics::PixelFormat &dstFmt, const Graphics::PixelFormat &srcFmt); - -} // end of namespace Graphics - -#endif // GRAPHICS_CONVERSION_H diff --git a/graphics/jpeg.cpp b/graphics/jpeg.cpp deleted file mode 100644 index 0ad2cf7699..0000000000 --- a/graphics/jpeg.cpp +++ /dev/null @@ -1,638 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * 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 - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "graphics/jpeg.h" - -#include "common/endian.h" -#include "common/util.h" - -namespace Graphics { - -// Order used to traverse the quantization tables -uint8 JPEG::_zigZagOrder[64] = { -	0,   1,  8, 16,  9,  2,  3, 10, -	17, 24, 32, 25, 18, 11,  4,  5, -	12, 19, 26, 33, 40, 48, 41, 34, -	27, 20, 13,  6,  7, 14, 21, 28, -	35, 42, 49, 56, 57, 50, 43, 36, -	29, 22, 15, 23, 30, 37, 44, 51, -	58, 59, 52, 45, 38, 31, 39, 46, -	53, 60, 61, 54, 47, 55, 62, 63 -}; - -JPEG::JPEG() : -	_str(NULL), _w(0), _h(0), _numComp(0), _components(NULL), _numScanComp(0), -	_scanComp(NULL), _currentComp(NULL) { - -	// Initialize the quantization tables -	for (int i = 0; i < JPEG_MAX_QUANT_TABLES; i++) -		_quant[i] = NULL; - -	// Initialize the Huffman tables -	for (int i = 0; i < 2 * JPEG_MAX_HUFF_TABLES; i++) { -		_huff[i].count = 0; -		_huff[i].values = NULL; -		_huff[i].sizes = NULL; -		_huff[i].codes = NULL; -	} -} - -JPEG::~JPEG() { -	reset(); -} - -void JPEG::reset() { -	// Reset member variables -	_str = NULL; -	_w = _h = 0; - -	// Free the components -	for (int c = 0; c < _numComp; c++) -		_components[c].surface.free(); -	delete[] _components; _components = NULL; -	_numComp = 0; - -	// Free the scan components -	delete[] _scanComp; _scanComp = NULL; -	_numScanComp = 0; -	_currentComp = NULL; - -	// Free the quantization tables -	for (int i = 0; i < JPEG_MAX_QUANT_TABLES; i++) { -		delete[] _quant[i]; -		_quant[i] = NULL; -	} - -	// Free the Huffman tables -	for (int i = 0; i < 2 * JPEG_MAX_HUFF_TABLES; i++) { -		_huff[i].count = 0; -		delete[] _huff[i].values; _huff[i].values = NULL; -		delete[] _huff[i].sizes; _huff[i].sizes = NULL; -		delete[] _huff[i].codes; _huff[i].codes = NULL; -	} -} - -bool JPEG::read(Common::SeekableReadStream *str) { -	// Reset member variables and tables from previous reads -	reset(); - -	// Save the input stream -	_str = str; - -	bool ok = true; -	bool done = false; -	while (!_str->eos() && ok && !done) { -		// Read the marker -		uint16 marker = _str->readByte(); -		if (marker != 0xFF) { -			error("JPEG: Invalid marker[0]: 0x%02X", marker); -			ok = false; -			break; -		} -		 -		while (marker == 0xFF) -			marker = _str->readByte(); - -		// Process the marker data -		switch (marker) { -		case 0xC0: // Start Of Frame -			ok = readSOF0(); -			break; -		case 0xC4: // Define Huffman Tables -			ok = readDHT(); -			break; -		case 0xD8: // Start Of Image -			break; -		case 0xD9: // End Of Image -			done = true; -			break; -		case 0xDA: // Start Of Scan -			ok = readSOS(); -			break; -		case 0xDB: // Define Quantization Tables -			ok = readDQT(); -			break; -		case 0xE0: // JFIF/JFXX segment -			ok = readJFIF(); -			break; -		case 0xFE: // Comment -			_str->seek(_str->readUint16BE() - 2, SEEK_CUR); -			break; -		default: { // Unknown marker -			uint16 size = _str->readUint16BE(); -			warning("JPEG: Unknown marker %02X, skipping %d bytes", marker, size - 2); -			_str->seek(size - 2, SEEK_CUR); -		} -		} -	} -	return ok; -} - -bool JPEG::readJFIF() { -	/* uint16 length = */ _str->readUint16BE(); -	uint32 tag = _str->readUint32BE(); -	if (tag != MKID_BE('JFIF')) -		return false; -	_str->readByte(); // NULL -	/* byte majorVersion = */ _str->readByte(); -	/* byte minorVersion = */ _str->readByte(); -	/* byte densityUnits = */ _str->readByte(); -	/* uint16 xDensity = */ _str->readUint16BE(); -	/* uint16 yDensity = */ _str->readUint16BE(); -	byte thumbW = _str->readByte(); -	byte thumbH = _str->readByte(); -	_str->seek(thumbW * thumbH * 3, SEEK_CUR); // Ignore thumbnail -	return true; -} - -// Marker 0xC0 (Start Of Frame, Baseline DCT) -bool JPEG::readSOF0() { -	debug(5, "JPEG: readSOF0"); -	uint16 size = _str->readUint16BE(); - -	// Read the sample precision -	uint8 precision = _str->readByte(); -	if (precision != 8) { -		warning("JPEG: Just 8 bit precision supported at the moment"); -		return false; -	} - -	// Image size -	_h = _str->readUint16BE(); -	_w = _str->readUint16BE(); - -	// Number of components -	_numComp = _str->readByte(); -	if (size != 8 + 3 * _numComp) { -		warning("JPEG: Invalid number of components"); -		return false; -	} - -	// Allocate the new components -	delete[] _components; -	_components = new Component[_numComp]; - -	// Read the components details -	for (int c = 0; c < _numComp; c++) { -		_components[c].id = _str->readByte(); -		_components[c].factorH = _str->readByte(); -		_components[c].factorV = _components[c].factorH & 0xF; -		_components[c].factorH >>= 4; -		_components[c].quantTableSelector = _str->readByte(); -	} - -	return true; -} - -// Marker 0xC4 (Define Huffman Tables) -bool JPEG::readDHT() { -	debug(5, "JPEG: readDHT"); -	uint16 size = _str->readUint16BE() - 2; -	uint32 pos = _str->pos(); - -	while ((uint32)_str->pos() < (size + pos)) { -		// Read the table type and id -		uint8 tableId = _str->readByte(); -		uint8 tableType = tableId >> 4; // type 0: DC, 1: AC -		tableId &= 0xF; -		uint8 tableNum = (tableId << 1) + tableType; - -		// Free the Huffman table -		delete[] _huff[tableNum].values; _huff[tableNum].values = NULL; -		delete[] _huff[tableNum].sizes; _huff[tableNum].sizes = NULL; -		delete[] _huff[tableNum].codes;	_huff[tableNum].codes = NULL; - -		// Read the number of values for each length -		uint8 numValues[16]; -		_huff[tableNum].count = 0; -		for (int len = 0; len < 16; len++) { -			numValues[len] = _str->readByte(); -			_huff[tableNum].count += numValues[len]; -		} - -		// Allocate memory for the current table -		_huff[tableNum].values = new uint8[_huff[tableNum].count]; -		_huff[tableNum].sizes = new uint8[_huff[tableNum].count]; -		_huff[tableNum].codes = new uint16[_huff[tableNum].count]; - -		// Read the table contents -		int cur = 0; -		for (int len = 0; len < 16; len++) { -			for (int i = 0; i < numValues[len]; i++) { -				_huff[tableNum].values[cur] = _str->readByte(); -				_huff[tableNum].sizes[cur] = len + 1; -				cur++; -			} -		} - -		// Fill the table of Huffman codes -		cur = 0; -		uint16 curCode = 0; -		uint8 curCodeSize = _huff[tableNum].sizes[0]; -		while (cur < _huff[tableNum].count) { -			// Increase the code size to fit the request -			while (_huff[tableNum].sizes[cur] != curCodeSize) { -				curCode <<= 1; -				curCodeSize++; -			} - -			// Assign the current code -			_huff[tableNum].codes[cur] = curCode; -			curCode++; -			cur++; -		} -	} -	 -	return true; -} - -// Marker 0xDA (Start Of Scan) -bool JPEG::readSOS() { -	debug(5, "JPEG: readSOS"); -	uint16 size = _str->readUint16BE(); - -	// Number of scan components -	_numScanComp = _str->readByte(); -	if (size != 6 + 2 * _numScanComp) { -		warning("JPEG: Invalid number of components"); -		return false; -	} - -	// Allocate the new scan components -	delete[] _scanComp; -	_scanComp = new Component *[_numScanComp]; - -	// Reset the maximum sampling factors -	_maxFactorV = 0; -	_maxFactorH = 0; - -	// Component-specification parameters -	for (int c = 0; c < _numScanComp; c++) { -		// Read the desired component id -		uint8 id = _str->readByte(); - -		// Search the component with the specified id -		bool found = false; -		for (int i = 0; !found && i < _numComp; i++) { -			if (_components[i].id == id) { -				// We found the desired component -				found = true; - -				// Assign the found component to the c'th scan component -				_scanComp[c] = &_components[i]; -			} -		} -		 -		if (!found) { -			warning("JPEG: Invalid component"); -			return false; -		} - -		// Read the entropy table selectors -		_scanComp[c]->DCentropyTableSelector = _str->readByte(); -		_scanComp[c]->ACentropyTableSelector = _scanComp[c]->DCentropyTableSelector & 0xF; -		_scanComp[c]->DCentropyTableSelector >>= 4; - -		// Calculate the maximum sampling factors -		if (_scanComp[c]->factorV > _maxFactorV) -			_maxFactorV = _scanComp[c]->factorV; - -		if (_scanComp[c]->factorH > _maxFactorH) -			_maxFactorH = _scanComp[c]->factorH; - -		// Initialize the DC predictor -		_scanComp[c]->DCpredictor = 0; -	} -	 -	// Initialize the scan surfaces -	for (int c = 0; c < _numScanComp; c++) -		_scanComp[c]->surface.create(_w, _h, 1); - -	// Start of spectral selection -	if (_str->readByte() != 0) { -		warning("JPEG: Progressive scanning not supported"); -		return false; -	} - -	// End of spectral selection -	if (_str->readByte() != 63) { -		warning("JPEG: Progressive scanning not supported"); -		return false; -	} - -	// Successive approximation parameters -	if (_str->readByte() != 0) { -		warning("JPEG: Progressive scanning not supported"); -		return false; -	} - -	// Entropy coded sequence starts, initialize Huffman decoder -	_bitsNumber = 0; - -	// Read all the scan MCUs -	uint16 xMCU = _w / (_maxFactorH * 8); -	uint16 yMCU = _h / (_maxFactorV * 8); - -	// Check for non- multiple-of-8 dimensions -	if (_w % 8 != 0) -		xMCU++; -	if (_h % 8 != 0) -		yMCU++; - -	bool ok = true; -	for (int y = 0; ok && (y < yMCU); y++)  -		for (int x = 0; ok && (x < xMCU); x++) -			ok = readMCU(x, y); - -	return ok; -} - -// Marker 0xDB (Define Quantization Tables) -bool JPEG::readDQT() { -	debug(5, "JPEG: readDQT"); -	uint16 size = _str->readUint16BE() - 2; -	uint32 pos = _str->pos(); -	 -	while ((uint32)_str->pos() < (pos + size)) {	 -		// Read the table precision and id -		uint8 tableId = _str->readByte(); -		bool highPrecision = (tableId & 0xF0) != 0; -		 -		// Validate the table id -		tableId &= 0xF; -		if (tableId > JPEG_MAX_QUANT_TABLES) { -			warning("JPEG: Invalid number of components"); -			return false; -		} - -		// Create the new table if necessary -		if (!_quant[tableId]) -			_quant[tableId] = new uint16[64]; - -		// Read the table (stored in Zig-Zag order) -		for (int i = 0; i < 64; i++) -			_quant[tableId][i] = highPrecision ? _str->readUint16BE() : _str->readByte(); -	} -	 -	return true; -} - -bool JPEG::readMCU(uint16 xMCU, uint16 yMCU) { -	bool ok = true; -	for (int c = 0; ok && (c < _numComp); c++) { -		// Set the current component -		_currentComp = _scanComp[c]; - -		// Read the data units of the current component -		for (int y = 0; ok && (y < _scanComp[c]->factorV); y++) -			for (int x = 0; ok && (x < _scanComp[c]->factorH); x++) -				ok = readDataUnit(xMCU * _scanComp[c]->factorH + x, yMCU * _scanComp[c]->factorV + y); -	} - -	return ok; -} - -float JPEG::idct(int x, int y, int weight, int fx, int fy) { -	float vx = cos((2 * x + 1) * fx * PI / 16); -	float vy = cos((2 * y + 1) * fy * PI / 16); -	float ret = (float)weight * vx * vy; -	 -	if (fx == 0) -		ret /= sqrt(2.0f); -		 -	if (fy == 0) -		ret /= sqrt(2.0f); - -	return ret; -} - -bool JPEG::readDataUnit(uint16 x, uint16 y) { -	// Prepare an empty data array -	int16 readData[64]; -	for (int i = 1; i < 64; i++) -		readData[i] = 0; - -	// Read the DC component -	readData[0] = _currentComp->DCpredictor + readDC(); -	_currentComp->DCpredictor = readData[0]; - -	// Read the AC components (stored in Zig-Zag) -	readAC(readData); - -	// Calculate the DCT coefficients from the input sequence -	int16 DCT[64]; -	for (int i = 0; i < 64; i++) { -		// Dequantize -		int16 val = readData[i]; -		int16 quant = _quant[_currentComp->quantTableSelector][i]; -		val *= quant; - -		// Store the normalized coefficients, undoing the Zig-Zag -		DCT[_zigZagOrder[i]] = val; -	} - -	// Shortcut the IDCT for DC component -	float result[64]; -	for (int i = 0; i < 64; i++) -		result[i] = DCT[0] / 2; - -	// Apply the IDCT (PAG31) -	for (int i = 1; i < 64; i++) { -		if (DCT[i]) -			for (int _y = 0; _y < 8; _y++) -				for (int _x = 0; _x < 8; _x++) -					result[_y * 8 + _x] += idct(_x, _y, DCT[i], i % 8, i / 8); -	} - -	// Level shift to make the values unsigned -	// Divide by 4 is final part of IDCT -	for (int i = 0; i < 64; i++) { -		result[i] = result[i] / 4 + 128; -		 -		if (result[i] < 0) -			result[i] = 0; - -		if (result[i] > 255) -			result[i] = 255; -	} - -	// Paint the component surface -	uint8 scalingV = _maxFactorV / _currentComp->factorV; -	uint8 scalingH = _maxFactorH / _currentComp->factorH; - -	// Convert coordinates from MCU blocks to pixels -	x <<= 3; -	y <<= 3; - -	// Handle non- multiple-of-8 dimensions -	byte xLim = 8; -	byte yLim = 8; -	if (x*scalingH + 8 > _w) -		xLim -= (x*scalingH + 8 - _w); -	if (y*scalingV + 8 > _h) -		yLim -= (y*scalingV + 8 - _h); - -	for (int j = 0; j < yLim; j++) { -		for (int sV = 0; sV < scalingV; sV++) { -			// Get the beginning of the block line -			byte *ptr = (byte *)_currentComp->surface.getBasePtr(x * scalingH, (y + j) * scalingV + sV); - -			for (int i = 0; i < xLim; i++) { -				for (uint8 sH = 0; sH < scalingH; sH++) { -					*ptr = (byte)(result[j * 8 + i]); -					ptr++; -				} -			} -		} -	} - -	return true; -} - -int16 JPEG::readDC() { -	// DC is type 0 -	uint8 tableNum = _currentComp->DCentropyTableSelector << 1; - -	// Get the number of bits to read -	uint8 numBits = readHuff(tableNum); - -	// Read the requested bits -	return readSignedBits(numBits); -} - -void JPEG::readAC(int16 *out) { -	// AC is type 1 -	uint8 tableNum = (_currentComp->ACentropyTableSelector << 1) + 1; - -	// Start reading AC element 1 -	uint8 cur = 1; -	while (cur < 64) { -		uint8 s = readHuff(tableNum); -		uint8 r = s >> 4; -		s &= 0xF; - -		if (s == 0) { -			if (r == 15) { -				// Skip 16 values -				cur += 16; -			} else { -				// EOB: end of block -				cur = 64; -			} -		} else { -			// Skip r values -			cur += r; - -			// Read the next value -			out[cur] = readSignedBits(s); -			cur++; -		} -	} -} - -int16 JPEG::readSignedBits(uint8 numBits) { -	uint16 ret = 0; -	if (numBits > 16) error("requested %d bits", numBits); //XXX - -	// MSB=0 for negatives, 1 for positives -	for (int i = 0; i < numBits; i++) -		ret = (ret << 1) + readBit(); - -	// Extend sign bits (PAG109) -	if (!(ret >> (numBits - 1))) -	{ -		uint16 tmp = ((uint16)-1 << numBits) + 1; -		ret = ret + tmp; -	} -	return ret; -} - -// TODO: optimize? -uint8 JPEG::readHuff(uint8 table) { -	bool foundCode = false; -	uint8 val = 0; - -	uint8 cur = 0; -	uint8 codeSize = 1; -	uint16 code = readBit(); -	while (!foundCode) { -		// Prepare a code of the current size -		while (codeSize < _huff[table].sizes[cur]) { -			code = (code << 1) + readBit(); -			codeSize++; -		} - -		// Compare the codes of the current size -		while (!foundCode && (codeSize == _huff[table].sizes[cur])) { -			if (code == _huff[table].codes[cur]) { -				// Found the code -				val = _huff[table].values[cur]; -				foundCode = true; -			} else { -				// Continue reading -				cur++; -			} -		} -	} - -	return val; -} - -uint8 JPEG::readBit() { -	// Read a whole byte if necessary -	if (_bitsNumber == 0) { -		_bitsData = _str->readByte(); -		_bitsNumber = 8; - -		// Detect markers -		if (_bitsData == 0xFF) { -			uint8 byte2 = _str->readByte(); - -			// A stuffed 0 validates the previous byte -			if (byte2 != 0) { -				if (byte2 == 0xDC) { -					// DNL marker: Define Number of Lines -					// TODO: terminate scan -					printf("DNL marker detected: terminate scan\n"); -				} else { -					printf("Error: marker 0x%02X read in entropy data\n", byte2); -				} -			} -		} -	} -	_bitsNumber--; - -	return (_bitsData & (1 << _bitsNumber)) ? 1 : 0; -} - -Surface *JPEG::getComponent(uint c) { -	for (int i = 0; i < _numComp; i++) -		if (_components[i].id == c) // We found the desired component -			return &_components[i].surface; - -	return NULL; -} - -} // End of Graphics namespace diff --git a/graphics/jpeg.h b/graphics/jpeg.h deleted file mode 100644 index f4743a5e83..0000000000 --- a/graphics/jpeg.h +++ /dev/null @@ -1,118 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * 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 - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef GRAPHICS_JPEG_H -#define GRAPHICS_JPEG_H - -#include "common/stream.h" -#include "graphics/surface.h" - -namespace Graphics { - -#define JPEG_MAX_QUANT_TABLES 4 -#define JPEG_MAX_HUFF_TABLES 2 - -class JPEG { -public: -	JPEG(); -	~JPEG(); - -	bool read(Common::SeekableReadStream *str); -	Surface *getComponent(uint c); - -private: -	void reset(); - -	Common::SeekableReadStream *_str; -	uint16 _w, _h; - -	// Image components -	uint8 _numComp; -	struct Component { -		// Global values -		uint8 id; -		uint8 factorH; -		uint8 factorV; -		uint8 quantTableSelector; - -		// Scan specific values -		uint8 DCentropyTableSelector; -		uint8 ACentropyTableSelector; -		int16 DCpredictor; -		 -		// Result image for this component -		Surface surface; -	} *_components; - -	// Scan components -	uint8 _numScanComp; -	Component **_scanComp; -	Component *_currentComp; - -	// Maximum sampling factors, used to calculate the interleaving of the MCU -	uint8 _maxFactorV; -	uint8 _maxFactorH; - -	// Zig-Zag order -	static uint8 _zigZagOrder[64]; - -	// Quantization tables -	uint16 *_quant[JPEG_MAX_QUANT_TABLES]; - -	// Huffman tables -	struct HuffmanTable { -		uint8 count; -		uint8 *values; -		uint8 *sizes; -		uint16 *codes; -	} _huff[2 * JPEG_MAX_HUFF_TABLES]; - -	// Marker read functions -	bool readJFIF(); -	bool readSOF0(); -	bool readDHT(); -	bool readSOS(); -	bool readDQT(); - -	// Helper functions -	bool readMCU(uint16 xMCU, uint16 yMCU); -	bool readDataUnit(uint16 x, uint16 y); -	int16 readDC(); -	void readAC(int16 *out); -	int16 readSignedBits(uint8 numBits); - -	// Huffman decoding -	uint8 readHuff(uint8 table); -	uint8 readBit(); -	uint8 _bitsData; -	uint8 _bitsNumber; -	 -	// Discrete Cosine Transformation -	float idct(int x, int y, int weight, int fx, int fy); -}; - -} // End of Graphics namespace - -#endif // GRAPHICS_JPEG_H diff --git a/sound/mods/maxtrax.cpp b/sound/mods/maxtrax.cpp new file mode 100644 index 0000000000..90ac3d55ca --- /dev/null +++ b/sound/mods/maxtrax.cpp @@ -0,0 +1,1038 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/scummsys.h" +#include "common/endian.h" +#include "common/stream.h" +#include "common/util.h" +#include "common/debug.h" + +#include "sound/mods/maxtrax.h" + +// test for engines using this class. +#if defined(SOUND_MODS_MAXTRAX_H) + +namespace { + +enum { K_VALUE = 0x9fd77, PREF_PERIOD = 0x8fd77, PERIOD_LIMIT = 0x6f73d }; +enum { NO_BEND = 64 << 7, MAX_BEND_RANGE = 24 }; + +int32 precalcNote(byte baseNote, int16 tune, byte octave) { +	return K_VALUE + 0x3C000 - ((baseNote << 14) + (tune << 11) / 3) / 3 - (octave << 16); +} + +int32 calcVolumeDelta(int32 delta, uint16 time, uint16 vBlankFreq) { +	const int32 div = time * vBlankFreq; +	// div <= 1000 means time to small (or even 0) +	return (div <= 1000) ? delta : (1000 * delta) / div; +} + +int32 calcTempo(const uint16 tempo, uint16 vBlankFreq) { +	return (int32)(((uint32)(tempo & 0xFFF0) << 8) / (uint16)(5 * vBlankFreq)); +} + +void nullFunc(int) {} + +// Function to calculate 2^x, where x is a fixedpoint number with 16 fraction bits +// using exp would be more accurate and needs less space if mathlibrary is already linked +// but this function should be faster and doesnt use floats +#if 1 +inline uint32 pow2Fixed(int32 val) { +	static const uint16 tablePow2[] = { +			0,   178,   356,   535,   714,   893,  1073,  1254,  1435,  1617,  1799,  1981,  2164,  2348,  2532,  2716, +		 2902,  3087,  3273,  3460,  3647,  3834,  4022,  4211,  4400,  4590,  4780,  4971,  5162,  5353,  5546,  5738, +		 5932,  6125,  6320,  6514,  6710,  6906,  7102,  7299,  7496,  7694,  7893,  8092,  8292,  8492,  8693,  8894, +		 9096,  9298,  9501,  9704,  9908, 10113, 10318, 10524, 10730, 10937, 11144, 11352, 11560, 11769, 11979, 12189, +		12400, 12611, 12823, 13036, 13249, 13462, 13676, 13891, 14106, 14322, 14539, 14756, 14974, 15192, 15411, 15630, +		15850, 16071, 16292, 16514, 16737, 16960, 17183, 17408, 17633, 17858, 18084, 18311, 18538, 18766, 18995, 19224, +		19454, 19684, 19915, 20147, 20379, 20612, 20846, 21080, 21315, 21550, 21786, 22023, 22260, 22498, 22737, 22977, +		23216, 23457, 23698, 23940, 24183, 24426, 24670, 24915, 25160, 25406, 25652, 25900, 26148, 26396, 26645, 26895, +		27146, 27397, 27649, 27902, 28155, 28409, 28664, 28919, 29175, 29432, 29690, 29948, 30207, 30466, 30727, 30988, +		31249, 31512, 31775, 32039, 32303, 32568, 32834, 33101, 33369, 33637, 33906, 34175, 34446, 34717, 34988, 35261, +		35534, 35808, 36083, 36359, 36635, 36912, 37190, 37468, 37747, 38028, 38308, 38590, 38872, 39155, 39439, 39724, +		40009, 40295, 40582, 40870, 41158, 41448, 41738, 42029, 42320, 42613, 42906, 43200, 43495, 43790, 44087, 44384, +		44682, 44981, 45280, 45581, 45882, 46184, 46487, 46791, 47095, 47401, 47707, 48014, 48322, 48631, 48940, 49251, +		49562, 49874, 50187, 50500, 50815, 51131, 51447, 51764, 52082, 52401, 52721, 53041, 53363, 53685, 54008, 54333, +		54658, 54983, 55310, 55638, 55966, 56296, 56626, 56957, 57289, 57622, 57956, 58291, 58627, 58964, 59301, 59640, +		59979, 60319, 60661, 61003, 61346, 61690, 62035, 62381, 62727, 63075, 63424, 63774, 64124, 64476, 64828, 65182, +			0 +	}; +	const uint16 whole = val >> 16; +	const uint8 index = (uint8)(val >> 8); +	// calculate fractional part. +	const uint16 base = tablePow2[index]; +	// linear interpolation and add 1.0 +	uint32 exponent = ((uint32)(uint16)(tablePow2[index + 1] - base) * (uint8)val) + ((uint32)base << 8) + (1 << 24); + +	if (whole < 24) { +		// shift away all but the last fractional bit which is used for rounding, +		// then round to nearest integer +		exponent = ((exponent >> (23 - whole)) + 1) >> 1; +	} else if (whole < 32) { +		// no need to round here +		exponent <<= whole - 24; +	} else if (val > 0) { +		// overflow +		exponent = 0xFFFFFFFF; +	} else  { +		// negative integer, test if >= -0.5 +		exponent = (val >= -0x8000) ? 1 : 0; +	} +	return exponent; +} +#else +inline uint32 pow2Fixed(int32 val) { +	return (uint32)(expf((float)val * (float)(0.69314718055994530942 / (1 << 16))) + 0.5f); +} +#endif + +}	// End of namespace + +namespace Audio { + +MaxTrax::MaxTrax(int rate, bool stereo, uint16 vBlankFreq, uint16 maxScores) +	: Paula(stereo, rate, rate / vBlankFreq), +	  _patch(), +	  _scores(), +	  _numScores() { +	_playerCtx.maxScoreNum = maxScores; +	_playerCtx.vBlankFreq = vBlankFreq; +	_playerCtx.frameUnit = (uint16)((1000 << 8) /  vBlankFreq); +	_playerCtx.scoreIndex = -1; +	_playerCtx.volume = 0x40; + +	_playerCtx.tempo = 120; +	_playerCtx.tempoTime = 0; +	_playerCtx.filterOn = true; +	_playerCtx.syncCallBack = &nullFunc; + +	resetPlayer(); +	for (int i = 0; i < ARRAYSIZE(_channelCtx); ++i) +		_channelCtx[i].regParamNumber = 0; +} + +MaxTrax::~MaxTrax() { +	stopMusic(); +	freePatches(); +	freeScores(); +} + +void MaxTrax::interrupt() { +	// a5 - maxtraxm a4 . globaldata + +	// TODO +	// test for changes in shared struct and make changes +	// specifically all used channels get marked altered + +	_playerCtx.ticks += _playerCtx.tickUnit; +	const int32 millis = _playerCtx.ticks >> 8; // d4 + +	for (int i = 0; i < ARRAYSIZE(_voiceCtx); ++i) { +		VoiceContext &voice = _voiceCtx[i]; +		if (voice.stopEventTime >= 0) { +			assert(voice.channel); +			voice.stopEventTime -= (voice.channel < &_channelCtx[kNumChannels]) ? _playerCtx.tickUnit : _playerCtx.frameUnit; +			if (voice.stopEventTime <= 0 && voice.status > VoiceContext::kStatusRelease) { +				if ((voice.channel->flags & ChannelContext::kFlagDamper) != 0) +					voice.hasDamper = true; +				else +					voice.status = VoiceContext::kStatusRelease; +			} +		} +	} + +	if (_playerCtx.scoreIndex >= 0) { +		const Event *curEvent = _playerCtx.nextEvent; +		int32 eventDelta = _playerCtx.nextEventTime - millis; +		for (; eventDelta <= 0; eventDelta += (++curEvent)->startTime) { +			const byte cmd = curEvent->command; +			ChannelContext &channel = _channelCtx[curEvent->parameter & 0x0F]; + +			// outPutEvent(*curEvent); +			// debug("CurTime, EventDelta, NextDelta: %d, %d, %d", millis, eventDelta, eventDelta + curEvent[1].startTime ); + +			if (cmd < 0x80) {	// Note +				const int8 voiceIndex = noteOn(channel, cmd, (curEvent->parameter & 0xF0) >> 1, kPriorityScore); +				if (voiceIndex >= 0) +					_voiceCtx[voiceIndex].stopEventTime = MAX(0, (eventDelta + curEvent->stopTime) << 8); + +			} else { +				switch (cmd) { + +				case 0x80:	// TEMPO +					if ((_playerCtx.tickUnit >> 8) > curEvent->stopTime) { +						_playerCtx.tickUnit = calcTempo(curEvent->parameter << 4, _playerCtx.vBlankFreq); +						_playerCtx.tempoTime = 0; +					} else { +						_playerCtx.tempoStart = _playerCtx.tempo; +						_playerCtx.tempoDelta = (curEvent->parameter << 4) - _playerCtx.tempoStart; +						_playerCtx.tempoTime  = (curEvent->stopTime << 8); +						_playerCtx.tempoTicks = 0; +					} +					break; +				 +				case 0xC0:	// PROGRAM +					channel.patch = &_patch[curEvent->stopTime & (kNumPatches - 1)]; +					break; + +				case 0xE0:	// BEND +					channel.pitchBend = ((curEvent->stopTime & 0x7F00) >> 1) | (curEvent->stopTime & 0x7f); +					channel.pitchReal = (((int32)channel.pitchBendRange * channel.pitchBend) >> 5) - (channel.pitchBendRange << 8); +					channel.isAltered = true; +					break; + +				case 0xFF:	// END +					if (_playerCtx.musicLoop) { +						curEvent = _scores[_playerCtx.scoreIndex].events; +						eventDelta = curEvent->startTime - millis; +						_playerCtx.ticks = 0; +					} else +						_playerCtx.scoreIndex = -1; +					// stop processing for this tick +					goto endOfEventLoop; + +				case 0xA0: 	// SPECIAL +					switch (curEvent->stopTime >> 8){ +					case 0x01:	// SPECIAL_SYNC +						_playerCtx.syncCallBack(curEvent->stopTime & 0xFF); +						break; +					case 0x02:	// SPECIAL_BEGINREP +						// we allow a depth of 4 loops +						for (int i = 0; i < ARRAYSIZE(_playerCtx.repeatPoint); ++i) { +							if (!_playerCtx.repeatPoint[i]) { +								_playerCtx.repeatPoint[i] = curEvent; +								_playerCtx.repeatCount[i] = curEvent->stopTime & 0xFF; +								break; +							} +						} +						break; +					case 0x03:	// SPECIAL_ENDREP +						for (int i = ARRAYSIZE(_playerCtx.repeatPoint) - 1; i >= 0; --i) { +							if (_playerCtx.repeatPoint[i]) { +								if (_playerCtx.repeatCount[i]--) +									curEvent = _playerCtx.repeatPoint[i]; // gets incremented by 1 at end of loop +								else +									_playerCtx.repeatPoint[i] = 0; +								break; +							} +						} +						break; +					} +					break; + +				case 0xB0:	// CONTROL +					controlCh(channel, (byte)(curEvent->stopTime >> 8), (byte)curEvent->stopTime); +					break; + +				default: +					debug("Unhandled Command"); +					outPutEvent(*curEvent); +				} +			} +		} +endOfEventLoop: +		_playerCtx.nextEvent = curEvent; +		_playerCtx.nextEventTime = eventDelta + millis; + +		// tempoEffect +		if (_playerCtx.tempoTime) { +			_playerCtx.tempoTicks += _playerCtx.tickUnit; +			uint16 newTempo = _playerCtx.tempoStart; +			if (_playerCtx.tempoTicks < _playerCtx.tempoTime) { +				newTempo += (uint16)((_playerCtx.tempoTicks * _playerCtx.tempoDelta) / _playerCtx.tempoTime); +			} else { +				_playerCtx.tempoTime = 0; +				newTempo += _playerCtx.tempoDelta; +			} +			_playerCtx.tickUnit = calcTempo(newTempo, _playerCtx.vBlankFreq); +		} +	} + +	// Handling of Envelopes and Portamento +	for (int i = 0; i < ARRAYSIZE(_voiceCtx); ++i) { +		VoiceContext &voice = _voiceCtx[i]; +		if (!voice.channel) +			continue; +		const ChannelContext &channel = *voice.channel; +		const Patch &patch = *voice.patch; + +		switch (voice.status) { +		case VoiceContext::kStatusSustain: +			// we need to check if some voices have no sustainSample. +			// in that case they are finished after the attackSample is done +			if (voice.dmaOff && Paula::getChannelDmaCount((byte)i) >= voice.dmaOff ) { +				voice.dmaOff = 0; +				voice.isBlocked = 0; +				voice.priority = 0; +				// disable it in next tick +				voice.stopEventTime = 0; +			} +			if (!channel.isAltered && !voice.hasPortamento && !channel.modulation) +				continue; +			// Update Volume and Period +			break; + +		case VoiceContext::kStatusHalt: +			killVoice((byte)i); +			continue; + +		case VoiceContext::kStatusStart: +			if (patch.attackLen) { +				voice.envelope = patch.attackPtr; +				const uint16 duration = voice.envelope->duration; +				voice.envelopeLeft = patch.attackLen; +				voice.ticksLeft = duration << 8; +				voice.status = VoiceContext::kStatusAttack; +				voice.incrVolume = calcVolumeDelta((int32)voice.envelope->volume, duration, _playerCtx.vBlankFreq); +				// Process Envelope +			} else { +				voice.status = VoiceContext::kStatusSustain; +				voice.baseVolume = patch.volume; +				// Update Volume and Period +			} +			break; + +		case VoiceContext::kStatusRelease: +			if (patch.releaseLen) { +				voice.envelope = patch.attackPtr + patch.attackLen; +				const uint16 duration = voice.envelope->duration; +				voice.envelopeLeft = patch.releaseLen; +				voice.ticksLeft = duration << 8; +				voice.status = VoiceContext::kStatusDecay; +				voice.incrVolume = calcVolumeDelta((int32)voice.envelope->volume - voice.baseVolume, duration, _playerCtx.vBlankFreq); +				// Process Envelope +			} else { +				voice.status = VoiceContext::kStatusHalt; +				voice.lastVolume = 0; +				// Send Audio Packet +			} +			voice.stopEventTime = -1; +			break; +		} + +		// Process Envelope +		const uint16 envUnit = _playerCtx.frameUnit; +		if (voice.envelope) { +			if (voice.ticksLeft > envUnit) {	// envelope still active +				voice.baseVolume = (uint16)MIN(MAX(0, voice.baseVolume + voice.incrVolume), 0x8000); +				voice.ticksLeft -= envUnit; +				// Update Volume and Period + +			} else {	// next or last Envelope +				voice.baseVolume = voice.envelope->volume; +				assert(voice.envelopeLeft > 0); +				if (--voice.envelopeLeft) { +					++voice.envelope; +					const uint16 duration = voice.envelope->duration; +					voice.ticksLeft = duration << 8; +					voice.incrVolume = calcVolumeDelta((int32)voice.envelope->volume - voice.baseVolume, duration, _playerCtx.vBlankFreq); +					// Update Volume and Period +				} else if (voice.status == VoiceContext::kStatusDecay) { +					voice.status = VoiceContext::kStatusHalt; +					voice.envelope = 0; +					voice.lastVolume = 0; +					// Send Audio Packet +				} else { +					assert(voice.status == VoiceContext::kStatusAttack); +					voice.status = VoiceContext::kStatusSustain; +					voice.envelope = 0; +					// Update Volume and Period +				} +			} +		} + +		// Update Volume and Period +		if (voice.status >= VoiceContext::kStatusDecay) { +			// Calc volume +			uint16 vol = (voice.noteVolume < (1 << 7)) ? (voice.noteVolume * _playerCtx.volume) >> 7 : _playerCtx.volume; +			if (voice.baseVolume < (1 << 15)) +				vol = (uint16)(((uint32)vol * voice.baseVolume) >> 15); +			if (voice.channel->volume < (1 << 7)) +				vol = (vol * voice.channel->volume) >> 7; +			voice.lastVolume = (byte)MIN(vol, (uint16)0x64); + +			// Calc Period +			if (voice.hasPortamento) { +				voice.portaTicks += envUnit; +				if ((uint16)(voice.portaTicks >> 8) >= channel.portamentoTime) { +					voice.hasPortamento = false; +					voice.baseNote = voice.endNote; +					voice.preCalcNote = precalcNote(voice.baseNote, patch.tune, voice.octave); +				} +				voice.lastPeriod = calcNote(voice); +			} else if (channel.isAltered || channel.modulation) +				voice.lastPeriod = calcNote(voice); +		} + +		// Send Audio Packet +		Paula::setChannelPeriod((byte)i, (voice.lastPeriod) ? voice.lastPeriod : 1000); +		Paula::setChannelVolume((byte)i, (voice.lastPeriod) ? voice.lastVolume : 0); +	} +	for (ChannelContext *c = _channelCtx; c != &_channelCtx[ARRAYSIZE(_channelCtx)]; ++c) +		c->isAltered = false; + +#ifdef MAXTRAX_HAS_MODULATION +	// original player had _playerCtx.sineValue = _playerCtx.frameUnit >> 2 +	// this should fit the comments that modtime=1000 is one second ? +	_playerCtx.sineValue += _playerCtx.frameUnit; +#endif +} + +void MaxTrax::controlCh(ChannelContext &channel, const byte command, const byte data) { +	switch (command) { +	case 0x01:	// modulation level MSB +		channel.modulation = data << 8; +		break; +	case 0x21:	// modulation level LSB +		channel.modulation = (channel.modulation & 0xFF00) || ((data * 2) & 0xFF); +		break; +	case 0x05:	// portamento time MSB +		channel.portamentoTime = data << 7; +		break; +	case 0x25:	// portamento time LSB +		channel.portamentoTime = (channel.portamentoTime & 0x3f80) || data; +		break; +	case 0x06:	// data entry MSB +		if (channel.regParamNumber == 0) { +			channel.pitchBendRange = (int8)MIN((uint8)MAX_BEND_RANGE, (uint8)data); +			channel.pitchReal = (((int32)channel.pitchBendRange * channel.pitchBend) >> 5) - (channel.pitchBendRange << 8); +			channel.isAltered = true; +		} +		break; +	case 0x07:	// Main Volume MSB +		channel.volume = (data == 0) ? 0 : data + 1; +		channel.isAltered = true; +		break; +	case 0x0A:	// Pan +		if (data > 0x40 || (data == 0x40 && ((&channel - _channelCtx) & 1) != 0)) +			channel.flags |= ChannelContext::kFlagRightChannel; +		else +			channel.flags &= ~ChannelContext::kFlagRightChannel; +		break; +	case 0x10:	// GPC as Modulation Time MSB +		channel.modulationTime = data << 7; +		break; +	case 0x30:	// GPC as Modulation Time LSB +		channel.modulationTime = (channel.modulationTime & 0x3f80) || data; +		break; +	case 0x11:	// GPC as Microtonal Set MSB +		channel.microtonal = data << 8; +		break; +	case 0x31:	// GPC as Microtonal Set LSB +		channel.microtonal = (channel.microtonal & 0xFF00) || ((data * 2) & 0xFF); +		break; +	case 0x40:	// Damper Pedal +		if ((data & 0x40) != 0) +			channel.flags |= ChannelContext::kFlagDamper; +		else { +			channel.flags &= ~ChannelContext::kFlagDamper; +			// release all dampered voices on this channel +			for (int i = 0; i < ARRAYSIZE(_voiceCtx); ++i) { +				if (_voiceCtx[i].channel == &channel && _voiceCtx[i].hasDamper) { +					_voiceCtx[i].hasDamper = false; +					_voiceCtx[i].status = VoiceContext::kStatusRelease; +				} +			} +		} +		break; +	case 0x41:	// Portamento off/on +		if ((data & 0x40) != 0) +			channel.flags |= ChannelContext::kFlagPortamento; +		else +			channel.flags &= ~ChannelContext::kFlagPortamento; +		break; +	case 0x50:	// Microtonal off/on  +		if ((data & 0x40) != 0) +			channel.flags |= ChannelContext::kFlagMicrotonal; +		else +			channel.flags &= ~ChannelContext::kFlagMicrotonal; +		break; +	case 0x51:	// Audio Filter off/on +		Paula::setAudioFilter(data > 0x40 || (data == 0x40 && _playerCtx.filterOn)); +		break; +	case 0x65:	// RPN MSB +		channel.regParamNumber = (data << 8) || (channel.regParamNumber & 0xFF); +		break; +	case 0x64:	// RPN LSB +		channel.regParamNumber = (channel.regParamNumber & 0xFF00) || data; +		break; +	case 0x79:	// Reset All Controllers +		resetChannel(channel, ((&channel - _channelCtx) & 1) != 0); +		break; +	case 0x7E:	// MONO mode +		channel.flags |= ChannelContext::kFlagMono; +		goto allNotesOff; +	case 0x7F:	// POLY mode +		channel.flags &= ~ChannelContext::kFlagMono; +		// Fallthrough +	case 0x7B:	// All Notes Off +allNotesOff: +		for (int i = 0; i < ARRAYSIZE(_voiceCtx); ++i) { +			if (_voiceCtx[i].channel == &channel) { +				if ((channel.flags & ChannelContext::kFlagDamper) != 0) +					_voiceCtx[i].hasDamper = true; +				else +					_voiceCtx[i].status = VoiceContext::kStatusRelease; +			} +		} +		break; +	case 0x78:	// All Sounds Off +		for (int i = 0; i < ARRAYSIZE(_voiceCtx); ++i) { +			if (_voiceCtx[i].channel == &channel) +				killVoice((byte)i); +		} +		break; +	} +} + +void MaxTrax::setTempo(const uint16 tempo) { +	Common::StackLock lock(_mutex); +	_playerCtx.tickUnit = calcTempo(tempo, _playerCtx.vBlankFreq); +} + +void MaxTrax::resetPlayer() { +	for (int i = 0; i < ARRAYSIZE(_voiceCtx); ++i) +		killVoice((byte)i); + +	for (int i = 0; i < ARRAYSIZE(_channelCtx); ++i) { +		_channelCtx[i].flags = 0; +		_channelCtx[i].lastNote = (uint8)-1; +		resetChannel(_channelCtx[i], (i & 1) != 0); +		_channelCtx[i].patch = (i < kNumChannels) ? &_patch[i] : 0; +	} + +#ifdef MAXTRAX_HAS_MICROTONAL +	for (int i = 0; i < ARRAYSIZE(_microtonal); ++i) +		_microtonal[i] = (int16)(i << 8); +#endif +} + +void MaxTrax::stopMusic() { +	Common::StackLock lock(_mutex); +	_playerCtx.scoreIndex = -1; +	for (int i = 0; i < ARRAYSIZE(_voiceCtx); ++i) { +		if (_voiceCtx[i].channel < &_channelCtx[kNumChannels]) +			killVoice((byte)i); +	} +} + +bool MaxTrax::playSong(int songIndex, bool loop) { +	if (songIndex < 0 || songIndex >= _numScores) +		return false; +	Common::StackLock lock(_mutex); +	_playerCtx.scoreIndex = -1; +	resetPlayer(); +	for (int i = 0; i < ARRAYSIZE(_playerCtx.repeatPoint); ++i) +		_playerCtx.repeatPoint[i] = 0; + +	setTempo(_playerCtx.tempoInitial << 4); +	Paula::setAudioFilter(_playerCtx.filterOn); +	_playerCtx.musicLoop = loop; +	_playerCtx.tempoTime = 0; +	_playerCtx.scoreIndex = songIndex; +	_playerCtx.ticks = 0; + +	_playerCtx.nextEvent = _scores[songIndex].events;; +	_playerCtx.nextEventTime = _playerCtx.nextEvent->startTime; + +	Paula::startPaula(); +	return true; +} + +void MaxTrax::advanceSong(int advance) { +	Common::StackLock lock(_mutex); +	if (_playerCtx.scoreIndex >= 0) { +		const Event *cev = _playerCtx.nextEvent; +		if (cev) { +			for (; advance > 0; --advance) { +				// TODO - check for boundaries  +				for (; cev->command != 0xFF && (cev->command != 0xA0 || (cev->stopTime >> 8) != 0x00); ++cev) +					; // no end_command or special_command + end +			} +			_playerCtx.nextEvent = cev; +		} +	} +} + +void MaxTrax::killVoice(byte num) { +	VoiceContext &voice = _voiceCtx[num]; +	voice.channel = 0; +	voice.envelope = 0; +	voice.status = VoiceContext::kStatusFree; +	voice.isBlocked = 0; +	voice.hasDamper = false; +	voice.hasPortamento = false; +	voice.priority = 0; +	voice.stopEventTime = -1; +	voice.dmaOff = 0; +	voice.lastVolume = 0; +	voice.tieBreak = 0; +	//voice.uinqueId = 0; + +	// "stop" voice, set period to 1, vol to 0 +	Paula::disableChannel(num); +	Paula::setChannelPeriod(num, 1); +	Paula::setChannelVolume(num, 0); +} + +int8 MaxTrax::pickvoice(uint pick, int16 pri) { +	enum { kPrioFlagFixedSide = 1 << 3 }; +	pick &= 3; +	if ((pri & (kPrioFlagFixedSide)) == 0) { +		const bool leftSide = (uint)(pick - 1) > 1; +		const int leftBest = MIN(_voiceCtx[0].status, _voiceCtx[3].status); +		const int rightBest = MIN(_voiceCtx[1].status, _voiceCtx[2].status); +		const int sameSide = (leftSide) ? leftBest : rightBest; +		const int otherSide = leftBest + rightBest - sameSide; + +		if (sameSide > VoiceContext::kStatusRelease && otherSide <= VoiceContext::kStatusRelease) +			pick ^= 1; // switches sides +	} +	pri &= ~kPrioFlagFixedSide; + +	for (int i = 2; i > 0; --i) { +		VoiceContext *voice = &_voiceCtx[pick]; +		VoiceContext *alternate = &_voiceCtx[pick ^ 3]; + +		const uint16 voiceVal = voice->status << 8 | voice->lastVolume; +		const uint16 altVal = alternate->status << 8 | alternate->lastVolume; + +		if (voiceVal + voice->tieBreak > altVal  +			|| voice->isBlocked > alternate->isBlocked) { + +			// this is somewhat different to the original player, +			// but has a similar result +			voice->tieBreak = 0; +			alternate->tieBreak = 1; + +			pick ^= 3; // switch channels +			VoiceContext *tmp = voice; +			voice = alternate; +			alternate = tmp; +		} + +		if (voice->isBlocked || voice->priority > pri) { +			// if not already done, switch sides and try again +			pick ^= 1; +			continue; +		} +		// succeded +		return (int8)pick; +	} +	// failed +	debug(5, "MaxTrax: could not find channel for note"); +	return -1; +} + +uint16 MaxTrax::calcNote(const VoiceContext &voice) { +	const ChannelContext &channel = *voice.channel; +	int16 bend = channel.pitchReal; + +#ifdef MAXTRAX_HAS_MICROTONAL +	if (voice.hasPortamento) { +		if ((channel.flags & ChannelContext::kFlagMicrotonal) != 0) +			bend += (int16)(((_microtonal[voice.endNote] - _microtonal[voice.baseNote]) * voice.portaTicks) >> 8) / channel.portamentoTime; +		else +			bend += (int16)(((int8)(voice.endNote - voice.baseNote)) * voice.portaTicks) / channel.portamentoTime; +	} + +	if ((channel.flags & ChannelContext::kFlagMicrotonal) != 0) +		bend += _microtonal[voice.baseNote]; +#else +	if (voice.hasPortamento) +		bend += (int16)(((int8)(voice.endNote - voice.baseNote)) * voice.portaTicks) / channel.portamentoTime; +#endif + +#ifdef MAXTRAX_HAS_MODULATION +	static const uint8 tableSine[] = { +		  0,   5,  12,  18,  24,  30,  37,  43,  49,  55,  61,  67,  73,  79,  85,  91, +		 97, 103, 108, 114, 120, 125, 131, 136, 141, 146, 151, 156, 161, 166, 171, 176, +		180, 184, 189, 193, 197, 201, 205, 208, 212, 215, 219, 222, 225, 228, 230, 233, +		236, 238, 240, 242, 244, 246, 247, 249, 250, 251, 252, 253, 254, 254, 255, 255, +		255, 255, 255, 254, 254, 253, 252, 251, 250, 249, 247, 246, 244, 242, 240, 238, +		236, 233, 230, 228, 225, 222, 219, 215, 212, 208, 205, 201, 197, 193, 189, 184, +		180, 176, 171, 166, 161, 156, 151, 146, 141, 136, 131, 125, 120, 114, 108, 103, +		 97,  91,  85,  79,  73,  67,  61,  55,  49,  43,  37,  30,  24,  18,  12,   5 +	}; +	if (channel.modulation) { +		if ((channel.flags & ChannelContext::kFlagModVolume) == 0) { +			const uint8 sineByte = _playerCtx.sineValue / channel.modulationTime; +			const uint8 sineIndex = sineByte & 0x7F; +			const int16 modVal = ((uint32)(uint16)(tableSine[sineIndex] + (sineIndex ? 1 : 0)) * channel.modulation) >> 8; +			bend = (sineByte < 0x80) ? bend + modVal : bend - modVal; +		}  +	} +#endif + +	// tone = voice.baseNote << 8 + microtonal +	// bend = channelPitch + porta + modulation + +	const int32 tone = voice.preCalcNote + (bend << 6) / 3; + +	return (tone >= PERIOD_LIMIT) ? (uint16)pow2Fixed(tone) : 0; +} + +int8 MaxTrax::noteOn(ChannelContext &channel, const byte note, uint16 volume, uint16 pri) { +#ifdef MAXTRAX_HAS_MICROTONAL +	if (channel.microtonal >= 0) +		_microtonal[note % 127] = channel.microtonal; +#endif + +	if (!volume) +		return -1; + +	const Patch &patch = *channel.patch; +	if (!patch.samplePtr || patch.sampleTotalLen == 0) +		return -1; +	int8 voiceNum = -1; +	if ((channel.flags & ChannelContext::kFlagMono) == 0) { +		voiceNum = pickvoice((channel.flags & ChannelContext::kFlagRightChannel) != 0 ? 1 : 0, pri); +	} else { +		VoiceContext *voice = _voiceCtx + ARRAYSIZE(_voiceCtx) - 1; +		for (voiceNum = ARRAYSIZE(_voiceCtx) - 1; voiceNum >= 0 && voice->channel != &channel; --voiceNum, --voice) +			; +		if (voiceNum < 0) +			voiceNum = pickvoice((channel.flags & ChannelContext::kFlagRightChannel) != 0 ? 1 : 0, pri); +		else if (voice->status >= VoiceContext::kStatusSustain && (channel.flags & ChannelContext::kFlagPortamento) != 0) { +			// reset previous porta +			if (voice->hasPortamento) +				voice->baseNote = voice->endNote; +			voice->preCalcNote = precalcNote(voice->baseNote, patch.tune, voice->octave); +			voice->noteVolume = (_playerCtx.handleVolume) ? volume + 1 : 128; +			voice->portaTicks = 0; +			voice->hasPortamento = true; +			voice->endNote = channel.lastNote = note; +			return voiceNum; +		} +	}	 + +	if (voiceNum >= 0) { +		VoiceContext &voice = _voiceCtx[voiceNum]; +		voice.hasDamper = false; +		voice.isBlocked = 0; +		voice.hasPortamento = false; +		if (voice.channel) +			killVoice(voiceNum); +		voice.channel = &channel; +		voice.patch = &patch; +		voice.baseNote = note; + +		// always base octave on the note in the command, regardless of porta +		const int32 plainNote = precalcNote(note, patch.tune, 0); +		// calculate which sample to use +		const int useOctave = (plainNote <= PREF_PERIOD) ? 0 : MIN<int32>((plainNote + 0xFFFF - PREF_PERIOD) >> 16, patch.sampleOctaves - 1); +		voice.octave = (byte)useOctave; +		// adjust precalculated value +		voice.preCalcNote = plainNote - (useOctave << 16); + +		// next calculate the actual period which depends on wether porta is enabled +		if (&channel < &_channelCtx[kNumChannels] && (channel.flags & ChannelContext::kFlagPortamento) != 0) { +			if ((channel.flags & ChannelContext::kFlagMono) != 0 && channel.lastNote < 0x80 && channel.lastNote != note) { +				voice.portaTicks = 0; +				voice.baseNote = channel.lastNote; +				voice.endNote = note; +				voice.hasPortamento = true; +				voice.preCalcNote = precalcNote(voice.baseNote, patch.tune, voice.octave); +			} +			channel.lastNote = note; +		} +		 +		voice.lastPeriod = calcNote(voice); + +		voice.priority = (byte)pri; +		voice.status = VoiceContext::kStatusStart; + +		voice.noteVolume = (_playerCtx.handleVolume) ? volume + 1 : 128; +		voice.baseVolume = 0; + +		// TODO: since the original player is using the OS-functions, more than 1 sample could be queued up already +		// get samplestart for the given octave +		const int8 *samplePtr = patch.samplePtr + (patch.sampleTotalLen << useOctave) - patch.sampleTotalLen; +		if (patch.sampleAttackLen) { +			Paula::setChannelSampleStart(voiceNum, samplePtr); +			Paula::setChannelSampleLen(voiceNum, (patch.sampleAttackLen << useOctave) / 2); + +			Paula::enableChannel(voiceNum); +			// wait  for dma-clear +		} + +		if (patch.sampleTotalLen > patch.sampleAttackLen) { +			Paula::setChannelSampleStart(voiceNum, samplePtr + (patch.sampleAttackLen << useOctave)); +			Paula::setChannelSampleLen(voiceNum, ((patch.sampleTotalLen - patch.sampleAttackLen) << useOctave) / 2); +			if (!patch.sampleAttackLen) +				Paula::enableChannel(voiceNum); // need to enable channel +			// another pointless wait for DMA-Clear??? + +		} else { // no sustain sample +			// this means we must stop playback after the attacksample finished +			// so we queue up an "empty" sample and note that we need to kill the sample after dma finished +			Paula::setChannelSampleStart(voiceNum, 0); +			Paula::setChannelSampleLen(voiceNum, 0); +			Paula::setChannelDmaCount(voiceNum); +			voice.dmaOff = 1; +		} + +		Paula::setChannelPeriod(voiceNum, (voice.lastPeriod) ? voice.lastPeriod : 1000); +		Paula::setChannelVolume(voiceNum, 0); +	} +	return voiceNum; +} + +void MaxTrax::resetChannel(ChannelContext &chan, bool rightChannel) { +	chan.modulation = 0; +	chan.modulationTime = 1000; +	chan.microtonal = -1; +	chan.portamentoTime = 500; +	chan.pitchBend = NO_BEND; +	chan.pitchReal = 0; +	chan.pitchBendRange = MAX_BEND_RANGE; +	chan.volume = 128; +	chan.flags &= ~(ChannelContext::kFlagPortamento | ChannelContext::kFlagMicrotonal | ChannelContext::kFlagRightChannel); +	chan.isAltered = true; +	if (rightChannel) +		chan.flags |= ChannelContext::kFlagRightChannel; +} + +void MaxTrax::freeScores() { +	if (_scores) { +		for (int i = 0; i < _numScores; ++i) +			delete[] _scores[i].events; +		delete[] _scores; +		_scores = 0; +	} +	_numScores = 0; +	_playerCtx.tempo = 120; +	_playerCtx.filterOn = true; +} + +void MaxTrax::freePatches() { +	for (int i = 0; i < ARRAYSIZE(_patch); ++i) { +		delete[] _patch[i].samplePtr; +		delete[] _patch[i].attackPtr; +	} +	memset(_patch, 0, sizeof(_patch)); +} + +void MaxTrax::setSignalCallback(void (*callback) (int)) { +	Common::StackLock lock(_mutex); +	_playerCtx.syncCallBack = (callback == 0) ? nullFunc : callback; +} + +int MaxTrax::playNote(byte note, byte patch, uint16 duration, uint16 volume, bool rightSide) { +	Common::StackLock lock(_mutex); +	assert(patch < ARRAYSIZE(_patch)); + +	ChannelContext &channel = _channelCtx[kNumChannels]; +	channel.flags = (rightSide) ? ChannelContext::kFlagRightChannel : 0; +	channel.isAltered = false; +	channel.patch = &_patch[patch]; +	const int8 voiceIndex = noteOn(channel, note, (byte)volume, kPriorityNote); +	if (voiceIndex >= 0) +		_voiceCtx[voiceIndex].stopEventTime = duration << 8; +	return voiceIndex; +} + +bool MaxTrax::load(Common::SeekableReadStream &musicData, bool loadScores, bool loadSamples) { +	Common::StackLock lock(_mutex); +	stopMusic(); +	if (loadSamples) +		freePatches(); +	if (loadScores) +		freeScores(); +	const char *errorMsg = 0; +	// 0x0000: 4 Bytes Header "MXTX" +	// 0x0004: uint16 tempo +	// 0x0006: uint16 flags. bit0 = lowpassfilter, bit1 = attackvolume, bit15 = microtonal	 +	if (musicData.size() < 10 || musicData.readUint32BE() != 0x4D585458) { +		warning("Maxtrax: File is not a Maxtrax Module"); +		return false; +	} +	const uint16 songTempo = musicData.readUint16BE(); +	const uint16 flags = musicData.readUint16BE(); +	if (loadScores) { +		_playerCtx.tempoInitial = songTempo; +		_playerCtx.filterOn = (flags & 1) != 0; +		_playerCtx.handleVolume = (flags & 2) != 0; +	} + +	if (flags & (1 << 15)) { +		debug(5, "Maxtrax: Song has microtonal"); +#ifdef MAXTRAX_HAS_MICROTONAL +		if (loadScores) { +			for (int i = 0; i < ARRAYSIZE(_microtonal); ++i) +				_microtonal[i] = musicData.readUint16BE(); +		} else +			musicData.skip(128 * 2); +#else +		musicData.skip(128 * 2); +#endif +	} + +	int scoresLoaded = 0; +	// uint16 number of Scores +	const uint16 scoresInFile = musicData.readUint16BE(); + +	if (musicData.err() || musicData.eos()) +		goto ioError; + +	if (loadScores) { +		const uint16 tempScores = MIN(scoresInFile, _playerCtx.maxScoreNum); +		Score *curScore = new Score[tempScores]; +		if (!curScore) +			goto allocError; +		_scores = curScore; +		 +		for (scoresLoaded = 0; scoresLoaded < tempScores; ++scoresLoaded, ++curScore) { +			const uint32 numEvents = musicData.readUint32BE(); +			Event *curEvent = new Event[numEvents]; +			if (!curEvent) +				goto allocError; +			curScore->events = curEvent; +			for (int j = numEvents; j > 0; --j, ++curEvent) { +				curEvent->command = musicData.readByte(); +				curEvent->parameter = musicData.readByte(); +				curEvent->startTime = musicData.readUint16BE(); +				curEvent->stopTime = musicData.readUint16BE(); +			} +			curScore->numEvents = numEvents; +		} +		_numScores = scoresLoaded; +	} + +	if (loadSamples) { +		// skip over remaining scores in file +		for (int i = scoresInFile - scoresLoaded; i > 0; --i) +			musicData.skip(musicData.readUint32BE() * 6); + +		// uint16 number of Samples +		const uint16 wavesInFile = musicData.readUint16BE(); +		for (int i = wavesInFile; i > 0; --i) { +			// load disksample structure +			const uint16 number = musicData.readUint16BE(); +			assert(number < ARRAYSIZE(_patch)); + +			Patch &curPatch = _patch[number]; +			if (curPatch.attackPtr || curPatch.samplePtr) { +				delete curPatch.attackPtr; +				curPatch.attackPtr = 0; +				delete curPatch.samplePtr; +				curPatch.samplePtr = 0; +			} +			curPatch.tune = musicData.readSint16BE(); +			curPatch.volume = musicData.readUint16BE(); +			curPatch.sampleOctaves = musicData.readUint16BE(); +			curPatch.sampleAttackLen = musicData.readUint32BE(); +			const uint32 sustainLen = musicData.readUint32BE(); +			curPatch.sampleTotalLen = curPatch.sampleAttackLen + sustainLen; +			// each octave the number of samples doubles. +			const uint32 totalSamples = curPatch.sampleTotalLen * ((1 << curPatch.sampleOctaves) - 1); +			curPatch.attackLen = musicData.readUint16BE(); +			curPatch.releaseLen = musicData.readUint16BE(); +			const uint32 totalEnvs = curPatch.attackLen + curPatch.releaseLen; + +			// Allocate space for both attack and release Segment. +			Envelope *envPtr = new Envelope[totalEnvs]; +			if (!envPtr) +				goto allocError; +			// Attack Segment +			curPatch.attackPtr = envPtr; +			// Release Segment +			// curPatch.releasePtr = envPtr + curPatch.attackLen; + +			// Read Attack and Release Segments +			for (int j = totalEnvs; j > 0; --j, ++envPtr) { +				envPtr->duration = musicData.readUint16BE(); +				envPtr->volume = musicData.readUint16BE(); +			} + +			// read Samples +			int8 *allocSamples = new int8[totalSamples]; +			if (!allocSamples) +				goto allocError; +			curPatch.samplePtr = allocSamples; +			musicData.read(allocSamples, totalSamples); +		} +	} +	if (!musicData.err() && !musicData.eos()) +		return true; +ioError: +	errorMsg = "Maxtrax: Encountered IO-Error"; +allocError: +	if (!errorMsg) +		errorMsg = "Maxtrax: Could not allocate Memory"; + +	warning("%s", errorMsg); +	if (loadSamples) +		freePatches(); +	if (loadScores) +		freeScores(); +	return false; +} + +#if !defined(NDEBUG) && 0 +void MaxTrax::outPutEvent(const Event &ev, int num) { +	struct { +		byte cmd; +		const char *name; +		const char *param; +	} COMMANDS[] = { +		{0x80, "TEMPO   ", "TEMPO, N/A      "}, +		{0xa0, "SPECIAL ", "CHAN, SPEC # | VAL"}, +		{0xb0, "CONTROL ", "CHAN, CTRL # | VAL"}, +		{0xc0, "PROGRAM ", "CHANNEL, PROG # "}, +		{0xe0, "BEND    ", "CHANNEL, BEND VALUE"}, +		{0xf0, "SYSEX   ", "TYPE, SIZE      "}, +		{0xf8, "REALTIME", "REALTIME, N/A   "}, +		{0xff, "END     ", "N/A, N/A        "}, +		{0xff, "NOTE    ", "VOL | CHAN, STOP"}, +	}; + +	int i = 0; +	for (; i < ARRAYSIZE(COMMANDS) - 1 && ev.command != COMMANDS[i].cmd; ++i) +		; + +	if (num == -1) +		debug("Event    : %02X %s %s %02X %04X %04X", ev.command, COMMANDS[i].name, COMMANDS[i].param, ev.parameter, ev.startTime, ev.stopTime); +	else +		debug("Event %3d: %02X %s %s %02X %04X %04X", num, ev.command, COMMANDS[i].name, COMMANDS[i].param, ev.parameter, ev.startTime, ev.stopTime); +} + +void MaxTrax::outPutScore(const Score &sc, int num) { +	if (num == -1) +		debug("score   : %i Events", sc.numEvents); +	else +		debug("score %2d: %i Events", num, sc.numEvents); +	for (uint i = 0; i < sc.numEvents; ++i) +		outPutEvent(sc.events[i], i); +	debug(""); +} +#else +void MaxTrax::outPutEvent(const Event &ev, int num) {} +void MaxTrax::outPutScore(const Score &sc, int num) {} +#endif	// #ifndef NDEBUG + +}	// End of namespace Audio + +#endif // #if defined(SOUND_MODS_MAXTRAX_H) diff --git a/sound/mods/maxtrax.h b/sound/mods/maxtrax.h new file mode 100644 index 0000000000..3cd5ebc94b --- /dev/null +++ b/sound/mods/maxtrax.h @@ -0,0 +1,225 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +// see if all engines using this class are DISABLED +#if !defined(ENABLE_KYRA) + +// normal Header Guard +#elif !defined SOUND_MODS_MAXTRAX_H +#define SOUND_MODS_MAXTRAX_H + +// #define MAXTRAX_HAS_MODULATION +// #define MAXTRAX_HAS_MICROTONAL + +#include "sound/mods/paula.h" + +namespace Audio { + +class MaxTrax : public Paula { +public: +	MaxTrax(int rate, bool stereo, uint16 vBlankFreq = 50, uint16 maxScores = 128); +	virtual ~MaxTrax(); + +	bool load(Common::SeekableReadStream &musicData, bool loadScores = true, bool loadSamples = true); +	bool playSong(int songIndex, bool loop = false); +	void advanceSong(int advance = 1); +	int playNote(byte note, byte patch, uint16 duration, uint16 volume, bool rightSide); +	void setVolume(const byte volume) { Common::StackLock lock(_mutex); _playerCtx.volume = volume; } +	void setTempo(const uint16 tempo); +	void stopMusic(); +	/** +	 * Set a callback function for sync-events. +	 * @param callback Callback function, will be called synchronously, so DONT modify the player  +	 *		directly in response +	 */ +	void setSignalCallback(void (*callback) (int)); + +protected: +	void interrupt(); + +private: +	enum { kNumPatches = 64, kNumVoices = 4, kNumChannels = 16, kNumExtraChannels = 1 }; +	enum { kPriorityScore, kPriorityNote, kPrioritySound }; + +#ifdef MAXTRAX_HAS_MICROTONAL +	int16	_microtonal[128]; +#endif + +	struct Event { +		uint16	startTime; +		uint16	stopTime; +		byte	command; +		byte	parameter; +	}; + +	const struct Score { +		const Event	*events; +		uint32	numEvents; +	} *_scores; + +	int _numScores; + +	struct { +		uint32	sineValue; +		uint16	vBlankFreq; +		int32	ticks; +		int32	tickUnit; +		uint16	frameUnit; + +		uint16	maxScoreNum; +		uint16	tempo; +		uint16	tempoInitial; +		uint16	tempoStart; +		int16	tempoDelta; +		int32	tempoTime; +		int32	tempoTicks; + +		byte	volume; + +		bool	filterOn; +		bool	handleVolume; +		bool	musicLoop; + +		int		scoreIndex; +		const Event	*nextEvent; +		int32	nextEventTime; + +		void (*syncCallBack) (int); +		const Event	*repeatPoint[4]; +		byte	repeatCount[4]; +	} _playerCtx; + +	struct Envelope { +		uint16	duration; +		uint16	volume; +	}; + +	struct Patch { +		const Envelope *attackPtr; +		//Envelope *releasePtr; +		uint16	attackLen; +		uint16	releaseLen; + +		int16	tune; +		uint16	volume; + +		// this was the SampleData struct in the assembler source +		const int8	*samplePtr; +		uint32	sampleTotalLen; +		uint32	sampleAttackLen; +		uint16	sampleOctaves; +	} _patch[kNumPatches]; + +	struct ChannelContext { +		const Patch	*patch; +		uint16	regParamNumber; + +		uint16	modulation; +		uint16	modulationTime; + +		int16	microtonal; + +		uint16	portamentoTime; + +		int16	pitchBend; +		int16	pitchReal; +		int8	pitchBendRange; + +		uint8	volume; +//		uint8	voicesActive; + +		enum { +			kFlagRightChannel = 1 << 0, +			kFlagPortamento = 1 << 1, +			kFlagDamper = 1 << 2, +			kFlagMono = 1 << 3, +			kFlagMicrotonal = 1 << 4, +			kFlagModVolume = 1 << 5 +		}; +		byte	flags; +		bool	isAltered; + +		uint8	lastNote; +//		uint8	program; + +	} _channelCtx[kNumChannels + kNumExtraChannels]; + +	struct VoiceContext { +		ChannelContext *channel; +		const Patch	*patch; +		const Envelope *envelope; +//		uint32	uinqueId; +		int32	preCalcNote; +		uint32	ticksLeft; +		int32	portaTicks; +		int32	incrVolume; +//		int32	periodOffset; +		uint16	envelopeLeft; +		uint16	noteVolume; +		uint16	baseVolume; +		uint16	lastPeriod; +		byte	baseNote; +		byte	endNote; +		byte	octave; +//		byte	number; +//		byte	link; +		enum { +			kStatusFree, +			kStatusHalt, +			kStatusDecay, +			kStatusRelease, +			kStatusSustain, +			kStatusAttack, +			kStatusStart +		}; +		uint8	isBlocked; +		uint8	priority; +		byte	status; +		byte	lastVolume; +		byte	tieBreak; +		bool	hasDamper; +		bool	hasPortamento; +		byte	dmaOff; + +		int32	stopEventTime; +	} _voiceCtx[kNumVoices]; + +	void controlCh(ChannelContext &channel, byte command, byte data); +	void freePatches(); +	void freeScores(); +	void resetChannel(ChannelContext &chan, bool rightChannel); +	void resetPlayer(); + +	int8 pickvoice(uint pick, int16 pri); +	uint16 calcNote(const VoiceContext &voice); +	int8 noteOn(ChannelContext &channel, byte note, uint16 volume, uint16 pri); +	void killVoice(byte num); + +	static void outPutEvent(const Event &ev, int num = -1); +	static void outPutScore(const Score &sc, int num = -1); +}; +}	// End of namespace Audio + +#endif // !defined SOUND_MODS_MAXTRAX_H diff --git a/sound/mods/paula.cpp b/sound/mods/paula.cpp index 545390ff93..1f557e0ece 100644 --- a/sound/mods/paula.cpp +++ b/sound/mods/paula.cpp @@ -27,19 +27,20 @@  namespace Audio { -Paula::Paula(bool stereo, int rate, int interruptFreq) : -		_stereo(stereo), _rate(rate), _intFreq(interruptFreq) { +Paula::Paula(bool stereo, int rate, uint interruptFreq) : +		_stereo(stereo), _rate(rate), _periodScale((double)kPalPaulaClock / rate), _intFreq(interruptFreq) {  	clearVoices(); -	_voice[0].panning = 63; -	_voice[1].panning = 191; -	_voice[2].panning = 191; -	_voice[3].panning = 63; +	_voice[0].panning = 191; +	_voice[1].panning = 63; +	_voice[2].panning = 63; +	_voice[3].panning = 191; -	if (_intFreq <= 0) +	if (_intFreq == 0)  		_intFreq = _rate; -	_curInt = _intFreq; +	_curInt = 0; +	_timerBase = 1;  	_playing = false;  	_end = true;  } @@ -57,6 +58,7 @@ void Paula::clearVoice(byte voice) {  	_voice[voice].period = 0;  	_voice[voice].volume = 0;  	_voice[voice].offset = 0; +	_voice[voice].dmaCount = 0;  }  int Paula::readBuffer(int16 *buffer, const int numSamples) { @@ -95,18 +97,17 @@ int Paula::readBufferIntern(int16 *buffer, const int numSamples) {  		// Handle 'interrupts'. This gives subclasses the chance to adjust the channel data  		// (e.g. insert new samples, do pitch bending, whatever). -		if (_curInt == _intFreq) { +		if (_curInt == 0) { +			_curInt = _intFreq;  			interrupt(); -			_curInt = 0;  		}  		// Compute how many samples to generate: at most the requested number of samples,  		// of course, but we may stop earlier when an 'interrupt' is expected. -		const int nSamples = MIN(samples, _intFreq - _curInt); +		const uint nSamples = MIN((uint)samples, _curInt);  		// Loop over the four channels of the emulated Paula chip  		for (int voice = 0; voice < NUM_VOICES; voice++) { -  			// No data, or paused -> skip channel  			if (!_voice[voice].data || (_voice[voice].period <= 0))  				continue; @@ -115,8 +116,7 @@ int Paula::readBufferIntern(int16 *buffer, const int numSamples) {  			// the requested output sampling rate (typicall 44.1 kHz or 22.05 kHz)  			// as well as the "period" of the channel we are processing right now,  			// to compute the correct output 'rate'. -			const double frequency = (7093789.2 / 2.0) / _voice[voice].period; -			frac_t rate = doubleToFrac(frequency / _rate); +			frac_t rate = doubleToFrac(_periodScale / _voice[voice].period);  			// Cap the volume  			_voice[voice].volume = MIN((byte) 0x40, _voice[voice].volume); @@ -126,50 +126,67 @@ int Paula::readBufferIntern(int16 *buffer, const int numSamples) {  			frac_t offset = _voice[voice].offset;  			frac_t sLen = intToFrac(_voice[voice].length);  			const int8 *data = _voice[voice].data; +			int dmaCount = _voice[voice].dmaCount;  			int16 *p = buffer;  			int end = 0;  			int neededSamples = nSamples; +			assert(offset < sLen);  			// Compute the number of samples to generate; that is, either generate  			// just as many as were requested, or until the buffer is used up.  			// Note that dividing two frac_t yields an integer (as the denominators  			// cancel out each other).  			// Note that 'end' could be 0 here. No harm in that :-). -			end = MIN(neededSamples, (int)((sLen - offset + rate - 1) / rate)); +			const int leftSamples = (int)((sLen - offset + rate - 1) / rate); +			end = MIN(neededSamples, leftSamples);  			mixBuffer<stereo>(p, data, offset, rate, end, _voice[voice].volume, _voice[voice].panning);  			neededSamples -= end; -			// If we have not yet generated enough samples, and looping is active: loop! -			if (neededSamples > 0 && _voice[voice].lengthRepeat > 2) { - -				// At this point we know that we have used up all samples in the buffer, so reset it. -				_voice[voice].data = data = _voice[voice].dataRepeat; +			if (leftSamples > 0 && end == leftSamples) { +				dmaCount++; +				data = _voice[voice].data = _voice[voice].dataRepeat;  				_voice[voice].length = _voice[voice].lengthRepeat; +				// TODO: offset -= sLen; but make sure there is no way offset >= 2*sLen +				offset &= FRAC_LO_MASK; +			} + +			// If we have not yet generated enough samples, and looping is active: loop! +			if (neededSamples > 0 && _voice[voice].length > 2) {  				sLen = intToFrac(_voice[voice].length);  				// If the "rate" exceeds the sample rate, we would have to perform constant  				// wrap arounds. So, apply the first step of the euclidean algorithm to  				// achieve the same more efficiently: Take rate modulo sLen +				// TODO: This messes up dmaCount and shouldnt happen?  				if (sLen < rate) -					rate %= sLen; +					warning("Paula: length %d is lesser than rate", _voice[voice].length); +//					rate %= sLen;  				// Repeat as long as necessary.  				while (neededSamples > 0) { -					offset = 0; - +					// TODO: offset -= sLen; but make sure there is no way offset >= 2*sLen +					offset &= FRAC_LO_MASK; +					dmaCount++;  					// Compute the number of samples to generate (see above) and mix 'em.  					end = MIN(neededSamples, (int)((sLen - offset + rate - 1) / rate));  					mixBuffer<stereo>(p, data, offset, rate, end, _voice[voice].volume, _voice[voice].panning);  					neededSamples -= end;  				} + +				if (offset < sLen) +					dmaCount--; +				else +					offset &= FRAC_LO_MASK; +  			}  			// Write back the cached data  			_voice[voice].offset = offset; +			_voice[voice].dmaCount = dmaCount;  		}  		buffer += _stereo ? nSamples * 2 : nSamples; -		_curInt += nSamples; +		_curInt -= nSamples;  		samples -= nSamples;  	}  	return numSamples; diff --git a/sound/mods/paula.h b/sound/mods/paula.h index e3c6002451..647dc5fe56 100644 --- a/sound/mods/paula.h +++ b/sound/mods/paula.h @@ -40,12 +40,29 @@ namespace Audio {  class Paula : public AudioStream {  public:  	static const int NUM_VOICES = 4; +	enum { +		kPalSystemClock  = 7093790, +		kNtscSystemClock = 7159090, +		kPalCiaClock     = kPalSystemClock / 10, +		kNtscCiaClock    = kNtscSystemClock / 10, +		kPalPaulaClock   = kPalSystemClock / 2, +		kNtscPauleClock  = kNtscSystemClock / 2 +	}; -	Paula(bool stereo = false, int rate = 44100, int interruptFreq = 0); +	Paula(bool stereo = false, int rate = 44100, uint interruptFreq = 0);  	~Paula();  	bool playing() const { return _playing; } -	void setInterruptFreq(int freq) { _curInt = _intFreq = freq; } +	void setTimerBaseValue( uint32 ticksPerSecond ) { _timerBase = ticksPerSecond; } +	uint32 getTimerBaseValue() { return _timerBase; } +	void setSingleInterrupt(uint sampleDelay) { assert(sampleDelay < _intFreq); _curInt = sampleDelay; } +	void setSingleInterruptUnscaled(uint timerDelay) {  +		setSingleInterrupt((uint)(((double)timerDelay * getRate()) / _timerBase)); +	} +	void setInterruptFreq(uint sampleDelay) { _intFreq = sampleDelay; _curInt = 0; } +	void setInterruptFreqUnscaled(uint timerDelay) {  +		setInterruptFreq((uint)(((double)timerDelay * getRate()) / _timerBase)); +	}  	void clearVoice(byte voice);  	void clearVoices() { for (int i = 0; i < NUM_VOICES; ++i) clearVoice(i); }  	void startPlay(void) { _playing = true; } @@ -68,6 +85,7 @@ protected:  		byte volume;  		frac_t offset;  		byte panning; // For stereo mixing: 0 = far left, 255 = far right +		int dmaCount;  	};  	bool _end; @@ -90,6 +108,21 @@ protected:  		_voice[channel].panning = panning;  	} +	void disableChannel(byte channel) { +		assert(channel < NUM_VOICES); +		_voice[channel].data = 0; +	} + +	void enableChannel(byte channel) { +		assert(channel < NUM_VOICES); +		Channel &ch = _voice[channel]; +		ch.data = ch.dataRepeat; +		ch.length = ch.lengthRepeat; +		// actually first 2 bytes are dropped? +		ch.offset = intToFrac(0); +		// ch.period = ch.periodRepeat; +	} +  	void setChannelPeriod(byte channel, int16 period) {  		assert(channel < NUM_VOICES);  		_voice[channel].period = period; @@ -100,6 +133,17 @@ protected:  		_voice[channel].volume = volume;  	} +	void setChannelSampleStart(byte channel, const int8 *data) { +		assert(channel < NUM_VOICES); +		_voice[channel].dataRepeat = data; +	} + +	void setChannelSampleLen(byte channel, uint32 length) { +		assert(channel < NUM_VOICES); +		assert(length < 32768/2); +		_voice[channel].lengthRepeat = 2 * length; +	} +  	void setChannelData(uint8 channel, const int8 *data, const int8 *dataRepeat, uint32 length, uint32 lengthRepeat, int32 offset = 0) {  		assert(channel < NUM_VOICES); @@ -110,11 +154,14 @@ protected:  		assert(lengthRepeat < 32768);  		Channel &ch = _voice[channel]; -		ch.data = data; + +		ch.dataRepeat = data; +		ch.lengthRepeat = length; +		enableChannel(channel); +		ch.offset = intToFrac(offset); +  		ch.dataRepeat = dataRepeat; -		ch.length = length;  		ch.lengthRepeat = lengthRepeat; -		ch.offset = intToFrac(offset);  	}  	void setChannelOffset(byte channel, frac_t offset) { @@ -128,13 +175,29 @@ protected:  		return _voice[channel].offset;  	} +	int getChannelDmaCount(byte channel) { +		assert(channel < NUM_VOICES); +		return _voice[channel].dmaCount; +	} + +	void setChannelDmaCount(byte channel, int dmaVal = 0) { +		assert(channel < NUM_VOICES); +		_voice[channel].dmaCount = dmaVal; +	} + +	void setAudioFilter(bool enable) { +		// TODO: implement +	} +  private:  	Channel _voice[NUM_VOICES];  	const bool _stereo;  	const int _rate; -	int _intFreq; -	int _curInt; +	const double _periodScale; +	uint _intFreq; +	uint _curInt; +	uint32 _timerBase;  	bool _playing;  	template<bool stereo> diff --git a/sound/mods/soundfx.cpp b/sound/mods/soundfx.cpp index 101d8a077d..3af8ca19c6 100644 --- a/sound/mods/soundfx.cpp +++ b/sound/mods/soundfx.cpp @@ -46,8 +46,7 @@ public:  	enum {  		NUM_CHANNELS = 4, -		NUM_INSTRUMENTS = 15, -		CIA_FREQ = 715909 +		NUM_INSTRUMENTS = 15  	};  	SoundFx(int rate, bool stereo); @@ -75,12 +74,12 @@ protected:  	uint16 _curPos;  	uint8 _ordersTable[128];  	uint8 *_patternData; -	int _eventsFreq;  	uint16 _effects[NUM_CHANNELS];  };  SoundFx::SoundFx(int rate, bool stereo)  	: Paula(stereo, rate) { +	setTimerBaseValue(kPalCiaClock);  	_ticks = 0;  	_delay = 0;  	memset(_instruments, 0, sizeof(_instruments)); @@ -89,7 +88,6 @@ SoundFx::SoundFx(int rate, bool stereo)  	_curPos = 0;  	memset(_ordersTable, 0, sizeof(_ordersTable));  	_patternData = 0; -	_eventsFreq = 0;  	memset(_effects, 0, sizeof(_effects));  } @@ -167,8 +165,7 @@ void SoundFx::play() {  	_curPos = 0;  	_curOrder = 0;  	_ticks = 0; -	_eventsFreq = CIA_FREQ / _delay; -	setInterruptFreq(getRate() / _eventsFreq); +	setInterruptFreqUnscaled(_delay);  	startPaula();  } @@ -252,7 +249,7 @@ void SoundFx::handleTick() {  }  void SoundFx::disablePaulaChannel(uint8 channel) { -	setChannelPeriod(channel, 0); +	disableChannel(channel);  }  void SoundFx::setupPaulaChannel(uint8 channel, const int8 *data, uint16 len, uint16 repeatPos, uint16 repeatLen) { diff --git a/sound/mods/tfmx.cpp b/sound/mods/tfmx.cpp new file mode 100644 index 0000000000..2ef7d79b7a --- /dev/null +++ b/sound/mods/tfmx.cpp @@ -0,0 +1,1189 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/scummsys.h" +#include "common/endian.h" +#include "common/stream.h" +#include "common/util.h" +#include "common/debug.h" + +#include "sound/mods/tfmx.h" + +// test for engines using this class. +#if defined(SOUND_MODS_TFMX_H) + +// couple debug-functions +namespace { +	void displayPatternstep(const void *const vptr); +	void displayMacroStep(const void *const vptr); + +	const uint16 noteIntervalls[64] = { +	1710, 1614, 1524, 1438, 1357, 1281, 1209, 1141, 1077, 1017,  960,  908, +	 856,  810,  764,  720,  680,  642,  606,  571,  539,  509,  480,  454, +	 428,  404,  381,  360,  340,  320,  303,  286,  270,  254,  240,  227, +	 214,  202,  191,  180,  170,  160,  151,  143,  135,  127,  120,  113, +	 214,  202,  191,  180,  170,  160,  151,  143,  135,  127,  120,  113, +	 214,  202,  191,  180 }; +} + +namespace Audio { + +Tfmx::Tfmx(int rate, bool stereo) +	: Paula(stereo, rate),  +	  _resource(),  +	  _resourceSample(),  +	  _playerCtx(), +	  _deleteResource(false) { + +	_playerCtx.stopWithLastPattern = false; + +	for (int i = 0; i < kNumVoices; ++i)  +		_channelCtx[i].paulaChannel = (byte)i; + +	_playerCtx.volume = 0x40; +	_playerCtx.patternSkip = 6; +	stopSongImpl(); + +	setTimerBaseValue(kPalCiaClock); +	setInterruptFreqUnscaled(kPalDefaultCiaVal); +} + +Tfmx::~Tfmx() { +	freeResourceDataImpl(); +} + +void Tfmx::interrupt() { +	assert(!_end); +	++_playerCtx.tickCount; + +	for (int i = 0; i < kNumVoices; ++i) { +		if (_channelCtx[i].dmaIntCount) { +			// wait for DMA Interupts to happen +			int doneDma = getChannelDmaCount(i); +			if (doneDma >= _channelCtx[i].dmaIntCount) { +				_channelCtx[i].dmaIntCount = 0; +				_channelCtx[i].macroRun = true; +			} +		} +	} + +	for (int i = 0; i < kNumVoices; ++i) { +		ChannelContext &channel = _channelCtx[i]; + +		if (channel.sfxLockTime >= 0) +			--channel.sfxLockTime; +		else { +			channel.sfxLocked = false; +			channel.customMacroPrio = 0; +		} + +		// externally queued macros +		if (channel.customMacro) { +			const byte *const noteCmd = (const byte *)&channel.customMacro; +			channel.sfxLocked = false; +			noteCommand(noteCmd[0], noteCmd[1], (noteCmd[2] & 0xF0) | (uint8)i, noteCmd[3]); +			channel.customMacro = 0; +			channel.sfxLocked = (channel.customMacroPrio != 0); +		} + +		// apply timebased effects on Parameters +		if (channel.macroSfxRun > 0) +			effects(channel); + +		// see if we have to run the macro-program +		if (channel.macroRun) { +			if (!channel.macroWait) +				macroRun(channel); +			else +				--channel.macroWait; +		} + +		Paula::setChannelPeriod(i, channel.period); +		if (channel.macroSfxRun >= 0) +			channel.macroSfxRun = 1; + +		// TODO: handling pending DMAOff? +	} + +	// Patterns are only processed each _playerCtx.timerCount + 1 tick +	if (_playerCtx.song >= 0 && !_playerCtx.patternCount--) { +		_playerCtx.patternCount = _playerCtx.patternSkip; +		advancePatterns(); +	} +} + +void Tfmx::effects(ChannelContext &channel) { +	// addBegin +	if (channel.addBeginLength) { +		channel.sampleStart += channel.addBeginDelta; +		Paula::setChannelSampleStart(channel.paulaChannel, getSamplePtr(channel.sampleStart)); +		if (!(--channel.addBeginCount)) { +			channel.addBeginCount = channel.addBeginLength; +			channel.addBeginDelta = -channel.addBeginDelta; +		} +	} + +	// vibrato +	if (channel.vibLength) { +		channel.vibValue += channel.vibDelta; +		if (--channel.vibCount == 0) { +			channel.vibCount = channel.vibLength; +			channel.vibDelta = -channel.vibDelta; +		} +		if (!channel.portaDelta) { +			// 16x16 bit multiplication, casts needed for the right results +			channel.period = (uint16)(((uint32)channel.refPeriod * (uint16)((1 << 11) + channel.vibValue)) >> 11); +		} +	} + +	// portamento +	if (channel.portaDelta && !(--channel.portaCount)) { +		channel.portaCount = channel.portaSkip; + +		bool resetPorta = true; +		const uint16 period = channel.refPeriod; +		uint16 portaVal = channel.portaValue; + +		if (period > portaVal) { +			portaVal = ((uint32)portaVal * (uint16)((1 << 8) + channel.portaDelta)) >> 8; +			resetPorta = (period <= portaVal); + +		} else if (period < portaVal) { +			portaVal = ((uint32)portaVal * (uint16)((1 << 8) - channel.portaDelta)) >> 8; +			resetPorta = (period >= portaVal); +		} + +		if (resetPorta) { +			channel.portaDelta = 0; +			channel.portaValue = period & 0x7FF; +		} else +			channel.period = channel.portaValue = portaVal & 0x7FF; +	} + +	// envelope +	if (channel.envSkip && !channel.envCount--) { +		channel.envCount = channel.envSkip; + +		const int8 endVol = channel.envEndVolume; +		int8 volume = channel.volume; +		bool resetEnv = true; + +		if (endVol > volume) { +			volume += channel.envDelta; +			resetEnv = endVol <= volume; +		} else { +			volume -= channel.envDelta; +			resetEnv = volume <= 0 || endVol >= volume; +		} + +		if (resetEnv) { +			channel.envSkip = 0; +			volume = endVol; +		} +		channel.volume = volume; +	} + +	// Fade +	if (_playerCtx.fadeDelta && !(--_playerCtx.fadeCount)) { +		_playerCtx.fadeCount = _playerCtx.fadeSkip; + +		_playerCtx.volume += _playerCtx.fadeDelta; +		if (_playerCtx.volume == _playerCtx.fadeEndVolume) +			_playerCtx.fadeDelta = 0; +	} + +	// Volume +	const uint8 finVol = _playerCtx.volume * channel.volume >> 6; +	Paula::setChannelVolume(channel.paulaChannel, finVol); +} + +void Tfmx::macroRun(ChannelContext &channel) { +	bool deferWait = channel.deferWait; +	for (;;) { +		const byte *const macroPtr = (const byte *)(getMacroPtr(channel.macroOffset) + channel.macroStep); +		++channel.macroStep; + +		switch (macroPtr[0]) { +		case 0x00:	// Reset + DMA Off. Parameters: deferWait, addset, vol +			clearEffects(channel); +			// FT +		case 0x13:	// DMA Off. Parameters:  deferWait, addset, vol +			// TODO: implement PArameters +			Paula::disableChannel(channel.paulaChannel); +			channel.deferWait = deferWait = (macroPtr[1] != 0); +			if (deferWait) { +				// if set, then we expect a DMA On in the same tick. +				channel.period = 4; +				//Paula::setChannelPeriod(channel.paulaChannel, channel.period); +				Paula::setChannelSampleLen(channel.paulaChannel, 1); +				// in this state we then need to allow some commands that normally +				// would halt the macroprogamm to continue instead. +				// those commands are: Wait, WaitDMA, AddPrevNote, AddNote, SetNote, <unknown Cmd> +				// DMA On is affected aswell +				// TODO remember time disabled, remember pending dmaoff?. +			} + +			if (macroPtr[2] || macroPtr[3]) { +				channel.volume = (macroPtr[2] ? 0 : channel.relVol * 3) + macroPtr[3]; +				Paula::setChannelVolume(channel.paulaChannel, channel.volume); +			} +			continue; + +		case 0x01:	// DMA On +			// TODO: Parameter macroPtr[1] - en-/disable effects +			channel.dmaIntCount = 0; +			if (deferWait) { +				// TODO +				// there is actually a small delay in the player, but I think that +				// only allows to clear DMA-State on real Hardware +			} +			Paula::setChannelPeriod(channel.paulaChannel, channel.period); +			Paula::enableChannel(channel.paulaChannel); +			channel.deferWait = deferWait = false; +			continue; + +		case 0x02:	// Set Beginn. Parameters: SampleOffset(L) +			channel.addBeginLength = 0; +			channel.sampleStart = READ_BE_UINT32(macroPtr) & 0xFFFFFF; +			Paula::setChannelSampleStart(channel.paulaChannel, getSamplePtr(channel.sampleStart)); +			continue; + +		case 0x03:	// SetLength. Parameters: SampleLength(W) +			channel.sampleLen = READ_BE_UINT16(¯oPtr[2]); +			Paula::setChannelSampleLen(channel.paulaChannel, channel.sampleLen); +			continue; + +		case 0x04:	// Wait. Parameters: Ticks to wait(W). +			// TODO: some unkown Parameter? (macroPtr[1] & 1) +			channel.macroWait = READ_BE_UINT16(¯oPtr[2]); +			break; + +		case 0x10:	// Loop Key Up. Parameters: Loopcount, MacroStep(W) +			if (channel.keyUp) +				continue; +			// FT +		case 0x05:	// Loop. Parameters: Loopcount, MacroStep(W) +			if (channel.macroLoopCount != 0) { +				if (channel.macroLoopCount == 0xFF) +					channel.macroLoopCount = macroPtr[1]; +				channel.macroStep = READ_BE_UINT16(¯oPtr[2]); +			} +			--channel.macroLoopCount; +			continue; + +		case 0x06:	// Jump. Parameters: MacroIndex, MacroStep(W) +			// channel.macroIndex = macroPtr[1] & (kMaxMacroOffsets - 1); +			channel.macroOffset = _resource->macroOffset[macroPtr[1] & (kMaxMacroOffsets - 1)]; +			channel.macroStep = READ_BE_UINT16(¯oPtr[2]); +			channel.macroLoopCount = 0xFF; +			continue; + +		case 0x07:	// Stop Macro +			channel.macroRun = false; +			--channel.macroStep; +			return; + +		case 0x08:	// AddNote. Parameters: Note, Finetune(W) +			setNoteMacro(channel, channel.note + macroPtr[1], READ_BE_UINT16(¯oPtr[2])); +			break; + +		case 0x09:	// SetNote. Parameters: Note, Finetune(W) +			setNoteMacro(channel, macroPtr[1], READ_BE_UINT16(¯oPtr[2])); +			break; + +		case 0x0A:	// Clear Effects +			clearEffects(channel); +			continue; + +		case 0x0B:	// Portamento. Parameters: count, speed +			channel.portaSkip = macroPtr[1]; +			channel.portaCount = 1; +			// if porta is already running, then keep using old value +			if (!channel.portaDelta) +				channel.portaValue = channel.refPeriod; +			channel.portaDelta = READ_BE_UINT16(¯oPtr[2]); +			continue; + +		case 0x0C:	// Vibrato. Parameters: Speed, intensity +			channel.vibLength = macroPtr[1]; +			channel.vibCount = macroPtr[1] / 2; +			channel.vibDelta = macroPtr[3]; +			// TODO: Perhaps a bug, vibValue could be left uninitialised +			if (!channel.portaDelta) { +				channel.period = channel.refPeriod; +				channel.vibValue = 0; +			} +			continue; + +		case 0x0D:	// Add Volume. Parameters: note, addNoteFlag, volume +			if (macroPtr[2] == 0xFE) +				setNoteMacro(channel, channel.note + macroPtr[1], 0); +			channel.volume = channel.relVol * 3 + macroPtr[3]; +			continue; + +		case 0x0E:	// Set Volume. Parameters: note, addNoteFlag, volume +			if (macroPtr[2] == 0xFE) +				setNoteMacro(channel, channel.note + macroPtr[1], 0); +			channel.volume = macroPtr[3]; +			continue; + +		case 0x0F:	// Envelope. Parameters: speed, count, endvol +			channel.envDelta = macroPtr[1]; +			channel.envCount = channel.envSkip = macroPtr[2]; +			channel.envEndVolume = macroPtr[3]; +			continue; + +		case 0x11:	// Add Beginn. Parameters: times, Offset(W) +			channel.addBeginLength = channel.addBeginCount = macroPtr[1]; +			channel.addBeginDelta = (int16)READ_BE_UINT16(¯oPtr[2]); +			channel.sampleStart += channel.addBeginDelta; +			Paula::setChannelSampleStart(channel.paulaChannel, getSamplePtr(channel.sampleStart)); +			continue; + +		case 0x12:	// Add Length. Parameters: added Length(W) +			channel.sampleLen += (int16)READ_BE_UINT16(¯oPtr[2]); +			Paula::setChannelSampleLen(channel.paulaChannel, channel.sampleLen); +			continue; + +		case 0x14:	// Wait key up. Parameters: wait cycles +			if (channel.keyUp || channel.macroLoopCount == 0) { +				channel.macroLoopCount = 0xFF; +				continue; +			} else if (channel.macroLoopCount == 0xFF) +				channel.macroLoopCount = macroPtr[3]; +			--channel.macroLoopCount; +			--channel.macroStep; +			return; + +		case 0x15:	// Subroutine. Parameters: MacroIndex, Macrostep(W) +			channel.macroReturnOffset = channel.macroOffset; +			channel.macroReturnStep = channel.macroStep; + +			channel.macroOffset = _resource->macroOffset[macroPtr[1] & (kMaxMacroOffsets - 1)]; +			channel.macroStep = READ_BE_UINT16(¯oPtr[2]); +			// TODO: MI does some weird stuff there. Figure out which varioables need to be set +			continue; + +		case 0x16:	// Return from Sub. +			channel.macroOffset = channel.macroReturnOffset; +			channel.macroStep = channel.macroReturnStep; +			continue; + +		case 0x17:	// Set Period. Parameters: Period(W) +			channel.refPeriod = READ_BE_UINT16(¯oPtr[2]); +			if (!channel.portaDelta) { +				channel.period = channel.refPeriod; +				//Paula::setChannelPeriod(channel.paulaChannel, channel.period); +			} +			continue; + +		case 0x18: {	// Sampleloop. Parameters: Offset from Samplestart(W) +			// TODO: MI loads 24 bit, but thats useless? +			const uint16 temp = /* ((int8)macroPtr[1] << 16) | */ READ_BE_UINT16(¯oPtr[2]); +			if (macroPtr[1] || (temp & 1)) +				warning("Tfmx: Problematic value for sampleloop: %06X", (macroPtr[1] << 16) | temp); +			channel.sampleStart += temp & 0xFFFE; +			channel.sampleLen -= (temp / 2) /* & 0x7FFF */; +			Paula::setChannelSampleStart(channel.paulaChannel, getSamplePtr(channel.sampleStart)); +			Paula::setChannelSampleLen(channel.paulaChannel, channel.sampleLen); +			continue; +		} +		case 0x19:	// Set One-Shot Sample +			channel.addBeginLength = 0; +			channel.sampleStart = 0; +			channel.sampleLen = 1; +			Paula::setChannelSampleStart(channel.paulaChannel, getSamplePtr(0)); +			Paula::setChannelSampleLen(channel.paulaChannel, 1); +			continue; + +		case 0x1A:	// Wait on DMA. Parameters: Cycles-1(W) to wait +			channel.dmaIntCount = READ_BE_UINT16(¯oPtr[2]) + 1; +			channel.macroRun = false; +			Paula::setChannelDmaCount(channel.paulaChannel); +			break; + +/*		case 0x1B:	// Random play. Parameters: macro/speed/mode +			warnMacroUnimplemented(macroPtr, 0); +			continue;*/ + +		case 0x1C:	// Branch on Note. Parameters: note/macrostep(W) +			if (channel.note > macroPtr[1]) +				channel.macroStep = READ_BE_UINT16(¯oPtr[2]); +			continue; + +		case 0x1D:	// Branch on Volume. Parameters: volume/macrostep(W) +			if (channel.volume > macroPtr[1]) +				channel.macroStep = READ_BE_UINT16(¯oPtr[2]); +			continue; + +/*		case 0x1E:	// Addvol+note. Parameters: note/CONST./volume +			warnMacroUnimplemented(macroPtr, 0); +			continue;*/ + +		case 0x1F:	// AddPrevNote. Parameters: Note, Finetune(W) +			setNoteMacro(channel, channel.prevNote + macroPtr[1], READ_BE_UINT16(¯oPtr[2])); +			break; + +		case 0x20:	// Signal. Parameters: signalnumber, value(W) +			if (_playerCtx.numSignals > macroPtr[1]) +				_playerCtx.signal[macroPtr[1]] = READ_BE_UINT16(¯oPtr[2]); +			continue; + +		case 0x21:	// Play macro. Parameters: macro, chan, detune +			noteCommand(channel.note, macroPtr[1], (channel.relVol << 4) | macroPtr[2], macroPtr[3]); +			continue; + +		// 0x22 - 0x29 are used by Gem`X +		// 0x30 - 0x34 are used by Carribean Disaster + +		default: +			debug(3, "Tfmx: Macro %02X not supported", macroPtr[0]); +		} +		if (!deferWait) +			return; +	} +} + +void Tfmx::advancePatterns() { +startPatterns: +	int runningPatterns = 0; + +	for (int i = 0; i < kNumChannels; ++i) { +		PatternContext &pattern = _patternCtx[i]; +		const uint8 pattCmd = pattern.command; +		if (pattCmd < 0x90) {	// execute Patternstep +			++runningPatterns; +			if (!pattern.wait) { +				// issue all Steps for this tick +				if (patternRun(pattern)) { +					// we load the next Trackstep Command and then process all Channels again +					if (trackRun(true)) +						goto startPatterns; +					else +						break; +				} + +			} else  +				--pattern.wait; + +		} else if (pattCmd == 0xFE) {	// Stop voice in pattern.expose +			pattern.command = 0xFF; +			ChannelContext &channel = _channelCtx[pattern.expose & (kNumVoices - 1)]; +			if (!channel.sfxLocked) { +				haltMacroProgramm(channel); +				Paula::disableChannel(channel.paulaChannel); +			} +		} // else this pattern-Channel is stopped +	} +	if (_playerCtx.stopWithLastPattern && !runningPatterns) { +		stopPaula(); +	} +} + +bool Tfmx::patternRun(PatternContext &pattern) { +	for (;;) { +		const byte *const patternPtr = (const byte *)(getPatternPtr(pattern.offset) + pattern.step); +		++pattern.step; +		const byte pattCmd = patternPtr[0]; + +		if (pattCmd < 0xF0) { // Playnote +			bool doWait = false; +			byte noteCmd = pattCmd + pattern.expose; +			byte param3  = patternPtr[3]; +			if (pattCmd < 0xC0) {	// Note +				if (pattCmd >= 0x80) {	// Wait +					pattern.wait = param3; +					param3 = 0; +					doWait = true; +				} +				noteCmd &= 0x3F; +			}	// else Portamento  +			noteCommand(noteCmd, patternPtr[1], patternPtr[2], param3); +			if (doWait) +				return false; + +		} else {	// Patterncommand +			switch (pattCmd & 0xF) { +			case 0: 	// End Pattern + Next Trackstep +				pattern.command = 0xFF; +				--pattern.step; +				return true; + +			case 1: 	// Loop Pattern. Parameters: Loopcount, PatternStep(W) +				if (pattern.loopCount != 0) { +					if (pattern.loopCount == 0xFF) +						pattern.loopCount = patternPtr[1]; +					pattern.step = READ_BE_UINT16(&patternPtr[2]); +				} +				--pattern.loopCount; +				continue; + +			case 2: 	// Jump. Parameters: PatternIndex, PatternStep(W) +				pattern.offset = _resource->patternOffset[patternPtr[1] & (kMaxPatternOffsets - 1)]; +				pattern.step = READ_BE_UINT16(&patternPtr[2]); +				continue; + +			case 3: 	// Wait. Paramters: ticks to wait +				pattern.wait = patternPtr[1]; +				return false; + +			case 14: 	// Stop custompattern +				// TODO apparently toggles on/off pattern channel 7 +				debug(3, "Tfmx: Encountered 'Stop custompattern' command"); +				// FT +			case 4: 	// Stop this pattern +				pattern.command = 0xFF; +				--pattern.step; +				// TODO: try figuring out if this was the last Channel? +				return false; + +			case 5: 	// Key Up Signal. Paramters: channel +				if (!_channelCtx[patternPtr[2] & (kNumVoices - 1)].sfxLocked) +					_channelCtx[patternPtr[2] & (kNumVoices - 1)].keyUp = true; +				continue; + +			case 6: 	// Vibrato. Parameters: length, channel, rate +			case 7: 	// Envelope. Parameters: rate, tempo | channel, endVol +				noteCommand(pattCmd, patternPtr[1], patternPtr[2], patternPtr[3]); +				continue; + +			case 8: 	// Subroutine. Parameters: pattern, patternstep(W) +				pattern.savedOffset = pattern.offset; +				pattern.savedStep = pattern.step; + +				pattern.offset = _resource->patternOffset[patternPtr[1] & (kMaxPatternOffsets - 1)]; +				pattern.step = READ_BE_UINT16(&patternPtr[2]); +				continue; + +			case 9: 	// Return from Subroutine +				pattern.offset = pattern.savedOffset; +				pattern.step = pattern.savedStep; +				continue; + +			case 10:	// fade. Parameters: tempo, endVol +				initFadeCommand((uint8)patternPtr[1], (int8)patternPtr[3]); +				continue; + +			case 11:	// play pattern. Parameters: patternCmd, channel, expose +				initPattern(_patternCtx[patternPtr[2] & (kNumChannels - 1)], patternPtr[1], patternPtr[3], _resource->patternOffset[patternPtr[1] & (kMaxPatternOffsets - 1)]); +				continue; + +			case 12: 	// Lock. Parameters: lockFlag, channel, lockTime +				_channelCtx[patternPtr[2] & (kNumVoices - 1)].sfxLocked = (patternPtr[1] != 0); +				_channelCtx[patternPtr[2] & (kNumVoices - 1)].sfxLockTime = patternPtr[3]; +				continue; + +			case 13: 	// Cue. Parameters: signalnumber, value(W) +				if (_playerCtx.numSignals > patternPtr[1]) +					_playerCtx.signal[patternPtr[1]] = READ_BE_UINT16(&patternPtr[2]); +				continue; + +			case 15: 	// NOP +				continue; +			} +		} +	} +} + +bool Tfmx::trackRun(const bool incStep) { +	assert(_playerCtx.song >= 0); +	if (incStep) { +		// TODO Optionally disable looping +		if (_trackCtx.posInd == _trackCtx.stopInd) +			_trackCtx.posInd = _trackCtx.startInd; +		else +			++_trackCtx.posInd; +	} +	for (;;) { +		const uint16 *const trackData = getTrackPtr(_trackCtx.posInd); + +		if (trackData[0] != FROM_BE_16(0xEFFE)) { +			// 8 commands for Patterns +			for (int i = 0; i < 8; ++i) { +				const uint8 *patCmd = (const uint8 *)&trackData[i]; +				// First byte is pattern number +				const uint8 patNum = patCmd[0]; +				// if highest bit is set then keep previous pattern +				if (patNum < 0x80) { +					initPattern(_patternCtx[i], patNum, patCmd[1], _resource->patternOffset[patNum]); +				} else { +					_patternCtx[i].command = patNum; +					_patternCtx[i].expose = (int8)patCmd[1]; +				} +			} +			return true; + +		} else { +			// 16 byte Trackstep Command +			switch (READ_BE_UINT16(&trackData[1])) { +			case 0:	// Stop Player. No Parameters +				stopPaula(); +				return false; + +			case 1:	// Branch/Loop section of tracksteps. Parameters: branch target, loopcount +				if (_trackCtx.loopCount != 0) { +					if (_trackCtx.loopCount < 0) +						_trackCtx.loopCount = READ_BE_UINT16(&trackData[3]); +					_trackCtx.posInd    = READ_BE_UINT16(&trackData[2]); +					continue; +				} +				--_trackCtx.loopCount; +				break; + +			case 2:	{ // Set Tempo. Parameters: tempo, divisor +				_playerCtx.patternCount = _playerCtx.patternSkip = READ_BE_UINT16(&trackData[2]); // tempo +				const uint16 temp = READ_BE_UINT16(&trackData[3]); // divisor + +				if (!(temp & 0x8000) && (temp & 0x1FF)) +					setInterruptFreqUnscaled(temp & 0x1FF); +				break; +			} +			case 4:	// Fade. Parameters: tempo, endVol +				// load the LSB of the 16bit words +				initFadeCommand(((const uint8 *)&trackData[2])[1], ((const int8 *)&trackData[3])[1]); +				break; + +			case 3:	// Unknown, stops player aswell +			default: +				debug(3, "Tfmx: Unknown Trackstep Command: %02X", READ_BE_UINT16(&trackData[1])); +				// MI-Player handles this by stopping the player, we just continue +			} +		} + +		if (_trackCtx.posInd == _trackCtx.stopInd) { +			warning("Tfmx: Reached invalid Song-Position"); +			return false; +		} +		++_trackCtx.posInd; +	} +} + +void Tfmx::noteCommand(const uint8 note, const uint8 param1, const uint8 param2, const uint8 param3) { +	ChannelContext &channel = _channelCtx[param2 & (kNumVoices - 1)]; + +	if (note == 0xFC) {	// Lock command +		channel.sfxLocked = (param1 != 0); +		channel.sfxLockTime = param3; // only 1 byte read!  + +	} else if (channel.sfxLocked) {	// Channel still locked, do nothing +	 +	} else if (note < 0xC0) {	// Play Note - Parameters: note, macro, relVol | channel, finetune + +		channel.prevNote = channel.note; +		channel.note = note; +		// channel.macroIndex = param1 & (kMaxMacroOffsets - 1); +		channel.macroOffset = _resource->macroOffset[param1 & (kMaxMacroOffsets - 1)]; +		channel.relVol = param2 >> 4; +		channel.fineTune = (int8)param3; + +		// TODO: the point where the channel gets initialised varies with the games, needs more research. +		initMacroProgramm(channel); +		channel.keyUp = false; // key down = playing a Note + +	} else if (note < 0xF0) {	// Portamento - Parameters: note, tempo, channel, rate +		channel.portaSkip = param1; +		channel.portaCount = 1; +		if (!channel.portaDelta) +			channel.portaValue = channel.refPeriod; +		channel.portaDelta = param3; + +		channel.note = note & 0x3F; +		channel.refPeriod = noteIntervalls[channel.note]; + +	} else switch (note) {	// Command + +		case 0xF5:	// Key Up Signal +			channel.keyUp = true; +			break; + +		case 0xF6:	// Vibratio - Parameters: length, channel, rate +			channel.vibLength = param1 & 0xFE; +			channel.vibCount = param1 / 2; +			channel.vibDelta = param3; +			channel.vibValue = 0; +			break; + +		case 0xF7:	// Envelope - Parameters: rate, tempo | channel, endVol +			channel.envDelta = param1; +			channel.envCount = channel.envSkip = (param2 >> 4) + 1; +			channel.envEndVolume = param3; +			break; +	} +} + +void Tfmx::initMacroProgramm(ChannelContext &channel) { +	channel.macroStep = 0; +	channel.macroWait = 0; +	channel.macroRun = true; +	channel.macroSfxRun = 0; +	channel.macroLoopCount = 0xFF; +	channel.dmaIntCount = 0; +	channel.deferWait = false; + +	channel.macroReturnOffset = 0; +	channel.macroReturnStep = 0; +} + +void Tfmx::clearEffects(ChannelContext &channel) { +	channel.addBeginLength = 0; +	channel.envSkip = 0; +	channel.vibLength = 0; +	channel.portaDelta = 0; +} + +void Tfmx::haltMacroProgramm(ChannelContext &channel) { +	channel.macroRun = false; +	channel.dmaIntCount = 0; +} + +void Tfmx::unlockMacroChannel(ChannelContext &channel) { +	channel.customMacro = 0; +	channel.customMacroIndex = 0; +	channel.customMacroPrio = 0; +	channel.sfxLocked = false; +	channel.sfxLockTime = -1; +} + +void Tfmx::initPattern(PatternContext &pattern, uint8 cmd, int8 expose, uint32 offset) { +	pattern.command = cmd; +	pattern.offset = offset; +	pattern.expose = expose; +	pattern.step = 0; +	pattern.wait = 0; +	pattern.loopCount = 0xFF; + +	pattern.savedOffset = 0; +	pattern.savedStep = 0; +} + +void Tfmx::stopSongImpl(bool stopAudio) { +	 _playerCtx.song = -1; +	for (int i = 0; i < kNumChannels; ++i) { +		_patternCtx[i].command = 0xFF; +		_patternCtx[i].expose = 0; +	} +	if (stopAudio) { +		stopPaula(); +		for (int i = 0; i < kNumVoices; ++i) { +			clearEffects(_channelCtx[i]); +			unlockMacroChannel(_channelCtx[i]); +			haltMacroProgramm(_channelCtx[i]); +			_channelCtx[i].note = 0; +			_channelCtx[i].volume = 0; +			_channelCtx[i].macroSfxRun = -1; +			_channelCtx[i].vibValue = 0; + +			_channelCtx[i].sampleStart = 0; +			_channelCtx[i].sampleLen = 2; +			_channelCtx[i].refPeriod = 4; +			_channelCtx[i].period = 4; +			Paula::disableChannel(i); +		} +	} +} + +void Tfmx::setNoteMacro(ChannelContext &channel, uint note, int fineTune) { +	const uint16 noteInt = noteIntervalls[note & 0x3F]; +	const uint16 finetune = (uint16)(fineTune + channel.fineTune + (1 << 8)); +	channel.refPeriod = ((uint32)noteInt * finetune >> 8); +	if (!channel.portaDelta) +		channel.period = channel.refPeriod; +} + +void Tfmx::initFadeCommand(const uint8 fadeTempo, const int8 endVol) { +	_playerCtx.fadeCount = _playerCtx.fadeSkip = fadeTempo; +	_playerCtx.fadeEndVolume = endVol; + +	if (fadeTempo) { +		const int diff = _playerCtx.fadeEndVolume - _playerCtx.volume; +		_playerCtx.fadeDelta = (diff != 0) ? ((diff > 0) ? 1 : -1) : 0; +	} else { +		_playerCtx.volume = endVol; +		_playerCtx.fadeDelta = 0; +	} +} + +void Tfmx::setModuleData(Tfmx &otherPlayer) { +	setModuleData(otherPlayer._resource, otherPlayer._resourceSample.sampleData, otherPlayer._resourceSample.sampleLen, false); +} + +bool Tfmx::load(Common::SeekableReadStream &musicData, Common::SeekableReadStream &sampleData, bool autoDelete) { +	const MdatResource *mdat = loadMdatFile(musicData); +	if (mdat) { +		uint32 sampleLen = 0; +		const int8 *sampleDat = loadSampleFile(sampleLen, sampleData); +		if (sampleDat) { +			setModuleData(mdat, sampleDat, sampleLen, autoDelete); +			return true; +		} +		delete[] mdat->mdatAlloc; +		delete mdat; +	} +	return false; +} + +void Tfmx::freeResourceDataImpl() { +	if (_deleteResource) { +		if (_resource) { +			delete[] _resource->mdatAlloc; +			delete _resource; +		} +		delete[] _resourceSample.sampleData; +	} +	_resource = 0; +	_resourceSample.sampleData = 0; +	_resourceSample.sampleLen = 0; +	_deleteResource = false; +} + +void Tfmx::setModuleData(const MdatResource *resource, const int8 *sampleData, uint32 sampleLen, bool autoDelete) { +	Common::StackLock lock(_mutex); +	stopSongImpl(true); +	freeResourceDataImpl(); +	_resource = resource; +	_resourceSample.sampleData = sampleData; +	_resourceSample.sampleLen = sampleData ? sampleLen : 0; +	_deleteResource = autoDelete; +} + +const int8 *Tfmx::loadSampleFile(uint32 &sampleLen, Common::SeekableReadStream &sampleStream) { +	sampleLen = 0; + +	const int32 sampleSize = sampleStream.size(); +	if (sampleSize < 4) { +		warning("Tfmx: Cant load Samplefile"); +		return false; +	} + +	int8 *sampleAlloc = new int8[sampleSize]; +	if (!sampleAlloc) { +		warning("Tfmx: Could not allocate Memory: %dKB", sampleSize / 1024); +		return 0; +	} + +	if (sampleStream.read(sampleAlloc, sampleSize) == (uint32)sampleSize) { +		sampleAlloc[0] = sampleAlloc[1] = sampleAlloc[2] = sampleAlloc[3] = 0; +		sampleLen = sampleSize; +	} else { +		delete sampleAlloc; +		warning("Tfmx: Encountered IO-Error"); +		return 0; +	} +	return sampleAlloc; +} + +const Tfmx::MdatResource *Tfmx::loadMdatFile(Common::SeekableReadStream &musicData) { +	bool hasHeader = false; +	const int32 mdatSize = musicData.size(); +	if (mdatSize >= 0x200) { +		byte buf[16] = { 0 }; +		// 0x0000: 10 Bytes Header "TFMX-SONG " +		musicData.read(buf, 10); +		hasHeader = memcmp(buf, "TFMX-SONG ", 10) == 0; +	} +	 +	if (!hasHeader) { +		warning("Tfmx: File is not a Tfmx Module"); +		return 0; +	} + +	MdatResource *resource = new MdatResource; + +	resource->mdatAlloc = 0; +	resource->mdatData = 0; +	resource->mdatLen = 0; + +	// 0x000A: int16 flags +	resource->headerFlags = musicData.readUint16BE(); +	// 0x000C: int32 ? +	// 0x0010: 6*40 Textfield +	musicData.skip(4 + 6 * 40); + +	/* 0x0100: Songstart x 32*/ +	for (int i = 0; i < kNumSubsongs; ++i) +		resource->subsong[i].songstart = musicData.readUint16BE(); +	/* 0x0140: Songend x 32*/ +	for (int i = 0; i < kNumSubsongs; ++i) +		resource->subsong[i].songend = musicData.readUint16BE(); +	/* 0x0180: Tempo x 32*/ +	for (int i = 0; i < kNumSubsongs; ++i) +		resource->subsong[i].tempo  = musicData.readUint16BE(); + +	/* 0x01c0: unused ? */ +	musicData.skip(16); + +	/* 0x01d0: trackstep, pattern data p, macro data p */ +	const uint32 offTrackstep = musicData.readUint32BE(); +	uint32 offPatternP, offMacroP; + +	// This is how MI`s TFMX-Player tests for unpacked Modules. +	if (offTrackstep == 0) { // unpacked File +		resource->trackstepOffset = 0x600 + 0x200; +		offPatternP		= 0x200 + 0x200; +		offMacroP		= 0x400 + 0x200; +	} else { // packed File +		resource->trackstepOffset = offTrackstep; +		offPatternP = musicData.readUint32BE(); +		offMacroP = musicData.readUint32BE(); +	} + +	// End of basic header, check if everything worked ok +	if (musicData.err()) { +		warning("Tfmx: Encountered IO-Error"); +		delete resource; +		return 0; +	} + +	// TODO: if a File is packed it could have for Ex only 2 Patterns/Macros +	// the following loops could then read beyond EOF.  +	// To correctly handle this it would be necessary to sort the pointers and +	// figure out the number of Macros/Patterns +	// We could also analyze pointers if they are correct offsets, +	// so that accesses can be unchecked later + +	// Read in pattern starting offsets +	musicData.seek(offPatternP); +	for (int i = 0; i < kMaxPatternOffsets; ++i) +		resource->patternOffset[i] = musicData.readUint32BE(); + +	// use last PatternOffset (stored at 0x5FC in mdat) if unpacked File +	// or fixed offset 0x200 if packed +	resource->sfxTableOffset = offTrackstep ? 0x200 : resource->patternOffset[127]; + +	// Read in macro starting offsets +	musicData.seek(offMacroP); +	for (int i = 0; i < kMaxMacroOffsets; ++i) +		resource->macroOffset[i] = musicData.readUint32BE(); + +	// Read in mdat-file +	// TODO: we can skip everything thats already stored in the resource-structure. +	const int32 mdatOffset = offTrackstep ? 0x200 : 0x600;	// 0x200 is very conservative +	const uint32 allocSize = (uint32)mdatSize - mdatOffset; +	 +	byte *mdatAlloc = new byte[allocSize]; +	if (!mdatAlloc) { +		warning("Tfmx: Could not allocate Memory: %dKB", allocSize / 1024); +		delete resource; +		return 0; +	} +	musicData.seek(mdatOffset); +	if (musicData.read(mdatAlloc, allocSize) == allocSize) { +		resource->mdatAlloc = mdatAlloc; +		resource->mdatData = mdatAlloc - mdatOffset; +		resource->mdatLen = mdatSize; +	} else { +		delete mdatAlloc; +		warning("Tfmx: Encountered IO-Error"); +		delete resource; +		return 0; +	} + +	return resource; +} + +void Tfmx::doMacro(int note, int macro, int relVol, int finetune, int channelNo) { +	assert(0 <= macro && macro < kMaxMacroOffsets); +	assert(0 <= note && note < 0xC0); +	Common::StackLock lock(_mutex); + +	if (!hasResources()) +		return; +	channelNo &= (kNumVoices - 1); +	ChannelContext &channel = _channelCtx[channelNo]; +	unlockMacroChannel(channel); + +	noteCommand((uint8)note, (uint8)macro, (uint8)((relVol << 4) | channelNo), (uint8)finetune); +	startPaula(); +} + +void Tfmx::stopMacroEffect(int channel) { +	assert(0 <= channel && channel < kNumVoices); +	Common::StackLock lock(_mutex); +	unlockMacroChannel(_channelCtx[channel]); +	haltMacroProgramm(_channelCtx[channel]); +	Paula::disableChannel(_channelCtx[channel].paulaChannel); +} + +void Tfmx::doSong(int songPos, bool stopAudio) { +	assert(0 <= songPos && songPos < kNumSubsongs); +	Common::StackLock lock(_mutex); + +	stopSongImpl(stopAudio); + +	if (!hasResources()) +		return; + +	_trackCtx.loopCount = -1; +	_trackCtx.startInd = _trackCtx.posInd = _resource->subsong[songPos].songstart; +	_trackCtx.stopInd = _resource->subsong[songPos].songend; +	_playerCtx.song = (int8)songPos; + +	const bool palFlag = (_resource->headerFlags & 2) != 0; +	const uint16 tempo = _resource->subsong[songPos].tempo; +	uint16 ciaIntervall; +	if (tempo >= 0x10) { +		ciaIntervall = (uint16)(kCiaBaseInterval / tempo); +		_playerCtx.patternSkip = 0; +	} else { +		ciaIntervall = palFlag ? (uint16)kPalDefaultCiaVal : (uint16)kNtscDefaultCiaVal; +		_playerCtx.patternSkip = tempo; +	} +	setInterruptFreqUnscaled(ciaIntervall); +	Paula::setAudioFilter(true); + +	_playerCtx.patternCount = 0; +	if (trackRun()) +		startPaula(); +} + +int Tfmx::doSfx(uint16 sfxIndex, bool unlockChannel) { +	assert(sfxIndex < 128); +	Common::StackLock lock(_mutex); + +	if (!hasResources()) +		return -1; +	const byte *sfxEntry = getSfxPtr(sfxIndex); +	if (sfxEntry[0] == 0xFB) { +		warning("Tfmx: custom patterns are not supported"); +		// custompattern +		/* const uint8 patCmd = sfxEntry[2]; +		const int8 patExp = (int8)sfxEntry[3]; */ +	} else { +		// custommacro +		const byte channelNo = ((_playerCtx.song >= 0) ? sfxEntry[2] : sfxEntry[4]) & (kNumVoices - 1); +		const byte priority = sfxEntry[5] & 0x7F; + +		ChannelContext &channel = _channelCtx[channelNo]; +		if (unlockChannel) +			unlockMacroChannel(channel); + +		const int16 sfxLocktime = channel.sfxLockTime; +		if (priority >= channel.customMacroPrio || sfxLocktime < 0) { +			if (sfxIndex != channel.customMacroIndex || sfxLocktime < 0 || (sfxEntry[5] < 0x80)) { +				channel.customMacro = READ_UINT32(sfxEntry); // intentionally not "endian-correct" +				channel.customMacroPrio = priority; +				channel.customMacroIndex = (uint8)sfxIndex; +				debug(3, "Tfmx: running Macro %08X on channel %i - priority: %02X", TO_BE_32(channel.customMacro), channelNo, priority); +				return channelNo; +			} +		} +	} +	return -1; +} + +}	// End of namespace Audio + +// some debugging functions +namespace { +#if !defined(NDEBUG) && 0 +void displayMacroStep(const void *const vptr) { +	const char *tableMacros[] = { +		"DMAoff+Resetxx/xx/xx flag/addset/vol   ", +		"DMAon (start sample at selected begin) ", +		"SetBegin    xxxxxx   sample-startadress", +		"SetLen      ..xxxx   sample-length     ", +		"Wait        ..xxxx   count (VBI''s)    ", +		"Loop        xx/xxxx  count/step        ", +		"Cont        xx/xxxx  macro-number/step ", +		"-------------STOP----------------------", +		"AddNote     xx/xxxx  note/detune       ", +		"SetNote     xx/xxxx  note/detune       ", +		"Reset   Vibrato-Portamento-Envelope    ", +		"Portamento  xx/../xx count/speed       ", +		"Vibrato     xx/../xx speed/intensity   ", +		"AddVolume   ....xx   volume 00-3F      ", +		"SetVolume   ....xx   volume 00-3F      ", +		"Envelope    xx/xx/xx speed/count/endvol", +		"Loop key up xx/xxxx  count/step        ", +		"AddBegin    xx/xxxx  count/add to start", +		"AddLen      ..xxxx   add to sample-len ", +		"DMAoff stop sample but no clear        ", +		"Wait key up ....xx   count (VBI''s)    ", +		"Go submacro xx/xxxx  macro-number/step ", +		"--------Return to old macro------------", +		"Setperiod   ..xxxx   DMA period        ", +		"Sampleloop  ..xxxx   relative adress   ", +		"-------Set one shot sample-------------", +		"Wait on DMA ..xxxx   count (Wavecycles)", +		"Random play xx/xx/xx macro/speed/mode  ", +		"Splitkey    xx/xxxx  key/macrostep     ", +		"Splitvolume xx/xxxx  volume/macrostep  ", +		"Addvol+note xx/fe/xx note/CONST./volume", +		"SetPrevNote xx/xxxx  note/detune       ", +		"Signal      xx/xxxx  signalnumber/value", +		"Play macro  xx/.x/xx macro/chan/detune ", +		"SID setbeg  xxxxxx   sample-startadress", +		"SID setlen  xx/xxxx  buflen/sourcelen  ", +		"SID op3 ofs xxxxxx   offset            ", +		"SID op3 frq xx/xxxx  speed/amplitude   ", +		"SID op2 ofs xxxxxx   offset            ", +		"SID op2 frq xx/xxxx  speed/amplitude   ", +		"SID op1     xx/xx/xx speed/amplitude/TC", +		"SID stop    xx....   flag (1=clear all)" +	}; + +	const byte *const macroData = (const byte *const)vptr; +	if (macroData[0] < ARRAYSIZE(tableMacros)) +		debug("%s %02X%02X%02X", tableMacros[macroData[0]], macroData[1], macroData[2], macroData[3]); +	else +		debug("Unkown Macro #%02X %02X%02X%02X", macroData[0], macroData[1], macroData[2], macroData[3]); +} + +void displayPatternstep(const void *const vptr) { +	const char *tablePatterns[] = { +		"End --Next track  step--", +		"Loop[count     / step.w]", +		"Cont[patternno./ step.w]", +		"Wait[count 00-FF--------", +		"Stop--Stop this pattern-", +		"Kup^-Set key up/channel]", +		"Vibr[speed     / rate.b]", +		"Enve[speed /endvolume.b]", +		"GsPt[patternno./ step.w]", +		"RoPt-Return old pattern-", +		"Fade[speed /endvolume.b]", +		"PPat[patt./track+transp]", +		"Lock---------ch./time.b]", +		"Cue [number.b/  value.w]", +		"Stop-Stop custompattern-", +		"NOP!-no operation-------" +	}; + +	const byte *const patData = (const byte *const)vptr; +	const byte command = patData[0]; +	if (command < 0xF0) { // Playnote +		const byte flags = command >> 6; // 0-1 means note+detune, 2 means wait, 3 means portamento? +		const char *flagsSt[] = { "Note ", "Note ", "Wait ", "Porta" }; +		debug("%s %02X%02X%02X%02X", flagsSt[flags], patData[0], patData[1], patData[2], patData[3]); +	} else +		debug("%s %02X%02X%02X",tablePatterns[command & 0xF], patData[1], patData[2], patData[3]); +} +#else +void displayMacroStep(const void *const vptr, int chan, int index) {} +void displayPatternstep(const void *const vptr) {} +#endif +}	// End of namespace + +#endif // #if defined(SOUND_MODS_TFMX_H) diff --git a/sound/mods/tfmx.h b/sound/mods/tfmx.h new file mode 100644 index 0000000000..26018d9466 --- /dev/null +++ b/sound/mods/tfmx.h @@ -0,0 +1,284 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +// see if all engines using this class are DISABLED +#if !defined(ENABLE_SCUMM) + +// normal Header Guard +#elif !defined(SOUND_MODS_TFMX_H) +#define SOUND_MODS_TFMX_H + +#include "sound/mods/paula.h" + +namespace Audio { + +class Tfmx : public Paula { +public: +	Tfmx(int rate, bool stereo); +	virtual ~Tfmx(); + +	/** +	 * Stops a playing Song (but leaves macros running) and optionally also stops the player +	 * +	 * @param stopAudio	stops player and audio output +	 * @param dataSize	number of bytes to be written +	 * @return the number of bytes which were actually written. +	 */ +	void stopSong(bool stopAudio = true) { Common::StackLock lock(_mutex); stopSongImpl(stopAudio); } +	/** +	 * Stops currently playing Song (if any) and cues up a new one. +	 * if stopAudio is specified, the player gets reset before starting the new song +	 * +	 * @param songPos	index of Song to play +	 * @param stopAudio	stops player and audio output +	 * @param dataSize	number of bytes to be written +	 * @return the number of bytes which were actually written. +	 */ +	void doSong(int songPos, bool stopAudio = false); +	/** +	 * plays an effect from the sfx-table, does not start audio-playback.  +	 * +	 * @param sfxIndex	index of effect to play +	 * @param unlockChannel	overwrite higher priority effects +	 * @return	index of the channel which now queued up the effect. +	 *			-1 in case the effect couldnt be queued up +	 */ +	int doSfx(uint16 sfxIndex, bool unlockChannel = false); +	/** +	 * stop a running macro channel +	 * +	 * @param channel	index of effect to stop +	 */ +	void stopMacroEffect(int channel); + +	void doMacro(int note, int macro, int relVol = 0, int finetune = 0, int channelNo = 0); +	int getTicks() const { return _playerCtx.tickCount; }  +	int getSongIndex() const { return _playerCtx.song; } +	void setSignalPtr(uint16 *ptr, uint16 numSignals) { _playerCtx.signal = ptr; _playerCtx.numSignals = numSignals; } +	void freeResources() { _deleteResource = true; freeResourceDataImpl(); } +	bool load(Common::SeekableReadStream &musicData, Common::SeekableReadStream &sampleData, bool autoDelete = true); +	void setModuleData(Tfmx &otherPlayer); + +protected: +	void interrupt(); + +private: +	enum { kPalDefaultCiaVal = 11822, kNtscDefaultCiaVal = 14320, kCiaBaseInterval = 0x1B51F8 }; +	enum { kNumVoices = 4, kNumChannels = 8, kNumSubsongs = 32, kMaxPatternOffsets = 128, kMaxMacroOffsets = 128 }; + +	struct MdatResource { +		const byte *mdatAlloc;	//!< allocated Block of Memory +		const byte *mdatData;  	//!< Start of mdat-File, might point before mdatAlloc to correct Offset +		uint32 mdatLen; + +		uint16 headerFlags; +//		uint32 headerUnknown; +//		char textField[6 * 40]; + +		struct Subsong { +			uint16 songstart;	//!< Index in Trackstep-Table +			uint16 songend;		//!< Last index in Trackstep-Table +			uint16 tempo; +		} subsong[kNumSubsongs]; + +		uint32 trackstepOffset;	//!< Offset in mdat +		uint32 sfxTableOffset; + +		uint32 patternOffset[kMaxPatternOffsets];	//!< Offset in mdat +		uint32 macroOffset[kMaxMacroOffsets];	//!< Offset in mdat + +		void boundaryCheck(const void *address, size_t accessLen = 1) const { +			assert(mdatAlloc <= address && (const byte *)address + accessLen <= (const byte *)mdatData + mdatLen); +		} +	} const *_resource; + +	struct SampleResource { +		const int8 *sampleData;	//!< The whole sample-File +		uint32 sampleLen; + +		void boundaryCheck(const void *address, size_t accessLen = 2) const { +			assert(sampleData <= address && (const byte *)address + accessLen <= (const byte *)sampleData + sampleLen); +		} +	} _resourceSample; + +	bool _deleteResource; + +	bool hasResources() { +		return _resource && _resource->mdatLen && _resourceSample.sampleLen; +	} + +	struct ChannelContext { +		byte	paulaChannel; + +//		byte	macroIndex; +		uint16	macroWait; +		uint32	macroOffset; +		uint32	macroReturnOffset; +		uint16	macroStep; +		uint16	macroReturnStep; +		uint8	macroLoopCount; +		bool	macroRun; +		int8	macroSfxRun;	//!< values are the folowing: -1 macro disabled, 0 macro init, 1 macro running + +		uint32	customMacro; +		uint8	customMacroIndex; +		uint8	customMacroPrio; + +		bool	sfxLocked; +		int16	sfxLockTime; +		bool	keyUp; + +		bool	deferWait; +		uint16	dmaIntCount; + +		uint32	sampleStart; +		uint16	sampleLen; +		uint16	refPeriod; +		uint16	period; + +		int8	volume; +		uint8	relVol; +		uint8	note; +		uint8	prevNote; +		int16	fineTune; // always a signextended byte + +		uint8	portaSkip; +		uint8	portaCount; +		uint16	portaDelta; +		uint16	portaValue; + +		uint8	envSkip; +		uint8	envCount; +		uint8	envDelta; +		int8	envEndVolume; + +		uint8	vibLength; +		uint8	vibCount; +		int16	vibValue; +		int8	vibDelta; + +		uint8	addBeginLength; +		uint8	addBeginCount; +		int32	addBeginDelta; +	} _channelCtx[kNumVoices]; + +	struct PatternContext { +		uint32	offset; // patternStart, Offset from mdat +		uint32	savedOffset;	// for subroutine calls +		uint16	step;	// distance from patternStart +		uint16	savedStep; + +		uint8	command; +		int8	expose;  +		uint8	loopCount; +		uint8	wait;	//!< how many ticks to wait before next Command +	} _patternCtx[kNumChannels]; + +	struct TrackStepContext { +		uint16	startInd; +		uint16	stopInd; +		uint16	posInd; +		int16	loopCount; +	} _trackCtx; + +	struct PlayerContext { +		int8	song;	//!< >= 0 if Song is running (means process Patterns) + +		uint16	patternCount; +		uint16	patternSkip;	//!< skip that amount of CIA-Interrupts + +		int8	volume;	//!< Master Volume + +		uint8	fadeSkip; +		uint8	fadeCount; +		int8	fadeEndVolume; +		int8	fadeDelta; + +		int		tickCount; + +		uint16	*signal; +		uint16	numSignals; + +		bool	stopWithLastPattern; //!< hack to automatically stop the whole player if no Pattern is running +	} _playerCtx; + +	const byte *getSfxPtr(uint16 index = 0) const { +		const byte *sfxPtr = (const byte *)(_resource->mdatData + _resource->sfxTableOffset + index * 8); + +		_resource->boundaryCheck(sfxPtr, 8); +		return sfxPtr; +	} + +	const uint16 *getTrackPtr(uint16 trackstep = 0) const { +		const uint16 *trackData = (const uint16 *)(_resource->mdatData + _resource->trackstepOffset + 16 * trackstep); + +		_resource->boundaryCheck(trackData, 16); +		return trackData; +	} + +	const uint32 *getPatternPtr(uint32 offset) const { +		const uint32 *pattData = (const uint32 *)(_resource->mdatData + offset); + +		_resource->boundaryCheck(pattData, 4); +		return pattData; +	} + +	const uint32 *getMacroPtr(uint32 offset) const { +		const uint32 *macroData = (const uint32 *)(_resource->mdatData + offset); + +		_resource->boundaryCheck(macroData, 4); +		return macroData; +	} + +	const int8 *getSamplePtr(const uint32 offset) const { +		const int8 *sample = _resourceSample.sampleData + offset; + +		_resourceSample.boundaryCheck(sample, 2); +		return sample; +	} + +	static inline void initMacroProgramm(ChannelContext &channel); +	static inline void clearEffects(ChannelContext &channel); +	static inline void haltMacroProgramm(ChannelContext &channel); +	static inline void unlockMacroChannel(ChannelContext &channel); +	static inline void initPattern(PatternContext &pattern, uint8 cmd, int8 expose, uint32 offset); +	void stopSongImpl(bool stopAudio = true); +	static void inline setNoteMacro(ChannelContext &channel, uint note, int fineTune); +	void initFadeCommand(const uint8 fadeTempo, const int8 endVol); +	void setModuleData(const MdatResource *resource, const int8 *sampleData, uint32 sampleLen, bool autoDelete = true); +	static const MdatResource *loadMdatFile(Common::SeekableReadStream &musicData); +	static const int8 *loadSampleFile(uint32 &sampleLen, Common::SeekableReadStream &sampleStream);	 +	void freeResourceDataImpl(); +	void effects(ChannelContext &channel); +	void macroRun(ChannelContext &channel); +	void advancePatterns(); +	bool patternRun(PatternContext &pattern); +	bool trackRun(bool incStep = false); +	void noteCommand(uint8 note, uint8 param1, uint8 param2, uint8 param3); +}; + +}	// End of namespace Audio + +#endif // !defined(SOUND_MODS_TFMX_H) diff --git a/sound/module.mk b/sound/module.mk index 3bcdd47c56..aabe7fe729 100644 --- a/sound/module.mk +++ b/sound/module.mk @@ -24,11 +24,13 @@ MODULE_OBJS := \  	vorbis.o \  	wave.o \  	mods/infogrames.o \ +	mods/maxtrax.o \  	mods/module.o \  	mods/protracker.o \  	mods/paula.o \  	mods/rjp1.o \  	mods/soundfx.o \ +	mods/tfmx.o \  	softsynth/adlib.o \  	softsynth/opl/dosbox.o \  	softsynth/opl/mame.o \  | 
