diff options
| author | Paul Gilbert | 2009-12-19 05:47:31 +0000 | 
|---|---|---|
| committer | Paul Gilbert | 2009-12-19 05:47:31 +0000 | 
| commit | 63350a0ecca8bb1b3c102ffea698ace04337665a (patch) | |
| tree | 2cfd6ebc63f80c3f9050297b48d919cd7a1c3b22 | |
| parent | ae50fdca7238c6898e9289935ec392f66e0311ae (diff) | |
| download | scummvm-rg350-63350a0ecca8bb1b3c102ffea698ace04337665a.tar.gz scummvm-rg350-63350a0ecca8bb1b3c102ffea698ace04337665a.tar.bz2 scummvm-rg350-63350a0ecca8bb1b3c102ffea698ace04337665a.zip | |
Further implementation of dialog/message script language
svn-id: r46418
| -rw-r--r-- | engines/m4/console.cpp | 10 | ||||
| -rw-r--r-- | engines/m4/dialogs.cpp | 163 | ||||
| -rw-r--r-- | engines/m4/dialogs.h | 8 | 
3 files changed, 153 insertions, 28 deletions
| diff --git a/engines/m4/console.cpp b/engines/m4/console.cpp index 719c58fcaa..c8fa316533 100644 --- a/engines/m4/console.cpp +++ b/engines/m4/console.cpp @@ -364,13 +364,15 @@ bool Console::cmdMessage(int argc, const char **argv) {  	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); diff --git a/engines/m4/dialogs.cpp b/engines/m4/dialogs.cpp index 2796fe4030..442c31f35d 100644 --- a/engines/m4/dialogs.cpp +++ b/engines/m4/dialogs.cpp @@ -35,6 +35,13 @@ static void strToUpper(char *s) {  	}  } +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 RGB8 DIALOG_PALETTE[8] = {  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 @@ void Dialog::incLine() {  	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 @@ void Dialog::writeChars(const char *srcLine) {  	}  } +/** + * 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 @@ void Dialog::appendText(const char *line) {  	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 @@ void Dialog::addLine(const char *line, bool underlineP) {  	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 @@ void Dialog::addLine(const char *line, bool underlineP) {  	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 @@ Dialog::Dialog(M4Engine *vm, const char *msgData, const char *title): View(vm, C  	_lineX = 0;  	_widthX = 0;  	_dialogWidth = 0; +	_commandCase = false;  	char dialogLine[256];  	char cmdText[80]; @@ -226,7 +335,7 @@ Dialog::Dialog(M4Engine *vm, const char *msgData, const char *title): View(vm, C  				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 @@ Dialog::Dialog(M4Engine *vm, const char *msgData, const char *title): View(vm, C  				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 @@ Dialog::~Dialog() {  }  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 @@ void Dialog::draw() {  	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; diff --git a/engines/m4/dialogs.h b/engines/m4/dialogs.h index c9825b6d9b..c8b19338f3 100644 --- a/engines/m4/dialogs.h +++ b/engines/m4/dialogs.h @@ -37,8 +37,9 @@ public:  	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,7 +52,7 @@ private:  	RGBList *_palette;  	int _lineX;  	int _widthX; - +	bool _commandCase;  	void initDialog();  	void incLine(); @@ -59,6 +60,9 @@ private:  	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); | 
