aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sherlock/decompress.cpp48
-rw-r--r--engines/sherlock/map.cpp10
-rw-r--r--engines/sherlock/objects.cpp67
-rw-r--r--engines/sherlock/objects.h23
-rw-r--r--engines/sherlock/resources.cpp16
-rw-r--r--engines/sherlock/resources.h3
-rw-r--r--engines/sherlock/scalpel/scalpel.cpp16
-rw-r--r--engines/sherlock/scene.cpp67
-rw-r--r--engines/sherlock/scene.h13
-rw-r--r--engines/sherlock/screen.cpp76
-rw-r--r--engines/sherlock/screen.h19
-rw-r--r--engines/sherlock/sherlock.cpp3
-rw-r--r--engines/sherlock/sherlock.h4
-rw-r--r--engines/sherlock/tattoo/tattoo.cpp27
-rw-r--r--engines/sherlock/tattoo/tattoo.h5
-rw-r--r--engines/sherlock/user_interface.cpp9
16 files changed, 336 insertions, 70 deletions
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<BgfileheaderInfo> bgInfo;
_walkedInScene = false;
@@ -229,7 +256,7 @@ bool Scene::loadScene(const Common::String &filename) {
_sequenceBuffer.clear();
//
- // Load background shapes from <filename>.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<BgfileheaderInfo> 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;