Index: common/util.cpp
===================================================================
--- common/util.cpp	(revision 33614)
+++ common/util.cpp	(working copy)
@@ -288,6 +288,7 @@
 	{"macintosh", "mac", "mac", "Macintosh", kPlatformMacintosh},
 	{"pce", "pce", "pce", "PC-Engine", kPlatformPCEngine },
 	{"nes", "nes", "nes", "NES", kPlatformNES},
+	{"saturn", "saturn", "saturn", "Sega Saturn", kPlatformSaturn},
 	{"segacd", "segacd", "sega", "SegaCD", kPlatformSegaCD},
 	{"windows", "win", "win", "Windows", kPlatformWindows},
 
Index: common/util.h
===================================================================
--- common/util.h	(revision 33614)
+++ common/util.h	(working copy)
@@ -207,9 +207,9 @@
 	kPlatformSegaCD,
 	kPlatform3DO,
 	kPlatformPCEngine,
-
 	kPlatformApple2GS,
 	kPlatformPC98,
+	kPlatformSaturn,
 
 	kPlatformUnknown = -1
 };
Index: engines/made/cpkplayer.cpp
===================================================================
--- engines/made/cpkplayer.cpp	(revision 0)
+++ engines/made/cpkplayer.cpp	(revision 0)
@@ -0,0 +1,157 @@
+/* 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 "made/cpkplayer.h"
+#include "made/screen.h"
+
+#include "sound/adpcm.h"
+
+namespace Made {
+
+CpkPlayer::CpkPlayer(MadeEngine *vm, Audio::Mixer *mixer) : _fd(NULL), _vm(vm), _mixer(mixer) {
+}
+
+CpkPlayer::~CpkPlayer() {
+}
+
+struct SampleTableEntry {
+	uint32 offset;
+	uint32 length;
+	uint32 sampleInfo1;
+	uint32 sampleInfo2;
+};
+
+void CpkPlayer::play(const char *filename) {
+
+	// Note: Most of this code is based off the document from http://wiki.multimedia.cx/index.php?title=Sega_FILM
+
+	_abort = false;
+	_surface = new Graphics::Surface();
+
+	_fd = new Common::File();
+	_fd->open(filename);
+
+	// FILM Chunk
+	assert(_fd->readUint32BE() == MKID_BE('FILM'));
+	uint32 filmHeaderLength = _fd->readUint32BE();
+	uint32 filmVersion = _fd->readUint32BE();
+	_fd->readUint32BE(); // Reserved???
+	
+	// FDSC Chunk
+	assert(_fd->readUint32BE() == MKID_BE('FDSC'));
+	uint32 fdscChunkSize = _fd->readUint32BE();
+	uint32 videoCodec = _fd->readUint32BE();
+	uint32 height = _fd->readUint32BE();
+	uint32 width = _fd->readUint32BE();
+	_fd->readByte(); // Unknown
+	byte audioChannels = _fd->readByte();
+	byte audioSamplingBits = _fd->readByte();
+	_fd->readByte(); // Unknown
+	uint16 audioFrequency = _fd->readUint16BE();
+	
+	// STAB Chunk
+	assert(_fd->readUint32BE() == MKID_BE('STAB'));
+	uint32 stabChunkSize = _fd->readUint32BE();
+	uint32 frameRateBaseFreq = _fd->readUint32BE();
+	uint32 sampleTableEntryCount = _fd->readUint32BE();
+	SampleTableEntry *sampleTableEntries = new SampleTableEntry[sampleTableEntryCount];
+	for (uint32 i = 0; i < sampleTableEntryCount; i++) {
+		sampleTableEntries[i].offset = _fd->readUint32BE();
+		sampleTableEntries[i].length = _fd->readUint32BE();
+		sampleTableEntries[i].sampleInfo1 = _fd->readUint32BE();
+		sampleTableEntries[i].sampleInfo2 = _fd->readUint32BE();
+	}
+	
+	// Where's the actual frame rate? There is none! It's variable and can differ between frames.
+
+	_mixer->stopAll();
+
+	byte audioFlags = 0;
+	if (audioChannels == 2)
+		audioFlags |= Audio::Mixer::FLAG_STEREO;
+	if (audioSamplingBits == 16)
+		audioFlags |= Audio::Mixer::FLAG_16BITS;
+	
+	_audioStream = Audio::makeAppendableAudioStream(audioFrequency, audioFlags);
+	
+	
+	// Uh-oh.... is it 8bpp???
+	_surface->create(width, height, 1);
+
+	for (uint32 i = 0; i < sampleTableEntryCount && !_abort && !_fd->eof(); i++) {
+		_fd->seek(sampleTableEntries[i].offset + filmHeaderLength);
+		
+		// Audio Data
+		if (sampleTableEntries[i].sampleInfo1 == (uint32)~0) {
+			Common::SeekableSubReadStream *soundData = new Common::SeekableSubReadStream(_fd, 0, sampleTableEntries[i].length);
+			Audio::AudioStream *adpcmStream = Audio::makeADPCMStream(soundData, false, 0, Audio::kADPCMMS, audioFrequency, audioChannels, 0);
+			// TODO: L R L R L R L R
+			// The Sound data alternates left/right
+		} else {
+		// Video Data
+			// TODO: Cinepak for SEGA
+		}
+
+		handleEvents();
+		updateScreen();
+	}
+
+	_audioStream->finish();
+	_mixer->stopHandle(_audioStreamHandle);
+	
+	//delete _audioStream;
+	delete _fd;
+	delete _surface;
+
+}
+
+void CpkPlayer::handleEvents() {
+	Common::Event event;
+	while (_vm->_system->getEventManager()->pollEvent(event)) {
+		switch (event.type) {
+		case Common::EVENT_KEYDOWN:
+			if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
+				_abort = true;
+			break;
+		case Common::EVENT_QUIT:
+			_vm->_quit = true;
+			_abort = true;
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+void CpkPlayer::updateScreen() {
+	_vm->_system->copyRectToScreen((const byte*)_surface->pixels, _surface->pitch, 
+									(320 - _surface->w) / 2, (200 - _surface->h) / 2, _surface->w, _surface->h);
+	_vm->_system->updateScreen();
+}
+
+}

Property changes on: engines\made\cpkplayer.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Index: engines/made/cpkplayer.h
===================================================================
--- engines/made/cpkplayer.h	(revision 0)
+++ engines/made/cpkplayer.h	(revision 0)
@@ -0,0 +1,64 @@
+/* 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 MADE_CPKPLAYER_H
+#define MADE_CPKPLAYER_H
+
+#include "common/system.h"
+#include "common/events.h"
+#include "common/file.h"
+#include "common/endian.h"
+#include "graphics/surface.h"
+#include "sound/mixer.h"
+#include "sound/audiostream.h"
+
+#include "made/graphics.h"
+#include "made/sound.h"
+#include "made/made.h"
+
+namespace Made {
+
+class MadeEngine;
+
+class CpkPlayer {
+public:
+	CpkPlayer(MadeEngine *vm, Audio::Mixer *mixer);
+	~CpkPlayer();
+	void play(const char *filename);
+protected:
+	MadeEngine *_vm;
+	Audio::Mixer *_mixer;
+	Common::File *_fd;
+	Audio::AppendableAudioStream *_audioStream;
+	Audio::SoundHandle _audioStreamHandle;
+	Graphics::Surface *_surface;
+	bool _abort;
+	void handleEvents();
+	void updateScreen();
+};
+
+}
+
+#endif

Property changes on: engines\made\cpkplayer.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Index: engines/made/database.cpp
===================================================================
--- engines/made/database.cpp	(revision 33614)
+++ engines/made/database.cpp	(working copy)
@@ -242,8 +242,95 @@
 	return _objData + 6;
 }
 
+int ObjectSegaSaturn::load(Common::SeekableReadStream &source) {
+	_freeData = true;
+	source.readUint16BE(); // skip flags
+	uint16 type = source.readUint16BE();
+	if (type == 0x7FFF) {
+		_objSize = source.readUint16BE();
+	} else if (type == 0x7FFE) {
+		_objSize = source.readUint16BE() * 2;
+	} else if (type < 0x7FFE) {
+		byte count1 = source.readByte();
+		byte count2 = source.readByte();
+		_objSize = (count1 + count2) * 2;
+	}
+	source.seek(-6, SEEK_CUR);
+	_objSize += 6;
+	_objData = new byte[_objSize];
+	source.read(_objData, _objSize);
+	return _objSize;
+}
 
+int ObjectSegaSaturn::load(byte *source) {
+	_objData = source;
+	_freeData = false;
+	if (getClass() < 0x7FFE) {
+		_objSize = (getCount1() + getCount2()) * 2;
+	} else {
+		_objSize = getSize();
+	}
+	_objSize += 6;
+	return _objSize;
+}
 
+int ObjectSegaSaturn::save(Common::WriteStream &dest) {
+	// Not implemented/used for version 3 objects
+	return 0;
+}
+
+uint16 ObjectSegaSaturn::getFlags() {
+	return READ_BE_UINT16(_objData);
+}
+
+uint16 ObjectSegaSaturn::getClass() {
+	return READ_BE_UINT16(_objData + 2);
+}
+
+uint16 ObjectSegaSaturn::getSize() {
+	return READ_BE_UINT16(_objData + 4);
+}
+
+byte ObjectSegaSaturn::getCount1() {
+	return _objData[4];
+}
+
+byte ObjectSegaSaturn::getCount2() {
+	return _objData[5];
+}
+
+byte *ObjectSegaSaturn::getData() {
+	return _objData + 6;
+}
+
+int16 ObjectSegaSaturn::getVectorItem(int16 index) {
+	if (getClass() == 0x7FFF) {
+		byte *vector = (byte*)getData();
+		return vector[index];
+	} else if (getClass() == 0x7FFE) {
+		int16 *vector = (int16*)getData();
+		return READ_BE_UINT16(&vector[index]);
+	} else if (getClass() < 0x7FFE) {
+		int16 *vector = (int16*)getData();
+		return READ_BE_UINT16(&vector[index]);
+	} else {
+		// should never reach here
+		error("Unknown object class");
+		return 0;
+	}
+}
+
+void ObjectSegaSaturn::setVectorItem(int16 index, int16 value) {
+	if (getClass() == 0x7FFF) {
+		byte *vector = (byte*)getData();
+		vector[index] = value;
+	} else if (getClass() <= 0x7FFE) {
+		int16 *vector = (int16*)getData();
+		WRITE_BE_UINT16(&vector[index], value);
+	}
+}
+
+
 GameDatabase::GameDatabase(MadeEngine *vm) : _vm(vm) {
 }
 
@@ -678,4 +765,226 @@
 	return NULL;
 }
 
+// GameDatabaseSegaSaturn
+
+GameDatabaseSegaSaturn::GameDatabaseSegaSaturn(MadeEngine *vm) : GameDatabase(vm) {
+}
+
+int16 GameDatabaseSegaSaturn::getVar(int16 index) {
+	return (int16)READ_BE_UINT16(_gameState + index * 2);
+}
+
+void GameDatabaseSegaSaturn::setVar(int16 index, int16 value) {
+	WRITE_BE_UINT16(_gameState + index * 2, value);
+}
+
+int16 GameDatabaseSegaSaturn::getObjectProperty(int16 objectIndex, int16 propertyId) {
+	if (objectIndex == 0)
+		return 0;
+
+	int16 propertyFlag;
+	int16 *property = findObjectProperty(objectIndex, propertyId, propertyFlag);
+
+	if (property) {
+		return (int16)READ_BE_UINT16(property);
+	} else {
+		return 0;
+	}
+}
+
+int16 GameDatabaseSegaSaturn::setObjectProperty(int16 objectIndex, int16 propertyId, int16 value) {
+	if (objectIndex == 0)
+		return 0;
+
+	int16 propertyFlag;
+	int16 *property = findObjectProperty(objectIndex, propertyId, propertyFlag);
+
+	if (property) {
+		if (propertyFlag == 1) {
+			WRITE_BE_UINT16(property, value);
+		} else {
+			warning("GameDatabase::setObjectProperty(%04X, %04X, %04X) Trying to set constant property\n",
+				objectIndex, propertyId, value);
+		}
+		return value;
+	} else {
+		return 0;
+	}
+}
+
+void GameDatabaseSegaSaturn::load(Common::SeekableReadStream &sourceS) {
+	// TODO: Read/verify header
+
+	sourceS.seek(0x1E);
+
+	uint32 objectIndexOffs = sourceS.readUint32BE();
+	uint16 objectCount = sourceS.readUint16BE();
+	uint32 gameStateOffs = sourceS.readUint32BE();
+	_gameStateSize = sourceS.readUint32BE();
+	uint32 objectsOffs = sourceS.readUint32BE();
+	uint32 objectsSize = sourceS.readUint32BE();
+	_mainCodeObjectIndex = sourceS.readUint16BE();
+
+	debug(2, "objectIndexOffs = %08X; objectCount = %d; gameStateOffs = %08X; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n", objectIndexOffs, objectCount, gameStateOffs, _gameStateSize, objectsOffs, objectsSize);
+
+	_gameState = new byte[_gameStateSize];
+	sourceS.seek(gameStateOffs);
+	sourceS.read(_gameState, _gameStateSize);
+
+	Common::Array<uint32> objectOffsets;
+	sourceS.seek(objectIndexOffs);
+	for (uint32 i = 0; i < objectCount; i++)
+		objectOffsets.push_back(sourceS.readUint32BE());
+
+	for (uint32 i = 0; i < objectCount; i++) {
+		Object *obj = new ObjectSegaSaturn();
+
+		// The LSB indicates if it's a constant or variable object.
+		// Constant objects are loaded from disk, while variable objects exist
+		// in the _gameState buffer.
+
+		if (objectOffsets[i] & 1) {
+			sourceS.seek(objectsOffs + objectOffsets[i] - 1);
+			obj->load(sourceS);
+		} else {
+			obj->load(_gameState + objectOffsets[i]);
+		}
+		_objects.push_back(obj);
+	}
+}
+
+bool GameDatabaseSegaSaturn::getSavegameDescription(const char *filename, Common::String &description) {
+	Common::InSaveFile *in;
+	char desc[64];
+	if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
+		return false;
+	}
+	in->skip(4); // TODO: Verify marker 'SGAM'
+	in->skip(4); // TODO: Verify size
+	in->skip(2); // TODO: Verify version
+	in->read(desc, 64);
+	description = desc;
+	delete in;
+	return true;
+}
+
+int16 GameDatabaseSegaSaturn::savegame(const char *filename, const char *description, int16 version) {
+	Common::OutSaveFile *out;
+	char desc[64];
+	int16 result = 0;
+	uint32 size = 4 + 4 + 2 + _gameStateSize;
+	if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
+		warning("Can't create file '%s', game not saved", filename);
+		return 6;
+	}
+	strncpy(desc, description, 64);
+	out->writeUint32BE(MKID_BE('SGAM'));
+	out->writeUint32LE(size);
+	out->writeUint16LE(version);
+	out->write(desc, 64);
+	out->write(_gameState, _gameStateSize);
+	delete out;
+	return result;
+}
+
+int16 GameDatabaseSegaSaturn::loadgame(const char *filename, int16 version) {
+	Common::InSaveFile *in;
+	int16 result = 0;
+	//uint32 expectedSize = 4 + 4 + 2 + _gameStateSize;
+	if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
+		warning("Can't open file '%s', game not loaded", filename);
+		return 1;
+	}
+	in->skip(4); // TODO: Verify marker 'SGAM'
+	in->skip(4); // TODO: Verify size
+	in->skip(2); // TODO: Verify version
+	in->skip(64); // skip savegame description
+	in->read(_gameState, _gameStateSize);
+	delete in;
+	return result;
+}
+
+int16 *GameDatabaseSegaSaturn::findObjectProperty(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
+	Object *obj = getObject(objectIndex);
+
+	int16 *prop = (int16*)obj->getData();
+	byte count1 = obj->getCount1();
+	byte count2 = obj->getCount2();
+
+	int16 *propPtr1 = prop + count1;
+	int16 *propPtr2 = prop + count2;
+
+	// First see if the property exists in the given object
+	while (count2-- > 0) {
+		if ((READ_BE_UINT16(prop) & 0x3FFF) == propertyId) {
+			if (READ_BE_UINT16(prop) & 0x4000) {
+				propertyFlag = 1;
+				return (int16*)_gameState + READ_BE_UINT16(propPtr1);
+			} else {
+				propertyFlag = obj->getFlags() & 1;
+				return propPtr1;
+			}
+		}
+		prop++;
+		propPtr1++;
+	}
+
+	// Now check in the object hierarchy of the given object
+	int16 parentObjectIndex = obj->getClass();
+	if (parentObjectIndex == 0) {
+		return NULL;
+	}
+
+	while (parentObjectIndex != 0) {
+
+		obj = getObject(parentObjectIndex);
+
+		prop = (int16*)obj->getData();
+		count1 = obj->getCount1();
+		count2 = obj->getCount2();
+
+		propPtr1 = propPtr2 + count1 - count2;
+		int16 *propertyPtr = prop + count1;
+
+		while (count2-- > 0) {
+			if (!(READ_BE_UINT16(prop) & 0x8000)) {
+				if ((READ_BE_UINT16(prop) & 0x3FFF) == propertyId) {
+					if (READ_BE_UINT16(prop) & 0x4000) {
+						propertyFlag = 1;
+						return (int16*)_gameState + READ_BE_UINT16(propPtr1);
+					} else {
+						propertyFlag = obj->getFlags() & 1;
+						return propPtr1;
+					}
+				} else {
+					propPtr1++;
+				}
+			} else {
+				if ((READ_BE_UINT16(prop) & 0x3FFF) == propertyId) {
+					if (READ_BE_UINT16(prop) & 0x4000) {
+						propertyFlag = 1;
+						return (int16*)_gameState + READ_BE_UINT16(propertyPtr);
+					} else {
+						propertyFlag = obj->getFlags() & 1;
+						return propertyPtr;
+					}
+				}
+			}
+			prop++;
+			propertyPtr++;
+		}
+
+		parentObjectIndex = obj->getClass();
+
+	}
+
+	return NULL;
+	
+}
+
+const char *GameDatabaseSegaSaturn::getString(uint16 offset) {
+	// Not used in version 3 games
+	return NULL;
+}
+
 } // End of namespace Made
Index: engines/made/database.h
===================================================================
--- engines/made/database.h	(revision 33614)
+++ engines/made/database.h	(working copy)
@@ -107,6 +107,27 @@
 	
 };
 
+class ObjectSegaSaturn : public Object {
+public:
+	int load(Common::SeekableReadStream &source);
+	int load(byte *source);
+	int save(Common::WriteStream &dest);
+	uint16 getFlags();
+	uint16 getClass();
+	uint16 getSize();
+	byte getCount1();
+	byte getCount2();
+	byte *getData();
+	
+	int16 getVectorItem(int16 index);
+	void setVectorItem(int16 index, int16 value);
+	
+	bool isConstant() {
+		return !(getFlags() & 1);
+	}
+	
+};
+
 class GameDatabase {
 public:
 
@@ -180,6 +201,25 @@
 	void load(Common::SeekableReadStream &sourceS);
 };
 
+class GameDatabaseSegaSaturn : public GameDatabase {
+public:
+	GameDatabaseSegaSaturn(MadeEngine *vm);
+	int16 *findObjectProperty(int16 objectIndex, int16 propertyId, int16 &propertyFlag);
+	const char *getString(uint16 offset);
+	bool getSavegameDescription(const char *filename, Common::String &description);
+	int16 savegame(const char *filename, const char *description, int16 version);
+	int16 loadgame(const char *filename, int16 version);
+	
+	int16 getVar(int16 index);
+	void setVar(int16 index, int16 value);
+	
+	int16 getObjectProperty(int16 objectIndex, int16 propertyId);
+	int16 setObjectProperty(int16 objectIndex, int16 propertyId, int16 value);
+protected:
+	char *_gameText;
+	void load(Common::SeekableReadStream &sourceS);
+};
+
 } // End of namespace Made
 
 #endif /* MADE_H */
Index: engines/made/detection.cpp
===================================================================
--- engines/made/detection.cpp	(revision 33614)
+++ engines/made/detection.cpp	(working copy)
@@ -228,6 +228,22 @@
 		GF_FLOPPY,
 		0,
 	},
+	
+	{
+		// Return to Zork - Japanese Sega Saturn version
+		{
+			"rtz",
+			"",
+			AD_ENTRY1("rtz.dat", "023e46f6b43913792bd535558cce7bf7"),
+			Common::JA_JPN,
+			Common::kPlatformSaturn,
+			Common::ADGF_NO_FLAGS
+		},
+		GID_RTZ,
+		0,
+		GF_FLOPPY,
+		0,
+	},
 
 	{
 		// Return to Zork - Demo
Index: engines/made/made.cpp
===================================================================
--- engines/made/made.cpp	(revision 33614)
+++ engines/made/made.cpp	(working copy)
@@ -85,13 +85,17 @@
 		_system->openCD(cd_num);
 		
 	_pmvPlayer = new PmvPlayer(this, _mixer);
+	_cpkPlayer = new CpkPlayer(this, _mixer);
 	_res = new ProjectReader();
 	_screen = new Screen(this);
 
 	if (getGameID() == GID_LGOP2 || getGameID() == GID_MANHOLE || getGameID() == GID_RODNEY) {
 		_dat = new GameDatabaseV2(this);
 	} else if (getGameID() == GID_RTZ) {
-		_dat = new GameDatabaseV3(this);
+		if (getPlatform() == Common::kPlatformSaturn)
+			_dat = new GameDatabaseSegaSaturn(this);
+		else
+			_dat = new GameDatabaseV3(this);
 	} else {
 		error("Unknown GameID");
 	}
Index: engines/made/made.h
===================================================================
--- engines/made/made.h	(revision 33614)
+++ engines/made/made.h	(working copy)
@@ -45,6 +45,8 @@
 
 #include "engines/engine.h"
 
+#include "made/cpkplayer.h"
+
 namespace Made {
 
 enum MadeGameID {
@@ -66,6 +68,7 @@
 struct MadeGameDescription;
 
 class ProjectReader;
+class CpkPlayer;
 class PmvPlayer;
 class Screen;
 class ScriptInterpreter;
@@ -98,6 +101,7 @@
 private:
 public:
 	PmvPlayer *_pmvPlayer;
+	CpkPlayer *_cpkPlayer;
 	ProjectReader *_res;
 	Screen *_screen;
 	GameDatabase *_dat;
Index: engines/made/module.mk
===================================================================
--- engines/made/module.mk	(revision 33614)
+++ engines/made/module.mk	(working copy)
@@ -1,6 +1,7 @@
 MODULE := engines/made
 
 MODULE_OBJS = \
+	cpkplayer.o \
 	database.o \
 	detection.o \
 	graphics.o \
Index: engines/made/scriptfuncs.cpp
===================================================================
--- engines/made/scriptfuncs.cpp	(revision 33614)
+++ engines/made/scriptfuncs.cpp	(working copy)
@@ -45,7 +45,6 @@
 	_externalFuncs.push_back(new ExternalScriptFunc(this, &ScriptFunctions::x));  \
 	_externalFuncNames.push_back(#x);
 void ScriptFunctions::setupExternalsTable() {
-
 	External(sfSystemCall);
 	External(sfInitGraf);
 	External(sfRestoreGraf);
@@ -115,7 +114,8 @@
 	}
 	
 	if (_vm->getGameID() == GID_RTZ) {
-		External(sfPrintf);
+		if (_vm->getPlatform() != Common::kPlatformSaturn)
+			External(sfPrintf);
 		External(sfClearMono);
 		External(sfGetSoundEnergy);
 		External(sfClearText);
@@ -150,9 +150,13 @@
 		External(sfReadMenu);
 		External(sfDrawMenu);
 		External(sfGetMenuCount);
-		External(sfSaveGame);
-		External(sfLoadGame);
-		External(sfGetGameDescription);
+		if (_vm->getPlatform() == Common::kPlatformSaturn) {
+			External(sfFaceIcon);
+		} else {
+			External(sfSaveGame);
+			External(sfLoadGame);
+			External(sfGetGameDescription);
+		}
 		External(sfShakeScreen);
 		External(sfPlaceMenu);
 		External(sfSetSoundVolume);
@@ -879,6 +883,12 @@
 
 }
 
+int16 ScriptFunctions::sfFaceIcon(int16 argc, int16 *argv) {
+	// RTZ Sega Saturn
+	warning("Unimplemented opcode: sfFaceIcon");
+	return 0;
+}
+
 int16 ScriptFunctions::sfShakeScreen(int16 argc, int16 *argv) {
 	// TODO: Used in RTZ
 	warning("Unimplemented opcode: sfShakeScreen");
Index: engines/made/scriptfuncs.h
===================================================================
--- engines/made/scriptfuncs.h	(revision 33614)
+++ engines/made/scriptfuncs.h	(working copy)
@@ -161,6 +161,7 @@
 	int16 sfSaveGame(int16 argc, int16 *argv);
 	int16 sfLoadGame(int16 argc, int16 *argv);
 	int16 sfGetGameDescription(int16 argc, int16 *argv);
+	int16 sfFaceIcon(int16 argc, int16 *argv);
 	int16 sfShakeScreen(int16 argc, int16 *argv);
 	int16 sfPlaceMenu(int16 argc, int16 *argv);
 	int16 sfSetSoundVolume(int16 argc, int16 *argv);
