scummvm/engines/sherlock/user_interface.cpp
2015-08-07 19:44:16 -04:00

210 lines
6.0 KiB
C++

/* 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/user_interface.h"
#include "sherlock/scalpel/scalpel.h"
#include "sherlock/scalpel/scalpel_user_interface.h"
#include "sherlock/tattoo/tattoo.h"
#include "sherlock/tattoo/tattoo_user_interface.h"
namespace Sherlock {
UserInterface *UserInterface::init(SherlockEngine *vm) {
if (vm->getGameID() == GType_SerratedScalpel)
return new Scalpel::ScalpelUserInterface(vm);
else
return new Tattoo::TattooUserInterface(vm);
}
UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) {
_menuMode = STD_MODE;
_menuCounter = 0;
_infoFlag = false;
_windowOpen = false;
_endKeyActive = true;
_invLookFlag = 0;
_slideWindows = true;
_helpStyle = false;
_windowBounds = Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH - 1, SHERLOCK_SCREEN_HEIGHT - 1);
_lookScriptFlag = false;
_exitZone = -1;
_bgFound = _oldBgFound = -1;
_key = _oldKey = '\0';
_selector = _oldSelector = -1;
_temp = _oldTemp = 0;
_temp1 = 0;
_lookHelp = 0;
}
void UserInterface::checkAction(ActionType &action, int objNum, FixedTextActionId fixedTextActionId) {
Events &events = *_vm->_events;
FixedText &fixedText = *_vm->_fixedText;
People &people = *_vm->_people;
Scene &scene = *_vm->_scene;
Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
Point32 pt(-1, -1);
if (action._useFlag)
// Automatically set the given flag
_vm->setFlags(action._useFlag);
if (IS_SERRATED_SCALPEL && objNum >= 1000)
// Ignore actions done on characters
return;
if (IS_SERRATED_SCALPEL && !action._cAnimSpeed) {
// Invalid action, to print error message
_infoFlag = true;
clearInfo();
Common::String errorMessage = fixedText.getActionMessage(fixedTextActionId, action._cAnimNum);
screen.print(Common::Point(0, INFO_LINE + 1), COL_INFO_FOREGROUND, "%s", errorMessage.c_str());
_infoFlag = true;
// Set how long to show the message
_menuCounter = 30;
} else {
BaseObject *obj;
if (objNum >= 1000)
obj = &people[objNum - 1000];
else
obj = &scene._bgShapes[objNum];
int cAnimNum;
if (action._cAnimNum == 0)
// Really a 10
cAnimNum = 9;
else
cAnimNum = action._cAnimNum - 1;
int dir = -1;
if (action._cAnimNum != 99) {
CAnim &anim = scene._cAnim[cAnimNum];
if (action._cAnimNum != 99) {
if (action._cAnimSpeed & REVERSE_DIRECTION) {
pt = anim._teleport[0];
dir = anim._teleport[0]._facing;
} else {
pt = anim._goto[0];
dir = anim._goto[0]._facing;
}
}
} else {
pt = Point32(-1, -1);
dir = -1;
}
// Has a value, so do action
// Show wait cursor whilst walking to object and doing action
events.setCursor(WAIT);
bool printed = false;
for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) {
if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2
&& toupper(action._names[nameIdx][1]) == 'W') {
if (obj->checkNameForCodes(Common::String(action._names[nameIdx].c_str() + 2), fixedTextActionId)) {
if (!talk._talkToAbort)
printed = true;
}
}
}
bool doCAnim = true;
for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) {
if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2) {
char ch = toupper(action._names[nameIdx][1]);
if (ch == 'T' || ch == 'B') {
printed = true;
if (pt.x != -1)
// Holmes needs to walk to object before the action is done
people[HOLMES].walkToCoords(pt, dir);
if (!talk._talkToAbort) {
// Ensure Holmes is on the exact intended location
people[HOLMES]._position = pt;
people[HOLMES]._sequenceNumber = dir;
people[HOLMES].gotoStand();
talk.talkTo(action._names[nameIdx].c_str() + 2);
if (ch == 'T')
doCAnim = false;
}
}
}
}
if (doCAnim && !talk._talkToAbort) {
if (pt.x != -1)
// Holmes needs to walk to object before the action is done
people[HOLMES].walkToCoords(pt, dir);
}
for (int nameIdx = 0; nameIdx < NAMES_COUNT; ++nameIdx) {
if (action._names[nameIdx].hasPrefix("*") && action._names[nameIdx].size() >= 2
&& toupper(action._names[nameIdx][1]) == 'F') {
if (obj->checkNameForCodes(action._names[nameIdx].c_str() + 2, fixedTextActionId)) {
if (!talk._talkToAbort)
printed = true;
}
}
}
if (doCAnim && !talk._talkToAbort && action._cAnimNum != 99)
scene.startCAnim(cAnimNum, action._cAnimSpeed);
if (!talk._talkToAbort) {
for (int nameIdx = 0; nameIdx < NAMES_COUNT && !talk._talkToAbort; ++nameIdx) {
if (obj->checkNameForCodes(action._names[nameIdx], fixedTextActionId)) {
if (!talk._talkToAbort)
printed = true;
}
}
// Unless we're leaving the scene, print a "Done" message unless the printed flag has been set
if (IS_SERRATED_SCALPEL && scene._goToScene != 1 && !printed && !talk._talkToAbort) {
_infoFlag = true;
clearInfo();
screen.print(Common::Point(0, INFO_LINE + 1), COL_INFO_FOREGROUND, "Done...");
// Set how long to show the message
_menuCounter = 30;
}
}
}
// Reset cursor back to arrow
events.setCursor(ARROW);
}
void UserInterface::reset() {
_bgFound = _oldBgFound = -1;
_oldKey = -1;
_oldTemp = _temp = -1;
_exitZone = -1;
}
} // End of namespace Sherlock