Skip to content

Commit

Permalink
SHERLOCK: Beginnings of Rose Tattoo engine
Browse files Browse the repository at this point in the history
  • Loading branch information
dreammaster committed May 13, 2015
1 parent d4b964c commit 8432e75
Show file tree
Hide file tree
Showing 16 changed files with 336 additions and 70 deletions.
48 changes: 48 additions & 0 deletions engines/sherlock/decompress.cpp
Expand Up @@ -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
10 changes: 8 additions & 2 deletions engines/sherlock/map.cpp
Expand Up @@ -22,6 +22,7 @@

#include "sherlock/map.h"
#include "sherlock/sherlock.h"
#include "common/system.h"

namespace Sherlock {

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
67 changes: 51 additions & 16 deletions engines/sherlock/objects.cpp
Expand Up @@ -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))
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -496,34 +511,54 @@ 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();
_status = s.readUint16LE();
_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);
}
}

/**
Expand Down
23 changes: 17 additions & 6 deletions engines/sherlock/objects.h
Expand Up @@ -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 {
Expand Down Expand Up @@ -197,32 +198,42 @@ class Object {
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();

Expand Down
16 changes: 11 additions & 5 deletions engines/sherlock/resources.cpp
Expand Up @@ -107,9 +107,7 @@ Resources::Resources() {

addToCache("vgs.lib");
addToCache("talk.lib");
addToCache("sequence.txt");
addToCache("journal.txt");
addToCache("portrait.lib");
}

/**
Expand All @@ -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;
}
Expand Down Expand Up @@ -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];
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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();
Expand Down
3 changes: 2 additions & 1 deletion engines/sherlock/resources.h
Expand Up @@ -70,7 +70,8 @@ class Resources {
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();

Expand Down
16 changes: 11 additions & 5 deletions engines/sherlock/scalpel/scalpel.cpp
Expand Up @@ -23,6 +23,7 @@
#include "sherlock/scalpel/scalpel.h"
#include "sherlock/sherlock.h"
#include "sherlock/animation.h"
#include "engines/util.h"

namespace Sherlock {

Expand Down Expand Up @@ -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);
Expand All @@ -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();
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit 8432e75

Please sign in to comment.