180 lines
4.7 KiB
C++
180 lines
4.7 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 "mm/mm1/views_enh/interactions/interaction.h"
|
|
#include "mm/mm1/globals.h"
|
|
#include "mm/mm1/mm1.h"
|
|
#include "mm/mm1/sound.h"
|
|
#include "mm/shared/utils/strings.h"
|
|
|
|
namespace MM {
|
|
namespace MM1 {
|
|
namespace ViewsEnh {
|
|
namespace Interactions {
|
|
|
|
#define BTN_SIZE 10
|
|
|
|
Interaction::Interaction(const Common::String &name, int portrait) : PartyView(name) {
|
|
_bounds = Common::Rect(8, 8, 224, 140);
|
|
|
|
if (portrait != -1) {
|
|
_frame.load("frame.fac");
|
|
_portrait.load(Common::Path(Common::String::format("face%02d.fac", portrait)));
|
|
}
|
|
}
|
|
|
|
void Interaction::addText(const Common::String &str) {
|
|
setReduced(false);
|
|
_lines = splitLines(searchAndReplace(str, "\n", " "));
|
|
}
|
|
|
|
bool Interaction::msgGame(const GameMessage &msg) {
|
|
if (msg._name == "DISPLAY") {
|
|
addView(this);
|
|
return true;
|
|
}
|
|
|
|
return PartyView::msgGame(msg);
|
|
}
|
|
|
|
bool Interaction::msgUnfocus(const UnfocusMessage &msg) {
|
|
PartyView::msgUnfocus(msg);
|
|
return true;
|
|
}
|
|
|
|
void Interaction::draw() {
|
|
PartyView::draw();
|
|
|
|
Graphics::ManagedSurface s = getSurface();
|
|
|
|
if (!_frame.empty()) {
|
|
_frame.draw(&s, 0, Common::Point(8, 8));
|
|
_portrait.draw(&s, _portraitFrameNum, Common::Point(15, 14));
|
|
}
|
|
|
|
setReduced(false);
|
|
if (!_title.empty()) {
|
|
size_t strWidth = getStringWidth(_title);
|
|
writeString(125 - strWidth / 2, 20, _title);
|
|
}
|
|
|
|
// Write any text lines
|
|
for (uint i = 0; i < _lines.size(); ++i) {
|
|
writeString(0, (6 + i) * 9 - 5, _lines[i], ALIGN_MIDDLE);
|
|
}
|
|
|
|
// Write out any buttons
|
|
if (!_buttons.empty()) {
|
|
_textPos = Common::Point(0, (6 + _lines.size()) * 9);
|
|
setReduced(true);
|
|
|
|
// Create a blank button
|
|
Graphics::ManagedSurface btnSmall(BTN_SIZE, BTN_SIZE);
|
|
btnSmall.blitFrom(g_globals->_blankButton, Common::Rect(0, 0, 20, 20),
|
|
Common::Rect(0, 0, BTN_SIZE, BTN_SIZE));
|
|
|
|
for (uint i = 0; i < _buttons.size(); ++i, _textPos.x += 10) {
|
|
InteractionButton &btn = _buttons[i];
|
|
|
|
int itemWidth = BTN_SIZE + 5 + getStringWidth(_buttons[i]._text);
|
|
if ((_textPos.x + itemWidth) > _innerBounds.width()) {
|
|
_textPos.x = 0;
|
|
_textPos.y += BTN_SIZE + 2;
|
|
}
|
|
Common::Point pt = _textPos;
|
|
|
|
// Display button and write character in the middle
|
|
s.blitFrom(btnSmall, Common::Point(pt.x + _bounds.borderSize(),
|
|
pt.y + _bounds.borderSize()));
|
|
|
|
writeString(pt.x + (BTN_SIZE / 2) + 1, pt.y,
|
|
Common::String::format("%c", _buttons[i]._c), ALIGN_MIDDLE);
|
|
|
|
// Write text to the right of the button
|
|
writeString(pt.x + BTN_SIZE + 5, pt.y, _buttons[i]._text);
|
|
|
|
// Set up bounds for the area covered by the button & text
|
|
btn._bounds = Common::Rect(pt.x, pt.y,
|
|
pt.x + BTN_SIZE + 5 + itemWidth, pt.y + BTN_SIZE);
|
|
btn._bounds.translate(_innerBounds.left, _innerBounds.top);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Interaction::tick() {
|
|
if (_animated && ++_tickCtr >= 10) {
|
|
_tickCtr = 0;
|
|
_portraitFrameNum = g_engine->getRandomNumber(0, 2);
|
|
redraw();
|
|
}
|
|
|
|
return PartyView::tick();
|
|
}
|
|
|
|
void Interaction::leave() {
|
|
if (g_events->focusedView() == this)
|
|
close();
|
|
|
|
g_maps->turnAround();
|
|
g_events->redraw();
|
|
}
|
|
|
|
bool Interaction::msgKeypress(const KeypressMessage &msg) {
|
|
viewAction();
|
|
return true;
|
|
}
|
|
|
|
bool Interaction::msgAction(const ActionMessage &msg) {
|
|
if (msg._action == KEYBIND_ESCAPE) {
|
|
leave();
|
|
|
|
} else if (!PartyView::msgAction(msg)) {
|
|
viewAction();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Interaction::msgMouseDown(const MouseDownMessage &msg) {
|
|
if (!PartyView::msgMouseDown(msg)) {
|
|
// Check if a button was pressed
|
|
for (uint i = 0; i < _buttons.size(); ++i) {
|
|
const auto &btn = _buttons[i];
|
|
if (_buttons[i]._bounds.contains(msg._pos)) {
|
|
msgKeypress(KeypressMessage(Common::KeyState(
|
|
(Common::KeyCode)(Common::KEYCODE_a + btn._c - 'A'), btn._c
|
|
)));
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Fall back on treating click as a standard acknowledgement
|
|
viewAction();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
} // namespace Interactions
|
|
} // namespace ViewsEnh
|
|
} // namespace MM1
|
|
} // namespace MM
|