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

dreammaster at users.sourceforge.net dreammaster at users.sourceforge.net
Sat Jan 5 11:34:34 CET 2008


Revision: 30226
          http://scummvm.svn.sourceforge.net/scummvm/?rev=30226&view=rev
Author:   dreammaster
Date:     2008-01-05 02:34:34 -0800 (Sat, 05 Jan 2008)

Log Message:
-----------
Added extra handling for EGA dialogs, and added formalised parameters/methods for text positioning

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	2008-01-05 08:17:39 UTC (rev 30225)
+++ scummvm/trunk/engines/lure/surface.cpp	2008-01-05 10:34:34 UTC (rev 30226)
@@ -104,6 +104,97 @@
 	delete _data;
 }
 
+// textX / textY
+// Returns the offset into a dialog for writing text
+
+uint16 Surface::textX() { return LureEngine::getReference().isEGA() ? 10 : 12; }
+
+uint16 Surface::textY() { return LureEngine::getReference().isEGA() ? 8 : 12; }
+
+// getDialogBounds
+// Returns a suggested size for a dialog given a number of horizontal characters and rows
+
+void Surface::getDialogBounds(Common::Point &size, int charWidth, int numLines, bool squashedLines) {
+	size.x = Surface::textX() * 2 + FONT_WIDTH * charWidth;
+	size.y = Surface::textY() * 2 + (squashedLines ? (FONT_HEIGHT - 1) : FONT_HEIGHT) * numLines;
+}
+
+// egaCreateDialog
+// Forms a dialog encompassing the entire surface
+
+void Surface::egaCreateDialog(bool blackFlag) {
+	byte lineColours1[3] = {6, 0, 9};
+	byte lineColours2[3] = {7, 0, 12};
+
+	// Surface contents
+	data().setBytes(blackFlag ? 0 : 13, 0, data().size());
+	
+	// Top/bottom lines
+	for (int y = 2; y >= 0; --y) {
+		data().setBytes(lineColours1[y], y * width(), width());
+		data().setBytes(lineColours2[y], (height() - y - 1) * width(), width());
+		
+		for (int p = y + 1; p < height() - y; ++p) {
+			byte *line = data().data() + p * width();
+			*(line + y) = lineColours2[y];
+			*(line + width() - y - 1) = lineColours1[y];
+		}
+	}
+}
+
+// vgaCreateDialog
+// Forms a dialog encompassing the entire surface
+
+void copyLine(byte *pSrc, byte *pDest, uint16 leftSide, uint16 center, uint16 rightSide) {
+	// Left area
+	memcpy(pDest, pSrc, leftSide); 
+	pSrc += leftSide; pDest += leftSide; 
+	// Center area
+	memset(pDest, *pSrc, center);
+	++pSrc; pDest += center; 
+	// Right side
+	memcpy(pDest, pSrc, rightSide); 
+	pSrc += rightSide; pDest += rightSide; 
+}
+
+#define VGA_DIALOG_EDGE_WIDTH 9
+
+void Surface::vgaCreateDialog(bool blackFlag) {
+	byte *pSrc = int_dialog_frame->data();
+	byte *pDest = _data->data();
+	uint16 xCenter = _width - VGA_DIALOG_EDGE_WIDTH * 2;
+	uint16 yCenter = _height - VGA_DIALOG_EDGE_WIDTH * 2;
+	int y;
+
+	// Dialog top
+	for (y = 0; y < 9; ++y) {
+		copyLine(pSrc, pDest, VGA_DIALOG_EDGE_WIDTH - 2, xCenter + 2, VGA_DIALOG_EDGE_WIDTH);
+		pSrc += (VGA_DIALOG_EDGE_WIDTH - 2) + 1 + VGA_DIALOG_EDGE_WIDTH;
+		pDest += _width;
+	}
+
+	// Dialog sides - note that the same source data gets used for all side lines
+	for (y = 0; y < yCenter; ++y) {
+		copyLine(pSrc, pDest, VGA_DIALOG_EDGE_WIDTH, xCenter, VGA_DIALOG_EDGE_WIDTH);
+		pDest += _width;
+	}
+	pSrc += VGA_DIALOG_EDGE_WIDTH * 2 + 1;
+
+	// Dialog bottom
+	for (y = 0; y < 9; ++y) {
+		copyLine(pSrc, pDest, VGA_DIALOG_EDGE_WIDTH, xCenter + 1, VGA_DIALOG_EDGE_WIDTH - 1);
+		pSrc += VGA_DIALOG_EDGE_WIDTH + 1 + (VGA_DIALOG_EDGE_WIDTH - 1);
+		pDest += _width;
+	}
+
+	// Final processing - if black flag set, clear dialog inside area
+	if (blackFlag) {
+		Rect r = Rect(VGA_DIALOG_EDGE_WIDTH, VGA_DIALOG_EDGE_WIDTH, 
+			_width - VGA_DIALOG_EDGE_WIDTH, _height-VGA_DIALOG_EDGE_WIDTH);
+		fillRect(r, 0);
+	}
+}
+
 void Surface::loadScreen(uint16 resourceId) {
 	MemoryBlock *rawData = Disk::getReference().getEntry(resourceId);
 	loadScreen(rawData);
@@ -129,8 +220,10 @@
 	delete tmpScreen;
 }
 
-int Surface::writeChar(uint16 x, uint16 y, uint8 ascii, bool transparent, uint8 colour) {
+int Surface::writeChar(uint16 x, uint16 y, uint8 ascii, bool transparent, int colour) {
 	byte *const addr = _data->data() + (y * _width) + x;
+	if (colour == DEFAULT_TEXT_COLOUR) 
+		colour = LureEngine::getReference().isEGA() ? EGA_DIALOG_TEXT_COLOUR : VGA_DIALOG_TEXT_COLOUR;
 
 	if ((ascii < 32) || (ascii >= 32 + numFontChars))
 		error("Invalid ascii character passed for display '%d'", ascii);
@@ -158,14 +251,16 @@
 }
 
 void Surface::writeString(uint16 x, uint16 y, Common::String line, bool transparent, 
-						  uint8 colour, bool varLength) {
+						  int colour, bool varLength) {
 	writeSubstring(x, y, line, line.size(), transparent, colour, varLength);
 }
 
 void Surface::writeSubstring(uint16 x, uint16 y, Common::String line, int len, 
-		  bool transparent, uint8 colour, bool varLength) {
+		  bool transparent, int colour, bool varLength) {
 
 	const char *sPtr = line.c_str();
+	if (colour == DEFAULT_TEXT_COLOUR) 
+		colour = LureEngine::getReference().isEGA() ? EGA_DIALOG_TEXT_COLOUR : VGA_DIALOG_TEXT_COLOUR;
 
 	for (int index = 0; (index < len) && (*sPtr != '\0'); ++index, ++sPtr) {
 		writeChar(x, y, (uint8) *sPtr, transparent, colour);
@@ -256,57 +351,11 @@
 	}
 }
 
-// createDialog
-// Forms a dialog encompassing the entire surface
-
-void copyLine(byte *pSrc, byte *pDest, uint16 leftSide, uint16 center, uint16 rightSide) {
-	// Left area
-	memcpy(pDest, pSrc, leftSide); 
-	pSrc += leftSide; pDest += leftSide; 
-	// Center area
-	memset(pDest, *pSrc, center);
-	++pSrc; pDest += center; 
-	// Right side
-	memcpy(pDest, pSrc, rightSide); 
-	pSrc += rightSide; pDest += rightSide; 
-}
-
 void Surface::createDialog(bool blackFlag) {
-	if ((_width < 20) || (_height < 20)) return;
-
-	byte *pSrc = int_dialog_frame->data();
-	byte *pDest = _data->data();
-	uint16 xCenter = _width - DIALOG_EDGE_SIZE * 2;
-	uint16 yCenter = _height - DIALOG_EDGE_SIZE * 2;
-	int y;
-
-	// Dialog top
-	for (y = 0; y < 9; ++y) {
-		copyLine(pSrc, pDest, DIALOG_EDGE_SIZE - 2, xCenter + 2, DIALOG_EDGE_SIZE);
-		pSrc += (DIALOG_EDGE_SIZE - 2) + 1 + DIALOG_EDGE_SIZE;
-		pDest += _width;
-	}
-
-	// Dialog sides - note that the same source data gets used for all side lines
-	for (y = 0; y < yCenter; ++y) {
-		copyLine(pSrc, pDest, DIALOG_EDGE_SIZE, xCenter, DIALOG_EDGE_SIZE);
-		pDest += _width;
-	}
-	pSrc += DIALOG_EDGE_SIZE * 2 + 1;
-
-	// Dialog bottom
-	for (y = 0; y < 9; ++y) {
-		copyLine(pSrc, pDest, DIALOG_EDGE_SIZE, xCenter + 1, DIALOG_EDGE_SIZE - 1);
-		pSrc += DIALOG_EDGE_SIZE + 1 + (DIALOG_EDGE_SIZE - 1);
-		pDest += _width;
-	}
-
-	// Final processing - if black flag set, clear dialog inside area
-	if (blackFlag) {
-		Rect r = Rect(DIALOG_EDGE_SIZE, DIALOG_EDGE_SIZE, 
-			_width - DIALOG_EDGE_SIZE, _height-DIALOG_EDGE_SIZE);
-		fillRect(r, 0);
-	}
+	if (LureEngine::getReference().isEGA())
+		egaCreateDialog(blackFlag);
+	else
+		vgaCreateDialog(blackFlag);
 }
 
 void Surface::copyToScreen(uint16 x, uint16 y) {
@@ -409,22 +458,28 @@
 	debugC(ERROR_INTERMEDIATE, kLureDebugStrings, "wordWrap end - numLines=%d", numLines);
 }
 
-Surface *Surface::newDialog(uint16 width, uint8 numLines, const char **lines, bool varLength, uint8 colour) {
-	Surface *s = new Surface(width, (DIALOG_EDGE_SIZE + 3) * 2 + 
-		numLines * (FONT_HEIGHT - 1));
+Surface *Surface::newDialog(uint16 width, uint8 numLines, const char **lines, bool varLength, 
+							int colour, bool squashedLines) {
+	Point size;
+	Surface::getDialogBounds(size, 0, numLines, squashedLines);
+
+	Surface *s = new Surface(width, size.y);
 	s->createDialog();
 
-	for (uint8 ctr = 0; ctr < numLines; ++ctr)
-		s->writeString(DIALOG_EDGE_SIZE + 3, DIALOG_EDGE_SIZE + 2 + 
-			(ctr * (FONT_HEIGHT - 1)), lines[ctr], true, colour, varLength);
+	uint16 yP = Surface::textY();
+	for (uint8 ctr = 0; ctr < numLines; ++ctr) {
+		s->writeString(Surface::textX(), yP, lines[ctr], true, colour, varLength);
+		yP += squashedLines ? FONT_HEIGHT - 1 : FONT_HEIGHT;
+	}
+
 	return s;
 }
 
-Surface *Surface::newDialog(uint16 width, const char *line, uint8 colour) {
+Surface *Surface::newDialog(uint16 width, const char *line, int colour) {
 	char **lines;
 	char *lineCopy = strdup(line);
 	uint8 numLines;
-	wordWrap(lineCopy, width - (DIALOG_EDGE_SIZE + 3) * 2, lines, numLines);
+	wordWrap(lineCopy, width - (Surface::textX() * 2), lines, numLines);
 
 	// Create the dialog 
 	Surface *result = newDialog(width, numLines, const_cast<const char **>(lines), true, colour);
@@ -466,7 +521,7 @@
 
 	while (!abortFlag) {
 		// Display the string
-		screen.screen().writeString(x, y, newLine, true, DIALOG_TEXT_COLOUR, varLength);
+		screen.screen().writeString(x, y, newLine, true, DEFAULT_TEXT_COLOUR, varLength);
 		screen.update();
 		int stringSize = textWidth(newLine.c_str());
 
@@ -746,8 +801,9 @@
 
 	// Write out the character name
 	uint16 charWidth = Surface::textWidth(srcCharName);
-	_surface->writeString((TALK_DIALOG_WIDTH-charWidth)/2, TALK_DIALOG_EDGE_SIZE + 2,
-		srcCharName, true, DIALOG_WHITE_COLOUR);
+	byte white = LureEngine::getReference().isEGA() ?  EGA_DIALOG_WHITE_COLOUR : VGA_DIALOG_WHITE_COLOUR;
+	_surface->writeString((TALK_DIALOG_WIDTH - charWidth) / 2, TALK_DIALOG_EDGE_SIZE + 2,
+		srcCharName, true, white);
 	debugC(ERROR_DETAILED, kLureDebugAnimations, "TalkDialog end");
 }
 
@@ -826,14 +882,18 @@
 #define SR_SEPARATOR_HEIGHT 5
 #define SR_SAVEGAME_NAMES_Y (SR_SEPARATOR_Y + SR_SEPARATOR_HEIGHT + 1)
 
+
 void SaveRestoreDialog::toggleHightlight(int xs, int xe, int ys, int ye) {
 	Screen &screen = Screen::getReference();
 	byte *addr = screen.screen().data().data() + FULL_SCREEN_WIDTH * ys + xs;
+	const byte colourList[4] = {EGA_DIALOG_TEXT_COLOUR, EGA_DIALOG_WHITE_COLOUR,
+		VGA_DIALOG_TEXT_COLOUR, VGA_DIALOG_WHITE_COLOUR};
+	const byte *colours = LureEngine::getReference().isEGA() ? &colourList[0] : &colourList[2];
 
 	for (int y = 0; y < ye - ys + 1; ++y, addr += FULL_SCREEN_WIDTH) {
 		for (int x = 0; x < xe - xs + 1; ++x) {
-			if (addr[x] == DIALOG_TEXT_COLOUR) addr[x] = DIALOG_WHITE_COLOUR;
-			else if (addr[x] == DIALOG_WHITE_COLOUR) addr[x] = DIALOG_TEXT_COLOUR;
+			if (addr[x] == colours[0]) addr[x] = colours[1];
+			else if (addr[x] == colours[1]) addr[x] = colours[0];
 		}
 	}
 
@@ -885,7 +945,7 @@
 
 	// Write out any existing save names
 	for (index = 0; index < numSaves; ++index)
-		s->writeString(DIALOG_EDGE_SIZE, SR_SAVEGAME_NAMES_Y + (index * 8), saveNames[index]->c_str(), true);
+		s->writeString(Surface::textX(), SR_SAVEGAME_NAMES_Y + (index * 8), saveNames[index]->c_str(), true);
 
 	// Display the dialog
 	s->copyTo(&screen.screen(), SAVE_DIALOG_X, SAVE_DIALOG_Y);
@@ -914,8 +974,8 @@
 					int lineNum;
 
 					if (events.type() == Common::EVENT_MOUSEMOVE) {
-						if ((mouse.x() < (SAVE_DIALOG_X + DIALOG_EDGE_SIZE)) ||
-							(mouse.x() >= (SAVE_DIALOG_X + s->width() - DIALOG_EDGE_SIZE)) ||
+						if ((mouse.x() < (SAVE_DIALOG_X + Surface::textX())) ||
+							(mouse.x() >= (SAVE_DIALOG_X + s->width() - Surface::textX())) ||
 							(mouse.y() < SAVE_DIALOG_Y + SR_SAVEGAME_NAMES_Y) ||
 							(mouse.y() >= SAVE_DIALOG_Y + SR_SAVEGAME_NAMES_Y + numSaves * FONT_HEIGHT))
 							// Outside displayed lines
@@ -935,16 +995,16 @@
 					if (lineNum != selectedLine) {
 						if (selectedLine != -1)
 							// Deselect previously selected line
-							toggleHightlight(SAVE_DIALOG_X + DIALOG_EDGE_SIZE, 
-								SAVE_DIALOG_X + s->width() - DIALOG_EDGE_SIZE,
+							toggleHightlight(SAVE_DIALOG_X + Surface::textX(), 
+								SAVE_DIALOG_X + s->width() - Surface::textX(),
 								SAVE_DIALOG_Y + SR_SAVEGAME_NAMES_Y + selectedLine * FONT_HEIGHT,
 								SAVE_DIALOG_Y + SR_SAVEGAME_NAMES_Y + (selectedLine + 1) * FONT_HEIGHT - 1);
 
 						// Highlight new line
 						selectedLine = lineNum;
 						if (selectedLine != -1)
-							toggleHightlight(SAVE_DIALOG_X + DIALOG_EDGE_SIZE, 
-								SAVE_DIALOG_X + s->width() - DIALOG_EDGE_SIZE,
+							toggleHightlight(SAVE_DIALOG_X + Surface::textX(), 
+								SAVE_DIALOG_X + s->width() - Surface::textX(),
 								SAVE_DIALOG_Y + SR_SAVEGAME_NAMES_Y + selectedLine * FONT_HEIGHT,
 								SAVE_DIALOG_Y + SR_SAVEGAME_NAMES_Y + (selectedLine + 1) * FONT_HEIGHT - 1);
 					}
@@ -957,8 +1017,8 @@
 
 		// Deselect selected row
 		if (selectedLine != -1) 
-			toggleHightlight(SAVE_DIALOG_X + DIALOG_EDGE_SIZE, 
-				SAVE_DIALOG_X + s->width() - DIALOG_EDGE_SIZE,
+			toggleHightlight(SAVE_DIALOG_X + Surface::textX(), 
+				SAVE_DIALOG_X + s->width() - Surface::textX(),
 				SAVE_DIALOG_Y + SR_SAVEGAME_NAMES_Y + selectedLine * FONT_HEIGHT,
 				SAVE_DIALOG_Y + SR_SAVEGAME_NAMES_Y + (selectedLine + 1) * FONT_HEIGHT - 1);
 
@@ -971,15 +1031,15 @@
 		// If in save mode, allow the entry of a new savename
 		if (saveDialog) {
 			if (!screen.screen().getString(*saveNames[selectedLine], 
-				INFO_DIALOG_WIDTH - (DIALOG_EDGE_SIZE * 2), 
-				false, true, SAVE_DIALOG_X + DIALOG_EDGE_SIZE, 
+				INFO_DIALOG_WIDTH - (Surface::textX() * 2), 
+				false, true, SAVE_DIALOG_X + Surface::textX(), 
 				SAVE_DIALOG_Y + SR_SAVEGAME_NAMES_Y + selectedLine * FONT_HEIGHT)) {
 				// Aborted out of name selection, so restore old name and 
 				// go back to slot selection
 				screen.screen().writeString(
-					SAVE_DIALOG_X + DIALOG_EDGE_SIZE, 
+					SAVE_DIALOG_X + Surface::textX(), 
 					SAVE_DIALOG_Y + SR_SAVEGAME_NAMES_Y + selectedLine * FONT_HEIGHT,
-                    saveNames[selectedLine]->c_str(), true, DIALOG_TEXT_COLOUR, true);
+                    saveNames[selectedLine]->c_str(), true);
 				selectedLine = -1;
 				continue;
 			}

Modified: scummvm/trunk/engines/lure/surface.h
===================================================================
--- scummvm/trunk/engines/lure/surface.h	2008-01-05 08:17:39 UTC (rev 30225)
+++ scummvm/trunk/engines/lure/surface.h	2008-01-05 10:34:34 UTC (rev 30226)
@@ -35,14 +35,23 @@
 
 namespace Lure {
 
+#define DEFAULT_TEXT_COLOUR -1
+
 class Surface {
 private:
 	MemoryBlock *_data;
 	uint16 _width, _height;
+
+	void egaCreateDialog(bool blackFlag);
+	void vgaCreateDialog(bool blackFlag);
 public:
 	Surface(MemoryBlock *src, uint16 width, uint16 height);
 	Surface(uint16 width, uint16 height);
 	~Surface();
+	static uint16 textX();
+	static uint16 textY();
+	static void getDialogBounds(Common::Point &size, int charWidth, int numLines,
+		bool squashedLines = true);
 
 	static void initialise();
 	static void deinitialise();
@@ -53,11 +62,11 @@
 
 	void loadScreen(uint16 resourceId);
 	void loadScreen(MemoryBlock *data);
-	int writeChar(uint16 x, uint16 y, uint8 ascii, bool transparent, uint8 colour);
+	int writeChar(uint16 x, uint16 y, uint8 ascii, bool transparent, int colour);
 	void writeString(uint16 x, uint16 y, Common::String line, bool transparent,
-		uint8 colour = DIALOG_TEXT_COLOUR, bool varLength = true);
+		int colour = DEFAULT_TEXT_COLOUR, bool varLength = true);
 	void writeSubstring(uint16 x, uint16 y, Common::String line, int len, 
-		bool transparent, uint8 colour = DIALOG_TEXT_COLOUR, bool varLength = true);
+		bool transparent, int colour = DEFAULT_TEXT_COLOUR, bool varLength = true);
 	void transparentCopyTo(Surface *dest);
 	void copyTo(Surface *dest);
 	void copyTo(Surface *dest, uint16 x, uint16 y);
@@ -73,8 +82,9 @@
 
 	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, const 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 *newDialog(uint16 width, uint8 numLines, const char **lines, bool varLength = true, 
+		int colour = DEFAULT_TEXT_COLOUR, bool squashedLines = true);
+	static Surface *newDialog(uint16 width, const char *lines, int colour = DEFAULT_TEXT_COLOUR);
 	static Surface *getScreen(uint16 resourceId);
 	bool getString(Common::String &line, int maxSize, bool isNumeric, bool varLength, int16 x, int16 y);
 };


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