SHERLOCK: Implemented initial background clearing of RT doBgAnim

This commit is contained in:
Paul Gilbert 2015-05-27 20:26:40 -04:00
parent 483a72b8b8
commit 0d4163c6e9
12 changed files with 528 additions and 320 deletions

View File

@ -244,7 +244,7 @@ void Inventory::drawInventory(InvNewMode mode) {
}
assert(IS_SERRATED_SCALPEL);
((ScalpelUserInterface *)_vm->_ui)->_oldUse = -1;
((Scalpel::ScalpelUserInterface *)_vm->_ui)->_oldUse = -1;
}
void Inventory::invCommands(bool slamIt) {
@ -324,7 +324,7 @@ void Inventory::refreshInv() {
Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
ScalpelUserInterface &ui = *(ScalpelUserInterface *)_vm->_ui;
Scalpel::ScalpelUserInterface &ui = *(Scalpel::ScalpelUserInterface *)_vm->_ui;
ui._invLookFlag = true;
freeInv();

View File

@ -24,6 +24,7 @@
#include "sherlock/sherlock.h"
#include "sherlock/scalpel/scalpel.h"
#include "sherlock/screen.h"
#include "sherlock/tattoo/tattoo.h"
namespace Sherlock {
@ -152,9 +153,9 @@ void ScaleZone::load(Common::SeekableReadStream &s) {
Scene *Scene::init(SherlockEngine *vm) {
if (vm->getGameID() == GType_SerratedScalpel)
return new ScalpelScene(vm);
return new Scalpel::ScalpelScene(vm);
else
return new TattooScene(vm);
return new Tattoo::TattooScene(vm);
}
Scene::Scene(SherlockEngine *vm): _vm(vm) {
@ -1197,294 +1198,6 @@ int Scene::startCAnim(int cAnimNum, int playRate) {
return 1;
}
void Scene::doBgAnim() {
Events &events = *_vm->_events;
People &people = *_vm->_people;
Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
Common::Point mousePos = events.mousePos();
events.animateCursorIfNeeded();
screen.setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT));
talk._talkToAbort = false;
if (_restoreFlag) {
if (people[AL]._type == CHARACTER)
people[AL].checkSprite();
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE)
_bgShapes[idx].checkObject();
}
if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE)
people._portrait.checkObject();
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
if (_canimShapes[idx]._type != INVALID && _canimShapes[idx]._type != REMOVE)
_canimShapes[idx].checkObject();
}
if (_currentScene == 12 && IS_SERRATED_SCALPEL)
((Scalpel::ScalpelEngine *)_vm)->eraseMirror12();
// Restore the back buffer from the back buffer 2 in the changed area
Common::Rect bounds(people[AL]._oldPosition.x, people[AL]._oldPosition.y,
people[AL]._oldPosition.x + people[AL]._oldSize.x,
people[AL]._oldPosition.y + people[AL]._oldSize.y);
Common::Point pt(bounds.left, bounds.top);
if (people[AL]._type == CHARACTER)
screen.restoreBackground(bounds);
else if (people[AL]._type == REMOVE)
screen._backBuffer->blitFrom(screen._backBuffer2, pt, bounds);
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == ACTIVE_BG_SHAPE || o._type == HIDE_SHAPE || o._type == REMOVE)
screen.restoreBackground(o.getOldBounds());
}
if (people._portraitLoaded)
screen.restoreBackground(Common::Rect(
people._portrait._oldPosition.x, people._portrait._oldPosition.y,
people._portrait._oldPosition.x + people._portrait._oldSize.x,
people._portrait._oldPosition.y + people._portrait._oldSize.y
));
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == NO_SHAPE && ((o._flags & OBJ_BEHIND) == 0)) {
// Restore screen area
screen._backBuffer->blitFrom(screen._backBuffer2, o._position,
Common::Rect(o._position.x, o._position.y,
o._position.x + o._noShapeSize.x, o._position.y + o._noShapeSize.y));
o._oldPosition = o._position;
o._oldSize = o._noShapeSize;
}
}
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
Object &o = _canimShapes[idx];
if (o._type == ACTIVE_BG_SHAPE || o._type == HIDE_SHAPE || o._type == REMOVE)
screen.restoreBackground(Common::Rect(o._oldPosition.x, o._oldPosition.y,
o._oldPosition.x + o._oldSize.x, o._oldPosition.y + o._oldSize.y));
}
}
//
// Update the background objects and canimations
//
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == ACTIVE_BG_SHAPE || o._type == NO_SHAPE)
o.adjustObject();
}
if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE)
people._portrait.adjustObject();
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
if (_canimShapes[idx]._type != INVALID)
_canimShapes[idx].adjustObject();
}
if (people[AL]._type == CHARACTER && people._holmesOn)
people[AL].adjustSprite();
// Flag the bg shapes which need to be redrawn
checkBgShapes();
if (_currentScene == 12 && IS_SERRATED_SCALPEL)
((Scalpel::ScalpelEngine *)_vm)->doMirror12();
// Draw all active shapes which are behind the person
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND)
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
// Draw all canimations which are behind the person
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
Object &o = _canimShapes[idx];
if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) {
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
}
// Draw all active shapes which are HAPPEN and behind the person
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND)
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
// Draw all canimations which are NORMAL and behind the person
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
Object &o = _canimShapes[idx];
if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) {
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
}
// Draw the person if not animating
if (people[AL]._type == CHARACTER && people[AL]._walkLoaded) {
// If Holmes is too far to the right, move him back so he's on-screen
int xRight = SHERLOCK_SCREEN_WIDTH - 2 - people[AL]._imageFrame->_frame.w;
int tempX = MIN(people[AL]._position.x / FIXED_INT_MULTIPLIER, xRight);
bool flipped = people[AL]._sequenceNumber == WALK_LEFT || people[AL]._sequenceNumber == STOP_LEFT ||
people[AL]._sequenceNumber == WALK_UPLEFT || people[AL]._sequenceNumber == STOP_UPLEFT ||
people[AL]._sequenceNumber == WALK_DOWNRIGHT || people[AL]._sequenceNumber == STOP_DOWNRIGHT;
screen._backBuffer->transBlitFrom(*people[AL]._imageFrame,
Common::Point(tempX, people[AL]._position.y / FIXED_INT_MULTIPLIER - people[AL]._imageFrame->_frame.h), flipped);
}
// Draw all static and active shapes are NORMAL and are in front of the person
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD)
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
// Draw all static and active canimations that are NORMAL and are in front of the person
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
Object &o = _canimShapes[idx];
if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) {
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
}
// Draw all static and active shapes that are in front of the person
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD)
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
// Draw any active portrait
if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE)
screen._backBuffer->transBlitFrom(*people._portrait._imageFrame,
people._portrait._position, people._portrait._flags & OBJ_FLIPPED);
// Draw all static and active canimations that are in front of the person
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
Object &o = _canimShapes[idx];
if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) {
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
}
// Draw all NO_SHAPE shapes which have flag bit 0 clear
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == NO_SHAPE && (o._flags & OBJ_BEHIND) == 0)
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
// Bring the newly built picture to the screen
if (_animating == 2) {
_animating = 0;
screen.slamRect(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT));
} else {
if (people[AL]._type != INVALID && ((_goToScene == -1 || _canimShapes.empty()))) {
if (people[AL]._type == REMOVE) {
screen.slamRect(Common::Rect(
people[AL]._oldPosition.x, people[AL]._oldPosition.y,
people[AL]._oldPosition.x + people[AL]._oldSize.x,
people[AL]._oldPosition.y + people[AL]._oldSize.y
));
people[AL]._type = INVALID;
} else {
screen.flushImage(people[AL]._imageFrame,
Common::Point(people[AL]._position.x / FIXED_INT_MULTIPLIER,
people[AL]._position.y / FIXED_INT_MULTIPLIER - people[AL].frameHeight()),
&people[AL]._oldPosition.x, &people[AL]._oldPosition.y,
&people[AL]._oldSize.x, &people[AL]._oldSize.y);
}
}
if (_currentScene == 12 && IS_SERRATED_SCALPEL)
((Scalpel::ScalpelEngine *)_vm)->flushMirror12();
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if ((o._type == ACTIVE_BG_SHAPE || o._type == REMOVE) && _goToScene == -1) {
screen.flushImage(o._imageFrame, o._position,
&o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y);
}
}
if (people._portraitLoaded) {
if (people._portrait._type == REMOVE)
screen.slamRect(Common::Rect(
people._portrait._position.x, people._portrait._position.y,
people._portrait._position.x + people._portrait._delta.x,
people._portrait._position.y + people._portrait._delta.y
));
else
screen.flushImage(people._portrait._imageFrame, people._portrait._position,
&people._portrait._oldPosition.x, &people._portrait._oldPosition.y,
&people._portrait._oldSize.x, &people._portrait._oldSize.y);
if (people._portrait._type == REMOVE)
people._portrait._type = INVALID;
}
if (_goToScene == -1) {
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == NO_SHAPE && (o._flags & OBJ_BEHIND) == 0) {
screen.slamArea(o._position.x, o._position.y, o._oldSize.x, o._oldSize.y);
screen.slamArea(o._oldPosition.x, o._oldPosition.y, o._oldSize.x, o._oldSize.y);
} else if (o._type == HIDE_SHAPE) {
// Hiding shape, so flush it out and mark it as hidden
screen.flushImage(o._imageFrame, o._position,
&o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y);
o._type = HIDDEN;
}
}
}
for (int idx = _canimShapes.size() - 1; idx >= 0; --idx) {
Object &o = _canimShapes[idx];
if (o._type == INVALID) {
// Anim shape was invalidated by checkEndOfSequence, so at this point we can remove it
_canimShapes.remove_at(idx);
} else if (o._type == REMOVE) {
if (_goToScene == -1)
screen.slamArea(o._position.x, o._position.y, o._delta.x, o._delta.y);
// Shape for an animation is no longer needed, so remove it completely
_canimShapes.remove_at(idx);
} else if (o._type == ACTIVE_BG_SHAPE) {
screen.flushImage(o._imageFrame, o._position,
&o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y);
}
}
}
_restoreFlag = true;
_doBgAnimDone = true;
events.wait(3);
screen.resetDisplayBounds();
// Check if the method was called for calling a portrait, and a talk was
// interrupting it. This talk file would not have been executed at the time,
// since we needed to finish the 'doBgAnim' to finish clearing the portrait
if (people._clearingThePortrait && talk._scriptMoreFlag == 3) {
// Reset the flags and call to talk
people._clearingThePortrait = false;
talk._scriptMoreFlag = 0;
talk.talkTo(talk._scriptName);
}
}
int Scene::findBgShape(const Common::Rect &r) {
if (!_doBgAnimDone)
// New frame hasn't been drawn yet
@ -1614,6 +1327,8 @@ void Scene::checkBgShapes() {
/*----------------------------------------------------------------*/
namespace Scalpel {
void ScalpelScene::checkBgShapes() {
People &people = *_vm->_people;
Person &holmes = people._player;
@ -1638,7 +1353,7 @@ void ScalpelScene::checkBgShapes() {
}
}
void ScalpelScene::doBgAnim() {
void ScalpelScene::doBgAnimCheckCursor() {
Inventory &inv = *_vm->_inventory;
Events &events = *_vm->_events;
Sound &sound = *_vm->_sound;
@ -1669,15 +1384,307 @@ void ScalpelScene::doBgAnim() {
// Loaded sound just finished playing
sound.freeDigiSound();
}
// Handle doing the actual drawing
Scene::doBgAnim();
}
void ScalpelScene::doBgAnim() {
Scalpel::ScalpelEngine &vm = *((Scalpel::ScalpelEngine *)_vm);
Events &events = *_vm->_events;
People &people = *_vm->_people;
Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
screen.setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT));
talk._talkToAbort = false;
if (_restoreFlag) {
for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
if (people[idx]._type == CHARACTER)
people[idx].checkSprite();
}
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE)
_bgShapes[idx].checkObject();
}
if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE)
people._portrait.checkObject();
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
if (_canimShapes[idx]._type != INVALID && _canimShapes[idx]._type != REMOVE)
_canimShapes[idx].checkObject();
}
if (_currentScene == 12)
vm.eraseMirror12();
// Restore the back buffer from the back buffer 2 in the changed area
Common::Rect bounds(people[AL]._oldPosition.x, people[AL]._oldPosition.y,
people[AL]._oldPosition.x + people[AL]._oldSize.x,
people[AL]._oldPosition.y + people[AL]._oldSize.y);
Common::Point pt(bounds.left, bounds.top);
if (people[AL]._type == CHARACTER)
screen.restoreBackground(bounds);
else if (people[AL]._type == REMOVE)
screen._backBuffer->blitFrom(screen._backBuffer2, pt, bounds);
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == ACTIVE_BG_SHAPE || o._type == HIDE_SHAPE || o._type == REMOVE)
screen.restoreBackground(o.getOldBounds());
}
if (people._portraitLoaded)
screen.restoreBackground(Common::Rect(
people._portrait._oldPosition.x, people._portrait._oldPosition.y,
people._portrait._oldPosition.x + people._portrait._oldSize.x,
people._portrait._oldPosition.y + people._portrait._oldSize.y
));
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == NO_SHAPE && ((o._flags & OBJ_BEHIND) == 0)) {
// Restore screen area
screen._backBuffer->blitFrom(screen._backBuffer2, o._position,
Common::Rect(o._position.x, o._position.y,
o._position.x + o._noShapeSize.x, o._position.y + o._noShapeSize.y));
o._oldPosition = o._position;
o._oldSize = o._noShapeSize;
}
}
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
Object &o = _canimShapes[idx];
if (o._type == ACTIVE_BG_SHAPE || o._type == HIDE_SHAPE || o._type == REMOVE)
screen.restoreBackground(Common::Rect(o._oldPosition.x, o._oldPosition.y,
o._oldPosition.x + o._oldSize.x, o._oldPosition.y + o._oldSize.y));
}
}
//
// Update the background objects and canimations
//
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == ACTIVE_BG_SHAPE || o._type == NO_SHAPE)
o.adjustObject();
}
if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE)
people._portrait.adjustObject();
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
if (_canimShapes[idx]._type != INVALID)
_canimShapes[idx].adjustObject();
}
if (people[AL]._type == CHARACTER && people._holmesOn)
people[AL].adjustSprite();
// Flag the bg shapes which need to be redrawn
checkBgShapes();
if (_currentScene == 12)
vm.doMirror12();
// Draw all active shapes which are behind the person
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND)
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
// Draw all canimations which are behind the person
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
Object &o = _canimShapes[idx];
if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) {
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
}
// Draw all active shapes which are HAPPEN and behind the person
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND)
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
// Draw all canimations which are NORMAL and behind the person
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
Object &o = _canimShapes[idx];
if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) {
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
}
// Draw the person if not animating
if (people[AL]._type == CHARACTER && people[AL]._walkLoaded) {
// If Holmes is too far to the right, move him back so he's on-screen
int xRight = SHERLOCK_SCREEN_WIDTH - 2 - people[AL]._imageFrame->_frame.w;
int tempX = MIN(people[AL]._position.x / FIXED_INT_MULTIPLIER, xRight);
bool flipped = people[AL]._sequenceNumber == WALK_LEFT || people[AL]._sequenceNumber == STOP_LEFT ||
people[AL]._sequenceNumber == WALK_UPLEFT || people[AL]._sequenceNumber == STOP_UPLEFT ||
people[AL]._sequenceNumber == WALK_DOWNRIGHT || people[AL]._sequenceNumber == STOP_DOWNRIGHT;
screen._backBuffer->transBlitFrom(*people[AL]._imageFrame,
Common::Point(tempX, people[AL]._position.y / FIXED_INT_MULTIPLIER - people[AL]._imageFrame->_frame.h), flipped);
}
// Draw all static and active shapes are NORMAL and are in front of the person
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD)
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
// Draw all static and active canimations that are NORMAL and are in front of the person
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
Object &o = _canimShapes[idx];
if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) {
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
}
// Draw all static and active shapes that are in front of the person
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD)
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
// Draw any active portrait
if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE)
screen._backBuffer->transBlitFrom(*people._portrait._imageFrame,
people._portrait._position, people._portrait._flags & OBJ_FLIPPED);
// Draw all static and active canimations that are in front of the person
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
Object &o = _canimShapes[idx];
if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) {
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
}
// Draw all NO_SHAPE shapes which have flag bit 0 clear
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == NO_SHAPE && (o._flags & OBJ_BEHIND) == 0)
screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED);
}
// Bring the newly built picture to the screen
if (_animating == 2) {
_animating = 0;
screen.slamRect(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT));
} else {
if (people[AL]._type != INVALID && ((_goToScene == -1 || _canimShapes.empty()))) {
if (people[AL]._type == REMOVE) {
screen.slamRect(Common::Rect(
people[AL]._oldPosition.x, people[AL]._oldPosition.y,
people[AL]._oldPosition.x + people[AL]._oldSize.x,
people[AL]._oldPosition.y + people[AL]._oldSize.y
));
people[AL]._type = INVALID;
} else {
screen.flushImage(people[AL]._imageFrame,
Common::Point(people[AL]._position.x / FIXED_INT_MULTIPLIER,
people[AL]._position.y / FIXED_INT_MULTIPLIER - people[AL].frameHeight()),
&people[AL]._oldPosition.x, &people[AL]._oldPosition.y,
&people[AL]._oldSize.x, &people[AL]._oldSize.y);
}
}
if (_currentScene == 12)
vm.flushMirror12();
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if ((o._type == ACTIVE_BG_SHAPE || o._type == REMOVE) && _goToScene == -1) {
screen.flushImage(o._imageFrame, o._position,
&o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y);
}
}
if (people._portraitLoaded) {
if (people._portrait._type == REMOVE)
screen.slamRect(Common::Rect(
people._portrait._position.x, people._portrait._position.y,
people._portrait._position.x + people._portrait._delta.x,
people._portrait._position.y + people._portrait._delta.y
));
else
screen.flushImage(people._portrait._imageFrame, people._portrait._position,
&people._portrait._oldPosition.x, &people._portrait._oldPosition.y,
&people._portrait._oldSize.x, &people._portrait._oldSize.y);
if (people._portrait._type == REMOVE)
people._portrait._type = INVALID;
}
if (_goToScene == -1) {
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &o = _bgShapes[idx];
if (o._type == NO_SHAPE && (o._flags & OBJ_BEHIND) == 0) {
screen.slamArea(o._position.x, o._position.y, o._oldSize.x, o._oldSize.y);
screen.slamArea(o._oldPosition.x, o._oldPosition.y, o._oldSize.x, o._oldSize.y);
} else if (o._type == HIDE_SHAPE) {
// Hiding shape, so flush it out and mark it as hidden
screen.flushImage(o._imageFrame, o._position,
&o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y);
o._type = HIDDEN;
}
}
}
for (int idx = _canimShapes.size() - 1; idx >= 0; --idx) {
Object &o = _canimShapes[idx];
if (o._type == INVALID) {
// Anim shape was invalidated by checkEndOfSequence, so at this point we can remove it
_canimShapes.remove_at(idx);
} else if (o._type == REMOVE) {
if (_goToScene == -1)
screen.slamArea(o._position.x, o._position.y, o._delta.x, o._delta.y);
// Shape for an animation is no longer needed, so remove it completely
_canimShapes.remove_at(idx);
} else if (o._type == ACTIVE_BG_SHAPE) {
screen.flushImage(o._imageFrame, o._position,
&o._oldPosition.x, &o._oldPosition.y, &o._oldSize.x, &o._oldSize.y);
}
}
}
_restoreFlag = true;
_doBgAnimDone = true;
events.wait(3);
screen.resetDisplayBounds();
// Check if the method was called for calling a portrait, and a talk was
// interrupting it. This talk file would not have been executed at the time,
// since we needed to finish the 'doBgAnim' to finish clearing the portrait
if (people._clearingThePortrait && talk._scriptMoreFlag == 3) {
// Reset the flags and call to talk
people._clearingThePortrait = false;
talk._scriptMoreFlag = 0;
talk.talkTo(talk._scriptName);
}
}
} // End of namespace Scalpel
/*----------------------------------------------------------------*/
namespace Tattoo {
TattooScene::TattooScene(SherlockEngine *vm) : Scene(vm) {
_arrowZone = -1;
_mask = _mask1 = nullptr;
_maskCounter = 0;
}
void TattooScene::checkBgShapes() {
@ -1707,7 +1714,7 @@ void TattooScene::checkBgShapes() {
}
}
void TattooScene::doBgAnim() {
void TattooScene::doBgAnimCheckCursor() {
Events &events = *_vm->_events;
UserInterface &ui = *_vm->_ui;
Common::Point mousePos = events.mousePos();
@ -1731,10 +1738,106 @@ void TattooScene::doBgAnim() {
events.setCursor(cursorId);
}
// Handle doing the actual drawing
_restoreFlag = true;
Scene::doBgAnim();
}
void TattooScene::doBgAnimHandleMask() {
TattooEngine &vm = *((TattooEngine *)_vm);
People &people = *_vm->_people;
Screen &screen = *_vm->_screen;
TattooUserInterface &ui = *((TattooUserInterface *)_vm->_ui);
static const int16 OFFSETS[16] = { -1, -2, -3, -3, -2, -1, -1, 0, 1, 2, 3, 3, 2, 1, 0, 0 };
if (_mask != nullptr) {
if (screen._backBuffer1.w() > screen.w())
screen.blitFrom(screen._backBuffer1, Common::Point(0, 0), Common::Rect(screen._currentScroll, 0,
screen._currentScroll + screen.w(), screen.h()));
else
screen.blitFrom(screen._backBuffer1);
switch (_currentScene) {
case 7:
if (++_maskCounter == 2) {
_maskCounter = 0;
if (--_maskOffset.x < 0)
_maskOffset.x = SHERLOCK_SCREEN_WIDTH - 1;
}
break;
case 8:
_maskOffset.x += 2;
if (_maskOffset.x >= SHERLOCK_SCREEN_WIDTH)
_maskOffset.x = 0;
break;
case 18:
case 68:
++_maskCounter;
if (_maskCounter / 4 >= 16)
_maskCounter = 0;
_maskOffset.x = OFFSETS[_maskCounter / 4];
break;
case 53:
if (++_maskCounter == 2) {
_maskCounter = 0;
if (++_maskOffset.x == screen._backBuffer1.w())
_maskOffset.x = 0;
}
break;
default:
break;
}
} else {
// Standard scene without mask, so call user interface to erase any UI elements as necessary
ui.doBgAnimRestoreUI();
// Restore background for any areas covered by characters and shapes
for (uint idx = 0; idx < MAX_CHARACTERS; ++idx)
screen.restoreBackground(Common::Rect(people[idx]._oldPosition.x, people[idx]._oldPosition.y,
people[idx]._oldPosition.x + people[idx]._oldSize.x, people[idx]._oldPosition.y + people[idx]._oldSize.y));
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &obj = _bgShapes[idx];
if ((obj._type == ACTIVE_BG_SHAPE && (obj._maxFrames > 1 || obj._delta.x != 0 || obj._delta.y != 0)) ||
obj._type == HIDE_SHAPE || obj._type == REMOVE)
screen._backBuffer1.blitFrom(*obj._imageFrame, obj._oldPosition,
Common::Rect(obj._oldPosition.x, obj._oldPosition.y, obj._oldPosition.x + obj._oldSize.x,
obj._oldPosition.y + obj._oldSize.y));
}
// If credits are active, erase the area they cover
if (vm._creditsActive)
vm.eraseCredits();
}
}
void TattooScene::doBgAnim() {
doBgAnimCheckCursor();
// Events &events = *_vm->_events;
People &people = *_vm->_people;
// Scene &scene = *_vm->_scene;
Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
screen.setDisplayBounds(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT));
talk._talkToAbort = false;
for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
if (people[idx]._type == CHARACTER)
people[idx].checkSprite();
}
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE)
_bgShapes[idx].checkObject();
}
}
} // End of namespace Tattoo
} // End of namespace Sherlock

View File

@ -275,7 +275,7 @@ public:
/**
* Draw all objects and characters.
*/
virtual void doBgAnim();
virtual void doBgAnim() = 0;
/**
* Attempts to find a background shape within the passed bounds. If found,
@ -318,7 +318,11 @@ public:
void setNPCPath(int npc);
};
namespace Scalpel {
class ScalpelScene : public Scene {
private:
void doBgAnimCheckCursor();
protected:
/**
* Checks all the background shapes. If a background shape is animating,
@ -335,10 +339,19 @@ public:
virtual void doBgAnim();
};
} // End of namespace Scalpel
namespace Tattoo {
class TattooScene : public Scene {
private:
CAnimStream _activeCAnim;
int _arrowZone;
int _maskCounter;
Common::Point _maskOffset;
private:
void doBgAnimCheckCursor();
void doBgAnimHandleMask();
protected:
/**
* Checks all the background shapes. If a background shape is animating,
@ -346,6 +359,9 @@ protected:
* colliding with another shape, it will also flag it as needing drawing
*/
virtual void checkBgShapes();
public:
ImageFile *_mask, *_mask1;
CAnimStream _activeCAnim;
public:
TattooScene(SherlockEngine *vm);
@ -355,6 +371,8 @@ public:
virtual void doBgAnim();
};
} // End of namespace Tattoo
} // End of namespace Sherlock
#endif

View File

@ -72,7 +72,6 @@ private:
byte _lookupTable[PALETTE_COUNT];
byte _lookupTable1[PALETTE_COUNT];
int _scrollSize;
int _currentScroll;
int _targetScroll;
private:
/**
@ -102,6 +101,7 @@ public:
byte _cMap[PALETTE_SIZE];
byte _sMap[PALETTE_SIZE];
byte _tMap[PALETTE_SIZE];
int _currentScroll;
public:
Screen(SherlockEngine *vm);
virtual ~Screen();

View File

@ -25,6 +25,8 @@
namespace Sherlock {
namespace Scalpel {
static const int SETUP_POINTS[12][4] = {
{ 4, 154, 101, 53 }, // Exit
{ 4, 165, 101, 53 }, // Music Toggle
@ -333,4 +335,6 @@ void Settings::show(SherlockEngine *vm) {
ui._key = -1;
}
} // End of namespace Scalpel
} // End of namespace Sherlock

View File

@ -28,7 +28,8 @@
namespace Sherlock {
class SherlockEngine;
class UserInterface;
namespace Scalpel {
class Settings {
private:
@ -55,6 +56,8 @@ public:
static void show(SherlockEngine *vm);
};
} // End of namespace Scalpel
} // End of namespace Sherlock
#endif

View File

@ -332,7 +332,7 @@ void Talk::talkTo(const Common::String &filename) {
if (IS_SERRATED_SCALPEL) {
// Restore any pressed button
if (!ui._windowOpen && savedMode != STD_MODE)
((ScalpelUserInterface *)_vm->_ui)->restoreButton((int)(savedMode - 1));
((Scalpel::ScalpelUserInterface *)_vm->_ui)->restoreButton((int)(savedMode - 1));
}
// Clear the ui counter so that anything displayed on the info line

View File

@ -108,8 +108,8 @@ enum {
enum OpcodeReturn { RET_EXIT = -1, RET_SUCCESS = 0, RET_CONTINUE = 1 };
class SherlockEngine;
class ScalpelUserInterface;
class Talk;
namespace Scalpel { class ScalpelUserInterface; };
typedef OpcodeReturn(Talk::*OpcodeMethod)(const byte *&str);
@ -164,7 +164,7 @@ struct TalkSequences {
};
class Talk {
friend class ScalpelUserInterface;
friend class Scalpel::ScalpelUserInterface;
private:
/**
* Remove any voice commands from a loaded statement list

View File

@ -27,13 +27,15 @@ namespace Sherlock {
namespace Tattoo {
TattooEngine::TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc) :
SherlockEngine(syst, gameDesc) {
_creditsActive = false;
}
void TattooEngine::showOpening() {
// TODO
}
/**
* Initialize the engine
*/
void TattooEngine::initialize() {
initGraphics(640, 480, true);
@ -52,9 +54,6 @@ void TattooEngine::initialize() {
loadInitialPalette();
}
/**
* Starting a scene within the game
*/
void TattooEngine::startScene() {
// TODO
}
@ -69,6 +68,10 @@ void TattooEngine::loadInitialPalette() {
delete stream;
}
void TattooEngine::eraseCredits() {
// TODO
}
} // End of namespace Tattoo
} // End of namespace Scalpel

View File

@ -36,16 +36,27 @@ private:
*/
void loadInitialPalette();
protected:
/**
* Initialize the engine
*/
virtual void initialize();
virtual void showOpening();
/**
* Starting a scene within the game
*/
virtual void startScene();
public:
TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc) :
SherlockEngine(syst, gameDesc) {}
bool _creditsActive;
public:
TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
virtual ~TattooEngine() {}
/**
* Erase any area of the screen covered by credits
*/
void eraseCredits();
};
} // End of namespace Tattoo

View File

@ -82,9 +82,9 @@ const char *const MUSE[] = {
UserInterface *UserInterface::init(SherlockEngine *vm) {
if (vm->getGameID() == GType_SerratedScalpel)
return new ScalpelUserInterface(vm);
return new Scalpel::ScalpelUserInterface(vm);
else
return new TattooUserInterface(vm);
return new Tattoo::TattooUserInterface(vm);
}
UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) {
@ -108,6 +108,8 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) {
/*----------------------------------------------------------------*/
namespace Scalpel {
ScalpelUserInterface::ScalpelUserInterface(SherlockEngine *vm): UserInterface(vm) {
_controls = new ImageFile("menu.all");
_controlPanel = new ImageFile("controls.vgs");
@ -2296,10 +2298,15 @@ void ScalpelUserInterface::checkAction(ActionType &action, const char *const mes
events.setCursor(ARROW);
}
}
/*----------------------------------------------------------------*/
namespace Tattoo {
TattooUserInterface::TattooUserInterface(SherlockEngine *vm): UserInterface(vm) {
//
_menuBuffer = nullptr;
_invMenuBuffer = nullptr;
}
void TattooUserInterface::handleInput() {
@ -2307,4 +2314,44 @@ void TattooUserInterface::handleInput() {
_vm->_events->pollEventsAndWait();
}
void TattooUserInterface::doBgAnimRestoreUI() {
TattooScene &scene = *((TattooScene *)_vm->_scene);
Screen &screen = *_vm->_screen;
// If _oldMenuBounds was set, then either a new menu has been opened or the current menu has been closed.
// Either way, we need to restore the area where the menu was displayed
if (_oldMenuBounds.width() > 0)
screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldMenuBounds.left, _oldMenuBounds.top),
_oldMenuBounds);
if (_oldInvMenuBounds.width() > 0)
screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldInvMenuBounds.left, _oldInvMenuBounds.top),
_oldInvMenuBounds);
if (_menuBuffer != nullptr)
screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_menuBounds.left, _menuBounds.top), _menuBounds);
if (_invMenuBuffer != nullptr)
screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_invMenuBounds.left, _invMenuBounds.top), _invMenuBounds);
// If there is a Text Tag being display, restore the area underneath it
if (_oldTagBounds.width() > 0)
screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldTagBounds.left, _oldTagBounds.top),
_oldTagBounds);
// If there is an Inventory being shown, restore the graphics underneath it
if (_oldInvGraphicBounds.width() > 0)
screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldInvGraphicBounds.left, _oldInvGraphicBounds.top),
_oldInvGraphicBounds);
// If a canimation is active, restore the graphics underneath it
if (scene._activeCAnim._images != nullptr)
screen.restoreBackground(scene._activeCAnim._oldBounds);
// If a canimation just ended, remove it's graphics from the backbuffer
if (scene._activeCAnim._removeBounds.width() > 0)
screen.restoreBackground(scene._activeCAnim._removeBounds);
}
} // End of namespace Tattoo
} // End of namespace Sherlock

View File

@ -137,6 +137,8 @@ public:
virtual void printObjectDesc() {}
};
namespace Scalpel {
class ScalpelUserInterface: public UserInterface {
friend class Inventory;
friend class Settings;
@ -314,9 +316,24 @@ public:
virtual void printObjectDesc();
};
} // End of namespace Scalpel
namespace Tattoo {
class TattooUserInterface : public UserInterface {
private:
Common::Rect _menuBounds;
Common::Rect _oldMenuBounds;
Common::Rect _invMenuBounds;
Common::Rect _oldInvMenuBounds;
Common::Rect _oldTagBounds;
Common::Rect _oldInvGraphicBounds;
Surface *_menuBuffer;
Surface *_invMenuBuffer;
public:
TattooUserInterface(SherlockEngine *vm);
void doBgAnimRestoreUI();
public:
virtual ~TattooUserInterface() {}
@ -326,6 +343,8 @@ public:
virtual void handleInput();
};
} // End of namespace Tattoo
} // End of namespace Sherlock
#endif