mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
320 lines
8.5 KiB
C++
320 lines
8.5 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "engines/nancy/nancy.h"
|
|
#include "engines/nancy/graphics.h"
|
|
#include "engines/nancy/resource.h"
|
|
#include "engines/nancy/sound.h"
|
|
#include "engines/nancy/input.h"
|
|
#include "engines/nancy/util.h"
|
|
|
|
#include "engines/nancy/action/telephone.h"
|
|
|
|
#include "engines/nancy/state/scene.h"
|
|
|
|
namespace Nancy {
|
|
namespace Action {
|
|
|
|
void Telephone::init() {
|
|
_drawSurface.create(_screenPosition.width(), _screenPosition.height(), g_nancy->_graphicsManager->getInputPixelFormat());
|
|
_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
|
|
|
|
setTransparent(true);
|
|
|
|
g_nancy->_resource->loadImage(_imageName, _image);
|
|
|
|
NancySceneState.setShouldClearTextbox(false);
|
|
}
|
|
|
|
void Telephone::readData(Common::SeekableReadStream &stream) {
|
|
readFilename(stream, _imageName);
|
|
|
|
_srcRects.reserve(12);
|
|
for (uint i = 0; i < 12; ++i) {
|
|
_srcRects.push_back(Common::Rect());
|
|
readRect(stream, _srcRects.back());
|
|
}
|
|
|
|
_destRects.reserve(12);
|
|
for (uint i = 0; i < 12; ++i) {
|
|
_destRects.push_back(Common::Rect());
|
|
readRect(stream, _destRects.back());
|
|
|
|
if (i == 0) {
|
|
_screenPosition = _destRects.back();
|
|
} else {
|
|
_screenPosition.extend(_destRects.back());
|
|
}
|
|
}
|
|
|
|
_genericDialogueSound.read(stream, SoundDescription::kNormal);
|
|
_genericButtonSound.read(stream, SoundDescription::kNormal);
|
|
_ringSound.read(stream, SoundDescription::kNormal);
|
|
_dialToneSound.read(stream, SoundDescription::kNormal);
|
|
_dialAgainSound.read(stream, SoundDescription::kNormal);
|
|
_hangUpSound.read(stream, SoundDescription::kNormal);
|
|
|
|
_buttonSoundNames.reserve(12);
|
|
for (uint i = 0; i < 12; ++i) {
|
|
Common::String buttonSoundName;
|
|
readFilename(stream, buttonSoundName);
|
|
_buttonSoundNames.push_back(buttonSoundName);
|
|
}
|
|
|
|
char textBuf[200];
|
|
stream.read(textBuf, 200);
|
|
textBuf[199] = '\0';
|
|
_addressBookString = textBuf;
|
|
stream.read(textBuf, 200);
|
|
textBuf[199] = '\0';
|
|
_dialAgainString = textBuf;
|
|
_reloadScene.readData(stream);
|
|
stream.skip(2);
|
|
_flagOnReload.label = stream.readSint16LE();
|
|
_flagOnReload.flag = (NancyFlag)stream.readUint16LE();
|
|
_exitScene.readData(stream);
|
|
stream.skip(2);
|
|
_flagOnExit.label = stream.readSint16LE();
|
|
_flagOnExit.flag = (NancyFlag)stream.readUint16LE();
|
|
readRect(stream, _exitHotspot);
|
|
|
|
uint numCalls = stream.readUint16LE();
|
|
|
|
_calls.reserve(numCalls);
|
|
for (uint i = 0; i < numCalls; ++i) {
|
|
_calls.push_back(PhoneCall());
|
|
PhoneCall &call = _calls.back();
|
|
|
|
call.phoneNumber.reserve(11);
|
|
for (uint j = 0; j < 11; ++j) {
|
|
call.phoneNumber.push_back(stream.readByte());
|
|
}
|
|
|
|
readFilename(stream, call.soundName);
|
|
stream.read(textBuf, 200);
|
|
textBuf[199] = '\0';
|
|
call.text = textBuf;
|
|
call.sceneChange.readData(stream);
|
|
stream.skip(2);
|
|
call.flag.label = stream.readSint16LE();
|
|
call.flag.flag = (NancyFlag)stream.readUint16LE();
|
|
}
|
|
}
|
|
|
|
void Telephone::execute() {
|
|
switch (_state) {
|
|
case kBegin:
|
|
init();
|
|
registerGraphics();
|
|
g_nancy->_sound->loadSound(_dialToneSound);
|
|
g_nancy->_sound->playSound(_dialToneSound);
|
|
NancySceneState.getTextbox().clear();
|
|
NancySceneState.getTextbox().addTextLine(_addressBookString);
|
|
_state = kRun;
|
|
// fall through
|
|
case kRun:
|
|
switch (_callState) {
|
|
case kWaiting:
|
|
// Long phone numbers start with 1
|
|
if (_calledNumber.size() >= 11 || (_calledNumber.size() >= 7 && (_calledNumber[0] != 1))) {
|
|
NancySceneState.getTextbox().clear();
|
|
NancySceneState.getTextbox().addTextLine("ringing...<n><e>"); // Hardcoded in the original engine
|
|
g_nancy->_sound->loadSound(_ringSound);
|
|
g_nancy->_sound->playSound(_ringSound);
|
|
_callState = kRinging;
|
|
}
|
|
|
|
break;
|
|
case kButtonPress:
|
|
if (!g_nancy->_sound->isSoundPlaying(_genericButtonSound)) {
|
|
g_nancy->_sound->stopSound(_genericButtonSound);
|
|
undrawButton(_selected);
|
|
_callState = kWaiting;
|
|
}
|
|
|
|
break;
|
|
case kRinging:
|
|
if (!g_nancy->_sound->isSoundPlaying(_ringSound)) {
|
|
g_nancy->_sound->stopSound(_ringSound);
|
|
uint numberLength = _calledNumber[0] == 1 ? 11 : 7;
|
|
|
|
for (uint i = 0; i < _calls.size(); ++i) {
|
|
bool invalid = false;
|
|
|
|
for (uint j = 0; j < numberLength; ++j) {
|
|
if (_calledNumber[j] != _calls[i].phoneNumber[j]) {
|
|
// Invalid number, move onto next
|
|
invalid = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (invalid) {
|
|
continue;
|
|
}
|
|
|
|
NancySceneState.getTextbox().clear();
|
|
NancySceneState.getTextbox().addTextLine(_calls[i].text);
|
|
|
|
_genericDialogueSound.name = _calls[i].soundName;
|
|
g_nancy->_sound->loadSound(_genericDialogueSound);
|
|
g_nancy->_sound->playSound(_genericDialogueSound);
|
|
_selected = i;
|
|
_callState = kCall;
|
|
|
|
return;
|
|
}
|
|
|
|
NancySceneState.getTextbox().clear();
|
|
NancySceneState.getTextbox().addTextLine(_dialAgainString);
|
|
|
|
g_nancy->_sound->loadSound(_dialAgainSound);
|
|
g_nancy->_sound->playSound(_dialAgainSound);
|
|
_callState = kBadNumber;
|
|
return;
|
|
}
|
|
|
|
break;
|
|
case kBadNumber:
|
|
if (!g_nancy->_sound->isSoundPlaying(_dialAgainSound)) {
|
|
g_nancy->_sound->stopSound(_dialAgainSound);
|
|
|
|
_state = kActionTrigger;
|
|
}
|
|
|
|
break;
|
|
case kCall:
|
|
if (!g_nancy->_sound->isSoundPlaying(_genericDialogueSound)) {
|
|
g_nancy->_sound->stopSound(_genericDialogueSound);
|
|
|
|
_state = kActionTrigger;
|
|
}
|
|
|
|
break;
|
|
case kHangUp:
|
|
if (!g_nancy->_sound->isSoundPlaying(_hangUpSound)) {
|
|
g_nancy->_sound->stopSound(_hangUpSound);
|
|
|
|
_state = kActionTrigger;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
break;
|
|
case kActionTrigger:
|
|
switch (_callState) {
|
|
case kBadNumber:
|
|
NancySceneState.changeScene(_reloadScene);
|
|
_calledNumber.clear();
|
|
NancySceneState.setEventFlag(_flagOnReload);
|
|
_state = kRun;
|
|
_callState = kWaiting;
|
|
|
|
break;
|
|
case kCall: {
|
|
PhoneCall &call = _calls[_selected];
|
|
NancySceneState.changeScene(call.sceneChange);
|
|
NancySceneState.setEventFlag(call.flag);
|
|
|
|
break;
|
|
}
|
|
case kHangUp:
|
|
NancySceneState.changeScene(_exitScene);
|
|
NancySceneState.setEventFlag(_flagOnExit);
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
finishExecution();
|
|
NancySceneState.setShouldClearTextbox(true);
|
|
NancySceneState.getTextbox().clear();
|
|
}
|
|
}
|
|
|
|
void Telephone::handleInput(NancyInput &input) {
|
|
int buttonNr = -1;
|
|
// Cursor gets changed regardless of state
|
|
for (uint i = 0; i < 12; ++i) {
|
|
if (NancySceneState.getViewport().convertViewportToScreen(_destRects[i]).contains(input.mousePos)) {
|
|
g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
|
|
buttonNr = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (_callState != kWaiting) {
|
|
return;
|
|
}
|
|
|
|
if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
|
|
g_nancy->_cursorManager->setCursorType(CursorManager::kExit);
|
|
|
|
if (input.input & NancyInput::kLeftMouseButtonUp) {
|
|
g_nancy->_sound->loadSound(_hangUpSound);
|
|
g_nancy->_sound->playSound(_hangUpSound);
|
|
|
|
_callState = kHangUp;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (buttonNr != -1) {
|
|
if (input.input & NancyInput::kLeftMouseButtonUp) {
|
|
if (g_nancy->_sound->isSoundPlaying(_dialToneSound)) {
|
|
g_nancy->_sound->stopSound(_dialToneSound);
|
|
}
|
|
|
|
_calledNumber.push_back(buttonNr);
|
|
_genericButtonSound.name = _buttonSoundNames[buttonNr];
|
|
g_nancy->_sound->loadSound(_genericButtonSound);
|
|
g_nancy->_sound->playSound(_genericButtonSound);
|
|
|
|
drawButton(buttonNr);
|
|
|
|
_selected = buttonNr;
|
|
|
|
_callState = kButtonPress;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Telephone::drawButton(uint id) {
|
|
Common::Point destPoint(_destRects[id].left - _screenPosition.left, _destRects[id].top - _screenPosition.top);
|
|
_drawSurface.blitFrom(_image, _srcRects[id], destPoint);
|
|
|
|
_needsRedraw = true;
|
|
}
|
|
|
|
void Telephone::undrawButton(uint id) {
|
|
Common::Rect bounds = _destRects[id];
|
|
bounds.translate(-_screenPosition.left, -_screenPosition.top);
|
|
|
|
_drawSurface.fillRect(bounds, g_nancy->_graphicsManager->getTransColor());
|
|
_needsRedraw = true;
|
|
}
|
|
|
|
} // End of namespace Action
|
|
} // End of namespace Nancy
|