[Scummvm-cvs-logs] SF.net SVN: scummvm: [30311] scummvm/trunk/engines/parallaction

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Sun Jan 6 20:29:42 CET 2008


Revision: 30311
          http://scummvm.svn.sourceforge.net/scummvm/?rev=30311&view=rev
Author:   peres001
Date:     2008-01-06 11:29:41 -0800 (Sun, 06 Jan 2008)

Log Message:
-----------
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.

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/callables_ns.cpp
    scummvm/trunk/engines/parallaction/dialogue.cpp
    scummvm/trunk/engines/parallaction/exec_ns.cpp
    scummvm/trunk/engines/parallaction/graphics.cpp
    scummvm/trunk/engines/parallaction/graphics.h
    scummvm/trunk/engines/parallaction/parallaction.cpp

Modified: scummvm/trunk/engines/parallaction/callables_ns.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/callables_ns.cpp	2008-01-06 16:02:38 UTC (rev 30310)
+++ scummvm/trunk/engines/parallaction/callables_ns.cpp	2008-01-06 19:29:41 UTC (rev 30311)
@@ -352,6 +352,7 @@
 	}
 
 	waitUntilLeftClick();
+    _gfx->freeBalloons();
 
 	return;
 }

Modified: scummvm/trunk/engines/parallaction/dialogue.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/dialogue.cpp	2008-01-06 16:02:38 UTC (rev 30310)
+++ scummvm/trunk/engines/parallaction/dialogue.cpp	2008-01-06 19:29:41 UTC (rev 30311)
@@ -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 @@
 #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 @@
 
 	Question		*_q;
 
+    uint16          _visAnswers[5];
+    int             _numVisAnswers;
+
 public:
 	DialogueManager(Parallaction *vm, SpeakData *data) : _vm(vm), _data(data) {
 		_dialogue = _data->_dialogue;
@@ -85,10 +74,6 @@
 	void run();
 
 protected:
-	void clear() {
-		_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
-	}
-
 	void displayQuestion();
 	bool displayAnswers();
 	bool displayAnswer(uint16 i);
@@ -103,27 +88,20 @@
 uint16 DialogueManager::askPassword() {
 	debugC(3, kDebugExec, "checkDialoguePassword()");
 
-	uint16 passwordLen;
+	uint16 passwordLen = 0;
+    _password[0] = '\0';
 
-	while (true) {
-		clear();
+    _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);
 
-		passwordLen = 0;
-		_password[0] = '\0';
+    Common::Event e;
+    bool changed = true;    // force first refresh
 
-		Common::Rect r(_answerBalloonW[0], _answerBalloonH[0]);
-		r.moveTo(_answerBalloonX[0], _answerBalloonY[0]);
+	while (true) {
+	    e.kbd.ascii = 0;
 
-		_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) {
-
-			// 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 @@
 				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);
-		}
+                break;
 
-		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))) {
+            } else {
+                passwordLen = 0;
+                _password[0] = '\0';
+                changed = true;
+            }
 
-			break;
-
 		}
 
+        g_system->delayMillis(20);
+
 	}
 
+    _vm->_gfx->hideDialogueStuff();
+
 	return 0;
 
 }
@@ -164,70 +153,51 @@
 
 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];
 
+	uint32 flags = _vm->_localFlags[_vm->_currentLocationIndex];
+	if (a->_yesFlags & kFlagsGlobal)
+		flags = _commandFlags | kFlagsGlobal;
+
 	// display suitable answers
-	if (((_q->_answers[i]->_yesFlags & v28) == _q->_answers[i]->_yesFlags) && ((_q->_answers[i]->_noFlags & ~v28) == _q->_answers[i]->_noFlags)) {
+	if (((a->_yesFlags & flags) == a->_yesFlags) && ((a->_noFlags & ~flags) == a->_noFlags)) {
 
-		_vm->_gfx->getStringExtent(_q->_answers[i]->_text, MAX_BALLOON_WIDTH, &_answerBalloonW[i], &_answerBalloonH[i]);
+        uint id = _vm->_gfx->setDialogueBalloon(a->_text, 1, 3);
+        assert(id >= 0);
+        _visAnswers[id] = i;
 
-		Common::Rect r(_answerBalloonW[i], _answerBalloonH[i]);
-		r.moveTo(_answerBalloonX[i], _answerBalloonY[i]);
+        _askPassword = strstr(a->_text, "%p");
+        _numVisAnswers++;
 
-		_vm->_gfx->drawBalloon(r, 1);
-
-		_answerBalloonY[i+1] = 10 + _answerBalloonY[i] + _answerBalloonH[i];
-		_askPassword = _vm->_gfx->displayWrappedString(_q->_answers[i]->_text, _answerBalloonX[i], _answerBalloonY[i], 3, MAX_BALLOON_WIDTH);
-
 		return true;
 	}
 
-	_answerBalloonY[i+1] = _answerBalloonY[i];
-	_answerBalloonY[i] = SKIPPED_ANSWER;
-
 	return false;
-
 }
 
 bool DialogueManager::displayAnswers() {
 
-	bool displayed = false;
+    _numVisAnswers = 0;
 
-	uint16 i = 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);
+    _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);
 
-	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->updateScreen();
 	waitUntilLeftClick();
+    _vm->_gfx->hideDialogueStuff();
 
-	clear();
-
 	return;
 }
 
@@ -241,8 +211,6 @@
 		answer = askPassword();
 	}
 
-	clear();
-
 	debugC(3, kDebugExec, "runDialogue: user selected answer #%i", answer);
 
 	return answer;
@@ -256,8 +224,6 @@
 	_q = _dialogue->_questions[0];
 	int16 answer;
 
-	_vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
-
 	while (_q) {
 
 		answer = 0;
@@ -265,8 +231,6 @@
 		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 @@
 		_q = _q->_answers[answer]->_following._question;
 	}
 
-	clear();
-
 	if (cmdlist)
 		_vm->runCommands(*cmdlist);
 
@@ -285,97 +247,61 @@
 
 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;
+    int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
+    _vm->_gfx->setItemFrame(id, _q->_answers[0]->_mood & 0xF);
 
-		_di = i;
-		numAvailableAnswers++;
-	}
-	_answerBalloonY[i] = 2000;
-
 	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;
-	}
+		g_system->delayMillis(20);
 
-	return _si;
-}
+        oldSelection = selection;
+    }
 
+    _vm->_gfx->hideDialogueStuff();
 
-//
-//	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;
-
+	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;
 }
 

Modified: scummvm/trunk/engines/parallaction/exec_ns.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/exec_ns.cpp	2008-01-06 16:02:38 UTC (rev 30310)
+++ scummvm/trunk/engines/parallaction/exec_ns.cpp	2008-01-06 19:29:41 UTC (rev 30311)
@@ -487,23 +487,25 @@
 		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;

Modified: scummvm/trunk/engines/parallaction/graphics.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/graphics.cpp	2008-01-06 16:02:38 UTC (rev 30310)
+++ scummvm/trunk/engines/parallaction/graphics.cpp	2008-01-06 19:29:41 UTC (rev 30311)
@@ -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::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 @@
 	_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;
 
-	// 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);
+    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);
+    }
 
-	return balloon;
+	_numBalloons++;
+
+	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) {
+    int16 w, h;
 
-	Common::Rect rect;
-
 	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();

Modified: scummvm/trunk/engines/parallaction/graphics.h
===================================================================
--- scummvm/trunk/engines/parallaction/graphics.h	2008-01-06 16:02:38 UTC (rev 30310)
+++ scummvm/trunk/engines/parallaction/graphics.h	2008-01-06 19:29:41 UTC (rev 30311)
@@ -114,58 +114,6 @@
 
 };
 
-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 @@
 	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 @@
 	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:
+    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 @@
 
 	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 @@
 
 
 
+

Modified: scummvm/trunk/engines/parallaction/parallaction.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.cpp	2008-01-06 16:02:38 UTC (rev 30310)
+++ scummvm/trunk/engines/parallaction/parallaction.cpp	2008-01-06 19:29:41 UTC (rev 30311)
@@ -841,23 +841,7 @@
 }
 
 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,13 +875,11 @@
 	drawAnimations();
 
 	_gfx->swapBuffers();
-	_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
 
 	showLocationComment(_location._comment, false);
 	waitUntilLeftClick();
+	_gfx->freeBalloons();
 
-	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront );
-
 	// fades maximum intensity palette towards approximation of main palette
 	for (uint16 _si = 0; _si<6; _si++) {
 		pal.fadeTo(_gfx->_palette, 4);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list