[Scummvm-cvs-logs] SF.net SVN: scummvm:[46418] scummvm/trunk/engines/m4

dreammaster at users.sourceforge.net dreammaster at users.sourceforge.net
Sat Dec 19 06:47:31 CET 2009


Revision: 46418
          http://scummvm.svn.sourceforge.net/scummvm/?rev=46418&view=rev
Author:   dreammaster
Date:     2009-12-19 05:47:31 +0000 (Sat, 19 Dec 2009)

Log Message:
-----------
Further implementation of dialog/message script language

Modified Paths:
--------------
    scummvm/trunk/engines/m4/console.cpp
    scummvm/trunk/engines/m4/dialogs.cpp
    scummvm/trunk/engines/m4/dialogs.h

Modified: scummvm/trunk/engines/m4/console.cpp
===================================================================
--- scummvm/trunk/engines/m4/console.cpp	2009-12-19 05:46:26 UTC (rev 46417)
+++ scummvm/trunk/engines/m4/console.cpp	2009-12-19 05:47:31 UTC (rev 46418)
@@ -364,13 +364,15 @@
 	if (argc == 1)
 		DebugPrintf("message 'objnum'\n");
 	else {
-		int messageId = strToInt(argv[1]);
-		int idx = _vm->_globals->messageIndexOf(messageId);
-		if (idx == -1)
+		int messageIdx = strToInt(argv[1]);
+		if ((argc == 3) && !strcmp(argv[2], "id"))
+			messageIdx = _vm->_globals->messageIndexOf(messageIdx);
+
+		if (messageIdx == -1)
 			DebugPrintf("Unknown message");
 		else
 		{
-			const char *msg = _vm->_globals->loadMessage(idx);
+			const char *msg = _vm->_globals->loadMessage(messageIdx);
 			Dialog *dlg = new Dialog(_vm, msg, "TEST DIALOG");
 
 			_vm->_viewManager->addView(dlg);

Modified: scummvm/trunk/engines/m4/dialogs.cpp
===================================================================
--- scummvm/trunk/engines/m4/dialogs.cpp	2009-12-19 05:46:26 UTC (rev 46417)
+++ scummvm/trunk/engines/m4/dialogs.cpp	2009-12-19 05:47:31 UTC (rev 46418)
@@ -35,6 +35,13 @@
 	}
 }
 
+static void strToLower(char *s) {
+	while (*s) {
+		*s = tolower(*s);
+		++s;
+	}
+}
+
 const RGB8 DIALOG_PALETTE[8] = {
 	{0x80, 0x80, 0x80, 0xff}, {0x90, 0x90, 0x90, 0xff}, {0x70, 0x70, 0x70, 0xff}, {0x9c, 0x9c, 0x9c, 0xff},
 	{0x80, 0x80, 0x80, 0xff}, {0x90, 0x90, 0x90, 0xff}, {0xDC, 0xDC, 0xDC, 0xff}, {0x00, 0x00, 0x00, 0xff}
@@ -44,10 +51,16 @@
 
 const int DIALOG_SPACING = 1;
 
+/**
+ * Handles any dialog initialisation
+ */
 void Dialog::initDialog() {
 	incLine();
 }
 
+/**
+ * Adds a new line to the dialog output
+ */
 void Dialog::incLine() {
 	_lineX = 0;
 	_widthX = 0;
@@ -56,6 +69,10 @@
 	assert(_lines.size() <= 20);
 }
 
+/**
+ * Writes some text to the dialog output, taking care of word wrapping if the text size
+ * exceeds the dialog's width
+ */
 void Dialog::writeChars(const char *srcLine) {
 	char wordStr[80];
 	char line[80];
@@ -124,6 +141,9 @@
 	}
 }
 
+/**
+ * Appends some text to the current dialog line
+ */
 void Dialog::appendText(const char *line) {
 	_lineX += strlen(line);
 	_widthX += _vm->_font->getWidth(line, DIALOG_SPACING);
@@ -131,6 +151,9 @@
 	strcat(_lines[_lines.size() - 1].data, line);
 }
 
+/**
+ * Adds a line of text to the dialog lines list
+ */
 void Dialog::addLine(const char *line, bool underlineP) {
 	if ((_widthX > 0) || (_lineX > 0))
 		incLine();
@@ -141,7 +164,7 @@
 	if ((lineWidth > _dialogWidth) || (lineLen >= _widthChars))
 		writeChars(line);
 	else {
-		_lines[_lines.size() - 1].xp = (_dialogWidth - lineWidth) / 2;
+		_lines[_lines.size() - 1].xp = (_dialogWidth - 10 - lineWidth) / 2;
 		strcpy(_lines[_lines.size() - 1].data, line);
 	}
 
@@ -151,12 +174,97 @@
 	incLine();
 }
 
+/**
+ * Adds a bar separation line to the dialog lines list
+ */
+void Dialog::addBarLine() {
+	if ((_widthX > 0) || (_lineX > 0))
+		incLine();
+
+	// Flag the line as being a bar separator
+	_lines[_lines.size() - 1].barLine = true;
+	incLine();
+}
+
+/**
+ * Retrieves a specified vocab entry
+ */
+void Dialog::getVocab(int vocabId, char **line) {
+	assert(vocabId > 0);
+	const char *vocabStr = _vm->_globals->getVocab(vocabId);
+	strcpy(*line, vocabStr);
+
+	if (_commandCase)
+		strToUpper(*line);
+	else
+		strToLower(*line);
+
+	// Move the string pointer to after the added string
+	while (!**line)
+		++*line;
+}
+
+bool Dialog::handleNounSuffix(char *destP, int nounNum, const char *srcP) {
+	char srcLine[40];
+
+	// The next source character must be a colon in front of the first verb
+	if (*srcP != ':')
+		return false;
+
+	// Copy the remainder of the line into a temporary buffer to get the seperate verbs
+	strcpy(srcLine, ++srcP);
+	char *altP = strchr(srcLine, ':');
+	if (altP)
+		*altP = '\0';
+
+	if (*srcP != '\0') {
+		while (*srcP != ':') {
+			++srcP;
+			if (!*srcP) break;
+		}
+	}
+
+	if (*srcP != '\0')
+		++srcP;
+
+	// 
+	char var_FC[40];
+	char tempLine[40];
+	strcpy(var_FC, srcP);
+	char *tmpP = &tempLine[0];
+	char *tmp2P = tmpP;
+
+	uint16 _vocabIds[2] = {1, 1}; // FIXME/TODO: Proper vocab ids
+	getVocab(_vocabIds[nounNum], &tmpP);
+	
+	if ((*(tmpP - 1) != 'S') && (*(tmpP - 1) != 's')) {
+		// Singular object
+		tmpP = &var_FC[0];
+	} else if (!strcmp(tempLine, "a ")) {
+		// Pontially plural
+		char ch = tolower(*tmp2P);
+
+		if (!((ch > 'U') || ((ch != 'A') && (ch != 'E') && (ch != 'I') && (ch != 'O'))))
+			strcpy(tempLine, "an ");
+	}
+
+	strcpy(destP, tmpP);
+	return true;
+}
+
+/**
+ * Checks whether the start of an extracted command matches a specified given command constant
+ */
 bool Dialog::matchCommand(const char *s1, const char *s2) {
-	return strncmp(s1, s2, strlen(s2)) == 0;
+	bool result = scumm_strnicmp(s1, s2, strlen(s2)) == 0;
+	_commandCase = isupper(*s1);
+	return result;
 }
 
 Dialog::Dialog(M4Engine *vm, const char *msgData, const char *title): View(vm, Common::Rect(0, 0, 0, 0)) {
 	assert(msgData);
+	_vm->_font->setFont(FONT_INTERFACE_MADS);
+
 	const char *srcP = msgData;
 	bool skipLine = false;
 	bool initFlag = false;
@@ -172,6 +280,7 @@
 	_lineX = 0;
 	_widthX = 0;
 	_dialogWidth = 0;
+	_commandCase = false;
 
 	char dialogLine[256];
 	char cmdText[80];
@@ -226,7 +335,7 @@
 				if (id > 0) {
 					// Suffix provided - specifies the dialog width in number of chars
 					_widthChars = id * 2;
-					_dialogWidth = id * (_vm->_font->getMaxWidth() + 1) + 10;
+					_dialogWidth = id * (_vm->_font->getMaxWidth() + DIALOG_SPACING) + 10;
 				}
 			} else if (matchCommand(cmdText, "SENTENCE")) {
 				// Sentence command - loads the title into the line buffer
@@ -234,31 +343,45 @@
 				strToUpper(dialogLine);
 				lineP += strlen(dialogLine) + 1;
 
+			} else if (matchCommand(cmdText, "BAR")) {
+				// Adds a full-width line instead of normal text
+				addBarLine();
+
+			} else if (matchCommand(cmdText, "CENTER")) {
+				// Center command
+				skipLine = true;
+
 			} else if (matchCommand(cmdText, "CR")) {
 				// CR command
 				if (skipLine)
 					crFlag = true;
-				else {
+				else if (!initFlag) {
 					initDialog();
+					initFlag = true;
 				}
 
+			} else if (matchCommand(cmdText, "NOUN1")) {
+				// Noun command 1
+				handleNounSuffix(lineP, 1, cmdText + 5);
+
+			} else if (matchCommand(cmdText, "NOUN1")) {
+				// Noun command 2
+				handleNounSuffix(lineP, 2, cmdText + 5);
+
+			} else if (matchCommand(cmdText, "VERB")) {
+				// Verb/vocab retrieval
+				int verbId = 1; // TODO: Get correct vocab
+				getVocab(verbId, &lineP);
+
 			} else if (matchCommand(cmdText, "UNDER")) {
 				// Underline command
 				underline = true;
 
 			} else if (matchCommand(cmdText, "ASK")) {
 				// doAsk();
-			} else if (matchCommand(cmdText, "CENTER")) {
-				// Center command
-				skipLine = true;
-			} else if (matchCommand(cmdText, "VERB")) {
-				// Verb/vocab retrieval
-				/*getVocab(); */
 			} else if (matchCommand(cmdText, "INDEX")) {
 				// Index command
 				_dialogIndex = atoi(cmdText + 5);
-			} else if (matchCommand(cmdText, "NOUN")) {
-				// Noun command
 			} else {
 				error("Unknown dialog command '%s' encountered", cmdText);
 			}
@@ -279,19 +402,13 @@
 }
 
 void Dialog::draw() {
-	_vm->_font->setFont(FONT_INTERFACE_MADS);
+	assert(_widthChars != 0);
 
 	// Set up the palette for this view
 	_palette = new RGBList(8, NULL);
 	_palette->setRange(0, 8, DIALOG_PALETTE);
 	_vm->_palette->addRange(_palette);
 
-	// Validation
-	if (_widthChars == 0) {
-		warning("Dialog being shown without TITLE specified");
-		_widthChars = 30;
-	}
-
 	// Calculate bounds
 	int dlgWidth = _dialogWidth;
 	int dlgHeight = _lines.size() * (_vm->_font->getHeight() + 1) + 10;
@@ -338,10 +455,12 @@
 
 	for (uint lineCtr = 0, yp = 5; lineCtr < _lines.size(); ++lineCtr, yp += _vm->_font->getHeight() + 1) {
 
-		if (_lines[lineCtr].xp == 0xff) {
-			hLine(2, width() - 6, ((_vm->_font->getHeight() + 1) >> 1) + yp);
+		if (_lines[lineCtr].barLine) {
+			// Bar separation line
+			hLine(5, width() - 6, ((_vm->_font->getHeight() + 1) >> 1) + yp);
 		} else {
-			Common::Point pt((_lines[lineCtr].xp & 0x7f) + 5, yp);
+			// Standard line
+			Common::Point pt(_lines[lineCtr].xp + 5, yp);
 			if (_lines[lineCtr].xp & 0x40)
 				++pt.y;
 

Modified: scummvm/trunk/engines/m4/dialogs.h
===================================================================
--- scummvm/trunk/engines/m4/dialogs.h	2009-12-19 05:46:26 UTC (rev 46417)
+++ scummvm/trunk/engines/m4/dialogs.h	2009-12-19 05:47:31 UTC (rev 46418)
@@ -37,8 +37,9 @@
 	char data[100];
 	uint8 xp;
 	bool underline;
+	bool barLine;
 
-	DialogLine() { data[0] = '\0'; xp = 0; underline = false; }
+	DialogLine() { data[0] = '\0'; xp = 0; underline = barLine = false; }
 };
 
 class Dialog: public View {
@@ -51,14 +52,17 @@
 	RGBList *_palette;
 	int _lineX;
 	int _widthX;
+	bool _commandCase;
 
-
 	void initDialog();
 	void incLine();
 	bool matchCommand(const char *s1, const char *s2);
 	void writeChars(const char *line);
 	void addLine(const char *line, bool underlineP = false);
 	void appendText(const char *line);
+	void addBarLine();
+	void getVocab(int vocabId, char **line);
+	bool handleNounSuffix(char *destP, int nounNum, const char *srcP);
 	void draw();
 public:
 	Dialog(M4Engine *vm, const char *msgData, const char *title = NULL);


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