diff options
| author | Paul Gilbert | 2006-02-19 04:08:41 +0000 | 
|---|---|---|
| committer | Paul Gilbert | 2006-02-19 04:08:41 +0000 | 
| commit | b55cf4b0ffcfbbc7a300549a478f9d5c03f01dbd (patch) | |
| tree | 5e429b168ed5d4792a335fdd207299d527a66919 | |
| parent | 7ce5441ad65b68d870fe2fb91d8f7c20b75cbfd9 (diff) | |
| download | scummvm-rg350-b55cf4b0ffcfbbc7a300549a478f9d5c03f01dbd.tar.gz scummvm-rg350-b55cf4b0ffcfbbc7a300549a478f9d5c03f01dbd.tar.bz2 scummvm-rg350-b55cf4b0ffcfbbc7a300549a478f9d5c03f01dbd.zip | |
Added new class for displaying conversation talk dialogs
svn-id: r20760
| -rw-r--r-- | engines/lure/surface.cpp | 147 | ||||
| -rw-r--r-- | engines/lure/surface.h | 15 | 
2 files changed, 137 insertions, 25 deletions
| diff --git a/engines/lure/surface.cpp b/engines/lure/surface.cpp index e254cfe501..ed64eab918 100644 --- a/engines/lure/surface.cpp +++ b/engines/lure/surface.cpp @@ -287,24 +287,13 @@ uint16 Surface::textWidth(const char *s, int numChars) {  	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 @@ Surface *Surface::newDialog(uint16 width, const char *line, uint8 colour) {  			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,10 +339,29 @@ Surface *Surface::newDialog(uint16 width, const char *line, uint8 colour) {  	}  	// 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(const char *text) {  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 @@ void Dialog::showMessage(uint16 messageId, uint16 characterId) {  	}  } +/*--------------------------------------------------------------------------*/ + +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 diff --git a/engines/lure/surface.h b/engines/lure/surface.h index 9febf542f5..730a824ac1 100644 --- a/engines/lure/surface.h +++ b/engines/lure/surface.h @@ -66,6 +66,7 @@ public:  	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 @@ public:  	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 | 
