diff options
author | Nicola Mettifogo | 2008-07-04 00:29:21 +0000 |
---|---|---|
committer | Nicola Mettifogo | 2008-07-04 00:29:21 +0000 |
commit | d387d1af0ec869700da199578f07e5a0c00968f3 (patch) | |
tree | 9234158f922cec9fae0db41e798c9859216afd81 /engines | |
parent | d92085b5071b0bb62642d62857e5853006be3b2c (diff) | |
download | scummvm-rg350-d387d1af0ec869700da199578f07e5a0c00968f3.tar.gz scummvm-rg350-d387d1af0ec869700da199578f07e5a0c00968f3.tar.bz2 scummvm-rg350-d387d1af0ec869700da199578f07e5a0c00968f3.zip |
- Moved dialogue balloon management code from Gfx to its own class
- Added a class to draw balloons in BRA (still without text and with wrong placement)
svn-id: r32902
Diffstat (limited to 'engines')
-rw-r--r-- | engines/parallaction/balloons.cpp | 456 | ||||
-rw-r--r-- | engines/parallaction/callables_ns.cpp | 2 | ||||
-rw-r--r-- | engines/parallaction/dialogue.cpp | 24 | ||||
-rw-r--r-- | engines/parallaction/exec_br.cpp | 9 | ||||
-rw-r--r-- | engines/parallaction/exec_ns.cpp | 4 | ||||
-rw-r--r-- | engines/parallaction/graphics.cpp | 174 | ||||
-rw-r--r-- | engines/parallaction/graphics.h | 33 | ||||
-rw-r--r-- | engines/parallaction/gui_br.cpp | 2 | ||||
-rw-r--r-- | engines/parallaction/input.cpp | 2 | ||||
-rw-r--r-- | engines/parallaction/module.mk | 1 | ||||
-rw-r--r-- | engines/parallaction/parallaction.cpp | 6 | ||||
-rw-r--r-- | engines/parallaction/parallaction.h | 9 | ||||
-rw-r--r-- | engines/parallaction/parallaction_br.cpp | 3 |
13 files changed, 515 insertions, 210 deletions
diff --git a/engines/parallaction/balloons.cpp b/engines/parallaction/balloons.cpp new file mode 100644 index 0000000000..fab92dada9 --- /dev/null +++ b/engines/parallaction/balloons.cpp @@ -0,0 +1,456 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "parallaction/graphics.h" +#include "parallaction/parallaction.h" + +namespace Parallaction { + + +#define BALLOON_TRANSPARENT_COLOR_NS 2 +#define BALLOON_TRANSPARENT_COLOR_BR 0 + +#define BALLOON_TAIL_WIDTH 12 +#define BALLOON_TAIL_HEIGHT 10 + + +byte _resBalloonTail[2][BALLOON_TAIL_WIDTH*BALLOON_TAIL_HEIGHT] = { + { + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, + 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x00, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + }, + { + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x02, + 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02 + } +}; + +class BalloonManager_ns : public BalloonManager { + + static int16 _dialogueBalloonX[5]; + + struct Balloon { + Common::Rect outerBox; + Common::Rect innerBox; + Graphics::Surface *surface; + GfxObj *obj; + } _intBalloons[5]; + + uint _numBalloons; + + void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth); + int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness); + Balloon *getBalloon(uint id); + + Gfx *_gfx; + +public: + BalloonManager_ns(Gfx *gfx); + ~BalloonManager_ns(); + + void freeBalloons(); + int setLocationBalloon(char *text, bool endGame); + int setDialogueBalloon(char *text, uint16 winding, byte textColor); + int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor); + void setBalloonText(uint id, char *text, byte textColor); + int hitTestDialogueBalloon(int x, int y); +}; + +int16 BalloonManager_ns::_dialogueBalloonX[5] = { 80, 120, 150, 150, 150 }; + +BalloonManager_ns::BalloonManager_ns(Gfx *gfx) : _numBalloons(0), _gfx(gfx) { + +} + +BalloonManager_ns::~BalloonManager_ns() { + +} + + +BalloonManager_ns::Balloon* BalloonManager_ns::getBalloon(uint id) { + assert(id < _numBalloons); + return &_intBalloons[id]; +} + +int BalloonManager_ns::createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness) { + assert(_numBalloons < 5); + + int id = _numBalloons; + + Balloon *balloon = &_intBalloons[id]; + + int16 real_h = (winding == -1) ? h : h + 9; + balloon->surface = new Graphics::Surface; + balloon->surface->create(w, real_h, 1); + balloon->surface->fillRect(Common::Rect(w, real_h), BALLOON_TRANSPARENT_COLOR_NS); + + Common::Rect r(w, h); + balloon->surface->fillRect(r, 0); + balloon->outerBox = r; + + r.grow(-borderThickness); + balloon->surface->fillRect(r, 1); + balloon->innerBox = r; + + if (winding != -1) { + // draws tail + // TODO: this bitmap tail should only be used for Dos games. Amiga should use a polygon fill. + winding = (winding == 0 ? 1 : 0); + Common::Rect s(BALLOON_TAIL_WIDTH, BALLOON_TAIL_HEIGHT); + s.moveTo(r.width()/2 - 5, r.bottom - 1); + _gfx->blt(s, _resBalloonTail[winding], balloon->surface, LAYER_FOREGROUND, BALLOON_TRANSPARENT_COLOR_NS); + } + + _numBalloons++; + + return id; +} + + +int BalloonManager_ns::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) { + + int16 w, h; + + _gfx->getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); + + int id = createBalloon(w+5, h, winding, 1); + Balloon *balloon = &_intBalloons[id]; + + _gfx->drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + + // TODO: extract some text to make a name for obj + balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); + balloon->obj->x = x; + balloon->obj->y = y; + balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_NS; + + return id; +} + +int BalloonManager_ns::setDialogueBalloon(char *text, uint16 winding, byte textColor) { + + int16 w, h; + + _gfx->getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); + + int id = createBalloon(w+5, h, winding, 1); + Balloon *balloon = &_intBalloons[id]; + + _gfx->drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + + // TODO: extract some text to make a name for obj + balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); + balloon->obj->x = _dialogueBalloonX[id]; + balloon->obj->y = 10; + balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_NS; + + if (id > 0) { + balloon->obj->y += _intBalloons[id - 1].obj->y + _intBalloons[id - 1].outerBox.height(); + } + + + return id; +} + +void BalloonManager_ns::setBalloonText(uint id, char *text, byte textColor) { + Balloon *balloon = getBalloon(id); + balloon->surface->fillRect(balloon->innerBox, 1); + _gfx->drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); +} + + +int BalloonManager_ns::setLocationBalloon(char *text, bool endGame) { + + int16 w, h; + + _gfx->getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); + + int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR_NS); + Balloon *balloon = &_intBalloons[id]; + _gfx->drawWrappedText(_vm->_dialogueFont, balloon->surface, text, 0, MAX_BALLOON_WIDTH); + + // TODO: extract some text to make a name for obj + balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); + balloon->obj->x = 5; + balloon->obj->y = 5; + balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_NS; + + return id; +} + +int BalloonManager_ns::hitTestDialogueBalloon(int x, int y) { + + Common::Point p; + + for (uint i = 0; i < _numBalloons; i++) { + p.x = x - _intBalloons[i].obj->x; + p.y = y - _intBalloons[i].obj->y; + + if (_intBalloons[i].innerBox.contains(p)) + return i; + } + + return -1; +} + +void BalloonManager_ns::freeBalloons() { + _gfx->destroyBalloons(); + + for (uint i = 0; i < _numBalloons; i++) { + _intBalloons[i].obj = 0; + _intBalloons[i].surface = 0; // no need to delete surface, since it is done by destroyBalloons + } + + _numBalloons = 0; +} + + + + + + + + +class BalloonManager_br : public BalloonManager { + + struct Balloon { + Common::Rect box; + Graphics::Surface *surface; + GfxObj *obj; + } _intBalloons[3]; + + uint _numBalloons; + + Frames *_leftBalloon; + Frames *_rightBalloon; + Disk *_disk; + Gfx *_gfx; + + void cacheAnims(); + void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth); + int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness); + Balloon *getBalloon(uint id); + Graphics::Surface *expandBalloon(Frames *data, int frameNum); + + +public: + BalloonManager_br(Disk *disk, Gfx *gfx); + ~BalloonManager_br(); + + void freeBalloons(); + int setLocationBalloon(char *text, bool endGame); + int setDialogueBalloon(char *text, uint16 winding, byte textColor); + int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor); + void setBalloonText(uint id, char *text, byte textColor); + int hitTestDialogueBalloon(int x, int y); +}; + + + +BalloonManager_br::Balloon* BalloonManager_br::getBalloon(uint id) { + assert(id < _numBalloons); + return &_intBalloons[id]; +} + +Graphics::Surface *BalloonManager_br::expandBalloon(Frames *data, int frameNum) { + + Common::Rect rect; + data->getRect(frameNum, rect); + + rect.translate(-rect.left, -rect.top); + + Graphics::Surface *surf = new Graphics::Surface; + surf->create(rect.width(), rect.height(), 1); + + _gfx->unpackBlt(rect, data->getData(frameNum), data->getRawSize(frameNum), surf, 0, BALLOON_TRANSPARENT_COLOR_BR); + + return surf; +} + +int BalloonManager_br::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) { + cacheAnims(); + + int id = _numBalloons; + Frames *src = 0; + int srcFrame = 0; + + Balloon *balloon = &_intBalloons[id]; + + if (winding == 0) { + src = _leftBalloon; + srcFrame = 0; + } else + if (winding == 1) { + src = _rightBalloon; + srcFrame = 0; + } + + assert(src); + + balloon->surface = expandBalloon(src, srcFrame); + src->getRect(srcFrame, balloon->box); + +// drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + + // TODO: extract some text to make a name for obj + balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); + balloon->obj->x = x; + balloon->obj->y = y; + balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_BR; + + _numBalloons++; + + return id; +} + +int BalloonManager_br::setDialogueBalloon(char *text, uint16 winding, byte textColor) { + cacheAnims(); + + int id = _numBalloons; + Frames *src = 0; + int srcFrame = 0; + + Balloon *balloon = &_intBalloons[id]; + + if (winding == 0) { + src = _leftBalloon; + srcFrame = id; + } else + if (winding == 1) { + src = _rightBalloon; + srcFrame = 0; + } + + assert(src); + + balloon->surface = expandBalloon(src, srcFrame); + src->getRect(srcFrame, balloon->box); + +// drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + + // TODO: extract some text to make a name for obj + balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); + balloon->obj->x = 0; + balloon->obj->y = 10; + balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_BR; + + if (id > 0) { + balloon->obj->y += _intBalloons[id - 1].obj->y + _intBalloons[id - 1].box.height(); + } + + _numBalloons++; + + return id; +} + +void BalloonManager_br::setBalloonText(uint id, char *text, byte textColor) { } + +int BalloonManager_br::setLocationBalloon(char *text, bool endGame) { +/* + int16 w, h; + + getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); + + int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR); + Balloon *balloon = &_intBalloons[id]; + drawWrappedText(_vm->_dialogueFont, balloon->surface, text, 0, MAX_BALLOON_WIDTH); + + // TODO: extract some text to make a name for obj + balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); + balloon->obj->x = 5; + balloon->obj->y = 5; +*/ + return 0; +} + +int BalloonManager_br::hitTestDialogueBalloon(int x, int y) { + + Common::Point p; + + for (uint i = 0; i < _numBalloons; i++) { + p.x = x - _intBalloons[i].obj->x; + p.y = y - _intBalloons[i].obj->y; + + if (_intBalloons[i].box.contains(p)) + return i; + } + + return -1; +} + +void BalloonManager_br::freeBalloons() { + _gfx->destroyBalloons(); + + for (uint i = 0; i < _numBalloons; i++) { + _intBalloons[i].obj = 0; + _intBalloons[i].surface = 0; // no need to delete surface, since it is done by destroyBalloons + } + + _numBalloons = 0; +} + +void BalloonManager_br::cacheAnims() { + if (!_leftBalloon) { + _leftBalloon = _disk->loadFrames("fumetto.ani"); + _rightBalloon = _disk->loadFrames("fumdx.ani"); + } +} + +BalloonManager_br::BalloonManager_br(Disk *disk, Gfx *gfx) : _numBalloons(0), _disk(disk), _gfx(gfx), _leftBalloon(0), _rightBalloon(0) { +} + +BalloonManager_br::~BalloonManager_br() { + delete _leftBalloon; + delete _rightBalloon; +} + +void Parallaction::setupBalloonManager() { + if (_vm->getGameType() == GType_Nippon) { + _balloonMan = new BalloonManager_ns(_vm->_gfx); + } else + if (_vm->getGameType() == GType_BRA) { + _balloonMan = new BalloonManager_br(_vm->_disk, _vm->_gfx); + } else { + error("Unknown game type"); + } +} + +} // namespace Parallaction diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp index 3ecc7a9534..7c053715f6 100644 --- a/engines/parallaction/callables_ns.cpp +++ b/engines/parallaction/callables_ns.cpp @@ -341,7 +341,7 @@ void Parallaction_ns::_c_endComment(void *param) { } _input->waitUntilLeftClick(); - _gfx->freeBalloons(); + _balloonMan->freeBalloons(); return; } diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp index 3b6c35d3bb..1dc4fd5ab3 100644 --- a/engines/parallaction/dialogue.cpp +++ b/engines/parallaction/dialogue.cpp @@ -93,7 +93,7 @@ uint16 DialogueManager::askPassword() { uint16 passwordLen = 0; _password[0] = '\0'; - _vm->_gfx->setDialogueBalloon(_q->_answers[0]->_text, 1, 3); + _vm->_balloonMan->setDialogueBalloon(_q->_answers[0]->_text, 1, 3); int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y); _vm->_gfx->setItemFrame(id, 0); @@ -118,7 +118,7 @@ uint16 DialogueManager::askPassword() { } if (changed) { - _vm->_gfx->setBalloonText(0, _q->_answers[0]->_text, 3); + _vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 3); _vm->_gfx->updateScreen(); changed = false; } @@ -143,7 +143,7 @@ uint16 DialogueManager::askPassword() { } - _vm->_gfx->hideDialogueStuff(); + _vm->hideDialogueStuff(); return 0; @@ -162,7 +162,7 @@ bool DialogueManager::displayAnswer(uint16 i) { // display suitable answers if (((a->_yesFlags & flags) == a->_yesFlags) && ((a->_noFlags & ~flags) == a->_noFlags)) { - int id = _vm->_gfx->setDialogueBalloon(a->_text, 1, 3); + int id = _vm->_balloonMan->setDialogueBalloon(a->_text, 1, 3); assert(id >= 0); _visAnswers[id] = i; @@ -190,13 +190,13 @@ void DialogueManager::displayQuestion() { if (!scumm_stricmp(_q->_text, "NULL")) return; - _vm->_gfx->setSingleBalloon(_q->_text, QUESTION_BALLOON_X, QUESTION_BALLOON_Y, _q->_mood & 0x10, 0); + _vm->_balloonMan->setSingleBalloon(_q->_text, QUESTION_BALLOON_X, QUESTION_BALLOON_Y, _q->_mood & 0x10, 0); int id = _vm->_gfx->setItem(_questioner, QUESTION_CHARACTER_X, QUESTION_CHARACTER_Y); _vm->_gfx->setItemFrame(id, _q->_mood & 0xF); _vm->_gfx->updateScreen(); _vm->_input->waitUntilLeftClick(); - _vm->_gfx->hideDialogueStuff(); + _vm->hideDialogueStuff(); return; } @@ -261,9 +261,9 @@ int16 DialogueManager::selectAnswer() { _vm->_gfx->setItemFrame(id, _q->_answers[0]->_mood & 0xF); if (numAvailableAnswers == 1) { - _vm->_gfx->setBalloonText(0, _q->_answers[0]->_text, 0); + _vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 0); _vm->_input->waitUntilLeftClick(); - _vm->_gfx->hideDialogueStuff(); + _vm->hideDialogueStuff(); return 0; } @@ -277,15 +277,15 @@ int16 DialogueManager::selectAnswer() { _vm->_input->readInput(); _vm->_input->getCursorPos(p); event = _vm->_input->getLastButtonEvent(); - selection = _vm->_gfx->hitTestDialogueBalloon(p.x, p.y); + selection = _vm->_balloonMan->hitTestDialogueBalloon(p.x, p.y); if (selection != oldSelection) { if (oldSelection != -1) { - _vm->_gfx->setBalloonText(oldSelection, _q->_answers[_visAnswers[oldSelection]]->_text, 3); + _vm->_balloonMan->setBalloonText(oldSelection, _q->_answers[_visAnswers[oldSelection]]->_text, 3); } if (selection != -1) { - _vm->_gfx->setBalloonText(selection, _q->_answers[_visAnswers[selection]]->_text, 0); + _vm->_balloonMan->setBalloonText(selection, _q->_answers[_visAnswers[selection]]->_text, 0); _vm->_gfx->setItemFrame(0, _q->_answers[_visAnswers[selection]]->_mood & 0xF); } } @@ -300,7 +300,7 @@ int16 DialogueManager::selectAnswer() { oldSelection = selection; } - _vm->_gfx->hideDialogueStuff(); + _vm->hideDialogueStuff(); return _visAnswers[selection]; } diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp index 348af2b731..734360167b 100644 --- a/engines/parallaction/exec_br.cpp +++ b/engines/parallaction/exec_br.cpp @@ -100,8 +100,13 @@ void Parallaction_br::setupSubtitles(char *s, char *s2, int y) { } void Parallaction_br::clearSubtitles() { - _gfx->hideLabel(_subtitle[0]); - _gfx->hideLabel(_subtitle[1]); + if (_subtitle[0] != -1) { + _gfx->hideLabel(_subtitle[0]); + } + + if (_subtitle[1] != -1) { + _gfx->hideLabel(_subtitle[1]); + } } diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index bd2d54c0a0..abad9f273b 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -469,7 +469,7 @@ void Parallaction::displayComment(ExamineData *data) { } _gfx->setHalfbriteMode(true); - _gfx->setSingleBalloon(data->_description, 0, 90, 0, 0); + _balloonMan->setSingleBalloon(data->_description, 0, 90, 0, 0); Common::Rect r; data->_cnv->getRect(0, r); id = _gfx->setItem(data->_cnv, 140, (_screenHeight - r.height())/2); @@ -477,7 +477,7 @@ void Parallaction::displayComment(ExamineData *data) { id = _gfx->setItem(_char._head, 100, 152); _gfx->setItemFrame(id, 0); } else { - _gfx->setSingleBalloon(data->_description, 140, 10, 0, 0); + _balloonMan->setSingleBalloon(data->_description, 140, 10, 0, 0); id = _gfx->setItem(_char._talk, 190, 80); _gfx->setItemFrame(id, 0); } diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index 24c78d1703..f839f88778 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -64,10 +64,6 @@ int32 Gfx::getVar(const Common::String &name) { #define LABEL_TRANSPARENT_COLOR 0xFF -#define BALLOON_TRANSPARENT_COLOR 2 - - -int16 Gfx::_dialogueBalloonX[5] = { 80, 120, 150, 150, 150 }; void halfbritePixel(int x, int y, int color, void *data) { byte *buffer = (byte*)data; @@ -238,37 +234,6 @@ void Palette::rotate(uint first, uint last, bool forward) { } -#define BALLOON_TAIL_WIDTH 12 -#define BALLOON_TAIL_HEIGHT 10 - - -byte _resBalloonTail[2][BALLOON_TAIL_WIDTH*BALLOON_TAIL_HEIGHT] = { - { - 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, - 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x00, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - }, - { - 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, - 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x02, - 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02 - } -}; - void Gfx::setPalette(Palette pal) { byte sysPal[256*4]; @@ -777,7 +742,6 @@ Gfx::Gfx(Parallaction* vm) : setPalette(_palette); - _numBalloons = 0; _numItems = 0; _floatingLabel = NO_FLOATING_LABEL; @@ -828,44 +792,6 @@ void Gfx::setItemFrame(uint item, uint16 f) { _items[item].data->setFlags(kGfxObjVisible); } -Gfx::Balloon* Gfx::getBalloon(uint id) { - assert(id < _numBalloons); - return &_intBalloons[id]; -} - -int Gfx::createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness) { - assert(_numBalloons < 5); - - int id = _numBalloons; - - Gfx::Balloon *balloon = &_intBalloons[id]; - - int16 real_h = (winding == -1) ? h : h + 9; - balloon->surface = new Graphics::Surface; - balloon->surface->create(w, real_h, 1); - balloon->surface->fillRect(Common::Rect(w, real_h), BALLOON_TRANSPARENT_COLOR); - - Common::Rect r(w, h); - balloon->surface->fillRect(r, 0); - balloon->outerBox = r; - - r.grow(-borderThickness); - balloon->surface->fillRect(r, 1); - balloon->innerBox = r; - - if (winding != -1) { - // draws tail - // TODO: this bitmap tail should only be used for Dos games. Amiga should use a polygon fill. - winding = (winding == 0 ? 1 : 0); - Common::Rect s(BALLOON_TAIL_WIDTH, BALLOON_TAIL_HEIGHT); - s.moveTo(r.width()/2 - 5, r.bottom - 1); - blt(s, _resBalloonTail[winding], balloon->surface, LAYER_FOREGROUND, BALLOON_TRANSPARENT_COLOR); - } - - _numBalloons++; - - return id; -} GfxObj* Gfx::registerBalloon(Frames *frames, const char *text) { @@ -873,7 +799,6 @@ GfxObj* Gfx::registerBalloon(Frames *frames, const char *text) { obj->layer = LAYER_FOREGROUND; obj->frame = 0; - obj->transparentKey = BALLOON_TRANSPARENT_COLOR; obj->setFlags(kGfxObjVisible); _balloons.push_back(obj); @@ -881,110 +806,17 @@ GfxObj* Gfx::registerBalloon(Frames *frames, const char *text) { return obj; } -int Gfx::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) { - - int16 w, h; - - getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); - - int id = createBalloon(w+5, h, winding, 1); - Gfx::Balloon *balloon = &_intBalloons[id]; - - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); - - // TODO: extract some text to make a name for obj - balloon->obj = registerBalloon(new SurfaceToFrames(balloon->surface), 0); - balloon->obj->x = x; - balloon->obj->y = y; - - return id; -} - -int Gfx::setDialogueBalloon(char *text, uint16 winding, byte textColor) { - - int16 w, h; - - getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); - - int id = createBalloon(w+5, h, winding, 1); - Gfx::Balloon *balloon = &_intBalloons[id]; - - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); - - // TODO: extract some text to make a name for obj - balloon->obj = registerBalloon(new SurfaceToFrames(balloon->surface), 0); - balloon->obj->x = _dialogueBalloonX[id]; - balloon->obj->y = 10; - - if (id > 0) { - balloon->obj->y += _intBalloons[id - 1].obj->y + _intBalloons[id - 1].outerBox.height(); - } - - - return id; -} - -void Gfx::setBalloonText(uint id, char *text, byte textColor) { - Gfx::Balloon *balloon = getBalloon(id); - balloon->surface->fillRect(balloon->innerBox, 1); - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); -} - - -int Gfx::setLocationBalloon(char *text, bool endGame) { - - int16 w, h; - - getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); - - int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR); - Gfx::Balloon *balloon = &_intBalloons[id]; - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, 0, MAX_BALLOON_WIDTH); - - // TODO: extract some text to make a name for obj - balloon->obj = registerBalloon(new SurfaceToFrames(balloon->surface), 0); - balloon->obj->x = 5; - balloon->obj->y = 5; - - return id; -} - -int Gfx::hitTestDialogueBalloon(int x, int y) { - - Common::Point p; - - for (uint i = 0; i < _numBalloons; i++) { - p.x = x - _intBalloons[i].obj->x; - p.y = y - _intBalloons[i].obj->y; - - if (_intBalloons[i].innerBox.contains(p)) - return i; +void Gfx::destroyBalloons() { + for (uint i = 0; i < _balloons.size(); i++) { + delete _balloons[i]; } - - return -1; -} - - -void Gfx::freeBalloons() { _balloons.clear(); - - for (uint i = 0; i < _numBalloons; i++) { - delete _intBalloons[i].obj; - _intBalloons[i].obj = 0; - _intBalloons[i].surface = 0; // no need to delete surface, since it is done by obj (GfxObj) - } - _numBalloons = 0; } void Gfx::freeItems() { _numItems = 0; } -void Gfx::hideDialogueStuff() { - freeItems(); - freeBalloons(); -} - void Gfx::freeBackground() { _backgroundInfo.free(); } diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index b15da432d9..00718d8c26 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -450,6 +450,20 @@ enum { kBackgroundSlide = 2 }; + +class BalloonManager { +public: + virtual ~BalloonManager() { } + + virtual void freeBalloons() = 0; + virtual int setLocationBalloon(char *text, bool endGame) = 0; + virtual int setDialogueBalloon(char *text, uint16 winding, byte textColor) = 0; + virtual int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) = 0; + virtual void setBalloonText(uint id, char *text, byte textColor) = 0; + virtual int hitTestDialogueBalloon(int x, int y) = 0; +}; + + typedef Common::HashMap<Common::String, int32, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> VarMap; class Gfx { @@ -479,13 +493,9 @@ public: void freeLabels(); // dialogue balloons - int setLocationBalloon(char *text, bool endGame); - int setDialogueBalloon(char *text, uint16 winding, byte textColor); - int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor); - void setBalloonText(uint id, char *text, byte textColor); - int hitTestDialogueBalloon(int x, int y); void getStringExtent(Font *font, char *text, uint16 maxwidth, int16* width, int16* height); GfxObj* registerBalloon(Frames *frames, const char *text); + void destroyBalloons(); // other items int setItem(GfxObj* obj, uint16 x, uint16 y, byte transparentColor = 0); @@ -551,16 +561,6 @@ protected: int32 getRenderMode(const char *type); public: - static int16 _dialogueBalloonX[5]; - - struct Balloon { - Common::Rect outerBox; - Common::Rect innerBox; - Graphics::Surface *surface; - GfxObj *obj; - } _intBalloons[5]; - - uint _numBalloons; struct Item { GfxObj *data; @@ -585,9 +585,6 @@ public: void copyRect(const Common::Rect &r, Graphics::Surface &src, Graphics::Surface &dst); - int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness); - Balloon *getBalloon(uint id); - // low level text and patches void drawText(Font *font, Graphics::Surface* surf, uint16 x, uint16 y, const char *text, byte color); void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth); diff --git a/engines/parallaction/gui_br.cpp b/engines/parallaction/gui_br.cpp index 5551108693..0be070e345 100644 --- a/engines/parallaction/gui_br.cpp +++ b/engines/parallaction/gui_br.cpp @@ -195,7 +195,7 @@ int Parallaction_br::guiShowMenu() { } _system->showMouse(false); - _gfx->hideDialogueStuff(); + hideDialogueStuff(); for (i = 0; i < availItems; i++) { delete _lines[i]; diff --git a/engines/parallaction/input.cpp b/engines/parallaction/input.cpp index e758bbd41c..65acbcfe58 100644 --- a/engines/parallaction/input.cpp +++ b/engines/parallaction/input.cpp @@ -174,7 +174,7 @@ void Input::updateGameInput() { void Input::updateCommentInput() { waitUntilLeftClick(); - _vm->_gfx->hideDialogueStuff(); + _vm->hideDialogueStuff(); _vm->_gfx->setHalfbriteMode(false); _inputMode = kInputModeGame; diff --git a/engines/parallaction/module.mk b/engines/parallaction/module.mk index 2478b4b2e1..92c6ec5227 100644 --- a/engines/parallaction/module.mk +++ b/engines/parallaction/module.mk @@ -1,6 +1,7 @@ MODULE := engines/parallaction MODULE_OBJS := \ + balloons_o \ callables_br.o \ callables_ns.o \ debug.o \ diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index 5f5cfdb820..3a52b28e06 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -134,6 +134,8 @@ int Parallaction::init() { _debugger = new Debugger(this); + setupBalloonManager(); + return 0; } @@ -281,7 +283,7 @@ void Parallaction::setBackground(const char* name, const char* mask, const char* } void Parallaction::showLocationComment(const char *text, bool end) { - _gfx->setLocationBalloon(const_cast<char*>(text), end); + _balloonMan->setLocationBalloon(const_cast<char*>(text), end); } @@ -422,7 +424,7 @@ void Parallaction::doLocationEnterTransition() { showLocationComment(_location._comment, false); _input->waitUntilLeftClick(); - _gfx->freeBalloons(); + _balloonMan->freeBalloons(); // fades maximum intensity palette towards approximation of main palette for (uint16 _si = 0; _si<6; _si++) { diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index b1a5995e28..c095cab667 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -429,6 +429,15 @@ public: Inventory *_inventory; InventoryRenderer *_inventoryRenderer; + BalloonManager *_balloonMan; + + void setupBalloonManager(); + + void hideDialogueStuff() { + _gfx->freeItems(); + _balloonMan->freeBalloons(); + } + }; diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp index b22e1b0f2d..e7f08d0339 100644 --- a/engines/parallaction/parallaction_br.cpp +++ b/engines/parallaction/parallaction_br.cpp @@ -80,6 +80,9 @@ int Parallaction_br::init() { _part = -1; + _subtitle[0] = -1; + _subtitle[1] = -1; + Parallaction::init(); return 0; |