aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorNicola Mettifogo2008-01-06 19:29:41 +0000
committerNicola Mettifogo2008-01-06 19:29:41 +0000
commitdb51514dd389b7177eaa11eb1ce5b40fb36b4b3c (patch)
tree310d049d2d1738e6113fdb650c637d2e818f502d /engines
parent84e5398b1cf8b1758f2b4bad916ec279f33161ca (diff)
downloadscummvm-rg350-db51514dd389b7177eaa11eb1ce5b40fb36b4b3c.tar.gz
scummvm-rg350-db51514dd389b7177eaa11eb1ce5b40fb36b4b3c.tar.bz2
scummvm-rg350-db51514dd389b7177eaa11eb1ce5b40fb36b4b3c.zip
Moved balloons management into Gfx, which is now responsible for positioning and drawing. All balloons are now drawn on a different layer than the game graphics, thus simplifying screen management. Dialogue code has undergone a major revision, and the superior implementation of answer selection in the Amiga version is now used in place of the poor PC one. Other bits (where some changes had already been introduced) have been updated, too.
svn-id: r30311
Diffstat (limited to 'engines')
-rw-r--r--engines/parallaction/callables_ns.cpp1
-rw-r--r--engines/parallaction/dialogue.cpp246
-rw-r--r--engines/parallaction/exec_ns.cpp18
-rw-r--r--engines/parallaction/graphics.cpp135
-rw-r--r--engines/parallaction/graphics.h124
-rw-r--r--engines/parallaction/parallaction.cpp22
6 files changed, 278 insertions, 268 deletions
diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp
index 9a54859aba..fac5a23ed1 100644
--- a/engines/parallaction/callables_ns.cpp
+++ b/engines/parallaction/callables_ns.cpp
@@ -352,6 +352,7 @@ void Parallaction_ns::_c_endComment(void *param) {
}
waitUntilLeftClick();
+ _gfx->freeBalloons();
return;
}
diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp
index c1a8c91d9a..caecf7b0db 100644
--- a/engines/parallaction/dialogue.cpp
+++ b/engines/parallaction/dialogue.cpp
@@ -30,10 +30,6 @@
namespace Parallaction {
-#define SKIPPED_ANSWER 1000
-
-#define MAX_BALLOON_WIDTH 130
-
#define MAX_PASSWORD_LENGTH 7
#define QUESTION_BALLOON_X 140
@@ -44,16 +40,6 @@ namespace Parallaction {
#define ANSWER_CHARACTER_X 10
#define ANSWER_CHARACTER_Y 80
-int16 selectAnswer(Question *q, Graphics::Surface*);
-int16 getHoverAnswer(int16 x, int16 y, Question *q);
-
-int16 _answerBalloonX[10] = { 80, 120, 150, 150, 150, 0, 0, 0, 0, 0 };
-int16 _answerBalloonY[10] = { 10, 70, 130, 0, 0, 0, 0, 0, 0, 0 };
-int16 _answerBalloonW[10] = { 0 };
-int16 _answerBalloonH[10] = { 0 };
-
-
-
class DialogueManager {
Parallaction *_vm;
@@ -68,6 +54,9 @@ class DialogueManager {
Question *_q;
+ uint16 _visAnswers[5];
+ int _numVisAnswers;
+
public:
DialogueManager(Parallaction *vm, SpeakData *data) : _vm(vm), _data(data) {
_dialogue = _data->_dialogue;
@@ -85,10 +74,6 @@ public:
void run();
protected:
- void clear() {
- _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
- }
-
void displayQuestion();
bool displayAnswers();
bool displayAnswer(uint16 i);
@@ -103,27 +88,20 @@ protected:
uint16 DialogueManager::askPassword() {
debugC(3, kDebugExec, "checkDialoguePassword()");
- uint16 passwordLen;
-
- while (true) {
- clear();
+ uint16 passwordLen = 0;
+ _password[0] = '\0';
- passwordLen = 0;
- _password[0] = '\0';
+ _vm->_gfx->setDialogueBalloon(_q->_answers[0]->_text, 1, 3);
+ int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
+ _vm->_gfx->setItemFrame(id, 0);
- Common::Rect r(_answerBalloonW[0], _answerBalloonH[0]);
- r.moveTo(_answerBalloonX[0], _answerBalloonY[0]);
+ Common::Event e;
+ bool changed = true; // force first refresh
- _vm->_gfx->drawBalloon(r, 1);
- _vm->_gfx->displayWrappedString(_q->_answers[0]->_text, _answerBalloonX[0], _answerBalloonY[0], 3, MAX_BALLOON_WIDTH);
- _vm->_gfx->flatBlitCnv(_answerer, 0, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y, Gfx::kBitFront);
- _vm->_gfx->updateScreen();
-
- Common::Event e;
- while (e.kbd.ascii != Common::KEYCODE_RETURN && passwordLen < MAX_PASSWORD_LENGTH) {
+ while (true) {
+ e.kbd.ascii = 0;
- // FIXME: see comment for readInput()
- if (!g_system->getEventManager()->pollEvent(e)) continue;
+ if (g_system->getEventManager()->pollEvent(e)) {
if (e.type == Common::EVENT_QUIT) {
// TODO: don't quit() here, just have caller routines to check
// on kEngineQuit and exit gracefully to allow the engine to shut down
@@ -131,31 +109,42 @@ uint16 DialogueManager::askPassword() {
g_system->quit();
}
- if (e.type != Common::EVENT_KEYDOWN) continue;
- if (!isdigit(e.kbd.ascii)) continue;
+ if ((e.type == Common::EVENT_KEYDOWN) && isdigit(e.kbd.ascii)) {
+ _password[passwordLen] = e.kbd.ascii;
+ passwordLen++;
+ _password[passwordLen] = '\0';
+ changed = true;
+ }
+ }
- _password[passwordLen] = e.kbd.ascii;
- passwordLen++;
- _password[passwordLen] = '\0';
+ if (changed) {
+ _vm->_gfx->setBalloonText(0, _q->_answers[0]->_text, 3);
+ _vm->_gfx->updateScreen();
+ changed = false;
+ }
+ if ((passwordLen == MAX_PASSWORD_LENGTH) || (e.kbd.ascii == Common::KEYCODE_RETURN)) {
- _vm->_gfx->drawBalloon(r, 1);
- _vm->_gfx->displayWrappedString(_q->_answers[0]->_text, _answerBalloonX[0], _answerBalloonY[0], 3, MAX_BALLOON_WIDTH);
- _vm->_gfx->updateScreen();
+ if ((!scumm_stricmp(_vm->_char.getBaseName(), _doughName) && !scumm_strnicmp(_password, "1732461", 7)) ||
+ (!scumm_stricmp(_vm->_char.getBaseName(), _donnaName) && !scumm_strnicmp(_password, "1622", 4)) ||
+ (!scumm_stricmp(_vm->_char.getBaseName(), _dinoName) && !scumm_strnicmp(_password, "179", 3))) {
- g_system->delayMillis(20);
- }
-
- if ((!scumm_stricmp(_vm->_char.getBaseName(), _doughName) && !scumm_strnicmp(_password, "1732461", 7)) ||
- (!scumm_stricmp(_vm->_char.getBaseName(), _donnaName) && !scumm_strnicmp(_password, "1622", 4)) ||
- (!scumm_stricmp(_vm->_char.getBaseName(), _dinoName) && !scumm_strnicmp(_password, "179", 3))) {
+ break;
- break;
+ } else {
+ passwordLen = 0;
+ _password[0] = '\0';
+ changed = true;
+ }
}
+ g_system->delayMillis(20);
+
}
+ _vm->_gfx->hideDialogueStuff();
+
return 0;
}
@@ -164,69 +153,50 @@ uint16 DialogueManager::askPassword() {
bool DialogueManager::displayAnswer(uint16 i) {
- uint32 v28 = _vm->_localFlags[_vm->_currentLocationIndex];
- if (_q->_answers[i]->_yesFlags & kFlagsGlobal)
- v28 = _commandFlags | kFlagsGlobal;
+ Answer *a = _q->_answers[i];
- // display suitable answers
- if (((_q->_answers[i]->_yesFlags & v28) == _q->_answers[i]->_yesFlags) && ((_q->_answers[i]->_noFlags & ~v28) == _q->_answers[i]->_noFlags)) {
-
- _vm->_gfx->getStringExtent(_q->_answers[i]->_text, MAX_BALLOON_WIDTH, &_answerBalloonW[i], &_answerBalloonH[i]);
+ uint32 flags = _vm->_localFlags[_vm->_currentLocationIndex];
+ if (a->_yesFlags & kFlagsGlobal)
+ flags = _commandFlags | kFlagsGlobal;
- Common::Rect r(_answerBalloonW[i], _answerBalloonH[i]);
- r.moveTo(_answerBalloonX[i], _answerBalloonY[i]);
+ // display suitable answers
+ if (((a->_yesFlags & flags) == a->_yesFlags) && ((a->_noFlags & ~flags) == a->_noFlags)) {
- _vm->_gfx->drawBalloon(r, 1);
+ uint id = _vm->_gfx->setDialogueBalloon(a->_text, 1, 3);
+ assert(id >= 0);
+ _visAnswers[id] = i;
- _answerBalloonY[i+1] = 10 + _answerBalloonY[i] + _answerBalloonH[i];
- _askPassword = _vm->_gfx->displayWrappedString(_q->_answers[i]->_text, _answerBalloonX[i], _answerBalloonY[i], 3, MAX_BALLOON_WIDTH);
+ _askPassword = strstr(a->_text, "%p");
+ _numVisAnswers++;
return true;
}
- _answerBalloonY[i+1] = _answerBalloonY[i];
- _answerBalloonY[i] = SKIPPED_ANSWER;
-
return false;
-
}
bool DialogueManager::displayAnswers() {
- bool displayed = false;
-
- uint16 i = 0;
+ _numVisAnswers = 0;
- while (i < NUM_ANSWERS && _q->_answers[i]) {
- if (displayAnswer(i))
- displayed = true;
-
- i++;
+ for (int i = 0; i < NUM_ANSWERS && _q->_answers[i]; i++) {
+ displayAnswer(i);
}
- _vm->_gfx->updateScreen();
- return displayed;
+ return _numVisAnswers > 0;
}
void DialogueManager::displayQuestion() {
- int16 w = 0, h = 0;
-
if (!scumm_stricmp(_q->_text, "NULL")) return;
- _vm->_gfx->flatBlitCnv(_questioner, _q->_mood & 0xF, QUESTION_CHARACTER_X, QUESTION_CHARACTER_Y, Gfx::kBitFront);
- _vm->_gfx->getStringExtent(_q->_text, MAX_BALLOON_WIDTH, &w, &h);
-
- Common::Rect r(w, h);
- r.moveTo(QUESTION_BALLOON_X, QUESTION_BALLOON_Y);
-
- _vm->_gfx->drawBalloon(r, _q->_mood & 0x10);
- _vm->_gfx->displayWrappedString(_q->_text, QUESTION_BALLOON_X, QUESTION_BALLOON_Y, 0, MAX_BALLOON_WIDTH);
- _vm->_gfx->updateScreen();
+ _vm->_gfx->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();
waitUntilLeftClick();
-
- clear();
+ _vm->_gfx->hideDialogueStuff();
return;
}
@@ -241,8 +211,6 @@ uint16 DialogueManager::getAnswer() {
answer = askPassword();
}
- clear();
-
debugC(3, kDebugExec, "runDialogue: user selected answer #%i", answer);
return answer;
@@ -256,8 +224,6 @@ void DialogueManager::run() {
_q = _dialogue->_questions[0];
int16 answer;
- _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
-
while (_q) {
answer = 0;
@@ -265,8 +231,6 @@ void DialogueManager::run() {
displayQuestion();
if (_q->_answers[0] == NULL) break;
- _answerBalloonY[0] = 10;
-
if (scumm_stricmp(_q->_answers[0]->_text, "NULL")) {
if (!displayAnswers()) break;
answer = getAnswer();
@@ -276,8 +240,6 @@ void DialogueManager::run() {
_q = _q->_answers[answer]->_following._question;
}
- clear();
-
if (cmdlist)
_vm->runCommands(*cmdlist);
@@ -285,97 +247,61 @@ void DialogueManager::run() {
int16 DialogueManager::selectAnswer() {
- int16 numAvailableAnswers = 0;
- int16 _si = 0;
- int16 _di = 0;
+ int16 numAvailableAnswers = _numVisAnswers;
- int16 i = 0;
- for (; _q->_answers[i]; i++) {
- if (_answerBalloonY[i] == SKIPPED_ANSWER) continue;
-
- _di = i;
- numAvailableAnswers++;
- }
- _answerBalloonY[i] = 2000;
+ int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
+ _vm->_gfx->setItemFrame(id, _q->_answers[0]->_mood & 0xF);
if (numAvailableAnswers == 1) {
- _vm->_gfx->displayWrappedString(_q->_answers[_di]->_text, _answerBalloonX[_di], _answerBalloonY[_di], 0, MAX_BALLOON_WIDTH);
- _vm->_gfx->flatBlitCnv(_answerer, _q->_answers[_di]->_mood & 0xF, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y, Gfx::kBitFront);
- _vm->_gfx->updateScreen();
+ _vm->_gfx->setBalloonText(0, _q->_answers[0]->_text, 0);
waitUntilLeftClick();
- return _di;
+ _vm->_gfx->hideDialogueStuff();
+ return 0;
}
- int16 v2 = -1;
+ int oldSelection = -1;
+ int selection;
- _mouseButtons = kMouseNone;
- while (_mouseButtons != kMouseLeftUp) {
+ while (true) {
_vm->readInput();
- _si = getHoverAnswer(_vm->_mousePos.x, _vm->_mousePos.y);
+ selection = _vm->_gfx->hitTestDialogueBalloon(_vm->_mousePos.x, _vm->_mousePos.y);
- if (_si != v2 && _si != -1) {
+ if (selection != oldSelection) {
+ if (oldSelection != -1) {
+ _vm->_gfx->setBalloonText(oldSelection, _q->_answers[_visAnswers[oldSelection]]->_text, 3);
+ }
- if (v2 != -1)
- _vm->_gfx->displayWrappedString(_q->_answers[v2]->_text, _answerBalloonX[v2], _answerBalloonY[v2], 3, MAX_BALLOON_WIDTH);
+ if (selection != -1) {
+ _vm->_gfx->setBalloonText(selection, _q->_answers[_visAnswers[selection]]->_text, 0);
+ _vm->_gfx->setItemFrame(0, _q->_answers[_visAnswers[selection]]->_mood & 0xF);
+ }
+ }
- _vm->_gfx->displayWrappedString(_q->_answers[_si]->_text, _answerBalloonX[_si], _answerBalloonY[_si], 0, MAX_BALLOON_WIDTH);
- _vm->_gfx->flatBlitCnv(_answerer, _q->_answers[_si]->_mood & 0xF, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y, Gfx::kBitFront);
- }
+ if ((selection != -1) && (_mouseButtons == kMouseLeftUp)) {
+ break;
+ }
_vm->_gfx->updateScreen();
- g_system->delayMillis(30);
- v2 = _si;
- }
-
- return _si;
-}
+ g_system->delayMillis(20);
+ oldSelection = selection;
+ }
-//
-// finds out which answer is currently selected
-//
-int16 DialogueManager::getHoverAnswer(int16 x, int16 y) {
-
- int16 top = 1000;
- int16 bottom = 1000;
-
- for (int16 _si = 0; _si < NUM_ANSWERS; _si++) {
- if (_q->_answers[_si] == NULL) break;
-
- if (_answerBalloonY[_si] != SKIPPED_ANSWER) {
- top = _answerBalloonY[_si];
- }
-
- int16 _di = _si + 1;
- for (; _answerBalloonY[_di] == SKIPPED_ANSWER; _di++) ;
-
- bottom = _answerBalloonY[_di];
-
- // mouse position is compared only with y coordinates
- if (y > top && y < bottom) return _si;
-
- }
-
- return -1;
+ _vm->_gfx->hideDialogueStuff();
+ return _visAnswers[selection];
}
-
void Parallaction::runDialogue(SpeakData *data) {
debugC(1, kDebugExec, "runDialogue: starting dialogue '%s'", data->_name);
_gfx->setFont(_dialogueFont);
- if (getPlatform() == Common::kPlatformPC)
- showCursor(false);
-
DialogueManager man(this, data);
man.run();
- showCursor(true);
-
return;
}
diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp
index 11f2209c5f..ef9d2243b2 100644
--- a/engines/parallaction/exec_ns.cpp
+++ b/engines/parallaction/exec_ns.cpp
@@ -487,23 +487,25 @@ void Parallaction::displayComment(ExamineData *data) {
return;
}
+ int id;
+
if (data->_filename) {
if (data->_cnv == 0) {
data->_cnv = _disk->loadStatic(data->_filename);
}
_gfx->setHalfbriteMode(true);
- _gfx->setDialogueBalloon(data->_description, 0, 90, 130, 0, 0);
+ _gfx->setSingleBalloon(data->_description, 0, 90, 0, 0);
Common::Rect r;
data->_cnv->getRect(0, r);
- _gfx->setItem(data->_cnv, 140, (_screenHeight - r.height())/2);
- _gfx->setItemFrame(0, 0);
- _gfx->setItem(_char._head, 100, 152);
- _gfx->setItemFrame(1, 0);
+ id = _gfx->setItem(data->_cnv, 140, (_screenHeight - r.height())/2);
+ _gfx->setItemFrame(id, 0);
+ id = _gfx->setItem(_char._head, 100, 152);
+ _gfx->setItemFrame(id, 0);
} else {
- _gfx->setDialogueBalloon(data->_description, 140, 10, 130, 0, 0);
- _gfx->setItem(_char._talk, 190, 80);
- _gfx->setItemFrame(0, 0);
+ _gfx->setSingleBalloon(data->_description, 140, 10, 0, 0);
+ id = _gfx->setItem(_char._talk, 190, 80);
+ _gfx->setItemFrame(id, 0);
}
_inputMode = kInputModeComment;
diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp
index 81922dd185..2acff90de8 100644
--- a/engines/parallaction/graphics.cpp
+++ b/engines/parallaction/graphics.cpp
@@ -32,6 +32,7 @@
namespace Parallaction {
+int16 Gfx::_dialogueBalloonX[5] = { 80, 120, 150, 150, 150 };
void halfbritePixel(int x, int y, int color, void *data) {
byte *buffer = (byte*)data;
@@ -970,11 +971,16 @@ void Gfx::freeBuffers() {
}
-void Gfx::setItem(Frames* frames, uint16 x, uint16 y) {
- _items[_numItems].data = frames;
- _items[_numItems].x = x;
- _items[_numItems].y = y;
+int Gfx::setItem(Frames* frames, uint16 x, uint16 y) {
+ int id = _numItems;
+
+ _items[id].data = frames;
+ _items[id].x = x;
+ _items[id].y = y;
+
_numItems++;
+
+ return id;
}
void Gfx::setItemFrame(uint item, uint16 f) {
@@ -984,46 +990,125 @@ void Gfx::setItemFrame(uint item, uint16 f) {
_items[item].rect.moveTo(_items[item].x, _items[item].y);
}
-Gfx::Balloon *Gfx::createBalloon(char *text, uint16 maxwidth, uint16 winding) {
+Gfx::Balloon* Gfx::getBalloon(uint id) {
+ assert(id < _numBalloons);
+ return &_balloons[id];
+}
+
+int Gfx::createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness) {
assert(_numBalloons < 5);
- Gfx::Balloon *balloon = &_balloons[_numBalloons];
- _numBalloons++;
+ int id = _numBalloons;
- int16 w, h;
- getStringExtent(text, maxwidth, &w, &h);
+ Gfx::Balloon *balloon = &_balloons[id];
- balloon->surface.create(w + 5, h + 9, 1);
- balloon->surface.fillRect(Common::Rect(w + 5, h + 9), 2);
+ int16 real_h = (winding == -1) ? h : h + 9;
+ balloon->surface.create(w, real_h, 1);
+ balloon->surface.fillRect(Common::Rect(w, real_h), 2);
- Common::Rect r(w + 5, h);
+ Common::Rect r(w, h);
balloon->surface.fillRect(r, 0);
- r.grow(-1);
+ 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);
+ flatBlit(s, _resBalloonTail[winding], &balloon->surface, 2);
+ }
- // 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);
- flatBlit(s, _resBalloonTail[winding], &balloon->surface, 2);
+ _numBalloons++;
- return balloon;
+ return id;
}
+int Gfx::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) {
-void Gfx::setDialogueBalloon(char *text, uint16 x, uint16 y, uint16 maxwidth, uint16 winding, byte textColor) {
-
- Common::Rect rect;
+ int16 w, h;
setFont(_vm->_dialogueFont);
- Gfx::Balloon *balloon = createBalloon(text, maxwidth, winding);
- drawWrappedText(&balloon->surface, text, textColor, maxwidth);
+ getStringExtent(text, MAX_BALLOON_WIDTH, &w, &h);
+
+ int id = createBalloon(w+5, h, winding, 1);
+ Gfx::Balloon *balloon = &_balloons[id];
+
+ drawWrappedText(&balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
balloon->x = x;
balloon->y = y;
+
+ return id;
+}
+
+int Gfx::setDialogueBalloon(char *text, uint16 winding, byte textColor) {
+
+ int16 w, h;
+
+ setFont(_vm->_dialogueFont);
+ getStringExtent(text, MAX_BALLOON_WIDTH, &w, &h);
+
+ int id = createBalloon(w+5, h, winding, 1);
+ Gfx::Balloon *balloon = &_balloons[id];
+
+ drawWrappedText(&balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
+
+ balloon->x = _dialogueBalloonX[id];
+ balloon->y = 10;
+
+ if (id > 0) {
+ balloon->y += _balloons[id - 1].y + _balloons[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(&balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
+}
+
+
+int Gfx::setLocationBalloon(char *text, bool endGame) {
+
+ int16 w, h;
+
+ setFont(_vm->_dialogueFont);
+ getStringExtent(text, MAX_BALLOON_WIDTH, &w, &h);
+
+ int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, 2);
+ Gfx::Balloon *balloon = &_balloons[id];
+ drawWrappedText(&balloon->surface, text, 0, MAX_BALLOON_WIDTH);
+
+ balloon->x = 5;
+ balloon->y = 5;
+
+ return id;
+}
+
+int Gfx::hitTestDialogueBalloon(int x, int y) {
+
+ Common::Point p;
+
+ for (uint i = 0; i < _numBalloons; i++) {
+ p.x = x - _balloons[i].x;
+ p.y = y - _balloons[i].y;
+
+ if (_balloons[i].innerBox.contains(p))
+ return i;
+ }
+
+ return -1;
}
+
void Gfx::freeBalloons() {
for (uint i = 0; i < _numBalloons; i++) {
_balloons[i].surface.free();
diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h
index 778c2e6e0a..31032bd44f 100644
--- a/engines/parallaction/graphics.h
+++ b/engines/parallaction/graphics.h
@@ -114,58 +114,6 @@ public:
};
-struct Cnv : public Frames {
- uint16 _count; // # of frames
- uint16 _width; //
- uint16 _height; //
- byte** field_8; // unused
- byte* _data;
-
-public:
- Cnv() {
- _width = _height = _count = 0;
- _data = NULL;
- }
-
- Cnv(uint16 numFrames, uint16 width, uint16 height, byte* data) : _count(numFrames), _width(width), _height(height), _data(data) {
-
- }
-
- ~Cnv() {
- free(_data);
- }
-
- byte* getFramePtr(uint16 index) {
- if (index >= _count)
- return NULL;
- return &_data[index * _width * _height];
- }
-
- uint16 getNum() {
- return _count;
- }
-
- byte *getData(uint16 index) {
- return getFramePtr(index);
- }
-
- void getRect(uint16 index, Common::Rect &r) {
- r.left = 0;
- r.top = 0;
- r.setWidth(_width);
- r.setHeight(_height);
- }
-};
-
-
-#define NUM_BUFFERS 4
-
-class Parallaction;
-
-struct DoorData;
-struct GetData;
-struct Label;
-
struct MaskBuffer {
// handles a 2-bit depth buffer used for z-buffering
@@ -227,6 +175,61 @@ public:
void rotate(uint first, uint last, bool forward);
};
+
+struct Cnv : public Frames {
+ uint16 _count; // # of frames
+ uint16 _width; //
+ uint16 _height; //
+ byte** field_8; // unused
+ byte* _data;
+
+public:
+ Cnv() {
+ _width = _height = _count = 0;
+ _data = NULL;
+ }
+
+ Cnv(uint16 numFrames, uint16 width, uint16 height, byte* data) : _count(numFrames), _width(width), _height(height), _data(data) {
+
+ }
+
+ ~Cnv() {
+ free(_data);
+ }
+
+ byte* getFramePtr(uint16 index) {
+ if (index >= _count)
+ return NULL;
+ return &_data[index * _width * _height];
+ }
+
+ uint16 getNum() {
+ return _count;
+ }
+
+ byte *getData(uint16 index) {
+ return getFramePtr(index);
+ }
+
+ void getRect(uint16 index, Common::Rect &r) {
+ r.left = 0;
+ r.top = 0;
+ r.setWidth(_width);
+ r.setHeight(_height);
+ }
+};
+
+
+#define NUM_BUFFERS 4
+#define MAX_BALLOON_WIDTH 130
+
+class Parallaction;
+
+struct DoorData;
+struct GetData;
+struct Label;
+
+
class Gfx {
public:
@@ -261,8 +264,13 @@ public:
void backupGetBackground(GetData *data, int16 x, int16 y);
void restoreGetBackground(const Common::Rect& r, byte *data);
- void setDialogueBalloon(char *text, uint16 x, uint16 y, uint16 maxwidth, uint16 winding, byte textColor);
- void setItem(Frames* frames, uint16 x, uint16 y);
+ 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);
+
+ int setItem(Frames* frames, uint16 x, uint16 y);
void setItemFrame(uint item, uint16 f);
void hideDialogueStuff();
void freeBalloons();
@@ -323,9 +331,13 @@ protected:
protected:
+ static int16 _dialogueBalloonX[5];
+
struct Balloon {
uint16 x;
uint16 y;
+ Common::Rect outerBox;
+ Common::Rect innerBox;
uint16 winding;
Graphics::Surface surface;
} _balloons[5];
@@ -354,7 +366,8 @@ protected:
void copyRect(uint width, uint height, byte *dst, uint dstPitch, byte *src, uint srcPitch);
- Balloon *createBalloon(char *text, uint16 maxwidth, uint16 winding);
+ int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness);
+ Balloon *getBalloon(uint id);
void drawText(Graphics::Surface* surf, uint16 x, uint16 y, const char *text, byte color);
bool drawWrappedText(Graphics::Surface* surf, char *text, byte color, int16 wrapwidth);
@@ -372,3 +385,4 @@ protected:
+
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index e4f936cda8..45a1d1631b 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -841,23 +841,7 @@ void Parallaction::setBackground(const char* name, const char* mask, const char*
}
void Parallaction::showLocationComment(const char *text, bool end) {
-
- _gfx->setFont(_dialogueFont);
-
- int16 w, h;
- _gfx->getStringExtent(const_cast<char*>(text), 130, &w, &h);
-
- Common::Rect r(w + (end ? 5 : 10), h + 5);
- r.moveTo(5, 5);
-
- _gfx->floodFill(Gfx::kBitFront, r, 0);
- r.grow(-2);
- _gfx->floodFill(Gfx::kBitFront, r, 1);
- _gfx->displayWrappedString(const_cast<char*>(text), 3, 5, 0, 130);
-
- _gfx->updateScreen();
-
- return;
+ _gfx->setLocationBalloon(const_cast<char*>(text), end);
}
@@ -891,12 +875,10 @@ void Parallaction::doLocationEnterTransition() {
drawAnimations();
_gfx->swapBuffers();
- _gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
showLocationComment(_location._comment, false);
waitUntilLeftClick();
-
- _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront );
+ _gfx->freeBalloons();
// fades maximum intensity palette towards approximation of main palette
for (uint16 _si = 0; _si<6; _si++) {