SHERLOCK: Setting up game specific People descendant classes

This commit is contained in:
Paul Gilbert 2015-06-06 22:40:29 -04:00
parent 3511f30a26
commit 933e675194
20 changed files with 465 additions and 230 deletions

View file

@ -8,11 +8,13 @@ MODULE_OBJS = \
scalpel/drivers/mt32.o \
scalpel/tsage/logo.o \
scalpel/tsage/resources.o \
scalpel/scalpel_people.o \
scalpel/scalpel_scene.o \
scalpel/scalpel_talk.o \
scalpel/scalpel_user_interface.o \
scalpel/settings.o \
tattoo/tattoo.o \
tattoo/tattoo_people.o \
tattoo/tattoo_resources.o \
tattoo/tattoo_scene.o \
tattoo/tattoo_talk.o \

View file

@ -20,11 +20,12 @@
*
*/
#include "sherlock/objects.h"
#include "common/util.h"
#include "sherlock/sherlock.h"
#include "sherlock/objects.h"
#include "sherlock/people.h"
#include "sherlock/scene.h"
#include "common/util.h"
#include "sherlock/scalpel/scalpel_people.h"
namespace Sherlock {
@ -256,14 +257,14 @@ void Sprite::adjustSprite() {
if (_walkSequences[_sequenceNumber][_frameNumber] == 0) {
switch (_sequenceNumber) {
case STOP_UP:
case STOP_DOWN:
case STOP_LEFT:
case STOP_RIGHT:
case STOP_UPRIGHT:
case STOP_UPLEFT:
case STOP_DOWNRIGHT:
case STOP_DOWNLEFT:
case Scalpel::STOP_UP:
case Scalpel::STOP_DOWN:
case Scalpel::STOP_LEFT:
case Scalpel::STOP_RIGHT:
case Scalpel::STOP_UPRIGHT:
case Scalpel::STOP_UPLEFT:
case Scalpel::STOP_DOWNRIGHT:
case Scalpel::STOP_DOWNLEFT:
// We're in a stop sequence, so reset back to the last frame, so
// the character is shown as standing still
--_frameNumber;

View file

@ -22,6 +22,8 @@
#include "sherlock/people.h"
#include "sherlock/sherlock.h"
#include "sherlock/scalpel/scalpel_people.h"
#include "sherlock/tattoo/tattoo_people.h"
namespace Sherlock {
@ -91,6 +93,13 @@ void Person::updateNPC() {
/*----------------------------------------------------------------*/
People *People::init(SherlockEngine *vm) {
if (vm->getGameID() == GType_SerratedScalpel)
return new Scalpel::ScalpelPeople(vm);
else
return new Tattoo::TattooPeople(vm);
}
People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) {
_holmesOn = true;
_oldWalkSequence = -1;
@ -137,7 +146,7 @@ void People::reset() {
else
p._position = Point32(36 * FIXED_INT_MULTIPLIER, 29 * FIXED_INT_MULTIPLIER);
p._sequenceNumber = STOP_DOWNRIGHT;
p._sequenceNumber = Scalpel::STOP_DOWNRIGHT;
p._imageFrame = nullptr;
p._frameNumber = 1;
p._delta = Point32(0, 0);
@ -323,10 +332,10 @@ void People::setWalking() {
// Set the initial frame sequence for the left and right, as well
// as setting the delta x depending on direction
if (_walkDest.x < (_player._position.x / FIXED_INT_MULTIPLIER)) {
_player._sequenceNumber = (map._active ? (int)MAP_LEFT : (int)WALK_LEFT);
_player._sequenceNumber = (map._active ? (int)MAP_LEFT : (int)Scalpel::WALK_LEFT);
_player._delta.x = speed.x * -FIXED_INT_MULTIPLIER;
} else {
_player._sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)WALK_RIGHT);
_player._sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)Scalpel::WALK_RIGHT);
_player._delta.x = speed.x * FIXED_INT_MULTIPLIER;
}
@ -353,22 +362,22 @@ assert(_player._position.y >= 10000);/***DEBUG****/
if (_player._delta.y > 150) {
if (!map._active) {
switch (_player._sequenceNumber) {
case WALK_LEFT:
_player._sequenceNumber = WALK_DOWNLEFT;
case Scalpel::WALK_LEFT:
_player._sequenceNumber = Scalpel::WALK_DOWNLEFT;
break;
case WALK_RIGHT:
_player._sequenceNumber = WALK_DOWNRIGHT;
case Scalpel::WALK_RIGHT:
_player._sequenceNumber = Scalpel::WALK_DOWNRIGHT;
break;
}
}
} else if (_player._delta.y < -150) {
if (!map._active) {
switch (_player._sequenceNumber) {
case WALK_LEFT:
_player._sequenceNumber = WALK_UPLEFT;
case Scalpel::WALK_LEFT:
_player._sequenceNumber = Scalpel::WALK_UPLEFT;
break;
case WALK_RIGHT:
_player._sequenceNumber = WALK_UPRIGHT;
case Scalpel::WALK_RIGHT:
_player._sequenceNumber = Scalpel::WALK_UPRIGHT;
break;
}
}
@ -377,10 +386,10 @@ assert(_player._position.y >= 10000);/***DEBUG****/
// Major movement is vertical, so set the sequence for up and down,
// and set the delta Y depending on the direction
if (_walkDest.y < (_player._position.y / FIXED_INT_MULTIPLIER)) {
_player._sequenceNumber = WALK_UP;
_player._sequenceNumber = Scalpel::WALK_UP;
_player._delta.y = speed.y * -FIXED_INT_MULTIPLIER;
} else {
_player._sequenceNumber = WALK_DOWN;
_player._sequenceNumber = Scalpel::WALK_DOWN;
_player._delta.y = speed.y * FIXED_INT_MULTIPLIER;
}
@ -422,38 +431,38 @@ void People::gotoStand(Sprite &sprite) {
sprite._walkCount = 0;
switch (sprite._sequenceNumber) {
case WALK_UP:
sprite._sequenceNumber = STOP_UP;
case Scalpel::WALK_UP:
sprite._sequenceNumber = Scalpel::STOP_UP;
break;
case WALK_DOWN:
sprite._sequenceNumber = STOP_DOWN;
case Scalpel::WALK_DOWN:
sprite._sequenceNumber = Scalpel::STOP_DOWN;
break;
case TALK_LEFT:
case WALK_LEFT:
sprite._sequenceNumber = STOP_LEFT;
case Scalpel::TALK_LEFT:
case Scalpel::WALK_LEFT:
sprite._sequenceNumber = Scalpel::STOP_LEFT;
break;
case TALK_RIGHT:
case WALK_RIGHT:
sprite._sequenceNumber = STOP_RIGHT;
case Scalpel::TALK_RIGHT:
case Scalpel::WALK_RIGHT:
sprite._sequenceNumber = Scalpel::STOP_RIGHT;
break;
case WALK_UPRIGHT:
sprite._sequenceNumber = STOP_UPRIGHT;
case Scalpel::WALK_UPRIGHT:
sprite._sequenceNumber = Scalpel::STOP_UPRIGHT;
break;
case WALK_UPLEFT:
sprite._sequenceNumber = STOP_UPLEFT;
case Scalpel::WALK_UPLEFT:
sprite._sequenceNumber = Scalpel::STOP_UPLEFT;
break;
case WALK_DOWNRIGHT:
sprite._sequenceNumber = STOP_DOWNRIGHT;
case Scalpel::WALK_DOWNRIGHT:
sprite._sequenceNumber = Scalpel::STOP_DOWNRIGHT;
break;
case WALK_DOWNLEFT:
sprite._sequenceNumber = STOP_DOWNLEFT;
case Scalpel::WALK_DOWNLEFT:
sprite._sequenceNumber = Scalpel::STOP_DOWNLEFT;
break;
default:
break;
}
// Only restart frame at 0 if the sequence number has changed
if (_oldWalkSequence != -1 || sprite._sequenceNumber == STOP_UP)
if (_oldWalkSequence != -1 || sprite._sequenceNumber == Scalpel::STOP_UP)
sprite._frameNumber = 0;
if (map._active) {
@ -653,65 +662,6 @@ void People::clearTalking() {
}
}
void People::setTalking(int speaker) {
Resources &res = *_vm->_res;
// If no speaker is specified, then we can exit immediately
if (speaker == -1)
return;
if (_portraitsOn) {
delete _talkPics;
Common::String filename = Common::String::format("%s.vgs", _characters[speaker]._portrait);
_talkPics = new ImageFile(filename);
// Load portrait sequences
Common::SeekableReadStream *stream = res.load("sequence.txt");
stream->seek(speaker * MAX_FRAME);
int idx = 0;
do {
_portrait._sequences[idx] = stream->readByte();
++idx;
} while (idx < 2 || _portrait._sequences[idx - 2] || _portrait._sequences[idx - 1]);
delete stream;
_portrait._maxFrames = idx;
_portrait._frameNumber = 0;
_portrait._sequenceNumber = 0;
_portrait._images = _talkPics;
_portrait._imageFrame = &(*_talkPics)[0];
_portrait._position = Common::Point(_portraitSide, 10);
_portrait._delta = Common::Point(0, 0);
_portrait._oldPosition = Common::Point(0, 0);
_portrait._goto = Common::Point(0, 0);
_portrait._flags = 5;
_portrait._status = 0;
_portrait._misc = 0;
_portrait._allow = 0;
_portrait._type = ACTIVE_BG_SHAPE;
_portrait._name = " ";
_portrait._description = " ";
_portrait._examine = " ";
_portrait._walkCount = 0;
if (_holmesFlip || _speakerFlip) {
_portrait._flags |= 2;
_holmesFlip = false;
_speakerFlip = false;
}
if (_portraitSide == 20)
_portraitSide = 220;
else
_portraitSide = 20;
_portraitLoaded = true;
}
}
void People::synchronize(Common::Serializer &s) {
s.syncAsByte(_holmesOn);

View file

@ -39,53 +39,6 @@ enum PeopleId {
MAX_NPC_PATH = 200
};
// 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,
};
enum TattooSequences {
// Walk Sequences Numbers for NPCs
RT_WALK_UP = 0,
RT_WALK_UPRIGHT = 1,
RT_WALK_RIGHT = 2,
RT_WALK_DOWNRIGHT = 3,
RT_WALK_DOWN = 4,
RT_WALK_DOWNLEFT = 5,
RT_WALK_LEFT = 6,
RT_WALK_UPLEFT = 7,
// Stop Sequences Numbers for NPCs
RT_STOP_UP = 8,
RT_STOP_UPRIGHT = 9,
RT_STOP_RIGHT = 10,
RT_STOP_DOWNRIGHT = 11,
RT_STOP_DOWN = 12,
RT_STOP_DOWNLEFT = 13,
RT_STOP_LEFT = 14,
RT_STOP_UPLEFT = 15,
// NPC Talk Sequence Numbers
RT_TALK_UPRIGHT = 16,
RT_TALK_RIGHT = 17,
RT_TALK_DOWNRIGHT = 18,
RT_TALK_DOWNLEFT = 19,
RT_TALK_LEFT = 20,
RT_TALK_UPLEFT = 21,
// NPC Listen Sequence Numbers
RT_LISTEN_UPRIGHT = 22,
RT_LISTEN_RIGHT = 23,
RT_LISTEN_DOWNRIGHT = 24,
RT_LISTEN_DOWNLEFT = 25,
RT_LISTEN_LEFT = 26,
RT_LISTEN_UPLEFT = 27
};
enum {
MAP_UP = 1, MAP_UPRIGHT = 2, MAP_RIGHT = 1, MAP_DOWNRIGHT = 4,
MAP_DOWN = 5, MAP_DOWNLEFT = 6, MAP_LEFT = 2, MAP_UPLEFT = 8
@ -142,10 +95,13 @@ class SherlockEngine;
class People {
private:
SherlockEngine *_vm;
Person _data[MAX_CHARACTERS];
int _oldWalkSequence;
int _srcZone, _destZone;
protected:
SherlockEngine *_vm;
People(SherlockEngine *vm);
public:
Common::Array<PersonData> _characters;
ImageFile *_talkPics;
@ -169,8 +125,8 @@ public:
int _walkControl;
public:
People(SherlockEngine *vm);
~People();
static People *init(SherlockEngine *vm);
virtual ~People();
Person &operator[](PeopleId id) {
assert(id < MAX_CHARACTERS);
@ -231,11 +187,6 @@ public:
*/
void clearTalking();
/**
* Setup the data for an animating speaker portrait at the top of the screen
*/
void setTalking(int speaker);
/**
* Synchronize the data for a savegame
*/

View file

@ -22,6 +22,7 @@
#include "engines/util.h"
#include "sherlock/scalpel/scalpel.h"
#include "sherlock/scalpel/scalpel_people.h"
#include "sherlock/scalpel/tsage/logo.h"
#include "sherlock/sherlock.h"
#include "sherlock/music.h"

View file

@ -0,0 +1,91 @@
/* 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/scalpel/scalpel_people.h"
#include "sherlock/sherlock.h"
namespace Sherlock {
namespace Scalpel {
void ScalpelPeople::setTalking(int speaker) {
Resources &res = *_vm->_res;
// If no speaker is specified, then we can exit immediately
if (speaker == -1)
return;
if (_portraitsOn) {
delete _talkPics;
Common::String filename = Common::String::format("%s.vgs", _characters[speaker]._portrait);
_talkPics = new ImageFile(filename);
// Load portrait sequences
Common::SeekableReadStream *stream = res.load("sequence.txt");
stream->seek(speaker * MAX_FRAME);
int idx = 0;
do {
_portrait._sequences[idx] = stream->readByte();
++idx;
} while (idx < 2 || _portrait._sequences[idx - 2] || _portrait._sequences[idx - 1]);
delete stream;
_portrait._maxFrames = idx;
_portrait._frameNumber = 0;
_portrait._sequenceNumber = 0;
_portrait._images = _talkPics;
_portrait._imageFrame = &(*_talkPics)[0];
_portrait._position = Common::Point(_portraitSide, 10);
_portrait._delta = Common::Point(0, 0);
_portrait._oldPosition = Common::Point(0, 0);
_portrait._goto = Common::Point(0, 0);
_portrait._flags = 5;
_portrait._status = 0;
_portrait._misc = 0;
_portrait._allow = 0;
_portrait._type = ACTIVE_BG_SHAPE;
_portrait._name = " ";
_portrait._description = " ";
_portrait._examine = " ";
_portrait._walkCount = 0;
if (_holmesFlip || _speakerFlip) {
_portrait._flags |= 2;
_holmesFlip = false;
_speakerFlip = false;
}
if (_portraitSide == 20)
_portraitSide = 220;
else
_portraitSide = 20;
_portraitLoaded = true;
}
}
} // End of namespace Scalpel
} // End of namespace Sherlock

View file

@ -0,0 +1,59 @@
/* 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_SCALPEL_PEOPLE_H
#define SHERLOCK_SCALPEL_PEOPLE_H
#include "common/scummsys.h"
#include "sherlock/people.h"
namespace Sherlock {
class SherlockEngine;
namespace Scalpel {
// Animation sequence identifiers for characters
enum ScalpelSequences {
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 ScalpelPeople : public People {
public:
ScalpelPeople(SherlockEngine *vm) : People(vm) {}
virtual ~ScalpelPeople() {}
/**
* Setup the data for an animating speaker portrait at the top of the screen
*/
void setTalking(int speaker);
};
} // End of namespace Scalpel
} // End of namespace Sherlock
#endif

View file

@ -21,6 +21,7 @@
*/
#include "sherlock/scalpel/scalpel_scene.h"
#include "sherlock/scalpel/scalpel_people.h"
#include "sherlock/scalpel/scalpel.h"
#include "sherlock/events.h"
#include "sherlock/people.h"

View file

@ -21,6 +21,7 @@
*/
#include "sherlock/scalpel/scalpel_talk.h"
#include "sherlock/scalpel/scalpel_people.h"
#include "sherlock/scalpel/scalpel_user_interface.h"
#include "sherlock/sherlock.h"
#include "sherlock/screen.h"
@ -154,6 +155,28 @@ ScalpelTalk::ScalpelTalk(SherlockEngine *vm) : Talk(vm) {
_opcodeTable = OPCODE_METHODS;
}
OpcodeReturn ScalpelTalk::cmdSwitchSpeaker(const byte *&str) {
ScalpelPeople &people = *(ScalpelPeople *)_vm->_people;
UserInterface &ui = *_vm->_ui;
if (!(_speaker & SPEAKER_REMOVE))
people.clearTalking();
if (_talkToAbort)
return RET_EXIT;
ui.clearWindow();
_yp = CONTROLS_Y + 12;
_charCount = _line = 0;
_speaker = *++str - 1;
people.setTalking(_speaker);
pullSequence();
pushSequence(_speaker);
setSequence(_speaker);
return RET_SUCCESS;
}
OpcodeReturn ScalpelTalk::cmdAssignPortraitLocation(const byte *&str) {
People &people = *_vm->_people;

View file

@ -37,6 +37,7 @@ namespace Scalpel {
class ScalpelTalk : public Talk {
private:
OpcodeReturn cmdSwitchSpeaker(const byte *&str);
OpcodeReturn cmdAssignPortraitLocation(const byte *&str);
OpcodeReturn cmdClearInfoLine(const byte *&str);
OpcodeReturn cmdClearWindow(const byte *&str);

View file

@ -21,6 +21,7 @@
*/
#include "sherlock/scalpel/scalpel_user_interface.h"
#include "sherlock/scalpel/scalpel_people.h"
#include "sherlock/sherlock.h"
#include "sherlock/scalpel/settings.h"
@ -1468,7 +1469,7 @@ void ScalpelUserInterface::doPickControl() {
void ScalpelUserInterface::doTalkControl() {
Events &events = *_vm->_events;
Journal &journal = *_vm->_journal;
People &people = *_vm->_people;
ScalpelPeople &people = *(ScalpelPeople *)_vm->_people;
Screen &screen = *_vm->_screen;
Sound &sound = *_vm->_sound;
Talk &talk = *_vm->_talk;

View file

@ -22,9 +22,10 @@
#include "sherlock/scene.h"
#include "sherlock/sherlock.h"
#include "sherlock/scalpel/scalpel.h"
#include "sherlock/scalpel/scalpel_scene.h"
#include "sherlock/screen.h"
#include "sherlock/scalpel/scalpel.h"
#include "sherlock/scalpel/scalpel_people.h"
#include "sherlock/scalpel/scalpel_scene.h"
#include "sherlock/tattoo/tattoo.h"
#include "sherlock/tattoo/tattoo_scene.h"
#include "sherlock/tattoo/tattoo_user_interface.h"
@ -32,8 +33,8 @@
namespace Sherlock {
static const int FS_TRANS[8] = {
STOP_UP, STOP_UPRIGHT, STOP_RIGHT, STOP_DOWNRIGHT, STOP_DOWN,
STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT
Scalpel::STOP_UP, Scalpel::STOP_UPRIGHT, Scalpel::STOP_RIGHT, Scalpel::STOP_DOWNRIGHT,
Scalpel::STOP_DOWN, Scalpel::STOP_DOWNLEFT, Scalpel::STOP_LEFT, Scalpel::STOP_UPLEFT
};
/*----------------------------------------------------------------*/

View file

@ -213,6 +213,11 @@ public:
*/
int charWidth(char c);
/**
* Return the font height
*/
int fontHeight() const { return _fontHeight; }
/**
* Fills an area on the back buffer, and then copies it to the screen
*/

View file

@ -97,7 +97,7 @@ void SherlockEngine::initialize() {
_map = new Map(this);
_music = new Music(this, _mixer);
_journal = new Journal(this);
_people = new People(this);
_people = People::init(this);
_saves = new SaveManager(this, _targetName);
_scene = Scene::init(this);
_screen = new Screen(this);

View file

@ -23,6 +23,7 @@
#include "sherlock/talk.h"
#include "sherlock/sherlock.h"
#include "sherlock/screen.h"
#include "sherlock/scalpel/scalpel_people.h"
#include "sherlock/scalpel/scalpel_talk.h"
#include "sherlock/scalpel/scalpel_user_interface.h"
#include "sherlock/tattoo/tattoo_talk.h"
@ -949,7 +950,6 @@ void Talk::doScript(const Common::String &script) {
_scriptStart = (const byte *)script.c_str();
_scriptEnd = _scriptStart + script.size();
const byte *str = _scriptStart;
_yp = CONTROLS_Y + 12;
_charCount = 0;
_line = 0;
_wait = 0;
@ -958,6 +958,11 @@ void Talk::doScript(const Common::String &script) {
_noTextYet = true;
_endStr = false;
if (IS_SERRATED_SCALPEL)
_yp = CONTROLS_Y + 12;
else
_yp = (_talkTo == -1) ? 5 : screen.fontHeight() + 11;
if (IS_ROSE_TATTOO) {
for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) {
Person &p = people[idx];
@ -1015,12 +1020,14 @@ void Talk::doScript(const Common::String &script) {
str += 2;
}
if (IS_SERRATED_SCALPEL) {
// Remove portrait?
if (str[0] == _opcodes[OP_REMOVE_PORTRAIT]) {
if ( str[0] == _opcodes[OP_REMOVE_PORTRAIT]) {
_speaker = -1;
} else {
// Nope, so set the first speaker
people.setTalking(_speaker);
((Scalpel::ScalpelPeople *)_vm->_people)->setTalking(_speaker);
}
}
}
}
@ -1567,28 +1574,6 @@ OpcodeReturn Talk::cmdStealthModeDeactivate(const byte *&str) {
return RET_SUCCESS;
}
OpcodeReturn Talk::cmdSwitchSpeaker(const byte *&str) {
People &people = *_vm->_people;
UserInterface &ui = *_vm->_ui;
if (!(_speaker & SPEAKER_REMOVE))
people.clearTalking();
if (_talkToAbort)
return RET_EXIT;
ui.clearWindow();
_yp = CONTROLS_Y + 12;
_charCount = _line = 0;
_speaker = *++str - 1;
people.setTalking(_speaker);
pullSequence();
pushSequence(_speaker);
setSequence(_speaker);
return RET_SUCCESS;
}
OpcodeReturn Talk::cmdToggleObject(const byte *&str) {
Scene &scene = *_vm->_scene;
Common::String tempString;

View file

@ -248,7 +248,6 @@ protected:
OpcodeReturn cmdSetObject(const byte *&str);
OpcodeReturn cmdStealthModeActivate(const byte *&str);
OpcodeReturn cmdStealthModeDeactivate(const byte *&str);
OpcodeReturn cmdSwitchSpeaker(const byte *&str);
OpcodeReturn cmdToggleObject(const byte *&str);
OpcodeReturn cmdWalkToCAnimation(const byte *&str);
OpcodeReturn cmdWalkToCoords(const byte *&str);

View file

@ -0,0 +1,39 @@
/* 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/tattoo/tattoo_people.h"
namespace Sherlock {
namespace Tattoo {
void TattooPeople::setListenSequence(int speaker, int sequenceNum) {
// TODO
}
void TattooPeople::setTalkSequence(int speaker, int sequenceNum) {
// TODO
}
} // End of namespace Tattoo
} // End of namespace Sherlock

View file

@ -0,0 +1,104 @@
/* 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_TATTOO_PEOPLE_H
#define SHERLOCK_TATTOO_PEOPLE_H
#include "common/scummsys.h"
#include "sherlock/people.h"
namespace Sherlock {
class SherlockEngine;
namespace Tattoo {
// Animation sequence identifiers for characters
enum TattooSequences {
// Walk Sequences Numbers for NPCs
WALK_UP = 0,
WALK_UPRIGHT = 1,
WALK_RIGHT = 2,
WALK_DOWNRIGHT = 3,
WALK_DOWN = 4,
WALK_DOWNLEFT = 5,
WALK_LEFT = 6,
WALK_UPLEFT = 7,
// Stop Sequences Numbers for NPCs
STOP_UP = 8,
STOP_UPRIGHT = 9,
STOP_RIGHT = 10,
STOP_DOWNRIGHT = 11,
STOP_DOWN = 12,
STOP_DOWNLEFT = 13,
STOP_LEFT = 14,
STOP_UPLEFT = 15,
// NPC Talk Sequence Numbers
TALK_UPRIGHT = 16,
TALK_RIGHT = 17,
TALK_DOWNRIGHT = 18,
TALK_DOWNLEFT = 19,
TALK_LEFT = 20,
TALK_UPLEFT = 21,
// NPC Listen Sequence Numbers
LISTEN_UPRIGHT = 22,
LISTEN_RIGHT = 23,
LISTEN_DOWNRIGHT = 24,
LISTEN_DOWNLEFT = 25,
LISTEN_LEFT = 26,
LISTEN_UPLEFT = 27
};
class TattooPeople : public People {
public:
TattooPeople(SherlockEngine *vm) : People(vm) {}
virtual ~TattooPeople() {}
/**
* If the specified speaker is a background object, it will set it so that it uses
* the Listen Sequence (specified by the sequence number). If the current sequence
* has an Allow Talk Code in it, the _gotoSeq field will be set so that the object
* begins listening as soon as it hits the Allow Talk Code. If there is no Abort Code,
* the Listen Sequence will begin immediately.
* @param speaker Who is speaking
* @param sequenceNum Which listen sequence to use
*/
void setListenSequence(int speaker, int sequenceNum);
/**
* If the specified speaker is a background object, this will set it so that it uses
* the Talk Sequence specified. If the current sequence has an Allow Talk Code in it,
* _gotoSeq will be set so that the object begins talking as soon as it hits the
* Allow Talk Code. If there is no Abort Code, the Talk Sequence will begin immediately.
*/
void setTalkSequence(int speaker, int sequenceNum);
};
} // End of namespace Scalpel
} // End of namespace Sherlock
#endif

View file

@ -21,6 +21,7 @@
*/
#include "sherlock/tattoo/tattoo_talk.h"
#include "sherlock/tattoo/tattoo_people.h"
#include "sherlock/sherlock.h"
#include "sherlock/screen.h"
@ -29,10 +30,9 @@ namespace Sherlock {
namespace Tattoo {
static const uint8 DIRECTION_CONVERSION[] = {
WALK_RIGHT, WALK_DOWN, WALK_LEFT, WALK_UP,
STOP_RIGHT, STOP_DOWN, STOP_LEFT, STOP_UP,
WALK_UPRIGHT, WALK_DOWNRIGHT, WALK_UPLEFT, WALK_DOWNLEFT,
STOP_UPRIGHT, STOP_UPLEFT, STOP_DOWNRIGHT, STOP_DOWNLEFT
WALK_RIGHT, WALK_DOWN, WALK_LEFT, WALK_UP, STOP_RIGHT, STOP_DOWN, STOP_LEFT, STOP_UP,
WALK_UPRIGHT, WALK_DOWNRIGHT, WALK_UPLEFT, WALK_DOWNLEFT, STOP_UPRIGHT, STOP_UPLEFT,
STOP_DOWNRIGHT, STOP_DOWNLEFT
};
const byte TATTOO_OPCODES[] = {
@ -207,45 +207,45 @@ void TattooTalk::setSequence(int speaker, int sequenceNum) {
int newDir = person._sequenceNumber;
switch (newDir) {
case RT_WALK_UP:
case RT_STOP_UP:
case RT_WALK_UPRIGHT:
case RT_STOP_UPRIGHT:
case RT_TALK_UPRIGHT:
case RT_LISTEN_UPRIGHT:
newDir = RT_TALK_UPRIGHT;
case WALK_UP:
case STOP_UP:
case WALK_UPRIGHT:
case STOP_UPRIGHT:
case TALK_UPRIGHT:
case LISTEN_UPRIGHT:
newDir = TALK_UPRIGHT;
break;
case RT_WALK_RIGHT:
case RT_STOP_RIGHT:
case RT_TALK_RIGHT:
case RT_LISTEN_RIGHT:
newDir = RT_TALK_RIGHT;
case WALK_RIGHT:
case STOP_RIGHT:
case TALK_RIGHT:
case LISTEN_RIGHT:
newDir = TALK_RIGHT;
break;
case RT_WALK_DOWNRIGHT:
case RT_STOP_DOWNRIGHT:
case RT_TALK_DOWNRIGHT:
case RT_LISTEN_DOWNRIGHT:
newDir = RT_TALK_DOWNRIGHT;
case WALK_DOWNRIGHT:
case STOP_DOWNRIGHT:
case TALK_DOWNRIGHT:
case LISTEN_DOWNRIGHT:
newDir = TALK_DOWNRIGHT;
break;
case RT_WALK_DOWN:
case RT_STOP_DOWN:
case RT_WALK_DOWNLEFT:
case RT_STOP_DOWNLEFT:
case RT_TALK_DOWNLEFT:
case RT_LISTEN_DOWNLEFT:
newDir = RT_TALK_DOWNLEFT;
case WALK_DOWN:
case STOP_DOWN:
case WALK_DOWNLEFT:
case STOP_DOWNLEFT:
case TALK_DOWNLEFT:
case LISTEN_DOWNLEFT:
newDir = TALK_DOWNLEFT;
break;
case RT_WALK_LEFT:
case RT_STOP_LEFT:
case RT_TALK_LEFT:
case RT_LISTEN_LEFT:
newDir = RT_TALK_LEFT;
case WALK_LEFT:
case STOP_LEFT:
case TALK_LEFT:
case LISTEN_LEFT:
newDir = TALK_LEFT;
break;
case RT_WALK_UPLEFT:
case RT_STOP_UPLEFT:
case RT_TALK_UPLEFT:
case RT_LISTEN_UPLEFT:
newDir = RT_TALK_UPLEFT;
case WALK_UPLEFT:
case STOP_UPLEFT:
case TALK_UPLEFT:
case LISTEN_UPLEFT:
newDir = TALK_UPLEFT;
break;
default:
break;
@ -268,6 +268,26 @@ void TattooTalk::setSequence(int speaker, int sequenceNum) {
}
}
OpcodeReturn TattooTalk::cmdSwitchSpeaker(const byte *&str) {
TattooPeople &people = *(TattooPeople *)_vm->_people;
Screen &screen = *_vm->_screen;
UserInterface &ui = *_vm->_ui;
if (_talkToAbort)
return RET_EXIT;
ui.clearWindow();
_yp = screen.fontHeight() + 11;
_charCount = _line = 0;
people.setListenSequence(_speaker, 129);
_speaker = *++str - 1;
people.setTalkSequence(_speaker, 1);
return RET_SUCCESS;
}
OpcodeReturn TattooTalk::cmdMouseOnOff(const byte *&str) {
Events &events = *_vm->_events;
bool mouseOn = *++str == 2;

View file

@ -37,6 +37,7 @@ namespace Tattoo {
class TattooTalk : public Talk {
private:
OpcodeReturn cmdSwitchSpeaker(const byte *&str);
OpcodeReturn cmdMouseOnOff(const byte *&str);
OpcodeReturn cmdNextSong(const byte *&str);
OpcodeReturn cmdPassword(const byte *&str);