From 7a46c84c0d02ec3fb5aa9d607519af8fbcd2715e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 May 2015 22:02:59 -0400 Subject: SHERLOCK: Beginnings of Rose Tattoo engine --- engines/sherlock/decompress.cpp | 48 +++++++++++++++++++++++ engines/sherlock/map.cpp | 10 ++++- engines/sherlock/objects.cpp | 67 +++++++++++++++++++++++-------- engines/sherlock/objects.h | 23 ++++++++--- engines/sherlock/resources.cpp | 16 +++++--- engines/sherlock/resources.h | 3 +- engines/sherlock/scalpel/scalpel.cpp | 16 +++++--- engines/sherlock/scene.cpp | 67 ++++++++++++++++++++++++++----- engines/sherlock/scene.h | 13 +++++- engines/sherlock/screen.cpp | 76 +++++++++++++++++++++++++++--------- engines/sherlock/screen.h | 19 +++++++++ engines/sherlock/sherlock.cpp | 3 -- engines/sherlock/sherlock.h | 4 +- engines/sherlock/tattoo/tattoo.cpp | 27 +++++++++++++ engines/sherlock/tattoo/tattoo.h | 5 +++ engines/sherlock/user_interface.cpp | 9 ++++- 16 files changed, 336 insertions(+), 70 deletions(-) (limited to 'engines/sherlock') diff --git a/engines/sherlock/decompress.cpp b/engines/sherlock/decompress.cpp index dfa573209f..8e02da3212 100644 --- a/engines/sherlock/decompress.cpp +++ b/engines/sherlock/decompress.cpp @@ -77,4 +77,52 @@ Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int return outS; } + +/** + * Decompresses a Rose Tattoo resource + * +Common::SeekableReadStream *decompress32(Common::SeekableReadStream &source, int32 outSize) { + if (outSize == -1) { + outSize = source.readSint32LE(); + } + + byte lzWindow[8192]; + byte *outBuffer = new byte[outSize]; + byte *outBufferEnd = outBuffer + outSize; + Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES); + + memset(lzWindow, 0xFF, 8192); + int lzWindowPos = 0xFEE; + int cmd = 0; + + do { + cmd >>= 1; + if (!(cmd & 0x100)) + cmd = source.readByte() | 0xFF00; + + if (cmd & 1) { + byte literal = source.readByte(); + *outBuffer++ = literal; + lzWindow[lzWindowPos] = literal; + lzWindowPos = (lzWindowPos + 1) & 0x0FFF; + } else { + int copyPos, copyLen; + copyPos = source.readByte(); + copyLen = source.readByte(); + copyPos = copyPos | ((copyLen & 0xF0) << 4); + copyLen = (copyLen & 0x0F) + 3; + while (copyLen--) { + byte literal = lzWindow[copyPos]; + copyPos = (copyPos + 1) & 0x0FFF; + *outBuffer++ = literal; + lzWindow[lzWindowPos] = literal; + lzWindowPos = (lzWindowPos + 1) & 0x0FFF; + } + } + } while (outBuffer < outBufferEnd); + + return outS; +} +*/ + } // namespace Sherlock diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index e178dece0c..c2eedd46ee 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -22,6 +22,7 @@ #include "sherlock/map.h" #include "sherlock/sherlock.h" +#include "common/system.h" namespace Sherlock { @@ -52,7 +53,7 @@ const byte *MapPaths::getPath(int srcLocation, int destLocation) { /*----------------------------------------------------------------*/ -Map::Map(SherlockEngine *vm): _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) { +Map::Map(SherlockEngine *vm): _vm(vm), _topLine(g_system->getWidth(), 12) { _active = false; _mapCursors = nullptr; _shapes = nullptr; @@ -94,8 +95,13 @@ void Map::loadSequences(int count, const byte *seq) { * Load data needed for the map */ void Map::loadData() { + // TODO: Remove this + if (_vm->getGameID() == GType_RoseTattoo) + return; + // Load the list of location names - Common::SeekableReadStream *txtStream = _vm->_res->load("chess.txt"); + Common::SeekableReadStream *txtStream = _vm->_res->load( + _vm->getGameID() == GType_SerratedScalpel ? "chess.txt" : "map.txt"); int streamSize = txtStream->size(); while (txtStream->pos() < streamSize) { diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index b4371cd71b..772f9d23d1 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -122,8 +122,8 @@ void Sprite::adjustSprite() { people.gotoStand(*this); } } else if (!map._active) { - _position.y = CLIP((int)_position.y, UPPER_LIMIT, LOWER_LIMIT); - _position.x = CLIP((int)_position.x, LEFT_LIMIT, RIGHT_LIMIT); + _position.y = CLIP((int)_position.y, (int)UPPER_LIMIT, (int)LOWER_LIMIT); + _position.x = CLIP((int)_position.x, (int)LEFT_LIMIT, (int)RIGHT_LIMIT); } if (!map._active || (map._frameChangeFlag = !map._frameChangeFlag)) @@ -393,9 +393,14 @@ UseType::UseType() { /** * Load the data for the UseType */ -void UseType::load(Common::SeekableReadStream &s) { +void UseType::load(Common::SeekableReadStream &s, bool isRoseTattoo) { char buffer[12]; + if (isRoseTattoo) { + s.read(buffer, 12); + _verb = Common::String(buffer); + } + _cAnimNum = s.readByte(); _cAnimSpeed = s.readByte(); if (_cAnimSpeed & 0x80) @@ -407,9 +412,12 @@ void UseType::load(Common::SeekableReadStream &s) { } _useFlag = s.readSint16LE(); - _dFlag[0] = s.readSint16LE(); - _lFlag[0] = s.readSint16LE(); - _lFlag[1] = s.readSint16LE(); + + if (!isRoseTattoo) { + _dFlag[0] = s.readSint16LE(); + _lFlag[0] = s.readSint16LE(); + _lFlag[1] = s.readSint16LE(); + } s.read(buffer, 12); _target = Common::String(buffer); @@ -456,12 +464,19 @@ Object::Object() { _descOffset = 0; _seqCounter2 = 0; _seqSize = 0; + + _quickDraw = 0; + _scaleVal = 0; + _requiredFlag1 = 0; + _gotoSeq = 0; + _talkSeq = 0; + _restoreSlot = 0; } /** * Load the data for the object */ -void Object::load(Common::SeekableReadStream &s) { +void Object::load(Common::SeekableReadStream &s, bool isRoseTattoo) { char buffer[41]; s.read(buffer, 12); _name = Common::String(buffer); @@ -496,7 +511,8 @@ void Object::load(Common::SeekableReadStream &s) { _pickup = s.readByte(); _defaultCommand = s.readByte(); _lookFlag = s.readUint16LE(); - _pickupFlag = s.readUint16LE(); + if (!isRoseTattoo) + _pickupFlag = s.readUint16LE(); _requiredFlag = s.readSint16LE(); _noShapeSize.x = s.readUint16LE(); _noShapeSize.y = s.readUint16LE(); @@ -504,26 +520,45 @@ void Object::load(Common::SeekableReadStream &s) { _misc = s.readByte(); _maxFrames = s.readUint16LE(); _flags = s.readByte(); - _aOpen.load(s); + + if (!isRoseTattoo) + _aOpen.load(s); + _aType = (AType)s.readByte(); _lookFrames = s.readByte(); _seqCounter = s.readByte(); _lookPosition.x = s.readUint16LE(); - _lookPosition.y = s.readByte(); + _lookPosition.y = isRoseTattoo ? s.readSint16LE() : s.readByte(); _lookFacing = s.readByte(); _lookcAnim = s.readByte(); - _aClose.load(s); + + if (!isRoseTattoo) + _aClose.load(s); + _seqStack = s.readByte(); _seqTo = s.readByte(); _descOffset = s.readUint16LE(); _seqCounter2 = s.readByte(); _seqSize = s.readUint16LE(); - s.skip(1); - _aMove.load(s); - s.skip(8); - for (int idx = 0; idx < 4; ++idx) - _use[idx].load(s); + if (isRoseTattoo) { + for (int idx = 0; idx < 6; ++idx) + _use[idx].load(s, true); + + _quickDraw = s.readByte(); + _scaleVal = s.readUint16LE(); + _requiredFlag1 = s.readUint16LE(); + _gotoSeq = s.readByte(); + _talkSeq = s.readByte(); + _restoreSlot = s.readByte(); + } else { + s.skip(1); + _aMove.load(s); + s.skip(8); + + for (int idx = 0; idx < 4; ++idx) + _use[idx].load(s, false); + } } /** diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 4068973e58..2073f06f88 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -159,9 +159,10 @@ struct UseType { int _dFlag[1]; int _lFlag[2]; Common::String _target; + Common::String _verb; UseType(); - void load(Common::SeekableReadStream &s); + void load(Common::SeekableReadStream &s, bool isRoseTattoo); }; class Object { @@ -197,32 +198,42 @@ public: int _pickup; int _defaultCommand; // Default right-click command int _lookFlag; // Which flag LOOK will set (if any) - int _pickupFlag; // Which flag PICKUP will set (if any) int _requiredFlag; // Object will be hidden if not set Common::Point _noShapeSize; // Size of a NO_SHAPE int _status; // Status (open/closed, moved/not) int8 _misc; // Misc field -- use varies with type int _maxFrames; // Number of frames int _flags; // Tells if object can be walked behind - ActionType _aOpen; // Holds data for moving object AType _aType; // Tells if this is an object, person, talk, etc. int _lookFrames; // How many frames to play of the look anim before pausing int _seqCounter; // How many times this sequence has been executed Common::Point _lookPosition; // Where to walk when examining object int _lookFacing; // Direction to face when examining object int _lookcAnim; - ActionType _aClose; int _seqStack; // Allows gosubs to return to calling frame int _seqTo; // Allows 1-5, 8-3 type sequences encoded in 2 bytes uint _descOffset; // Tells where description starts in DescText int _seqCounter2; // Counter of calling frame sequence uint _seqSize; // Tells where description starts + UseType _use[6]; // Serrated Scalpel uses 4, Rose Tattoo 6 + + // Serrated Scalpel fields + int _pickupFlag; // Which flag PICKUP will set (if any) + ActionType _aOpen; // Holds data for moving object + ActionType _aClose; ActionType _aMove; - UseType _use[4]; + + // Rose Tattoo fields + int _quickDraw; + int _scaleVal; + int _requiredFlag1; + int _gotoSeq; + int _talkSeq; + int _restoreSlot; Object(); - void load(Common::SeekableReadStream &s); + void load(Common::SeekableReadStream &s, bool isRoseTattoo); void toggleHidden(); diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index f50f780195..9f2704ac62 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -107,9 +107,7 @@ Resources::Resources() { addToCache("vgs.lib"); addToCache("talk.lib"); - addToCache("sequence.txt"); addToCache("journal.txt"); - addToCache("portrait.lib"); } /** @@ -122,8 +120,11 @@ void Resources::addToCache(const Common::String &filename) { // Check to see if the file is a library Common::SeekableReadStream *stream = load(filename); uint32 header = stream->readUint32BE(); + if (header == MKTAG('L', 'I', 'B', 26)) - loadLibraryIndex(filename, stream); + loadLibraryIndex(filename, stream, false); + else if (header == MKTAG('L', 'I', 'C', 26)) + loadLibraryIndex(filename, stream, true); delete stream; } @@ -193,7 +194,7 @@ Common::SeekableReadStream *Resources::load(const Common::String &filename, cons // Check if the library has already had it's index read, and if not, load it if (!_indexes.contains(libraryFile)) - loadLibraryIndex(libraryFile, libStream); + loadLibraryIndex(libraryFile, libStream, false); // Extract the data for the specified resource and return it LibraryEntry &entry = _indexes[libraryFile][filename]; @@ -216,7 +217,7 @@ bool Resources::exists(const Common::String &filename) const { * Reads in the index from a library file, and caches it's index for later use */ void Resources::loadLibraryIndex(const Common::String &libFilename, - Common::SeekableReadStream *stream) { + Common::SeekableReadStream *stream, bool isNewStyle) { uint32 offset, nextOffset; // Create an index entry @@ -227,6 +228,9 @@ void Resources::loadLibraryIndex(const Common::String &libFilename, stream->seek(4); int count = stream->readUint16LE(); + if (isNewStyle) + stream->seek((count + 1) * 8, SEEK_CUR); + // Loop through reading in the entries for (int idx = 0; idx < count; ++idx) { // Read the name of the resource @@ -304,10 +308,12 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool // Animation cutscene image files use a 16-bit x offset frame._offset.x = stream.readUint16LE(); frame._rleEncoded = (frame._offset.x & 0xff) == 1; + frame._offset.y = stream.readByte(); } else { // Standard image files have a separate byte for the RLE flag, and an 8-bit X offset frame._rleEncoded = stream.readByte() == 1; frame._offset.x = stream.readByte(); + frame._offset.y = stream.readByte(); } frame._offset.y = stream.readByte(); diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index e1f97f1def..bbaac60a33 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -70,7 +70,8 @@ private: LibraryIndexes _indexes; int _resourceIndex; - void loadLibraryIndex(const Common::String &libFilename, Common::SeekableReadStream *stream); + void loadLibraryIndex(const Common::String &libFilename, Common::SeekableReadStream *stream, + bool isNewStyle); public: Resources(); diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 6959e435d2..b982079714 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -23,6 +23,7 @@ #include "sherlock/scalpel/scalpel.h" #include "sherlock/sherlock.h" #include "sherlock/animation.h" +#include "engines/util.h" namespace Sherlock { @@ -242,6 +243,9 @@ ScalpelEngine::~ScalpelEngine() { * Game initialization */ void ScalpelEngine::initialize() { + initGraphics(320, 200, false); + + // Let the base engine intialize SherlockEngine::initialize(); _darts = new Darts(this); @@ -250,11 +254,13 @@ void ScalpelEngine::initialize() { _flags[3] = true; // Turn on Alley _flags[39] = true; // Turn on Baker Street - if (!getIsDemo()) { + // Add some more files to the cache + _res->addToCache("sequence.txt"); + _res->addToCache("portrait.lib"); + // Load the map co-ordinates for each scene and sequence data _map->loadPoints(NUM_PLACES, &MAP_X[0], &MAP_Y[0], &MAP_TRANSLATE[0]); _map->loadSequences(3, &MAP_SEQUENCES[0][0]); - } // Load the inventory loadInventory(); @@ -454,9 +460,9 @@ bool ScalpelEngine::scrollCredits() { _screen->transBlitFrom(creditsImages[1], Common::Point(10, 400 - idx), false, 0); // Don't show credit text on the top and bottom ten rows of the screen - _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, 10)); - _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - 10), - Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 10, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, _screen->w, 10)); + _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, _screen->h - 10), + Common::Rect(0, _screen->h - 10, _screen->w, _screen->h)); _events->delay(100); } diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index f473004d9a..d4662ed559 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -24,16 +24,42 @@ #include "sherlock/sherlock.h" #include "sherlock/scalpel/scalpel.h" #include "sherlock/decompress.h" +#include "sherlock/screen.h" namespace Sherlock { -void BgFileHeader::synchronize(Common::SeekableReadStream &s) { +BgFileHeader::BgFileHeader() { + _numStructs = -1; + _numImages = -1; + _numcAnimations = -1; + _descSize = -1; + _seqSize = -1; + + // Serrated Scalpel + _fill = -1; + + // Rose Tattoo + _scrollSize = -1; + _bytesWritten = -1; + _fadeStyle = -1; + Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); +} + +void BgFileHeader::synchronize(Common::SeekableReadStream &s, bool isRoseTattoo) { _numStructs = s.readUint16LE(); _numImages = s.readUint16LE(); _numcAnimations = s.readUint16LE(); _descSize = s.readUint16LE(); _seqSize = s.readUint16LE(); - _fill = s.readUint16LE(); + + if (isRoseTattoo) { + _scrollSize = s.readUint16LE(); + _bytesWritten = s.readUint32LE(); + _fadeStyle = s.readByte(); + } else { + _fill = s.readUint16LE(); + + } } /*----------------------------------------------------------------*/ @@ -215,6 +241,7 @@ bool Scene::loadScene(const Common::String &filename) { Sound &sound = *_vm->_sound; UserInterface &ui = *_vm->_ui; bool flag; + Common::Array bgInfo; _walkedInScene = false; @@ -229,7 +256,7 @@ bool Scene::loadScene(const Common::String &filename) { _sequenceBuffer.clear(); // - // Load background shapes from .rrm + // Load the room resource file for the scene // Common::String rrmFile = filename + ".rrm"; @@ -238,30 +265,52 @@ bool Scene::loadScene(const Common::String &filename) { Common::SeekableReadStream *rrmStream = _vm->_res->load(rrmFile); rrmStream->seek(39); - _version = rrmStream->readByte(); - _lzwMode = _version == 10; + if (_vm->getGameID() == GType_SerratedScalpel) { + _version = rrmStream->readByte(); + _lzwMode = _version == 10; + } else { + _lzwMode = rrmStream->readByte() > 0; + } // Go to header and read it in rrmStream->seek(rrmStream->readUint32LE()); + BgFileHeader bgHeader; - bgHeader.synchronize(*rrmStream); + bgHeader.synchronize(*rrmStream, _vm->getGameID() == GType_RoseTattoo); _invGraphicItems = bgHeader._numImages + 1; + if (_vm->getGameID() == GType_RoseTattoo) { + screen.initPaletteFade(bgHeader._bytesWritten); + screen.fadeRead(*rrmStream, screen._cMap, PALETTE_SIZE); + screen.setupBGArea(screen._cMap); + + screen.initScrollVars(); + + // Read in background + if (_lzwMode) { + Common::SeekableReadStream *stream = decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT); + stream->read(screen._backBuffer1.getPixels(), stream->size()); + delete stream; + } else { + rrmStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT); + } + } + // Read in the shapes header info - Common::Array bgInfo; bgInfo.resize(bgHeader._numStructs); for (uint idx = 0; idx < bgInfo.size(); ++idx) bgInfo[idx].synchronize(*rrmStream); // Read information + int shapeSize = _vm->getGameID() == GType_SerratedScalpel ? 569 : 591; Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : - decompressLZ(*rrmStream, bgHeader._numImages * 569 + + decompressLZ(*rrmStream, bgHeader._numImages * shapeSize + bgHeader._descSize + bgHeader._seqSize); _bgShapes.resize(bgHeader._numStructs); for (int idx = 0; idx < bgHeader._numStructs; ++idx) - _bgShapes[idx].load(*infoStream); + _bgShapes[idx].load(*infoStream, _vm->getGameID() == GType_RoseTattoo); if (bgHeader._descSize) { _descText.resize(bgHeader._descSize); diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 96714c4a3a..b4b88fa0a1 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -29,6 +29,7 @@ #include "common/serializer.h" #include "sherlock/objects.h" #include "sherlock/resources.h" +#include "sherlock/screen.h" namespace Sherlock { @@ -44,9 +45,19 @@ struct BgFileHeader { int _numcAnimations; int _descSize; int _seqSize; + + // Serrated Scalpel int _fill; - void synchronize(Common::SeekableReadStream &s); + // Rose Tattoo + int _scrollSize; + int _bytesWritten; // Size of the main body of the RRM + int _fadeStyle; // Fade style + byte _palette[PALETTE_SIZE]; // Palette + + + BgFileHeader(); + void synchronize(Common::SeekableReadStream &s, bool isRoseTattoo); }; struct BgfileheaderInfo { diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index fb155bf502..0ca10b4a4a 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -28,9 +28,9 @@ namespace Sherlock { -Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _vm(vm), - _backBuffer1(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), - _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), +Screen::Screen(SherlockEngine *vm) : Surface(g_system->getWidth(), g_system->getHeight()), _vm(vm), + _backBuffer1(g_system->getWidth(), g_system->getHeight()), + _backBuffer2(g_system->getWidth(), g_system->getHeight()), _backBuffer(&_backBuffer1) { _transitionSeed = 1; _fadeStyle = false; @@ -38,11 +38,19 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR _fontHeight = 0; Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0); Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0); + Common::fill(&_tMap[0], &_tMap[PALETTE_SIZE], 0); setFont(1); // Set dummy surface used for restricted scene drawing _sceneSurface.format = Graphics::PixelFormat::createFormatCLUT8(); - _sceneSurface.pitch = SHERLOCK_SCREEN_WIDTH; + _sceneSurface.pitch = pitch; + + // Rose Tattoo specific fields + _fadeBytesRead = _fadeBytesToRead = 0; + _oldFadePercent = 0; + _scrollSize = 0; + _currentScroll = 0; + _targetScroll = 0; } Screen::~Screen() { @@ -213,7 +221,7 @@ void Screen::randomTransition() { _transitionSeed = _transitionSeed * TRANSITION_MULTIPLIER + 1; int offset = _transitionSeed & 65535; - if (offset < (SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT)) + if (offset < (this->w * this->h)) *((byte *)getPixels() + offset) = *((const byte *)_backBuffer->getPixels() + offset); if (idx != 0 && (idx % 100) == 0) { @@ -236,12 +244,12 @@ void Screen::randomTransition() { void Screen::verticalTransition() { Events &events = *_vm->_events; - byte table[SHERLOCK_SCREEN_WIDTH]; - Common::fill(&table[0], &table[SHERLOCK_SCREEN_WIDTH], 0); + byte table[640]; + Common::fill(&table[0], &table[640], 0); - for (int yp = 0; yp < SHERLOCK_SCREEN_HEIGHT; ++yp) { - for (int xp = 0; xp < SHERLOCK_SCREEN_WIDTH; ++xp) { - int temp = (table[xp] >= 197) ? SHERLOCK_SCREEN_HEIGHT - table[xp] : + for (int yp = 0; yp < this->h; ++yp) { + for (int xp = 0; xp < this->w; ++xp) { + int temp = (table[xp] >= (this->h - 3)) ? this->h - table[xp] : _vm->getRandomNumber(3) + 1; if (temp) { @@ -261,7 +269,7 @@ void Screen::verticalTransition() { void Screen::restoreBackground(const Common::Rect &r) { if (r.width() > 0 && r.height() > 0) { Common::Rect tempRect = r; - tempRect.clip(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT)); + tempRect.clip(Common::Rect(0, 0, this->w, SHERLOCK_SCENE_HEIGHT)); if (tempRect.isValidRect()) _backBuffer1.blitFrom(_backBuffer2, Common::Point(tempRect.left, tempRect.top), tempRect); @@ -281,7 +289,7 @@ void Screen::slamArea(int16 xp, int16 yp, int16 width, int16 height) { void Screen::slamRect(const Common::Rect &r) { if (r.width() && r.height() > 0) { Common::Rect tempRect = r; - tempRect.clip(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + tempRect.clip(Common::Rect(0, 0, this->w, this->h)); if (tempRect.isValidRect()) blitFrom(*_backBuffer, Common::Point(tempRect.left, tempRect.top), tempRect); @@ -338,13 +346,13 @@ void Screen::print(const Common::Point &pt, byte color, const char *formatStr, . pos.y--; // Font is always drawing one line higher if (!pos.x) // Center text horizontally - pos.x = (SHERLOCK_SCREEN_WIDTH - width) / 2; + pos.x = (this->w - width) / 2; Common::Rect textBounds(pos.x, pos.y, pos.x + width, pos.y + _fontHeight); - if (textBounds.right > SHERLOCK_SCREEN_WIDTH) - textBounds.moveTo(SHERLOCK_SCREEN_WIDTH - width, textBounds.top); - if (textBounds.bottom > SHERLOCK_SCREEN_HEIGHT) - textBounds.moveTo(textBounds.left, SHERLOCK_SCREEN_HEIGHT - _fontHeight); + if (textBounds.right > this->w) + textBounds.moveTo(this->w - width, textBounds.top); + if (textBounds.bottom > this->h) + textBounds.moveTo(textBounds.left, this->h - _fontHeight); // Write out the string at the given position writeString(str, Common::Point(textBounds.left, textBounds.top), color); @@ -505,7 +513,7 @@ void Screen::resetDisplayBounds() { */ Common::Rect Screen::getDisplayBounds() { return (_backBuffer == &_sceneSurface) ? Common::Rect(0, 0, _sceneSurface.w, _sceneSurface.h) : - Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + Common::Rect(0, 0, this->w, this->h); } /** @@ -518,4 +526,36 @@ void Screen::synchronize(Common::Serializer &s) { setFont(fontNumb); } +void Screen::initPaletteFade(int bytesToRead) { + Common::copy(&_cMap[0], &_cMap[PALETTE_SIZE], &_sMap[0]); + Common::copy(&_cMap[0], &_cMap[PALETTE_SIZE], &_tMap[0]); + + // Set how many bytes need to be read / have been read + _fadeBytesRead = 0; + _fadeBytesToRead = bytesToRead; + _oldFadePercent = 0; +} + +int Screen::fadeRead(Common::SeekableReadStream &stream, byte *buf, int totalSize) { + warning("TODO: fadeRead"); + stream.read(buf, totalSize); + return totalSize; +} + +/** + * Creates a grey-scale version of the passed palette + */ +void Screen::setupBGArea(const byte cMap[PALETTE_SIZE]) { + warning("TODO"); +} + +/** + * Initializes scroll variables + */ +void Screen::initScrollVars() { + _scrollSize = 0; + _currentScroll = 0; + _targetScroll = 0; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 501506f8ec..25389166d0 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -67,6 +67,15 @@ private: int _fontHeight; Surface _sceneSurface; + // Rose Tattoo fields + int _fadeBytesRead, _fadeBytesToRead; + int _oldFadePercent; + byte _lookupTable[PALETTE_COUNT]; + byte _lookupTable1[PALETTE_COUNT]; + int _scrollSize; + int _currentScroll; + int _targetScroll; +private: void mergeDirtyRects(); bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2); @@ -80,6 +89,7 @@ public: bool _fadeStyle; byte _cMap[PALETTE_SIZE]; byte _sMap[PALETTE_SIZE]; + byte _tMap[PALETTE_SIZE]; public: Screen(SherlockEngine *vm); virtual ~Screen(); @@ -132,6 +142,15 @@ public: int fontNumber() const { return _fontNumber; } void synchronize(Common::Serializer &s); + + // Rose Tattoo specific methods + void initPaletteFade(int bytesToRead); + + int fadeRead(Common::SeekableReadStream &stream, byte *buf, int totalSize); + + void setupBGArea(const byte cMap[PALETTE_SIZE]); + + void initScrollVars(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 2a5d9ec627..318267bb8f 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -25,7 +25,6 @@ #include "common/scummsys.h" #include "common/config-manager.h" #include "common/debug-channels.h" -#include "engines/util.h" namespace Sherlock { @@ -71,8 +70,6 @@ SherlockEngine::~SherlockEngine() { * Does basic initialization of the game engine */ void SherlockEngine::initialize() { - initGraphics(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, false); - DebugMan.addDebugChannel(kDebugScript, "scripts", "Script debug level"); ImageFile::setVm(this); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 501fdcb292..e21ac8c6d6 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -62,8 +62,8 @@ enum GameType { GType_RoseTattoo = 1 }; -#define SHERLOCK_SCREEN_WIDTH 320 -#define SHERLOCK_SCREEN_HEIGHT 200 +#define SHERLOCK_SCREEN_WIDTH _vm->_screen->w +#define SHERLOCK_SCREEN_HEIGHT _vm->_screen->h #define SHERLOCK_SCENE_HEIGHT 138 struct SherlockGameDescription; diff --git a/engines/sherlock/tattoo/tattoo.cpp b/engines/sherlock/tattoo/tattoo.cpp index d4059ac413..9039e3f9d4 100644 --- a/engines/sherlock/tattoo/tattoo.cpp +++ b/engines/sherlock/tattoo/tattoo.cpp @@ -21,6 +21,7 @@ */ #include "sherlock/tattoo/tattoo.h" +#include "engines/util.h" namespace Sherlock { @@ -30,6 +31,32 @@ void TattooEngine::showOpening() { // TODO } +/** + * Initialize the engine + */ +void TattooEngine::initialize() { + initGraphics(640, 480, true); + + // Initialize the base engine + SherlockEngine::initialize(); + + _flags.resize(100 * 8); + + // Add some more files to the cache + _res->addToCache("walk.lib"); + + // Starting scene + _scene->_goToScene = 91; +} + +/** + * Starting a scene within the game + */ +void TattooEngine::startScene() { + // TODO +} + + } // End of namespace Tattoo } // End of namespace Scalpel diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h index b98395597c..7bdeec55d1 100644 --- a/engines/sherlock/tattoo/tattoo.h +++ b/engines/sherlock/tattoo/tattoo.h @@ -31,10 +31,15 @@ namespace Tattoo { class TattooEngine : public SherlockEngine { protected: + virtual void initialize(); + virtual void showOpening(); + + virtual void startScene(); public: TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : SherlockEngine(syst, gameDesc) {} + virtual ~TattooEngine() {} }; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 41505b89fc..8e7254026b 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -81,8 +81,13 @@ const char *const MUSE[] = { /*----------------------------------------------------------------*/ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { - _controls = new ImageFile("menu.all"); - _controlPanel = new ImageFile("controls.vgs"); + if (_vm->getGameID() == GType_SerratedScalpel) { + _controls = new ImageFile("menu.all"); + _controlPanel = new ImageFile("controls.vgs"); + } else { + _controls = nullptr; + _controlPanel = nullptr; + } _bgFound = 0; _oldBgFound = -1; _keycode = Common::KEYCODE_INVALID; -- cgit v1.2.3