[Scummvm-cvs-logs] SF.net SVN: scummvm:[55801] scummvm/trunk/engines/sci

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Mon Feb 7 13:24:09 CET 2011


Revision: 55801
          http://scummvm.svn.sourceforge.net/scummvm/?rev=55801&view=rev
Author:   thebluegr
Date:     2011-02-07 12:24:09 +0000 (Mon, 07 Feb 2011)

Log Message:
-----------
SCI: Converted the robot decoder into a regular video decoder, and decoupled it from the
SciEngine class

- Robot videos are now shown in frameOut(), like they should, and kRobot(sync) is only
used for syncing with the game scripts
- Hooked video playing into the "play_video" console command

Modified Paths:
--------------
    scummvm/trunk/engines/sci/console.cpp
    scummvm/trunk/engines/sci/console.h
    scummvm/trunk/engines/sci/engine/kgraphics.cpp
    scummvm/trunk/engines/sci/engine/kvideo.cpp
    scummvm/trunk/engines/sci/graphics/frameout.cpp
    scummvm/trunk/engines/sci/graphics/paint32.cpp
    scummvm/trunk/engines/sci/graphics/paint32.h
    scummvm/trunk/engines/sci/module.mk
    scummvm/trunk/engines/sci/sci.cpp
    scummvm/trunk/engines/sci/sci.h

Added Paths:
-----------
    scummvm/trunk/engines/sci/video/robot_decoder.cpp
    scummvm/trunk/engines/sci/video/robot_decoder.h

Removed Paths:
-------------
    scummvm/trunk/engines/sci/graphics/robot.cpp
    scummvm/trunk/engines/sci/graphics/robot.h

Modified: scummvm/trunk/engines/sci/console.cpp
===================================================================
--- scummvm/trunk/engines/sci/console.cpp	2011-02-07 09:03:58 UTC (rev 55800)
+++ scummvm/trunk/engines/sci/console.cpp	2011-02-07 12:24:09 UTC (rev 55801)
@@ -53,6 +53,7 @@
 #include "sci/video/seq_decoder.h"
 #ifdef ENABLE_SCI32
 #include "video/coktel_decoder.h"
+#include "sci/video/robot_decoder.h"
 #endif
 
 #include "common/file.h"
@@ -119,9 +120,6 @@
 	DCmd_Register("set_palette",		WRAP_METHOD(Console, cmdSetPalette));
 	DCmd_Register("draw_pic",			WRAP_METHOD(Console, cmdDrawPic));
 	DCmd_Register("draw_cel",			WRAP_METHOD(Console, cmdDrawCel));
-#ifdef ENABLE_SCI32
-	DCmd_Register("draw_robot",			WRAP_METHOD(Console, cmdDrawRobot));
-#endif
 	DCmd_Register("undither",           WRAP_METHOD(Console, cmdUndither));
 	DCmd_Register("pic_visualize",		WRAP_METHOD(Console, cmdPicVisualize));
 	DCmd_Register("play_video",         WRAP_METHOD(Console, cmdPlayVideo));
@@ -243,16 +241,16 @@
 #ifdef ENABLE_SCI32
 		} else if (_videoFile.hasSuffix(".vmd")) {
 			videoDecoder = new Video::VMDDecoder(g_system->getMixer());
-#endif
+		} else if (_videoFile.hasSuffix(".rbt")) {
+			videoDecoder = new RobotDecoder(g_system->getMixer(), _engine->getPlatform() == Common::kPlatformMacintosh);
 		} else if (_videoFile.hasSuffix(".duk")) {
-#ifdef ENABLE_SCI32
 			duckMode = true;
-			videoDecoder = new Video::AviDecoder(g_system->getMixer());
-#else
-			warning("Duck videos require SCI32 support compiled in");
+			videoDecoder = new Video::AviDecoder(g_system->getMixer());	
 #endif
 		} else if (_videoFile.hasSuffix(".avi")) {
 			videoDecoder = new Video::AviDecoder(g_system->getMixer());
+		} else {
+			warning("Unrecognized video type");
 		}
 
 		if (videoDecoder && videoDecoder->loadFile(_videoFile)) {
@@ -1509,27 +1507,6 @@
 	return true;
 }
 
-#ifdef ENABLE_SCI32
-bool Console::cmdDrawRobot(int argc, const char **argv) {
-	if (argc < 2) {
-		DebugPrintf("Draws frames from a robot resource\n");
-		DebugPrintf("Usage: %s <resourceId>\n", argv[0]);
-		DebugPrintf("where <resourceId> is the id of the robot resource to draw\n");
-		return true;
-	}
-
-	uint16 resourceId = atoi(argv[1]);
-
-	if (_engine->_gfxPaint32) {
-		_engine->_gfxPaint32->debugDrawRobot(resourceId);
-	} else {
-		DebugPrintf("command not available in non-sci32 games");
-	}
-	return true;
-}
-
-#endif
-
 bool Console::cmdUndither(int argc, const char **argv) {
 	if (argc != 2) {
 		DebugPrintf("Enable/disable undithering.\n");
@@ -1569,7 +1546,7 @@
 
 bool Console::cmdPlayVideo(int argc, const char **argv) {
 	if (argc < 2) {
-		DebugPrintf("Plays a SEQ, AVI, DUK or VMD video.\n");
+		DebugPrintf("Plays a SEQ, AVI, VMD, RBT or DUK video.\n");
 		DebugPrintf("Usage: %s <video file name> <delay>\n", argv[0]);
 		DebugPrintf("The video file name should include the extension\n");
 		DebugPrintf("Delay is only used in SEQ videos and is measured in ticks (default: 10)\n");
@@ -1579,7 +1556,8 @@
 	Common::String filename = argv[1];
 	filename.toLowercase();
 
-	if (filename.hasSuffix(".seq") || filename.hasSuffix(".avi") || filename.hasSuffix(".vmd") || filename.hasSuffix(".duk")) {
+	if (filename.hasSuffix(".seq") || filename.hasSuffix(".avi") || filename.hasSuffix(".vmd") || 
+		filename.hasSuffix(".rbt") || filename.hasSuffix(".duk")) {
 		_videoFile = filename;
 		_videoFrameDelay = (argc == 2) ? 10 : atoi(argv[2]);
 		return Cmd_Exit(0, 0);

Modified: scummvm/trunk/engines/sci/console.h
===================================================================
--- scummvm/trunk/engines/sci/console.h	2011-02-07 09:03:58 UTC (rev 55800)
+++ scummvm/trunk/engines/sci/console.h	2011-02-07 12:24:09 UTC (rev 55801)
@@ -91,9 +91,6 @@
 	bool cmdSetPalette(int argc, const char **argv);
 	bool cmdDrawPic(int argc, const char **argv);
 	bool cmdDrawCel(int argc, const char **argv);
-#ifdef ENABLE_SCI32
-	bool cmdDrawRobot(int argc, const char **argv);
-#endif
 	bool cmdUndither(int argc, const char **argv);
 	bool cmdPicVisualize(int argc, const char **argv);
 	bool cmdPlayVideo(int argc, const char **argv);

Modified: scummvm/trunk/engines/sci/engine/kgraphics.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kgraphics.cpp	2011-02-07 09:03:58 UTC (rev 55800)
+++ scummvm/trunk/engines/sci/engine/kgraphics.cpp	2011-02-07 12:24:09 UTC (rev 55801)
@@ -48,12 +48,12 @@
 #include "sci/graphics/paint16.h"
 #include "sci/graphics/picture.h"
 #include "sci/graphics/ports.h"
-#include "sci/graphics/robot.h"
 #include "sci/graphics/screen.h"
 #include "sci/graphics/text16.h"
 #include "sci/graphics/view.h"
 #ifdef ENABLE_SCI32
 #include "sci/graphics/frameout.h"
+#include "sci/video/robot_decoder.h"
 #endif
 
 namespace Sci {
@@ -1398,7 +1398,6 @@
 reg_t kRobot(EngineState *s, int argc, reg_t *argv) {
 
 	int16 subop = argv[0].toUint16();
-	GfxRobot *robot = g_sci->_gfxRobot;
 
 	switch (subop) {
 		case 0: { // init
@@ -1408,7 +1407,8 @@
 			int16 x = argv[4].toUint16();
 			int16 y = argv[5].toUint16();
 			warning("kRobot(init), id %d, obj %04x:%04x, flag %d, x=%d, y=%d", id, PRINT_REG(obj), flag, x, y);
-			robot->init(id, x, y);
+			g_sci->_robotDecoder->load(id);
+			g_sci->_robotDecoder->setPos(x, y);
 			}
 			break;
 		case 1:	// LSL6 hires (startup)
@@ -1423,10 +1423,13 @@
 			warning("kRobot(%d)", subop);
 			break;
 		case 8: // sync
-			robot->processNextFrame();
-			// Signal the engine scripts that the video is done
-			if (robot->getCurFrame() ==  robot->getFrameCount())
+			if ((uint32)g_sci->_robotDecoder->getCurFrame() !=  g_sci->_robotDecoder->getFrameCount() - 1) {
+				writeSelector(s->_segMan, argv[1], SELECTOR(signal), NULL_REG);
+			} else {
+				g_sci->_robotDecoder->close();
+				// Signal the engine scripts that the video is done
 				writeSelector(s->_segMan, argv[1], SELECTOR(signal), SIGNAL_REG);
+			}
 			break;
 		default:
 			warning("kRobot(%d)", subop);

Modified: scummvm/trunk/engines/sci/engine/kvideo.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kvideo.cpp	2011-02-07 09:03:58 UTC (rev 55800)
+++ scummvm/trunk/engines/sci/engine/kvideo.cpp	2011-02-07 12:24:09 UTC (rev 55801)
@@ -51,12 +51,15 @@
 	uint16 screenWidth = g_system->getWidth();
 	uint16 screenHeight = g_system->getHeight();
 	bool isVMD = videoState.fileName.hasSuffix(".vmd");
+	bool isRobot = videoState.fileName.hasSuffix(".rbt");
 
-	if (screenWidth == 640 && width <= 320 && height <= 240 && ((videoState.flags & kDoubled) || !isVMD)) {
-		width *= 2;
-		height *= 2;
-		pitch *= 2;
-		scaleBuffer = new byte[width * height * bytesPerPixel];
+	if (!isRobot) {
+		if (screenWidth == 640 && width <= 320 && height <= 240 && ((videoState.flags & kDoubled) || !isVMD)) {
+			width *= 2;
+			height *= 2;
+			pitch *= 2;
+			scaleBuffer = new byte[width * height * bytesPerPixel];
+		}
 	}
 
 	uint16 x, y; 
@@ -73,8 +76,13 @@
 			y = (screenHeight - height) / 2;
 		}
 	} else {
-		x = (screenWidth - width) / 2;
-		y = (screenHeight - height) / 2;
+		if (!isRobot) {
+			x = (screenWidth - width) / 2;
+			y = (screenHeight - height) / 2;
+		} else {
+			x = 0;
+			y = 0;
+		}
 	}
 	bool skipVideo = false;
 
@@ -84,13 +92,18 @@
 	while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) {
 		if (videoDecoder->needsUpdate()) {
 			const Graphics::Surface *frame = videoDecoder->decodeNextFrame();
+
 			if (frame) {
 				if (scaleBuffer) {
 					// TODO: Probably should do aspect ratio correction in e.g. GK1 Windows 
 					g_sci->_gfxScreen->scale2x((byte *)frame->pixels, scaleBuffer, videoDecoder->getWidth(), videoDecoder->getHeight(), bytesPerPixel);
 					g_system->copyRectToScreen(scaleBuffer, pitch, x, y, width, height);
-				} else
-					g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, width, height);
+				} else {
+					if (!isRobot)
+						g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, width, height);
+					else	// Frames in robot videos have different dimensions
+						g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+				}
 
 				if (videoDecoder->hasDirtyPalette())
 					videoDecoder->setSystemPalette();

Modified: scummvm/trunk/engines/sci/graphics/frameout.cpp
===================================================================
--- scummvm/trunk/engines/sci/graphics/frameout.cpp	2011-02-07 09:03:58 UTC (rev 55800)
+++ scummvm/trunk/engines/sci/graphics/frameout.cpp	2011-02-07 12:24:09 UTC (rev 55801)
@@ -40,8 +40,8 @@
 #include "sci/graphics/paint32.h"
 #include "sci/graphics/palette.h"
 #include "sci/graphics/picture.h"
-#include "sci/graphics/robot.h"
 #include "sci/graphics/frameout.h"
+#include "sci/video/robot_decoder.h"
 
 namespace Sci {
 
@@ -339,8 +339,38 @@
 }
 
 void GfxFrameout::kernelFrameout() {
-	if (g_sci->_gfxRobot->isPlaying())
+	if (g_sci->_robotDecoder->isVideoLoaded()) {
+		bool skipVideo = false;
+		RobotDecoder *videoDecoder = g_sci->_robotDecoder;
+		uint16 x = videoDecoder->getPos().x;
+		uint16 y = videoDecoder->getPos().y;
+
+		if (videoDecoder->hasDirtyPalette())
+			videoDecoder->setSystemPalette();
+
+		while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) {
+			if (videoDecoder->needsUpdate()) {
+				const Graphics::Surface *frame = videoDecoder->decodeNextFrame();
+				if (frame) {
+					g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+
+					if (videoDecoder->hasDirtyPalette())
+						videoDecoder->setSystemPalette();
+
+					g_system->updateScreen();
+				}
+			}
+
+			Common::Event event;
+			while (g_system->getEventManager()->pollEvent(event)) {
+				if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
+					skipVideo = true;
+			}
+
+			g_system->delayMillis(10);
+		}
 		return;
+	}
 
 	_palette->palVaryUpdate();
 

Modified: scummvm/trunk/engines/sci/graphics/paint32.cpp
===================================================================
--- scummvm/trunk/engines/sci/graphics/paint32.cpp	2011-02-07 09:03:58 UTC (rev 55800)
+++ scummvm/trunk/engines/sci/graphics/paint32.cpp	2011-02-07 12:24:09 UTC (rev 55801)
@@ -39,7 +39,6 @@
 #include "sci/graphics/view.h"
 #include "sci/graphics/screen.h"
 #include "sci/graphics/palette.h"
-#include "sci/graphics/robot.h"
 
 namespace Sci {
 
@@ -81,13 +80,4 @@
 	_screen->drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, color, priority, control);
 }
 
-void GfxPaint32::debugDrawRobot(GuiResourceId robotId) {
-	GfxRobot *test = new GfxRobot(g_sci->getResMan(), _screen, _palette);
-	test->init(robotId, 0, 0);
-	while (test->getCurFrame() + 1 < test->getFrameCount()) {
-		test->processNextFrame();
-	}
-	delete test;
-}
-
 } // End of namespace Sci

Modified: scummvm/trunk/engines/sci/graphics/paint32.h
===================================================================
--- scummvm/trunk/engines/sci/graphics/paint32.h	2011-02-07 09:03:58 UTC (rev 55800)
+++ scummvm/trunk/engines/sci/graphics/paint32.h	2011-02-07 12:24:09 UTC (rev 55801)
@@ -48,8 +48,6 @@
 	void kernelDrawCel(GuiResourceId viewId, int16 loopNo, int16 celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, bool hiresMode, reg_t upscaledHiresHandle);
 	void kernelGraphDrawLine(Common::Point startPoint, Common::Point endPoint, int16 color, int16 priority, int16 control);
 
-	void debugDrawRobot(GuiResourceId robotId);
-
 private:
 	ResourceManager *_resMan;
 	SegManager *_segMan;

Deleted: scummvm/trunk/engines/sci/graphics/robot.cpp
===================================================================
--- scummvm/trunk/engines/sci/graphics/robot.cpp	2011-02-07 09:03:58 UTC (rev 55800)
+++ scummvm/trunk/engines/sci/graphics/robot.cpp	2011-02-07 12:24:09 UTC (rev 55801)
@@ -1,329 +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$
- *
- */
-
-// fopen() and friends so we can dump frames and stuff to disk, for debugging
-// #define FORBIDDEN_SYMBOL_ALLOW_ALL 
-
-#include "sci/sci.h"
-#include "sci/engine/state.h"
-#include "sci/graphics/screen.h"
-#include "sci/graphics/robot.h"
-#include "sci/graphics/palette.h"
-#include "sci/sound/audio.h"
-
-#include "graphics/surface.h"
-
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-
-#include "common/archive.h"
-#include "common/system.h"
-#include "common/stream.h"
-#include "common/substream.h"
-
-namespace Sci {
-
-// TODO:
-// - Positioning
-// - Proper handling of frame scaling - scaled frames look squashed
-//   (probably because both dimensions should be scaled)
-// - Timing - the arbitrary 100ms delay between each frame is not quite right
-// - Proper handling of sound chunks in some cases, so that the frame size
-//   table can be ignored (it's only used to determine the correct sound chunk
-//   size at the moment, cause it can be wrong in some cases)
-// - Fix audio "hiccups" - probably data that shouldn't be in the audio frames
-
-
-// Some non technical information on robot files, from an interview with
-// Greg Tomko-Pavia of Sierra On-Line
-// Taken from http://anthonylarme.tripod.com/phantas/phintgtp.html
-//
-// (...) What we needed was a way of playing video, but have it blend into
-// normal room art instead of occupying its own rectangular area. Room art 
-// consists of a background pic overlaid with various animating cels 
-// (traditional lingo: sprites). The cels each have a priority that determines 
-// who is on top and who is behind in the drawing order. Cels are read from 
-// *.v56 files (another proprietary format). A Robot is video frames with 
-// transparent background including priority and x,y information. Thus, it is 
-// like a cel, except it comes from an RBT - not a v56. Because it blends into
-// our graphics engine, it looks just like a part of the room. A RBT can move 
-// around the screen and go behind other objects. (...)
-
-#ifdef ENABLE_SCI32
-
-GfxRobot::GfxRobot(ResourceManager *resMan, GfxScreen *screen, GfxPalette *palette)
-	: _resMan(resMan), _screen(screen), _palette(palette), _outputBuffer(0),
-	_outputBufferSize(0), _audioStream(0), _frameTotalSize(0), _robotFile(0) {
-	_x = _y = 0;
-}
-
-GfxRobot::~GfxRobot() {
-	freeData();
-}
-
-void GfxRobot::init(GuiResourceId resourceId, uint16 x, uint16 y) {
-	_x = x;
-	_y = y;
-	_curFrame = 0;
-
-	Common::String fileName = Common::String::format("%d.rbt", resourceId);
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(fileName);
-
-	if (!stream) {
-		warning("Unable to open robot file %s", fileName.c_str());
-		return;
-	}
-
-	_robotFile = new Common::SeekableSubReadStreamEndian(stream, 0, stream->size(),
-			g_sci->getPlatform() == Common::kPlatformMacintosh, DisposeAfterUse::YES);
-
-	readHeaderChunk();
-
-	// There are several versions of robot files, ranging from 3 to 6.
-	// v3: no known examples
-	// v4: PQ:SWAT demo
-	// v5: SCI2.1 and SCI3 games
-	// v6: SCI3 games
-	if (_header.version < 4 || _header.version > 6)
-		error("Unknown robot version: %d", _header.version);
-
-	_frameTotalSize = new uint32[_header.frameCount];
-
-	if (_header.hasSound) {
-		_audioStream = Audio::makeQueuingAudioStream(11025, false);
-		g_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_audioHandle, _audioStream);
-	}
-
-	readPaletteChunk();
-	readFrameSizesChunk();
-
-	debug("Robot %d, %d frames, sound: %s\n", resourceId, _header.frameCount, _header.hasSound ? "yes" : "no");
-}
-
-void GfxRobot::readHeaderChunk() {
-	// Header (60 bytes)
-	_robotFile->skip(6);
-	_header.version = _robotFile->readUint16();
-	_header.audioChunkSize = _robotFile->readUint16();
-	_header.audioSilenceSize = _robotFile->readUint16();
-	_robotFile->skip(2);
-	_header.frameCount = _robotFile->readUint16();
-	_header.paletteDataSize = _robotFile->readUint16();
-	_header.unkChunkDataSize = _robotFile->readUint16();
-	_robotFile->skip(5);
-	_header.hasSound = _robotFile->readByte();
-	_robotFile->skip(34);
-
-	// Some videos (e.g. robot 1305 in Phantasmagoria and
-	// robot 184 in Lighthouse) have an unknown chunk before
-	// the palette chunk (probably used for sound preloading).
-	// Skip it here.
-	if (_header.unkChunkDataSize)
-		_robotFile->skip(_header.unkChunkDataSize);
-}
-
-void GfxRobot::readPaletteChunk() {
-	byte *paletteChunk = new byte[_header.paletteDataSize];
-	_robotFile->read(paletteChunk, _header.paletteDataSize);
-
-	int startIndex = paletteChunk[25];
-	int colorCount = READ_SCI11ENDIAN_UINT16(paletteChunk + 29);
-
-	if (colorCount > 256)
-		error("Invalid color count: %d", colorCount);
-
-	Palette resourcePal;
-	_palette->createFromData(paletteChunk, _header.paletteDataSize, &resourcePal);
-	delete[] paletteChunk;
-
-	byte robotPal[256 * 4];
-
-	for (int i = 0; i < 256; ++i) {
-		_savedPal[i * 4 + 0] = _palette->_sysPalette.colors[i].r;
-		_savedPal[i * 4 + 1] = _palette->_sysPalette.colors[i].g;
-		_savedPal[i * 4 + 2] = _palette->_sysPalette.colors[i].b;
-		_savedPal[i * 4 + 3] = 0;
-	}
-	
-	memcpy(robotPal, _savedPal, sizeof(_savedPal));
-
-	for (int i = 0; i < colorCount; ++i) {
-		int index = i + startIndex;
-		robotPal[index * 4 + 0] = resourcePal.colors[index].r;
-		robotPal[index * 4 + 1] = resourcePal.colors[index].g;
-		robotPal[index * 4 + 2] = resourcePal.colors[index].b;
-		robotPal[index * 4 + 3] = 0;
-	}
-
-	g_system->setPalette(robotPal, 0, 256);
-}
-
-
-void GfxRobot::readFrameSizesChunk() {
-	// The robot video file contains 2 tables, with one entry for each frame:
-	// - A table containing the size of the image in each video frame
-	// - A table containing the total size of each video frame.
-	// In v5 robots, the tables contain 16-bit integers, whereas in v6 robots,
-	// they contain 32-bit integers.
-
-	// TODO: The table reading code can probably be removed once the
-	// audio chunk size is figured out (check the TODO inside processNextFrame())
-#if 0
-	// We don't need any of the two tables to play the video, so we ignore
-	// both of them.
-	uint16 wordSize = _header.version == 6 ? 4 : 2;
-	_robotFile->skip(_header.frameCount * wordSize * 2);
-#else
-	switch (_header.version) {
-	case 4:
-	case 5:		// sizes are 16-bit integers
-		// Skip table with frame image sizes, as we don't need it
-		_robotFile->skip(_header.frameCount * 2);
-		for (int i = 0; i < _header.frameCount; ++i)
-			_frameTotalSize[i] = _robotFile->readUint16();
-		break;
-	case 6:		// sizes are 32-bit integers
-		// Skip table with frame image sizes, as we don't need it
-		_robotFile->skip(_header.frameCount * 4);
-		for (int i = 0; i < _header.frameCount; ++i)
-			_frameTotalSize[i] = _robotFile->readUint32();
-		break;
-	default:
-		error("Can't yet handle index table for robot version %d", _header.version);
-	}
-#endif
-
-	// 2 more unknown tables
-	_robotFile->skip(1024 + 512);
-
-	// Pad to nearest 2 kilobytes
-	uint32 curPos = _robotFile->pos();
-	if (curPos & 0x7ff)
-		_robotFile->seek((curPos & ~0x7ff) + 2048);
-}
-
-void GfxRobot::processNextFrame() {
-	// Make sure that we haven't reached the end of the video already
-	if (_curFrame == _header.frameCount)
-		return;
-
-	// Read frame image header (24 bytes)
-	_robotFile->skip(3);
-	byte frameScale = _robotFile->readByte();
-	uint16 frameWidth = _robotFile->readUint16();
-	uint16 frameHeight = _robotFile->readUint16();
-	_robotFile->skip(8); // x, y, width and height of the frame
-	uint16 compressedSize = _robotFile->readUint16();
-	uint16 frameFragments = _robotFile->readUint16();
-	_robotFile->skip(4); // unknown
-
-	uint32 decompressedSize = frameWidth * (frameHeight * frameScale / 100);
-
-	// Reallocate the output buffer, if its size has increased
-	if (decompressedSize > _outputBufferSize) {
-		delete[] _outputBuffer;
-		_outputBuffer = new byte[decompressedSize];
-	}
-	
-	_outputBufferSize = decompressedSize;
-
-	DecompressorLZS lzs;
-
-	if (_header.version == 4) {
-		// v4 has just the one fragment, it seems, and ignores the fragment count
-		Common::SeekableSubReadStream fragmentStream(_robotFile, _robotFile->pos(), _robotFile->pos() + compressedSize);
-		lzs.unpack(&fragmentStream, _outputBuffer, compressedSize, decompressedSize);
-	} else {
-		byte *outPtr = _outputBuffer;
-
-		for (uint16 i = 0; i < frameFragments; ++i) {
-			uint32 compressedFragmentSize = _robotFile->readUint32();
-			uint32 decompressedFragmentSize = _robotFile->readUint32();
-			uint16 compressionType = _robotFile->readUint16();
-
-			if (compressionType == 0) {
-				Common::SeekableSubReadStream fragmentStream(_robotFile, _robotFile->pos(), _robotFile->pos() + compressedFragmentSize);
-				lzs.unpack(&fragmentStream, outPtr, compressedFragmentSize, decompressedFragmentSize);
-			} else if (compressionType == 2) {	// untested
-				_robotFile->read(outPtr, compressedFragmentSize);
-			} else {
-				error("Unknown frame compression found: %d", compressionType);
-			}
-
-			outPtr += decompressedFragmentSize;
-		}
-	}
-
-	uint32 audioChunkSize = _frameTotalSize[_curFrame] - (24 + compressedSize);
-
-// TODO: The audio chunk size below is usually correct, but there are some
-// exceptions (e.g. robot 4902 in Phantasmagoria, towards its end)
-#if 0
-	// Read frame audio header (14 bytes)
-	_robotFile->skip(2); // buffer position
-	_robotFile->skip(2); // unknown (usually 1)
-	_robotFile->skip(2); /*uint16 audioChunkSize = _robotFile->readUint16() + 8;*/
-	_robotFile->skip(2);
-#endif
-
-	// Queue the next audio frame
-	// FIXME: For some reason, there are audio hiccups/gaps
-	if (_header.hasSound) {
-		_robotFile->skip(8);	// header
-		_audioStream->queueBuffer(g_sci->_audio->getDecodedRobotAudioFrame(_robotFile, audioChunkSize - 8), 
-									(audioChunkSize - 8) * 2, DisposeAfterUse::NO, 
-									Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN);
-	} else {
-		_robotFile->skip(audioChunkSize);
-	}
-
-	// Show frame
-	g_system->copyRectToScreen(_outputBuffer, frameWidth, _x, _y, frameWidth, frameHeight * frameScale / 100);
-	g_system->updateScreen();
-	g_system->delayMillis(100);	// TODO: This isn't quite right
-
-	_curFrame++;
-
-	if (_curFrame == _header.frameCount) {
-		// End of robot video, restore palette
-		g_system->setPalette(_savedPal, 0, 256);
-		freeData();
-	}
-}
-
-void GfxRobot::freeData() {
-	if (_header.hasSound) {
-		g_system->getMixer()->stopHandle(_audioHandle);
-		//delete _audioStream; _audioStream = 0;
-	}
-	delete[] _frameTotalSize; _frameTotalSize = 0;
-	delete[] _outputBuffer; _outputBuffer = 0;
-	_outputBufferSize = 0;
-	delete _robotFile; _robotFile = 0;
-}	
-
-#endif
-
-} // End of namespace Sci

Deleted: scummvm/trunk/engines/sci/graphics/robot.h
===================================================================
--- scummvm/trunk/engines/sci/graphics/robot.h	2011-02-07 09:03:58 UTC (rev 55800)
+++ scummvm/trunk/engines/sci/graphics/robot.h	2011-02-07 12:24:09 UTC (rev 55801)
@@ -1,98 +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 SCI_GRAPHICS_ROBOT_H
-#define SCI_GRAPHICS_ROBOT_H
-
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/decoders/raw.h"
-
-namespace Common {
-	class SeekableSubReadStreamEndian;
-}
-
-namespace Sci {
-
-#ifdef ENABLE_SCI32
-
-struct RobotHeader {
-	// 6 bytes, identifier bytes
-	uint16 version;
-	uint16 audioChunkSize;
-	uint16 audioSilenceSize;
-	// 2 bytes, unknown
-	uint16 frameCount;
-	uint16 paletteDataSize;
-	uint16 unkChunkDataSize;
-	// 5 bytes, unknown
-	byte hasSound;
-	// 34 bytes, unknown
-};
-
-class GfxRobot {
-public:
-	GfxRobot(ResourceManager *resMan, GfxScreen *screen, GfxPalette *palette);
-	~GfxRobot();
-
-	void init(GuiResourceId resourceId, uint16 x, uint16 y);
-	void processNextFrame();
-	uint16 getCurFrame() { return _curFrame; }
-	uint16 getFrameCount() { return _header.frameCount; }
-	bool isPlaying() { return _robotFile != 0; }
-	void playAudio();
-
-private:
-	void readHeaderChunk();
-	void readPaletteChunk();
-	void readFrameSizesChunk();
-
-	void freeData();
-
-	ResourceManager *_resMan;
-	GfxScreen *_screen;
-	GfxPalette *_palette;
-
-	byte _savedPal[256 * 4];
-
-	Common::SeekableSubReadStreamEndian *_robotFile;
-	Audio::QueuingAudioStream *_audioStream;
-	Audio::SoundHandle _audioHandle;
-
-	RobotHeader _header;
-
-	uint16 _x;
-	uint16 _y;
-	uint16 _curFrame;
-	uint32 *_frameTotalSize;
-
-	byte *_outputBuffer;
-	uint32 _outputBufferSize;
-};
-#endif
-
-} // End of namespace Sci
-
-#endif

Modified: scummvm/trunk/engines/sci/module.mk
===================================================================
--- scummvm/trunk/engines/sci/module.mk	2011-02-07 09:03:58 UTC (rev 55800)
+++ scummvm/trunk/engines/sci/module.mk	2011-02-07 12:24:09 UTC (rev 55801)
@@ -79,7 +79,7 @@
 MODULE_OBJS += \
 	graphics/frameout.o \
 	graphics/paint32.o \
-	graphics/robot.o
+	video/robot_decoder.o
 endif
 
 # This module can be built as a plugin

Modified: scummvm/trunk/engines/sci/sci.cpp
===================================================================
--- scummvm/trunk/engines/sci/sci.cpp	2011-02-07 09:03:58 UTC (rev 55800)
+++ scummvm/trunk/engines/sci/sci.cpp	2011-02-07 12:24:09 UTC (rev 55801)
@@ -66,8 +66,8 @@
 #include "sci/graphics/transitions.h"
 
 #ifdef ENABLE_SCI32
-#include "sci/graphics/robot.h"
 #include "sci/graphics/frameout.h"
+#include "sci/video/robot_decoder.h"
 #endif
 
 namespace Sci {
@@ -151,7 +151,7 @@
 	DebugMan.clearAllDebugChannels();
 
 #ifdef ENABLE_SCI32
-	delete _gfxRobot;
+	delete _robotDecoder;
 	delete _gfxFrameout;
 #endif
 	delete _gfxMenu;
@@ -582,7 +582,7 @@
 	_gfxText16 = 0;
 	_gfxTransitions = 0;
 #ifdef ENABLE_SCI32
-	_gfxRobot = 0;
+	_robotDecoder = 0;
 	_gfxFrameout = 0;
 	_gfxPaint32 = 0;
 #endif
@@ -611,7 +611,7 @@
 		_gfxCompare = new GfxCompare(_gamestate->_segMan, _kernel, _gfxCache, _gfxScreen, _gfxCoordAdjuster);
 		_gfxPaint32 = new GfxPaint32(_resMan, _gamestate->_segMan, _kernel, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette);
 		_gfxPaint = _gfxPaint32;
-		_gfxRobot = new GfxRobot(_resMan, _gfxScreen, _gfxPalette);
+		_robotDecoder = new RobotDecoder(g_system->getMixer(), getPlatform() == Common::kPlatformMacintosh);
 		_gfxFrameout = new GfxFrameout(_gamestate->_segMan, _resMan, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette, _gfxPaint32);
 	} else {
 #endif

Modified: scummvm/trunk/engines/sci/sci.h
===================================================================
--- scummvm/trunk/engines/sci/sci.h	2011-02-07 09:03:58 UTC (rev 55800)
+++ scummvm/trunk/engines/sci/sci.h	2011-02-07 12:24:09 UTC (rev 55801)
@@ -77,7 +77,7 @@
 
 #ifdef ENABLE_SCI32
 class SciGui32;
-class GfxRobot;
+class RobotDecoder;
 class GfxFrameout;
 #endif
 
@@ -313,7 +313,7 @@
 	GfxMacIconBar *_gfxMacIconBar; // Mac Icon Bar manager
 
 #ifdef ENABLE_SCI32
-	GfxRobot *_gfxRobot;
+	RobotDecoder *_robotDecoder;
 	GfxFrameout *_gfxFrameout; // kFrameout and the like for 32-bit gfx
 #endif
 

Copied: scummvm/trunk/engines/sci/video/robot_decoder.cpp (from rev 55800, scummvm/trunk/engines/sci/graphics/robot.cpp)
===================================================================
--- scummvm/trunk/engines/sci/video/robot_decoder.cpp	                        (rev 0)
+++ scummvm/trunk/engines/sci/video/robot_decoder.cpp	2011-02-07 12:24:09 UTC (rev 55801)
@@ -0,0 +1,309 @@
+/* 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/debug.h"
+#include "common/endian.h"
+#include "common/archive.h"
+#include "common/stream.h"
+#include "common/system.h"
+#include "common/util.h"
+
+#include "graphics/surface.h"
+#include "sound/decoders/raw.h"
+
+#include "sci/resource.h"
+#include "sci/util.h"
+#include "sci/sound/audio.h"
+#include "sci/video/robot_decoder.h"
+
+namespace Sci {
+
+// TODO:
+// - Positioning
+// - Proper handling of frame scaling - scaled frames look squashed
+//   (probably because both dimensions should be scaled)
+// - Transparency support
+// - Timing - the arbitrary 100ms delay between each frame is not quite right
+// - Proper handling of sound chunks in some cases, so that the frame size
+//   table can be ignored (it's only used to determine the correct sound chunk
+//   size at the moment, cause it can be wrong in some cases)
+// - Fix audio "hiccups" - probably data that shouldn't be in the audio frames
+
+
+// Some non technical information on robot files, from an interview with
+// Greg Tomko-Pavia of Sierra On-Line
+// Taken from http://anthonylarme.tripod.com/phantas/phintgtp.html
+//
+// (...) What we needed was a way of playing video, but have it blend into
+// normal room art instead of occupying its own rectangular area. Room art 
+// consists of a background pic overlaid with various animating cels 
+// (traditional lingo: sprites). The cels each have a priority that determines 
+// who is on top and who is behind in the drawing order. Cels are read from 
+// *.v56 files (another proprietary format). A Robot is video frames with 
+// transparent background including priority and x,y information. Thus, it is 
+// like a cel, except it comes from an RBT - not a v56. Because it blends into
+// our graphics engine, it looks just like a part of the room. A RBT can move 
+// around the screen and go behind other objects. (...)
+
+#ifdef ENABLE_SCI32
+
+RobotDecoder::RobotDecoder(Audio::Mixer *mixer, bool isBigEndian) {
+	_surface = 0;
+	_fileStream = 0;
+	_audioStream = 0;
+	_dirtyPalette = false;
+	_pos = Common::Point(0, 0);
+	_mixer = mixer;
+	_isBigEndian = isBigEndian;
+}
+
+RobotDecoder::~RobotDecoder() {
+	close();
+}
+
+bool RobotDecoder::load(GuiResourceId id) {
+	Common::String fileName = Common::String::format("%d.rbt", id);
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(fileName);
+
+	if (!stream) {
+		warning("Unable to open robot file %s", fileName.c_str());
+		return false;
+	}
+
+	return load(stream);
+}
+
+bool RobotDecoder::load(Common::SeekableReadStream *stream) {
+	close();
+
+	_fileStream = new Common::SeekableSubReadStreamEndian(stream, 0, stream->size(), _isBigEndian, DisposeAfterUse::YES);
+	_surface = new Graphics::Surface();
+
+	readHeaderChunk();
+	
+	// There are several versions of robot files, ranging from 3 to 6.
+	// v3: no known examples
+	// v4: PQ:SWAT demo
+	// v5: SCI2.1 and SCI3 games
+	// v6: SCI3 games
+	if (_header.version < 4 || _header.version > 6)
+		error("Unknown robot version: %d", _header.version);
+
+	if (_header.hasSound) {
+		_audioStream = Audio::makeQueuingAudioStream(11025, false);
+		_mixer->playStream(Audio::Mixer::kMusicSoundType, &_audioHandle, _audioStream);
+	}
+
+	readPaletteChunk();
+	readFrameSizesChunk();
+	return true;
+}
+
+void RobotDecoder::readHeaderChunk() {
+	// Header (60 bytes)
+	_fileStream->skip(6);
+	_header.version = _fileStream->readUint16();
+	_header.audioChunkSize = _fileStream->readUint16();
+	_header.audioSilenceSize = _fileStream->readUint16();
+	_fileStream->skip(2);
+	_header.frameCount = _fileStream->readUint16();
+	_header.paletteDataSize = _fileStream->readUint16();
+	_header.unkChunkDataSize = _fileStream->readUint16();
+	_fileStream->skip(5);
+	_header.hasSound = _fileStream->readByte();
+	_fileStream->skip(34);
+
+	// Some videos (e.g. robot 1305 in Phantasmagoria and
+	// robot 184 in Lighthouse) have an unknown chunk before
+	// the palette chunk (probably used for sound preloading).
+	// Skip it here.
+	if (_header.unkChunkDataSize)
+		_fileStream->skip(_header.unkChunkDataSize);
+}
+
+void RobotDecoder::readPaletteChunk() {
+	byte *paletteData = new byte[_header.paletteDataSize];
+	_fileStream->read(paletteData, _header.paletteDataSize);
+
+	// SCI1.1 palette
+	uint16 palColorStart = READ_SCI11ENDIAN_UINT16(paletteData + 25);
+	uint16 palColorCount = READ_SCI11ENDIAN_UINT16(paletteData + 29);
+
+	int palOffset = 37;
+	memset(_palette, 0, 256 * 3);
+
+	for (uint16 colorNo = palColorStart; colorNo < palColorStart + palColorCount; colorNo++) {
+		_palette[colorNo * 3 + 0] = paletteData[palOffset++];
+		_palette[colorNo * 3 + 1] = paletteData[palOffset++];
+		_palette[colorNo * 3 + 2] = paletteData[palOffset++];
+	}
+
+	_dirtyPalette = true;
+	delete[] paletteData;
+}
+
+
+void RobotDecoder::readFrameSizesChunk() {
+	// The robot video file contains 2 tables, with one entry for each frame:
+	// - A table containing the size of the image in each video frame
+	// - A table containing the total size of each video frame.
+	// In v5 robots, the tables contain 16-bit integers, whereas in v6 robots,
+	// they contain 32-bit integers.
+
+	_frameTotalSize = new uint32[_header.frameCount];
+
+	// TODO: The table reading code can probably be removed once the
+	// audio chunk size is figured out (check the TODO inside processNextFrame())
+#if 0
+	// We don't need any of the two tables to play the video, so we ignore
+	// both of them.
+	uint16 wordSize = _header.version == 6 ? 4 : 2;
+	_fileStream->skip(_header.frameCount * wordSize * 2);
+#else
+	switch (_header.version) {
+	case 4:
+	case 5:		// sizes are 16-bit integers
+		// Skip table with frame image sizes, as we don't need it
+		_fileStream->skip(_header.frameCount * 2);
+		for (int i = 0; i < _header.frameCount; ++i)
+			_frameTotalSize[i] = _fileStream->readUint16();
+		break;
+	case 6:		// sizes are 32-bit integers
+		// Skip table with frame image sizes, as we don't need it
+		_fileStream->skip(_header.frameCount * 4);
+		for (int i = 0; i < _header.frameCount; ++i)
+			_frameTotalSize[i] = _fileStream->readUint32();
+		break;
+	default:
+		error("Can't yet handle index table for robot version %d", _header.version);
+	}
+#endif
+
+	// 2 more unknown tables
+	_fileStream->skip(1024 + 512);
+
+	// Pad to nearest 2 kilobytes
+	uint32 curPos = _fileStream->pos();
+	if (curPos & 0x7ff)
+		_fileStream->seek((curPos & ~0x7ff) + 2048);
+}
+
+const Graphics::Surface *RobotDecoder::decodeNextFrame() {
+	// Read frame image header (24 bytes)
+	_fileStream->skip(3);
+	byte frameScale = _fileStream->readByte();
+	uint16 frameWidth = _fileStream->readUint16();
+	uint16 frameHeight = _fileStream->readUint16();
+	_fileStream->skip(8); // x, y, width and height of the frame
+	uint16 compressedSize = _fileStream->readUint16();
+	uint16 frameFragments = _fileStream->readUint16();
+	_fileStream->skip(4); // unknown
+
+	uint32 decompressedSize = frameWidth * frameHeight * frameScale / 100;
+	_surface->free();
+	_surface->create(frameWidth, frameHeight, 1);
+	_surface->w = frameWidth * frameScale / 100;
+
+	DecompressorLZS lzs;
+
+	if (_header.version == 4) {
+		// v4 has just the one fragment, it seems, and ignores the fragment count
+		Common::SeekableSubReadStream fragmentStream(_fileStream, _fileStream->pos(), _fileStream->pos() + compressedSize);
+		lzs.unpack(&fragmentStream, (byte *)_surface->pixels, compressedSize, decompressedSize);
+	} else {
+		byte *outPtr = (byte *)_surface->pixels;
+
+		for (uint16 i = 0; i < frameFragments; ++i) {
+			uint32 compressedFragmentSize = _fileStream->readUint32();
+			uint32 decompressedFragmentSize = _fileStream->readUint32();
+			uint16 compressionType = _fileStream->readUint16();
+
+			if (compressionType == 0) {
+				Common::SeekableSubReadStream fragmentStream(_fileStream, _fileStream->pos(), _fileStream->pos() + compressedFragmentSize);
+				lzs.unpack(&fragmentStream, outPtr, compressedFragmentSize, decompressedFragmentSize);
+			} else if (compressionType == 2) {	// untested
+				_fileStream->read(outPtr, compressedFragmentSize);
+			} else {
+				error("Unknown frame compression found: %d", compressionType);
+			}
+
+			outPtr += decompressedFragmentSize;
+		}
+	}
+
+	// +1 because we start with frame number -1
+	uint32 audioChunkSize = _frameTotalSize[_curFrame + 1] - (24 + compressedSize);
+
+// TODO: The audio chunk size below is usually correct, but there are some
+// exceptions (e.g. robot 4902 in Phantasmagoria, towards its end)
+#if 0
+	// Read frame audio header (14 bytes)
+	_fileStream->skip(2); // buffer position
+	_fileStream->skip(2); // unknown (usually 1)
+	_fileStream->skip(2); /*uint16 audioChunkSize = _fileStream->readUint16() + 8;*/
+	_fileStream->skip(2);
+#endif
+
+	// Queue the next audio frame
+	// FIXME: For some reason, there are audio hiccups/gaps
+	if (_header.hasSound) {
+		_fileStream->skip(8);	// header
+		_audioStream->queueBuffer(g_sci->_audio->getDecodedRobotAudioFrame(_fileStream, audioChunkSize - 8), 
+									(audioChunkSize - 8) * 2, DisposeAfterUse::NO, 
+									Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN);
+	} else {
+		_fileStream->skip(audioChunkSize);
+	}
+
+	if (_curFrame == -1)
+		_startTime = g_system->getMillis();
+
+	_curFrame++;
+
+	return _surface;
+}
+
+void RobotDecoder::close() {
+	if (!_fileStream)
+		return;
+
+	delete _fileStream;
+	_fileStream = 0;
+
+	_surface->free();
+	delete _surface;
+	_surface = 0;
+
+	if (_header.hasSound) {
+		_mixer->stopHandle(_audioHandle);
+		//delete _audioStream; _audioStream = 0;
+	}
+
+	reset();
+}	
+
+#endif
+
+} // End of namespace Sci

Copied: scummvm/trunk/engines/sci/video/robot_decoder.h (from rev 55799, scummvm/trunk/engines/sci/graphics/robot.h)
===================================================================
--- scummvm/trunk/engines/sci/video/robot_decoder.h	                        (rev 0)
+++ scummvm/trunk/engines/sci/video/robot_decoder.h	2011-02-07 12:24:09 UTC (rev 55801)
@@ -0,0 +1,104 @@
+/* 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 SCI_VIDEO_ROBOT_DECODER_H
+#define SCI_VIDEO_ROBOT_DECODER_H
+
+#include "common/rational.h"
+#include "common/rect.h"
+#include "common/stream.h"
+#include "common/substream.h"
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "video/video_decoder.h"
+
+namespace Sci {
+
+#ifdef ENABLE_SCI32
+
+struct RobotHeader {
+	// 6 bytes, identifier bytes
+	uint16 version;
+	uint16 audioChunkSize;
+	uint16 audioSilenceSize;
+	// 2 bytes, unknown
+	uint16 frameCount;
+	uint16 paletteDataSize;
+	uint16 unkChunkDataSize;
+	// 5 bytes, unknown
+	byte hasSound;
+	// 34 bytes, unknown
+};
+
+class RobotDecoder : public Video::FixedRateVideoDecoder {
+public:
+	RobotDecoder(Audio::Mixer *mixer, bool isBigEndian);
+	virtual ~RobotDecoder();
+
+	bool load(Common::SeekableReadStream *stream);
+	bool load(GuiResourceId id);
+	void close();
+
+	bool isVideoLoaded() const { return _fileStream != 0; }
+	uint16 getWidth() const { assert(_surface); return _surface->w; }
+	uint16 getHeight() const { assert(_surface); return _surface->h; }
+	uint16 getPitch() const { assert(_surface); return _surface->pitch; }
+	uint32 getFrameCount() const { return _header.frameCount; }
+	const Graphics::Surface *decodeNextFrame();
+	Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
+	const byte *getPalette() { _dirtyPalette = false; return _palette; }
+	bool hasDirtyPalette() const { return _dirtyPalette; }
+	void setPos(uint16 x, uint16 y) { _pos = Common::Point(x, y); }
+	Common::Point getPos() const { return _pos; }
+
+protected:
+	Common::Rational getFrameRate() const { return Common::Rational(60, 10); }
+
+private:
+	void readHeaderChunk();
+	void readPaletteChunk();
+	void readFrameSizesChunk();
+
+	void freeData();
+
+	RobotHeader _header;
+	Common::Point _pos;
+	bool _isBigEndian;
+
+	Common::SeekableSubReadStreamEndian *_fileStream;
+
+	uint32 *_frameTotalSize;
+	byte _palette[256 * 3];
+	bool _dirtyPalette;
+	Graphics::Surface *_surface;
+	Audio::QueuingAudioStream *_audioStream;
+	Audio::SoundHandle _audioHandle;
+	Audio::Mixer *_mixer;
+};
+#endif
+
+} // End of namespace Sci
+
+#endif


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list