[Scummvm-cvs-logs] SF.net SVN: scummvm: [20760] scummvm/trunk/engines/lure

dreammaster at users.sourceforge.net dreammaster at users.sourceforge.net
Sat Feb 18 20:09:02 CET 2006


Revision: 20760
Author:   dreammaster
Date:     2006-02-18 20:08:41 -0800 (Sat, 18 Feb 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm?rev=20760&view=rev

Log Message:
-----------
Added new class for displaying conversation talk dialogs

Modified Paths:
--------------
    scummvm/trunk/engines/lure/surface.cpp
    scummvm/trunk/engines/lure/surface.h
Modified: scummvm/trunk/engines/lure/surface.cpp
===================================================================
--- scummvm/trunk/engines/lure/surface.cpp	2006-02-19 04:07:11 UTC (rev 20759)
+++ scummvm/trunk/engines/lure/surface.cpp	2006-02-19 04:08:41 UTC (rev 20760)
@@ -287,24 +287,13 @@
 	return result;
 }
 
-Surface *Surface::newDialog(uint16 width, uint8 numLines, char **lines, bool varLength, uint8 colour) {
-	Surface *s = new Surface(width, (DIALOG_EDGE_SIZE + 3) * 2 + 
-		numLines * (FONT_HEIGHT - 1));
-	s->createDialog();
-
-	for (uint8 ctr = 0; ctr < numLines; ++ctr)
-		s->writeString(DIALOG_EDGE_SIZE + 3, DIALOG_EDGE_SIZE + 3 + 
-			(ctr * (FONT_HEIGHT - 1)), lines[ctr], true, colour, varLength);
-	return s;
-}
-
-Surface *Surface::newDialog(uint16 width, const char *line, uint8 colour) {
-	uint8 numLines = 1;
+void Surface::wordWrap(char *text, uint16 width, char **&lines, uint8 &numLines) {
+	numLines = 1;
 	uint16 lineWidth = 0;
-	char *s, *lineCopy;
+	char *s;
 	bool newLine;
 
-	s = lineCopy = strdup(line);
+	s = text;
 
 	// Scan through the text and insert NULLs to break the line into allowable widths
 
@@ -320,20 +309,25 @@
 			newLine = false;
 		}
 
-		if (wordEnd) --wordEnd; // move back one to end of word
-		else wordEnd = strchr(s, '\0') - 1;
+		if (wordEnd) {
+			if (!newLine) --wordEnd;
+		} else {
+			wordEnd = strchr(s, '\0') - 1;
+		}
 
 		uint16 wordSize = textWidth(s, (int) (wordEnd - s + 1));
 
-		if (lineWidth + wordSize > width - (DIALOG_EDGE_SIZE + 3) * 2) {
+		if (lineWidth + wordSize > width) {
 			// Break word onto next line
 			*(wordStart - 1) = '\0';
 			++numLines;
-			lineWidth = textWidth(wordStart, (int) (wordEnd - wordStart + 1));
+			if (newLine)
+				lineWidth = 0;
+			else
+				lineWidth = textWidth(wordStart, (int) (wordEnd - wordStart + 1));
 		} else if (newLine) {
 			// Break on newline
 			++numLines;
-			++wordEnd;
 			*wordEnd = '\0';
 			lineWidth = 0;
 		} else {
@@ -345,11 +339,30 @@
 	}
 
 	// Set up a list for the start of each line 
-	char **lines = (char **) Memory::alloc(sizeof(char *) * numLines);
-	lines[0] = lineCopy;
+	lines = (char **) Memory::alloc(sizeof(char *) * numLines);
+	lines[0] = text;
 	for (int ctr = 1; ctr < numLines; ++ctr) 
 		lines[ctr] = strchr(lines[ctr-1], 0) + 1;
+}
 
+Surface *Surface::newDialog(uint16 width, uint8 numLines, char **lines, bool varLength, uint8 colour) {
+	Surface *s = new Surface(width, (DIALOG_EDGE_SIZE + 3) * 2 + 
+		numLines * (FONT_HEIGHT - 1));
+	s->createDialog();
+
+	for (uint8 ctr = 0; ctr < numLines; ++ctr)
+		s->writeString(DIALOG_EDGE_SIZE + 3, DIALOG_EDGE_SIZE + 3 + 
+			(ctr * (FONT_HEIGHT - 1)), lines[ctr], true, colour, varLength);
+	return s;
+}
+
+Surface *Surface::newDialog(uint16 width, const char *line, uint8 colour) {
+	char **lines;
+	char *lineCopy = strdup(line);
+	uint8 numLines;
+	wordWrap(lineCopy, width - (DIALOG_EDGE_SIZE + 3) * 2, lines, numLines);
+
+
 	// Create the dialog 
 	Surface *result = newDialog(width, numLines, lines, true, colour);
 
@@ -387,12 +400,11 @@
 
 void Dialog::show(uint16 stringId) {
 	char buffer[MAX_DESC_SIZE];
+	Resources &res = Resources::getReference();
 	Room &r = Room::getReference();
 	StringData &sl = StringData::getReference();
 
-	Action action = r.getCurrentAction();
-
-	const char *actionName = (action == NONE) ? NULL : actionList[action];
+	const char *actionName = res.getCurrentActionStr();
 	char hotspotName[MAX_HOTSPOT_NAME_SIZE];
 	if (r.hotspotId() == 0) 
 		strcpy(hotspotName, "");
@@ -453,4 +465,89 @@
 	}
 }
 
+/*--------------------------------------------------------------------------*/
+
+TalkDialog::TalkDialog(uint16 characterId, uint16 descId) {
+	StringData &strings = StringData::getReference();
+	Resources &res = Resources::getReference();
+	HotspotData *character = res.getHotspot(characterId);
+	char charName[MAX_DESC_SIZE];
+	strings.getString(character->nameId, charName, NULL, NULL);
+	strings.getString(descId, _desc, NULL, NULL);
+
+	// Apply word wrapping to figure out the needed size of the dialog
+	Surface::wordWrap(_desc, TALK_DIALOG_WIDTH - TALK_DIALOG_EDGE_SIZE * 2 - 2,
+		_lines, _numLines);
+
+	_surface = new Surface(TALK_DIALOG_WIDTH, 
+		(_numLines + 1) * FONT_HEIGHT + TALK_DIALOG_EDGE_SIZE * 4);
+
+	// Draw the dialog
+	byte *pSrc = res.getTalkDialogData().data();
+	byte *pDest = _surface->data().data();
+	int xPos, yPos;
+
+	// Handle the dialog top
+	for (yPos = 0; yPos < TALK_DIALOG_EDGE_SIZE; ++yPos) {
+		*pDest++ = *pSrc++;
+		*pDest++ = *pSrc++;
+
+		for (xPos = 0; xPos < TALK_DIALOG_WIDTH - TALK_DIALOG_EDGE_SIZE - 2; ++xPos) 
+			*pDest++ = *pSrc;
+		++pSrc;
+
+		for (xPos = 0; xPos < TALK_DIALOG_EDGE_SIZE; ++xPos)
+			*pDest++ = *pSrc++;
+	}
+
+	// Handle the middle section
+	for (yPos = 0; yPos < _surface->height() - TALK_DIALOG_EDGE_SIZE * 2; ++yPos) {
+		byte *pSrcTemp = pSrc;
+
+		// Left edge
+		for (xPos = 0; xPos < TALK_DIALOG_EDGE_SIZE; ++xPos)
+			*pDest++ = *pSrcTemp++;
+		
+		// Middle section
+		for (xPos = 0; xPos < _surface->width() - TALK_DIALOG_EDGE_SIZE * 2; ++xPos)
+			*pDest++ = *pSrcTemp;
+		++pSrcTemp;
+
+		// Right edge
+		for (xPos = 0; xPos < TALK_DIALOG_EDGE_SIZE; ++xPos)
+			*pDest++ = *pSrcTemp++;
+	}
+
+	//  Bottom section
+	pSrc += TALK_DIALOG_EDGE_SIZE * 2 + 1;
+	for (yPos = 0; yPos < TALK_DIALOG_EDGE_SIZE; ++yPos) {
+		for (xPos = 0; xPos < TALK_DIALOG_EDGE_SIZE; ++xPos)
+			*pDest++ = *pSrc++;
+
+		for (xPos = 0; xPos < TALK_DIALOG_WIDTH - TALK_DIALOG_EDGE_SIZE - 2; ++xPos) 
+			*pDest++ = *pSrc;
+		++pSrc;
+
+		*pDest++ = *pSrc++;
+		*pDest++ = *pSrc++;
+	}
+
+	// Write out the character name
+	uint16 charWidth = Surface::textWidth(charName);
+	_surface->writeString((TALK_DIALOG_WIDTH-charWidth)/2, TALK_DIALOG_EDGE_SIZE + 2,
+		charName, true, DIALOG_WHITE_COLOUR);
+
+	// TEMPORARY CODE - write out description. More properly, the text is meant to
+	// be displayed slowly, word by word
+	for (int lineCtr = 0; lineCtr < _numLines; ++lineCtr) 
+		_surface->writeString(TALK_DIALOG_EDGE_SIZE + 2, 
+			TALK_DIALOG_EDGE_SIZE + 4 + (lineCtr + 1) * FONT_HEIGHT,
+			_lines[lineCtr], true);
+}
+
+TalkDialog::~TalkDialog() {
+	delete _lines;
+	delete _surface;
+}
+
 } // end of namespace Lure

Modified: scummvm/trunk/engines/lure/surface.h
===================================================================
--- scummvm/trunk/engines/lure/surface.h	2006-02-19 04:07:11 UTC (rev 20759)
+++ scummvm/trunk/engines/lure/surface.h	2006-02-19 04:08:41 UTC (rev 20760)
@@ -66,6 +66,7 @@
 	void centerOnScreen();
 
 	static uint16 textWidth(const char *s, int numChars = 0);
+	static void wordWrap(char *text, uint16 width, char **&lines, uint8 &numLines);
 	static Surface *newDialog(uint16 width, uint8 numLines, char **lines, bool varLength = true, uint8 colour = DIALOG_TEXT_COLOUR);
 	static Surface *newDialog(uint16 width, const char *lines, uint8 colour = DIALOG_TEXT_COLOUR);
 	static Surface *getScreen(uint16 resourceId);
@@ -78,6 +79,20 @@
 	static void showMessage(uint16 messageId, uint16 characterId);
 };
 
+class TalkDialog {
+private:
+	Surface *_surface;
+	char _desc[MAX_DESC_SIZE];
+	char **_lines;
+	uint8 _numLines;
+public:
+	TalkDialog(uint16 characterId, uint16 descId);
+	~TalkDialog();
+
+	char *desc() { return _desc; }
+	Surface &surface() { return *_surface; }
+};
+
 } // End of namespace Lure
 
 #endif







More information about the Scummvm-git-logs mailing list