From 600d5199fcc9728e70972d2b27d60a8b591b100c Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 16 Oct 2009 08:26:41 +0000 Subject: Moved the SEQ decoder outside the gfx directory, as it is completely stand alone now and no longer uses any GUI-related code svn-id: r45153 --- dists/msvc8/sci.vcproj | 4 +- dists/msvc9/sci.vcproj | 4 +- engines/sci/engine/kgraphics.cpp | 2 +- engines/sci/gfx/seq_decoder.cpp | 237 --------------------------------------- engines/sci/gfx/seq_decoder.h | 68 ----------- engines/sci/module.mk | 2 +- engines/sci/seq_decoder.cpp | 237 +++++++++++++++++++++++++++++++++++++++ engines/sci/seq_decoder.h | 67 +++++++++++ 8 files changed, 310 insertions(+), 311 deletions(-) delete mode 100644 engines/sci/gfx/seq_decoder.cpp delete mode 100644 engines/sci/gfx/seq_decoder.h create mode 100644 engines/sci/seq_decoder.cpp create mode 100644 engines/sci/seq_decoder.h diff --git a/dists/msvc8/sci.vcproj b/dists/msvc8/sci.vcproj index 20f09824e0..9065c2ce7b 100644 --- a/dists/msvc8/sci.vcproj +++ b/dists/msvc8/sci.vcproj @@ -87,8 +87,6 @@ - - @@ -160,6 +158,8 @@ + + diff --git a/dists/msvc9/sci.vcproj b/dists/msvc9/sci.vcproj index cdb743fd6e..9ecffa953c 100644 --- a/dists/msvc9/sci.vcproj +++ b/dists/msvc9/sci.vcproj @@ -88,8 +88,6 @@ - - @@ -161,6 +159,8 @@ + + diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index e899c22466..fb84a34140 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -30,12 +30,12 @@ #include "sci/sci.h" #include "sci/debug.h" // for g_debug_sleeptime_factor #include "sci/resource.h" +#include "sci/seq_decoder.h" #include "sci/engine/state.h" #include "sci/engine/kernel.h" #include "sci/gfx/gfx_gui.h" #include "sci/gfx/gfx_widgets.h" #include "sci/gfx/gfx_state_internal.h" // required for GfxContainer, GfxPort, GfxVisual -#include "sci/gfx/seq_decoder.h" #include "sci/gui/gui.h" #include "sci/gui/gui_cursor.h" #include "sci/gui/gui_screen.h" diff --git a/engines/sci/gfx/seq_decoder.cpp b/engines/sci/gfx/seq_decoder.cpp deleted file mode 100644 index c5978c39bf..0000000000 --- a/engines/sci/gfx/seq_decoder.cpp +++ /dev/null @@ -1,237 +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 "common/debug.h" -#include "common/endian.h" -#include "common/archive.h" -#include "common/system.h" -#include "common/util.h" - -#include "graphics/surface.h" - -#include "sci/gfx/seq_decoder.h" - -namespace Graphics { - -enum seqPalTypes { - kSeqPalVariable = 0, - kSeqPalConstant = 1 -}; - -enum seqFrameTypes { - kSeqFrameFull = 0, - kSeqFrameDiff = 1 -}; - -SeqDecoder::~SeqDecoder() { - closeFile(); -} - -bool SeqDecoder::loadFile(const char *fileName, int frameDelay) { - closeFile(); - - _fileStream = SearchMan.createReadStreamForMember(fileName); - if (!_fileStream) - return false; - - // Seek to the first frame - _videoInfo.currentFrame = 0; - - _videoInfo.width = 320; - _videoInfo.height = 200; - _videoInfo.frameCount = _fileStream->readUint16LE(); - // Our frameDelay is calculated in 1/100 ms, so we convert it here - _videoInfo.frameDelay = 100 * frameDelay * 1000 / 60; - _videoFrameBuffer = new byte[_videoInfo.width * _videoInfo.height]; - - // Set palette - int paletteSize = _fileStream->readUint32LE(); - - byte *paletteData = new byte[paletteSize]; - _fileStream->read(paletteData, paletteSize); - - // SCI1.1 palette - byte palFormat = paletteData[32]; - uint16 palColorStart = READ_LE_UINT16(paletteData + 25); - uint16 palColorCount = READ_LE_UINT16(paletteData + 29); - - byte palette[256 * 4]; - int palOffset = 37; - - for (uint16 colorNo = palColorStart; colorNo < palColorStart + palColorCount; colorNo++) { - if (palFormat == kSeqPalVariable) - palOffset++; - palette[colorNo * 4 + 0] = paletteData[palOffset++]; - palette[colorNo * 4 + 1] = paletteData[palOffset++]; - palette[colorNo * 4 + 2] = paletteData[palOffset++]; - palette[colorNo * 4 + 3] = 0; - } - - g_system->setPalette(palette, 0, 256); - - delete paletteData; - - _videoInfo.firstframeOffset = _fileStream->pos(); - - return true; -} - -void SeqDecoder::closeFile() { - if (!_fileStream) - return; - - delete _fileStream; - _fileStream = 0; - - delete[] _videoFrameBuffer; - _videoFrameBuffer = 0; -} - -bool SeqDecoder::decodeNextFrame() { - int16 frameWidth = _fileStream->readUint16LE(); - int16 frameHeight = _fileStream->readUint16LE(); - int16 frameLeft = _fileStream->readUint16LE(); - int16 frameTop = _fileStream->readUint16LE(); - byte colorKey = _fileStream->readByte(); - byte frameType = _fileStream->readByte(); - _fileStream->skip(2); - uint16 frameSize = _fileStream->readUint16LE(); - _fileStream->skip(2); - uint16 rleSize = _fileStream->readUint16LE(); - _fileStream->skip(6); - uint32 offset = _fileStream->readUint32LE(); - - _fileStream->seek(offset); - - if (_videoInfo.currentFrame == 0) - _videoInfo.startTime = g_system->getMillis(); - - if (frameType == kSeqFrameFull) { - if (frameLeft != 0 && frameWidth != 320) { - // This case should never happen, but apparently it does in the - // seagulls video in KQ6 CD (most likely due to bad/incomplete data) - _fileStream->skip(frameSize); - } else { - _fileStream->read(_videoFrameBuffer + 320 * frameTop, frameSize); - } - } else { - byte *buf = new byte[frameSize]; - _fileStream->read(buf, frameSize); - decodeFrame(buf, rleSize, buf + rleSize, frameSize - rleSize, _videoFrameBuffer + 320 * frameTop, frameLeft, frameWidth, frameHeight, colorKey); - delete buf; - } - - return ++_videoInfo.currentFrame < _videoInfo.frameCount; -} - -#define WRITE_TO_BUFFER(n) \ - if (writeRow * 320 + writeCol + (n) > 320 * height) { \ - warning("SEQ player: writing out of bounds, aborting"); \ - return false; \ - } \ - if (litPos + (n) > litSize) { \ - warning("SEQ player: reading out of bounds, aborting"); \ - } \ - memcpy(dest + writeRow * 320 + writeCol, litData + litPos, n); - -bool SeqDecoder::decodeFrame(byte *rleData, int rleSize, byte *litData, int litSize, byte *dest, int left, int width, int height, int colorKey) { - int writeRow = 0; - int writeCol = left; - int litPos = 0; - int rlePos = 0; - - while (rlePos < rleSize) { - int op = rleData[rlePos++]; - - if ((op & 0xc0) == 0xc0) { - op &= 0x3f; - if (op == 0) { - // Go to next line in target buffer - writeRow++; - writeCol = left; - } else { - // Skip bytes on current line - writeCol += op; - } - } else if (op & 0x80) { - op &= 0x3f; - if (op == 0) { - // Copy remainder of current line - int rem = width - (writeCol - left); - - WRITE_TO_BUFFER(rem); - writeRow++; - writeCol = left; - litPos += rem; - } else { - // Copy bytes - WRITE_TO_BUFFER(op); - writeCol += op; - litPos += op; - } - } else { - uint16 count = ((op & 7) << 8) | rleData[rlePos++]; - - switch (op >> 3) { - case 2: - // Skip bytes - writeCol += count; - break; - case 3: - // Copy bytes - WRITE_TO_BUFFER(count); - writeCol += count; - litPos += count; - break; - case 6: { - // Copy rows - if (count == 0) - count = height - writeRow; - - for (int i = 0; i < count; i++) { - WRITE_TO_BUFFER(width); - litPos += width; - writeRow++; - } - break; - } - case 7: - // Skip rows - if (count == 0) - count = height - writeRow; - - writeRow += count; - break; - default: - warning("Unsupported operation %i encountered", op >> 3); - return false; - } - } - } - - return true; -} - -} // End of namespace Graphics diff --git a/engines/sci/gfx/seq_decoder.h b/engines/sci/gfx/seq_decoder.h deleted file mode 100644 index d4b9840d76..0000000000 --- a/engines/sci/gfx/seq_decoder.h +++ /dev/null @@ -1,68 +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 SEQ_DECODER_H -#define SEQ_DECODER_H - -#include "graphics/video/video_player.h" - -namespace Graphics { - -/** - * Implementation of the KQ6 DOS floppy/CD SEQ decoder - */ -class SeqDecoder : public VideoDecoder { -public: - SeqDecoder() {} - virtual ~SeqDecoder(); - - /** - * Load a SEQ encoded video file - * @param filename the filename to load - * @param frameDelay the delay between frames, in ms - */ - bool loadFile(const char *fileName) { return loadFile(fileName, 10); } - - /** - * Load a SEQ encoded video file - * @param filename the filename to load - * @param frameDelay the delay between frames, in ms - */ - bool loadFile(const char *fileName, int frameDelay); - - /** - * Close a SEQ encoded video file - */ - void closeFile(); - - bool decodeNextFrame(); - -private: - bool decodeFrame(byte *rleData, int rleSize, byte *litData, int litSize, byte *dest, int left, int width, int height, int colorKey); -}; - -} // End of namespace Graphics - -#endif diff --git a/engines/sci/module.mk b/engines/sci/module.mk index 6cd2cc0db7..26962db9c2 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -6,6 +6,7 @@ MODULE_OBJS = \ detection.o \ resource.o \ sci.o \ + seq_decoder.o \ tools.o \ vocabulary.o \ engine/game.o \ @@ -52,7 +53,6 @@ MODULE_OBJS = \ gfx/res_pal.o \ gfx/res_pic.o \ gfx/res_view.o \ - gfx/seq_decoder.o \ gui/gui.o \ gui/gui_animate.o \ gui/gui_cursor.o \ diff --git a/engines/sci/seq_decoder.cpp b/engines/sci/seq_decoder.cpp new file mode 100644 index 0000000000..3999abc0b5 --- /dev/null +++ b/engines/sci/seq_decoder.cpp @@ -0,0 +1,237 @@ +/* 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/system.h" +#include "common/util.h" + +#include "graphics/surface.h" + +#include "sci/seq_decoder.h" + +namespace Graphics { + +enum seqPalTypes { + kSeqPalVariable = 0, + kSeqPalConstant = 1 +}; + +enum seqFrameTypes { + kSeqFrameFull = 0, + kSeqFrameDiff = 1 +}; + +SeqDecoder::~SeqDecoder() { + closeFile(); +} + +bool SeqDecoder::loadFile(const char *fileName, int frameDelay) { + closeFile(); + + _fileStream = SearchMan.createReadStreamForMember(fileName); + if (!_fileStream) + return false; + + // Seek to the first frame + _videoInfo.currentFrame = 0; + + _videoInfo.width = 320; + _videoInfo.height = 200; + _videoInfo.frameCount = _fileStream->readUint16LE(); + // Our frameDelay is calculated in 1/100 ms, so we convert it here + _videoInfo.frameDelay = 100 * frameDelay * 1000 / 60; + _videoFrameBuffer = new byte[_videoInfo.width * _videoInfo.height]; + + // Set palette + int paletteSize = _fileStream->readUint32LE(); + + byte *paletteData = new byte[paletteSize]; + _fileStream->read(paletteData, paletteSize); + + // SCI1.1 palette + byte palFormat = paletteData[32]; + uint16 palColorStart = READ_LE_UINT16(paletteData + 25); + uint16 palColorCount = READ_LE_UINT16(paletteData + 29); + + byte palette[256 * 4]; + int palOffset = 37; + + for (uint16 colorNo = palColorStart; colorNo < palColorStart + palColorCount; colorNo++) { + if (palFormat == kSeqPalVariable) + palOffset++; + palette[colorNo * 4 + 0] = paletteData[palOffset++]; + palette[colorNo * 4 + 1] = paletteData[palOffset++]; + palette[colorNo * 4 + 2] = paletteData[palOffset++]; + palette[colorNo * 4 + 3] = 0; + } + + g_system->setPalette(palette, 0, 256); + + delete paletteData; + + _videoInfo.firstframeOffset = _fileStream->pos(); + + return true; +} + +void SeqDecoder::closeFile() { + if (!_fileStream) + return; + + delete _fileStream; + _fileStream = 0; + + delete[] _videoFrameBuffer; + _videoFrameBuffer = 0; +} + +bool SeqDecoder::decodeNextFrame() { + int16 frameWidth = _fileStream->readUint16LE(); + int16 frameHeight = _fileStream->readUint16LE(); + int16 frameLeft = _fileStream->readUint16LE(); + int16 frameTop = _fileStream->readUint16LE(); + byte colorKey = _fileStream->readByte(); + byte frameType = _fileStream->readByte(); + _fileStream->skip(2); + uint16 frameSize = _fileStream->readUint16LE(); + _fileStream->skip(2); + uint16 rleSize = _fileStream->readUint16LE(); + _fileStream->skip(6); + uint32 offset = _fileStream->readUint32LE(); + + _fileStream->seek(offset); + + if (_videoInfo.currentFrame == 0) + _videoInfo.startTime = g_system->getMillis(); + + if (frameType == kSeqFrameFull) { + if (frameLeft != 0 && frameWidth != 320) { + // This case should never happen, but apparently it does in the + // seagulls video in KQ6 CD (most likely due to bad/incomplete data) + _fileStream->skip(frameSize); + } else { + _fileStream->read(_videoFrameBuffer + 320 * frameTop, frameSize); + } + } else { + byte *buf = new byte[frameSize]; + _fileStream->read(buf, frameSize); + decodeFrame(buf, rleSize, buf + rleSize, frameSize - rleSize, _videoFrameBuffer + 320 * frameTop, frameLeft, frameWidth, frameHeight, colorKey); + delete buf; + } + + return ++_videoInfo.currentFrame < _videoInfo.frameCount; +} + +#define WRITE_TO_BUFFER(n) \ + if (writeRow * 320 + writeCol + (n) > 320 * height) { \ + warning("SEQ player: writing out of bounds, aborting"); \ + return false; \ + } \ + if (litPos + (n) > litSize) { \ + warning("SEQ player: reading out of bounds, aborting"); \ + } \ + memcpy(dest + writeRow * 320 + writeCol, litData + litPos, n); + +bool SeqDecoder::decodeFrame(byte *rleData, int rleSize, byte *litData, int litSize, byte *dest, int left, int width, int height, int colorKey) { + int writeRow = 0; + int writeCol = left; + int litPos = 0; + int rlePos = 0; + + while (rlePos < rleSize) { + int op = rleData[rlePos++]; + + if ((op & 0xc0) == 0xc0) { + op &= 0x3f; + if (op == 0) { + // Go to next line in target buffer + writeRow++; + writeCol = left; + } else { + // Skip bytes on current line + writeCol += op; + } + } else if (op & 0x80) { + op &= 0x3f; + if (op == 0) { + // Copy remainder of current line + int rem = width - (writeCol - left); + + WRITE_TO_BUFFER(rem); + writeRow++; + writeCol = left; + litPos += rem; + } else { + // Copy bytes + WRITE_TO_BUFFER(op); + writeCol += op; + litPos += op; + } + } else { + uint16 count = ((op & 7) << 8) | rleData[rlePos++]; + + switch (op >> 3) { + case 2: + // Skip bytes + writeCol += count; + break; + case 3: + // Copy bytes + WRITE_TO_BUFFER(count); + writeCol += count; + litPos += count; + break; + case 6: { + // Copy rows + if (count == 0) + count = height - writeRow; + + for (int i = 0; i < count; i++) { + WRITE_TO_BUFFER(width); + litPos += width; + writeRow++; + } + break; + } + case 7: + // Skip rows + if (count == 0) + count = height - writeRow; + + writeRow += count; + break; + default: + warning("Unsupported operation %i encountered", op >> 3); + return false; + } + } + } + + return true; +} + +} // End of namespace Graphics diff --git a/engines/sci/seq_decoder.h b/engines/sci/seq_decoder.h new file mode 100644 index 0000000000..a734b52fb2 --- /dev/null +++ b/engines/sci/seq_decoder.h @@ -0,0 +1,67 @@ +/* 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 SEQ_DECODER_H +#define SEQ_DECODER_H + +#include "graphics/video/video_player.h" + +namespace Graphics { + +/** + * Implementation of the KQ6 DOS floppy/CD SEQ decoder + */ +class SeqDecoder : public VideoDecoder { +public: + SeqDecoder() {} + virtual ~SeqDecoder(); + + /** + * Load a SEQ encoded video file + * @param filename the filename to load + */ + bool loadFile(const char *fileName) { return loadFile(fileName, 10); } + + /** + * Load a SEQ encoded video file + * @param filename the filename to load + * @param frameDelay the delay between frames, in ms + */ + bool loadFile(const char *fileName, int frameDelay); + + /** + * Close a SEQ encoded video file + */ + void closeFile(); + + bool decodeNextFrame(); + +private: + bool decodeFrame(byte *rleData, int rleSize, byte *litData, int litSize, byte *dest, int left, int width, int height, int colorKey); +}; + +} // End of namespace Graphics + +#endif -- cgit v1.2.3