From a02461fcb15da3b2e7e91d9cfb1bca559a1d277b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 19 Mar 2015 19:49:42 -0400 Subject: SHERLOCK: Refactorings, new Sprite and People classes --- engines/sherlock/animation.cpp | 23 +++--- engines/sherlock/events.cpp | 10 +-- engines/sherlock/events.h | 4 +- engines/sherlock/module.mk | 3 +- engines/sherlock/people.cpp | 73 +++++++++++++++++ engines/sherlock/people.h | 57 ++++++++++++++ engines/sherlock/resources.cpp | 121 ++++++++++++++++++++++++++++ engines/sherlock/resources.h | 29 +++++++ engines/sherlock/scalpel/scalpel.cpp | 16 ++-- engines/sherlock/scene.cpp | 19 ++++- engines/sherlock/scene.h | 13 +++- engines/sherlock/sherlock.cpp | 5 +- engines/sherlock/sherlock.h | 2 + engines/sherlock/sprite.cpp | 147 ----------------------------------- engines/sherlock/sprite.h | 65 ---------------- engines/sherlock/sprites.cpp | 27 +++++++ engines/sherlock/sprites.h | 83 ++++++++++++++++++++ 17 files changed, 451 insertions(+), 246 deletions(-) create mode 100644 engines/sherlock/people.cpp create mode 100644 engines/sherlock/people.h delete mode 100644 engines/sherlock/sprite.cpp delete mode 100644 engines/sherlock/sprite.h create mode 100644 engines/sherlock/sprites.cpp create mode 100644 engines/sherlock/sprites.h diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 6788cc51d7..2b12005079 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -22,7 +22,6 @@ #include "sherlock/animation.h" #include "sherlock/sherlock.h" -#include "sherlock/sprite.h" #include "common/algorithm.h" namespace Sherlock { @@ -95,7 +94,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f // Load initial image Common::String vdaName = baseName + ".vda"; - Sprite sprite(vdaName, true); + ImageFile images(vdaName, true); events.wait(minDelay); if (fade != 0 && fade != 255) @@ -103,37 +102,37 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f if (setPalette) { if (fade != 255) - screen.setPalette(sprite._palette); + screen.setPalette(images._palette); } int frameNumber = 0; - int spriteFrame; + int imageFrame; Common::Point pt; bool skipped = false; while (!_vm->shouldQuit()) { // Get the next sprite to display - spriteFrame = stream->readSint16LE(); + imageFrame = stream->readSint16LE(); - if (spriteFrame == -2) { + if (imageFrame == -2) { // End of animation reached break; - } else if (spriteFrame != -1) { + } else if (imageFrame != -1) { // Read position from either animation stream or the sprite frame itself - if (spriteFrame < 0) { - spriteFrame += 32769; + if (imageFrame < 0) { + imageFrame += 32769; pt.x = stream->readUint16LE(); pt.y = stream->readUint16LE(); } else { - pt = sprite[spriteFrame]._position; + pt = images[imageFrame]._position; } // Draw the sprite - screen.transBlitFrom(sprite[spriteFrame]._frame, pt); + screen.transBlitFrom(images[imageFrame]._frame, pt); } else { // No sprite to show for this animation frame if (fade == 255) { // Gradual fade in - if (screen.equalizePalette(sprite._palette) == 0) + if (screen.equalizePalette(images._palette) == 0) fade = 0; } diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 1a882eedea..ecdbdbe8d7 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -32,7 +32,7 @@ namespace Sherlock { EventsManager::EventsManager(SherlockEngine *vm) { _vm = vm; - _cursorSprites = nullptr; + _cursorImages = nullptr; _cursorIndex = -1; _frameCounter = 1; _priorFrameTime = 0; @@ -41,7 +41,7 @@ EventsManager::EventsManager(SherlockEngine *vm) { } EventsManager::~EventsManager() { - delete _cursorSprites; + delete _cursorImages; } /** @@ -49,9 +49,9 @@ EventsManager::~EventsManager() { */ void EventsManager::loadCursors(const Common::String &filename) { hideCursor(); - delete _cursorSprites; + delete _cursorImages; - _cursorSprites = new Sprite(filename); + _cursorImages = new ImageFile(filename); } /** @@ -61,7 +61,7 @@ void EventsManager::changeCursor(int cursorIndex) { _cursorIndex = cursorIndex; // Set the cursor data - Graphics::Surface &s = (*_cursorSprites)[cursorIndex]; + Graphics::Surface &s = (*_cursorImages)[cursorIndex]; CursorMan.replaceCursor(s.getPixels(), s.w, s.h, s.w / 2, s.h / 2, 0xff); showCursor(); diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index 1f7352eeb5..0fa6bf3a5e 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -26,7 +26,7 @@ #include "common/scummsys.h" #include "common/events.h" #include "common/stack.h" -#include "sherlock/sprite.h" +#include "sherlock/resources.h" namespace Sherlock { @@ -41,7 +41,7 @@ private: uint32 _frameCounter; uint32 _priorFrameTime; Common::Point _mousePos; - Sprite *_cursorSprites; + ImageFile *_cursorImages; bool checkForNextFrameCounter(); public: diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index eef27aa0b1..865b422ef9 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -12,12 +12,13 @@ MODULE_OBJS = \ events.o \ graphics.o \ journal.o \ + people.o \ resources.o \ scene.o \ screen.o \ sherlock.o \ sound.o \ - sprite.o \ + sprites.o \ talk.o # This module can be built as a plugin diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp new file mode 100644 index 0000000000..53ccaf5baf --- /dev/null +++ b/engines/sherlock/people.cpp @@ -0,0 +1,73 @@ +/* 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. + * + */ + +#include "sherlock/people.h" + +namespace Sherlock { + +// Characer animation sequences +static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = { + { 29, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Right + { 22, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Down + { 29, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Left + { 15, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Up + { 42, 1, 2, 3, 4, 5, 0 }, // Goto Stand Right + { 47, 1, 2, 3, 4, 5, 0 }, // Goto Stand Down + { 42, 1, 2, 3, 4, 5, 0 }, // Goto Stand Left + { 36, 1, 0 }, // Goto Stand Up + { 8, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Up Right + { 1, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Down Right + { 8, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Up Left + { 1, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Down Left + { 37, 1, 2, 3, 4, 5, 0 }, // Goto Stand Up Right + { 37, 1, 2, 3, 4, 5, 0 }, // Goto Stand Up Left + { 52, 1, 2, 3, 4, 0 }, // Goto Stand Down Right + { 52, 1, 2, 3, 4, 0 } // Goto Stand Down Left +}; + + +People::People(SherlockEngine *vm) : _vm(vm) { +} + +void People::reset() { + Sprite &p = _data[PLAYER]; + + p._description = "Sherlock Holmes!"; + p._type = CHARACTER; + p._position = Common::Point(10000, 11000); + p._sequenceNumber = STOP_DOWNRIGHT; + p._sequences = &CHARACTER_SEQUENCES; + p._spriteFrame = nullptr; + p._frameNumber = 1; + p._movement = Common::Point(0, 0); + p._oldPosition = Common::Point(0, 0); + p._oldSize = Common::Point(0, 0); + p._misc = 0; + p._walkCount = 0; + p._pickUp = ""; + p._allow = 0; + p._noShapeSize = Common::Point(0, 0); + p._goto = Common::Point(0, 0); + p._status = 0; +} + +} // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h new file mode 100644 index 0000000000..4ca7f51444 --- /dev/null +++ b/engines/sherlock/people.h @@ -0,0 +1,57 @@ +/* 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. + * + */ + +#ifndef SHERLOCK_PEOPLE_H +#define SHERLOCK_PEOPLE_H + +#include "common/scummsys.h" +#include "sherlock/sprites.h" + +namespace Sherlock { + +#define MAX_PEOPLE 2 +#define PLAYER 0 + +// Animation sequence identifiers for characters +enum { + WALK_RIGHT = 0, WALK_DOWN = 1, WALK_LEFT = 2, WALK_UP = 3, STOP_LEFT = 4, + STOP_DOWN = 5, STOP_RIGHT = 6, STOP_UP = 7, WALK_UPRIGHT = 8, + WALK_DOWNRIGHT = 9, WALK_UPLEFT = 10, WALK_DOWNLEFT = 11, + STOP_UPRIGHT = 12, STOP_UPLEFT = 13, STOP_DOWNRIGHT = 14, + STOP_DOWNLEFT = 15, TALK_RIGHT = 6, TALK_LEFT = 4 +}; + +class SherlockEngine; + +class People { +private: + SherlockEngine *_vm; + Sprite _data[MAX_PEOPLE]; +public: + People(SherlockEngine *vm); + + void reset(); +}; + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 6636ca5be8..cdea7bd296 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -22,6 +22,8 @@ #include "sherlock/resources.h" #include "sherlock/decompress.h" +#include "sherlock/screen.h" +#include "sherlock/sherlock.h" #include "common/debug.h" namespace Sherlock { @@ -241,4 +243,123 @@ int Resources::resourceIndex() const { return _resourceIndex; } +/*----------------------------------------------------------------*/ + +SherlockEngine *ImageFile::_vm; + +void ImageFile::setVm(SherlockEngine *vm) { + _vm = vm; +} + +ImageFile::ImageFile(const Common::String &name, bool skipPal) { + Common::SeekableReadStream *stream = _vm->_res->load(name); + + Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); + load(*stream, skipPal); + + delete stream; +} + +ImageFile::ImageFile(Common::SeekableReadStream &stream, bool skipPal) { + Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); + load(stream, skipPal); +} + +ImageFile::~ImageFile() { + for (uint idx = 0; idx < size(); ++idx) + (*this)[idx]._frame.free(); +} + +/** + * Load the data of the sprite + */ +void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) { + loadPalette(stream); + + while (stream.pos() < stream.size()) { + ImageFrame frame; + frame._width = stream.readUint16LE() + 1; + frame._height = stream.readUint16LE() + 1; + frame._flags = stream.readByte(); + frame._position.x = stream.readUint16LE(); + frame._position.y = stream.readByte(); + + frame._rleEncoded = !skipPalette && (frame._position.x == 1); + + if (frame._flags & 0xFF) { + // Nibble packed frame data + frame._size = (frame._width * frame._height) / 2; + } else if (frame._rleEncoded) { + // this size includes the header size, which we subtract + frame._size = stream.readUint16LE() - 11; + frame._rleMarker = stream.readByte(); + } else { + // Uncompressed data + frame._size = frame._width * frame._height; + } + + // Load data for frame and decompress it + byte *data = new byte[frame._size]; + stream.read(data, frame._size); + decompressFrame(frame, data); + delete data; + + push_back(frame); + } +} + +/** + * Gets the palette at the start of the sprite file + */ +void ImageFile::loadPalette(Common::SeekableReadStream &stream) { + // Check for palette + int v1 = stream.readUint16LE() + 1; + int v2 = stream.readUint16LE() + 1; + int size = v1 * v2; + + if ((size - 12) == PALETTE_SIZE) { + // Found palette, so read it in + stream.seek(4 + 12, SEEK_CUR); + for (int idx = 0; idx < PALETTE_SIZE; ++idx) + _palette[idx] = VGA_COLOR_TRANS(stream.readByte()); + } else { + // Not a palette, so rewind to start of frame data for normal frame processing + stream.seek(-4, SEEK_CUR); + } +} + +/** + * Decompress a single frame for the sprite + */ +void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) { + frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8()); + + if (frame._flags & 0xFF) { + error("TODO: ImageFile::decompressFrame() 4-bits/pixel\n"); + } else if (frame._rleEncoded) { + // RLE encoded + byte *dst = (byte *)frame._frame.getPixels(); + + int size = frame._width * frame._height; + while (size > 0) { + if (*src == frame._rleMarker) { + byte rleColor = src[1]; + byte rleCount = src[2]; + src += 3; + size -= rleCount; + while (rleCount--) + *dst++ = rleColor; + } else { + *dst++ = *src++; + --size; + } + } + assert(size == 0); + } else { + // Uncompressed frame + Common::copy(src, src + frame._width * frame._height, + (byte *)frame._frame.getPixels()); + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index cd6e60c325..ad9867c523 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -27,8 +27,10 @@ #include "common/file.h" #include "common/hashmap.h" #include "common/hash-str.h" +#include "common/rect.h" #include "common/str.h" #include "common/stream.h" +#include "graphics/surface.h" namespace Sherlock { @@ -83,6 +85,33 @@ public: int resourceIndex() const; }; +struct ImageFrame { + uint32 _size; + uint16 _width, _height; + int _flags; + bool _rleEncoded; + Common::Point _position; + byte _rleMarker; + Graphics::Surface _frame; + + operator Graphics::Surface &() { return _frame; } +}; + +class ImageFile : public Common::Array { +private: + static SherlockEngine *_vm; + + void load(Common::SeekableReadStream &stream, bool skipPalette); + void loadPalette(Common::SeekableReadStream &stream); + void decompressFrame(ImageFrame &frame, const byte *src); +public: + byte _palette[256 * 3]; +public: + ImageFile(const Common::String &name, bool skipPal = false); + ImageFile(Common::SeekableReadStream &stream, bool skipPal = false); + ~ImageFile(); + static void setVm(SherlockEngine *vm); +}; } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index d5f63b9c0d..ca04153594 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -83,18 +83,18 @@ bool ScalpelEngine::showCityCutscene() { bool finished = _animation->playPrologue("26open1", 1, 255, true, 2); if (finished) { - Sprite titleSprites("title2.vgs", true); + ImageFile titleImages("title2.vgs", true); _screen->_backBuffer.blitFrom(*_screen); _screen->_backBuffer2.blitFrom(*_screen); // London, England - _screen->_backBuffer.transBlitFrom(titleSprites[0], Common::Point(10, 11)); + _screen->_backBuffer.transBlitFrom(titleImages[0], Common::Point(10, 11)); _screen->randomTransition(); finished = _events->delay(1000, true); // November, 1888 if (finished) { - _screen->_backBuffer.transBlitFrom(titleSprites[1], Common::Point(101, 102)); + _screen->_backBuffer.transBlitFrom(titleImages[1], Common::Point(101, 102)); _screen->randomTransition(); finished = _events->delay(5000, true); } @@ -108,16 +108,16 @@ bool ScalpelEngine::showCityCutscene() { finished = _animation->playPrologue("26open2", 1, 0, false, 2); if (finished) { - Sprite titleSprites("title.vgs", true); + ImageFile titleImages("title.vgs", true); _screen->_backBuffer.blitFrom(*_screen); _screen->_backBuffer2.blitFrom(*_screen); // The Lost Files of - _screen->_backBuffer.transBlitFrom(titleSprites[0], Common::Point(75, 6)); + _screen->_backBuffer.transBlitFrom(titleImages[0], Common::Point(75, 6)); // Sherlock Holmes - _screen->_backBuffer.transBlitFrom(titleSprites[1], Common::Point(34, 21)); + _screen->_backBuffer.transBlitFrom(titleImages[1], Common::Point(34, 21)); // copyright - _screen->_backBuffer.transBlitFrom(titleSprites[2], Common::Point(4, 190)); + _screen->_backBuffer.transBlitFrom(titleImages[2], Common::Point(4, 190)); _screen->verticalTransition(); finished = _events->delay(4000, true); @@ -135,7 +135,7 @@ bool ScalpelEngine::showCityCutscene() { if (finished) { // In the alley... - _screen->transBlitFrom(titleSprites[3], Common::Point(72, 51)); + _screen->transBlitFrom(titleImages[3], Common::Point(72, 51)); _screen->fadeIn(palette, 3); finished = _events->delay(3000, true); } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index de351a5561..84ef44d7e1 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -30,12 +30,27 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) { _goToRoom = -1; _oldCharPoint = 0; _numExits = 0; + _windowOpen = _infoFlag = false; + _menuMode = _keyboardInput = 0; - _controlSprites = new Sprite("menu.all"); + _controls = nullptr; // new ImageFile("menu.all"); } Scene::~Scene() { - delete _controlSprites; + delete _controls; +} + +void Scene::selectScene() { + // Reset fields + _numExits = 0; + _windowOpen = _infoFlag = false; + _menuMode = _keyboardInput = 0; + _oldKey = _help = _oldHelp = 0; + _oldTemp = _temp = 0; + + // Set up player + + } } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 031245b122..f92dfccfad 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -24,7 +24,7 @@ #define SHERLOCK_SCENE_H #include "common/scummsys.h" -#include "sherlock/sprite.h" +#include "sherlock/resources.h" namespace Sherlock { @@ -35,6 +35,8 @@ class SherlockEngine; class Scene { private: SherlockEngine *_vm; + + void loadScene(); public: bool _stats[SCENES_COUNT][9]; bool _savedStats[SCENES_COUNT][9]; @@ -42,12 +44,17 @@ public: Common::Point _bigPos; Common::Point _overPos; int _oldCharPoint; - Sprite *_controlSprites; + ImageFile *_controls; int _numExits; + bool _windowOpen, _infoFlag; + int _menuMode, _keyboardInput; + int _oldKey, _help, _oldHelp; + int _oldTemp, _temp; public: Scene(SherlockEngine *vm); - ~Scene(); + + void selectScene(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 8b597df31b..a292ee675c 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -74,6 +74,7 @@ void SherlockEngine::initialize() { _midi->setNativeMT32(native_mt32); */ + ImageFile::setVm(this); _res = new Resources(); _animation = new Animation(this); _debugger = new Debugger(this); @@ -83,7 +84,6 @@ void SherlockEngine::initialize() { _screen = new Screen(this); _sound = new Sound(this); _talk = new Talk(); - Sprite::setVm(this); } Common::Error SherlockEngine::run() { @@ -97,6 +97,9 @@ Common::Error SherlockEngine::run() { if (shouldQuit()) break; + // Initialize the scene + _scene->selectScene(); + // TODO: Implement game and remove this dummy loop while (!shouldQuit()) _events->pollEventsAndWait(); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index c6023684b4..210e24c320 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -35,6 +35,7 @@ #include "sherlock/debugger.h" #include "sherlock/events.h" #include "sherlock/journal.h" +#include "sherlock/people.h" #include "sherlock/resources.h" #include "sherlock/scene.h" #include "sherlock/screen.h" @@ -77,6 +78,7 @@ public: Debugger *_debugger; EventsManager *_events; Journal *_journal; + People *_people; Resources *_res; Scene *_scene; Screen *_screen; diff --git a/engines/sherlock/sprite.cpp b/engines/sherlock/sprite.cpp deleted file mode 100644 index 8a7bb4cf29..0000000000 --- a/engines/sherlock/sprite.cpp +++ /dev/null @@ -1,147 +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. - * - */ - -#include "sherlock/sprite.h" -#include "sherlock/screen.h" -#include "sherlock/sherlock.h" -#include "common/debug.h" - -namespace Sherlock { - -SherlockEngine *Sprite::_vm; - -void Sprite::setVm(SherlockEngine *vm) { - _vm = vm; -} - -Sprite::Sprite(const Common::String &name, bool skipPal) { - Common::SeekableReadStream *stream = _vm->_res->load(name); - - Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); - load(*stream, skipPal); - - delete stream; -} - -Sprite::Sprite(Common::SeekableReadStream &stream, bool skipPal) { - Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); - load(stream, skipPal); -} - -Sprite::~Sprite() { - for (uint idx = 0; idx < size(); ++idx) - (*this)[idx]._frame.free(); -} - -/** - * Load the data of the sprite - */ -void Sprite::load(Common::SeekableReadStream &stream, bool skipPalette) { - loadPalette(stream); - - while (stream.pos() < stream.size()) { - SpriteFrame frame; - frame._width = stream.readUint16LE() + 1; - frame._height = stream.readUint16LE() + 1; - frame._flags = stream.readByte(); - frame._position.x = stream.readUint16LE(); - frame._position.y = stream.readByte(); - - frame._rleEncoded = !skipPalette && (frame._position.x == 1); - - if (frame._flags & 0xFF) { - // Nibble packed frame data - frame._size = (frame._width * frame._height) / 2; - } else if (frame._rleEncoded) { - // this size includes the header size, which we subtract - frame._size = stream.readUint16LE() - 11; - frame._rleMarker = stream.readByte(); - } else { - // Uncompressed data - frame._size = frame._width * frame._height; - } - - // Load data for frame and decompress it - byte *data = new byte[frame._size]; - stream.read(data, frame._size); - decompressFrame(frame, data); - delete data; - - push_back(frame); - } -} - -/** - * Gets the palette at the start of the sprite file - */ -void Sprite::loadPalette(Common::SeekableReadStream &stream) { - // Check for palette - int v1 = stream.readUint16LE() + 1; - int v2 = stream.readUint16LE() + 1; - int size = v1 * v2; - - if ((size - 12) == PALETTE_SIZE) { - // Found palette, so read it in - stream.seek(4 + 12, SEEK_CUR); - for (int idx = 0; idx < PALETTE_SIZE; ++idx) - _palette[idx] = VGA_COLOR_TRANS(stream.readByte()); - } else { - // Not a palette, so rewind to start of frame data for normal frame processing - stream.seek(-4, SEEK_CUR); - } -} - -/** - * Decompress a single frame for the sprite - */ -void Sprite::decompressFrame(SpriteFrame &frame, const byte *src) { - frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8()); - - if (frame._flags & 0xFF) { - debug("TODO: Sprite::decompressFrame() 4-bits/pixel\n"); - } else if (frame._rleEncoded) { - // RLE encoded - byte *dst = (byte *)frame._frame.getPixels(); - - int size = frame._width * frame._height; - while (size > 0) { - if (*src == frame._rleMarker) { - byte rleColor = src[1]; - byte rleCount = src[2]; - src += 3; - size -= rleCount; - while (rleCount--) - *dst++ = rleColor; - } else { - *dst++ = *src++; - --size; - } - } - assert(size == 0); - } else { - // Uncompressed frame - Common::copy(src, src + frame._width * frame._height, - (byte *)frame._frame.getPixels()); - } -} - -} // End of namespace Sherlock diff --git a/engines/sherlock/sprite.h b/engines/sherlock/sprite.h deleted file mode 100644 index 844013db43..0000000000 --- a/engines/sherlock/sprite.h +++ /dev/null @@ -1,65 +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. - * - */ - -#ifndef SHERLOCK_SPRITE_H -#define SHERLOCK_SPRITE_H - -#include "common/array.h" -#include "common/rect.h" -#include "common/stream.h" -#include "graphics/surface.h" - -namespace Sherlock { - -class SherlockEngine; - -struct SpriteFrame { - uint32 _size; - uint16 _width, _height; - int _flags; - bool _rleEncoded; - Common::Point _position; - byte _rleMarker; - Graphics::Surface _frame; - - operator Graphics::Surface &() { return _frame; } -}; - -class Sprite: public Common::Array { -private: - static SherlockEngine *_vm; - - void load(Common::SeekableReadStream &stream, bool skipPalette); - void loadPalette(Common::SeekableReadStream &stream); - void decompressFrame(SpriteFrame &frame, const byte *src); -public: - byte _palette[256 * 3]; -public: - Sprite(const Common::String &name, bool skipPal = false); - Sprite(Common::SeekableReadStream &stream, bool skipPal = false); - ~Sprite(); - static void setVm(SherlockEngine *vm); -}; - -} // End of namespace Sherlock - -#endif diff --git a/engines/sherlock/sprites.cpp b/engines/sherlock/sprites.cpp new file mode 100644 index 0000000000..6e33219309 --- /dev/null +++ b/engines/sherlock/sprites.cpp @@ -0,0 +1,27 @@ +/* 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. + * + */ + +#include "sherlock/sprites.h" + +namespace Sherlock { + +} // End of namespace Sherlock diff --git a/engines/sherlock/sprites.h b/engines/sherlock/sprites.h new file mode 100644 index 0000000000..631693d815 --- /dev/null +++ b/engines/sherlock/sprites.h @@ -0,0 +1,83 @@ +/* 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. + * + */ + +#ifndef SHERLOCK_SPRITES_H +#define SHERLOCK_SPRITES_H + +#include "common/scummsys.h" +#include "common/rect.h" +#include "common/str-array.h" +#include "common/str.h" +#include "sherlock/resources.h" + +namespace Sherlock { + +class SherlockEngine; + +enum ObjectAllow { + ALLOW_MOVEMENT = 1, ALLOW_OPEN = 2, ALLOW_CLOSE = 4 +}; + +enum SpriteType { + INVALID = 0, + CHARACTER = 1, + CURSOR = 2, + STATIC_BG_SHAPE = 3, // Background shape that doesn't animate + ACTIVE_BG_SHAPE = 4, // Background shape that animates + REMOVE = 5, // Object should be removed next frame + NO_SHAPE = 6, // Background object with no shape + HIDDEN = 7, // Hidden backgruond object + HIDE_SHAPE = 8 // Object needs to be hidden +}; + +#define MAX_HOLMES_SEQUENCE 16 +#define MAX_FRAME 30 + +struct Sprite { + Common::String _name; // Name + Common::String _description; // Description + Common::StringArray _examine; // Examine in-depth description + Common::String _pickUp; // Message for if you can't pick up object + + const uint8 (*_sequences)[MAX_HOLMES_SEQUENCE][MAX_FRAME]; // Holds animation sequences + Sprite *_sprites; // Sprite shapes + ImageFrame *_spriteFrame; // Pointer to shape in the sprite + int _walkCount; // Character walk counter + int _allow; // Allowed menu commands - ObjectAllow + int _frameNumber; // Frame number in rame sequence to draw + int _sequenceNumber; // Sequence being used + Common::Point _position; // Current position + Common::Point _movement; // Momvement amount + Common::Point _oldPosition; // Old position + Common::Point _oldSize; // Image's old size + Common::Point _goto; // Walk destination + SpriteType _type; // Type of object + int _pickup; + Common::Point _noShapeSize; // Size of a NO_SHAPE + int _status; // Status: open/closed, moved/not moved + byte _misc; // Miscellaneous use + int _numFrames; // How many frames the object has +}; + +} // End of namespace Sherlock + +#endif -- cgit v1.2.3