[Scummvm-cvs-logs] SF.net SVN: scummvm: [31756] scummvm/trunk/engines/made

john_doe at users.sourceforge.net john_doe at users.sourceforge.net
Mon Apr 28 12:56:22 CEST 2008


Revision: 31756
          http://scummvm.svn.sourceforge.net/scummvm/?rev=31756&view=rev
Author:   john_doe
Date:     2008-04-28 03:56:21 -0700 (Mon, 28 Apr 2008)

Log Message:
-----------
Implemented text drawing and cleanup.

Modified Paths:
--------------
    scummvm/trunk/engines/made/resource.cpp
    scummvm/trunk/engines/made/resource.h
    scummvm/trunk/engines/made/screen.cpp
    scummvm/trunk/engines/made/screen.h
    scummvm/trunk/engines/made/scriptfuncs.cpp

Modified: scummvm/trunk/engines/made/resource.cpp
===================================================================
--- scummvm/trunk/engines/made/resource.cpp	2008-04-28 09:42:29 UTC (rev 31755)
+++ scummvm/trunk/engines/made/resource.cpp	2008-04-28 10:56:21 UTC (rev 31756)
@@ -225,7 +225,7 @@
 	return _data[0];
 }
 
-int FontResource::getCharWidth(char c) const {
+int FontResource::getCharWidth(uint c) const {
 	byte *charData = getCharData(c);
 	if (charData)
 		return charData[0];
@@ -233,7 +233,7 @@
 		return 0;
 }
 
-byte *FontResource::getChar(char c) const {
+byte *FontResource::getChar(uint c) const {
 	byte *charData = getCharData(c);
 	if (charData)
 		return charData + 1;
@@ -241,7 +241,17 @@
 		return NULL;
 }
 
-byte *FontResource::getCharData(char c) const {
+int FontResource::getTextWidth(const char *text) {
+	int width = 0;
+	if (text) {
+		int len = strlen(text);
+		for (int pos = 0; pos < len; pos++)
+			width += getCharWidth(text[pos]);
+	}
+	return width;
+}
+
+byte *FontResource::getCharData(uint c) const {
 	if (c < 28 || c > 255)
 		return NULL;
 	return _data + 1 + (c - 28) * (getHeight() + 1);

Modified: scummvm/trunk/engines/made/resource.h
===================================================================
--- scummvm/trunk/engines/made/resource.h	2008-04-28 09:42:29 UTC (rev 31755)
+++ scummvm/trunk/engines/made/resource.h	2008-04-28 10:56:21 UTC (rev 31756)
@@ -118,12 +118,13 @@
 	~FontResource();
 	void load(byte *source, int size);
 	int getHeight() const;
-	int getCharWidth(char c) const;
-	byte *getChar(char c) const;
+	int getCharWidth(uint c) const;
+	int getTextWidth(const char *text);
+	byte *getChar(uint c) const;
 protected:
 	byte *_data;
 	int _size;
-	byte *getCharData(char c) const;
+	byte *getCharData(uint c) const;
 };
 
 class XmidiResource : public Resource {

Modified: scummvm/trunk/engines/made/screen.cpp
===================================================================
--- scummvm/trunk/engines/made/screen.cpp	2008-04-28 09:42:29 UTC (rev 31755)
+++ scummvm/trunk/engines/made/screen.cpp	2008-04-28 10:56:21 UTC (rev 31756)
@@ -26,6 +26,7 @@
 #include "made/made.h"
 #include "made/screen.h"
 #include "made/resource.h"
+#include "made/database.h"
 
 namespace Made {
 
@@ -66,8 +67,13 @@
 	
 	_textX = 0;
 	_textY = 0;
+	_textColor = 0;
+	_textRect.left = 0;
+	_textRect.top = 0;
+	_textRect.right = 320;
+	_textRect.bottom = 200;
 	_font = NULL;
-	_currentFontIndex = 0;
+	_currentFontNum = 0;
 	_fontDrawCtx.x = 0;
 	_fontDrawCtx.y = 0;
 	_fontDrawCtx.w = 320;
@@ -206,7 +212,7 @@
 				break;
 
 			case 2: // drawObjectText
-				// TODO
+				printObjectText(_channels[i].index, _channels[i].x, _channels[i].y, _channels[i].fontNum, _channels[i].textColor, _channels[i].outlineColor, clipInfo);
 				break;
 
 			case 3: // drawAnimFrame
@@ -454,7 +460,63 @@
 
 
 uint16 Screen::placeText(uint16 channelIndex, uint16 textObjectIndex, int16 x, int16 y, uint16 fontNum, int16 textColor, int16 outlineColor) {
-	return 0;
+
+	if (channelIndex < 1 || channelIndex >= 100 || textObjectIndex == 0 || fontNum == 0)
+		return 0;
+
+	channelIndex--;
+
+	Object *obj = _vm->_dat->getObject(textObjectIndex);
+	const char *text = obj->getString();
+
+	int16 x1, y1, x2, y2;
+
+	setFont(fontNum);
+
+	int textWidth = _font->getTextWidth(text);
+	int textHeight = _font->getHeight();
+	
+	if (outlineColor != -1) {
+		textWidth += 2;
+		textHeight += 2;
+		x--;
+		y--;
+	}
+
+	x1 = x;
+	y1 = y;
+	x2 = x + textWidth;
+	y2 = y + textHeight;
+	//TODO: clipRect(x1, y1, x2, y2);
+
+	if (textWidth > 0 && outlineColor != -1) {
+		x++;
+		y++;
+	}
+	
+	int16 state = 1;
+	
+	if (_ground == 0)
+		state |= 2;
+
+	_channels[channelIndex].state = state;
+	_channels[channelIndex].type = 2;
+	_channels[channelIndex].index = textObjectIndex;
+	_channels[channelIndex].x = x;
+	_channels[channelIndex].y = y;
+	_channels[channelIndex].textColor = textColor;
+	_channels[channelIndex].fontNum = fontNum;
+	_channels[channelIndex].outlineColor = outlineColor;
+	_channels[channelIndex].x1 = x1;
+	_channels[channelIndex].y1 = y1;
+	_channels[channelIndex].x2 = x2;
+	_channels[channelIndex].y2 = y2;
+	_channels[channelIndex].area = (x2 - x2) * (y2 - y1);
+
+	if (_channelsUsedCount <= channelIndex)
+		_channelsUsedCount = channelIndex + 1;
+
+	return channelIndex + 1;
 }
 
 void Screen::show() {
@@ -465,7 +527,6 @@
 		return;
 
 	drawSpriteChannels(_clipInfo1, 3, 0);
-	
 	memcpy(_screen2->pixels, _screen1->pixels, 64000);
 	drawSpriteChannels(_clipInfo2, 1, 2);
 
@@ -499,16 +560,16 @@
 	}
 }
 
-void Screen::setFont(int16 fontIndex) {
-	if (fontIndex == _currentFontIndex)
+void Screen::setFont(int16 fontNum) {
+	if (fontNum == _currentFontNum)
 		return;
 	if (_font)
 		_vm->_res->freeResource(_font);
-	_font = _vm->_res->getFont(fontIndex);
-	_currentFontIndex = fontIndex;
+	_font = _vm->_res->getFont(fontNum);
+	_currentFontNum = fontNum;
 }
 
-void Screen::printChar(char c, int16 x, int16 y, byte color) {
+void Screen::printChar(uint c, int16 x, int16 y, byte color) {
 
 	if (!_font)
 		return;
@@ -534,4 +595,123 @@
 
 }
 
+void Screen::printText(const char *text) {
+
+	const int tabWidth = 5;
+
+	if (!_font)
+		return;
+
+	int textLen = strlen(text);
+	int textHeight = _font->getHeight();
+	int linePos = 1;
+	int16 x = _textX;
+	int16 y = _textY;
+	
+	for (int textPos = 0; textPos < textLen; textPos++) {
+	
+		uint c = text[textPos];
+		int charWidth = _font->getCharWidth(c);
+
+		if (c == 9) {
+			linePos = ((linePos / tabWidth) + 1) * tabWidth;
+			x = _textRect.left + linePos * _font->getCharWidth(32);
+		} else if (c == 10) {
+			linePos = 1;
+			x = _textRect.left;
+			y += textHeight;
+		} else if (c == 13) {
+			linePos = 1;
+			x = _textRect.left;
+		} else if (c == 32) {
+			// TODO: Word-wrap
+			int wrapPos = textPos + 1;
+			int wrapX = x + charWidth;
+			while (wrapPos < textLen && text[wrapPos] != 0 && text[wrapPos] != 32 && text[wrapPos] >= 28) {
+				wrapX += _font->getCharWidth(text[wrapPos]);
+				wrapPos++;
+			}
+			if (wrapX >= _textRect.right) {
+				linePos = 1;
+				x = _textRect.left;
+				y += textHeight;
+				charWidth = 0;
+				// TODO: text[textPos] = '\x01';
+			}
+		}
+		
+		if (x + charWidth > _textRect.right) {
+			linePos = 1;
+			x = _textRect.left;
+			y += textHeight;
+		}
+		
+		if (y + textHeight > _textRect.bottom) {
+			// TODO
+		}
+		
+		if (c >= 28 && c <= 255) {
+			if (_dropShadowColor != -1) {
+				printChar(c, x + 1, y + 1, _dropShadowColor);
+			}
+			if (_outlineColor != -1) {
+				printChar(c, x, y - 1, _outlineColor);
+				printChar(c, x, y + 1, _outlineColor);
+				printChar(c, x - 1, y, _outlineColor);
+				printChar(c, x + 1, y, _outlineColor);
+				printChar(c, x - 1, y - 1, _outlineColor);
+				printChar(c, x - 1, y + 1, _outlineColor);
+				printChar(c, x + 1, y - 1, _outlineColor);
+				printChar(c, x + 1, y + 1, _outlineColor);
+			}
+			printChar(c, x, y, _textColor);
+			x += charWidth;
+			linePos++;
+		}
+	
+	}
+
+	_textX = x;
+	_textY = y;
+
+}
+
+void Screen::printTextEx(const char *text, int16 x, int16 y, int16 fontNum, int16 textColor, int16 outlineColor, const ClipInfo &clipInfo) {
+	if (*text == 0 || x == 0 || y == 0)
+		return;
+
+	int16 oldFontNum = _currentFontNum;
+	Common::Rect oldTextRect;
+
+	_fontDrawCtx = clipInfo;
+	
+	getTextRect(oldTextRect);
+	setFont(fontNum);
+	setTextColor(textColor);
+	setOutlineColor(outlineColor);
+	setTextXY(x, y);
+	printText(text);
+	setTextRect(oldTextRect);
+	setFont(oldFontNum);
+	
+}
+
+void Screen::printObjectText(int16 objectIndex, int16 x, int16 y, int16 fontNum, int16 textColor, int16 outlineColor, const ClipInfo &clipInfo) {
+
+	if (objectIndex == 0)
+		return;
+
+	Object *obj = _vm->_dat->getObject(objectIndex);
+	const char *text = obj->getString();
+	
+	printTextEx(text, x, y, fontNum, textColor, outlineColor, clipInfo);
+
+}
+
+int16 Screen::getTextWidth(int16 fontNum, const char *text) {
+	setFont(fontNum);
+	return _font->getTextWidth(text);
+}
+
+
 } // End of namespace Made

Modified: scummvm/trunk/engines/made/screen.h
===================================================================
--- scummvm/trunk/engines/made/screen.h	2008-04-28 09:42:29 UTC (rev 31755)
+++ scummvm/trunk/engines/made/screen.h	2008-04-28 10:56:21 UTC (rev 31756)
@@ -74,7 +74,17 @@
 	void setGround(uint16 ground) { _ground = ground; }
 	void setTextColor(int16 color) { _textColor = color; }
 
-	void setOutlineColor(int16 color) { 
+	void setTextRect(const Common::Rect &textRect) {
+		_textRect = textRect;
+		_textX = _textRect.left;
+		_textY = _textRect.top;
+	}
+
+	void getTextRect(Common::Rect &textRect) {
+		textRect = _textRect;
+	}
+
+	void setOutlineColor(int16 color) {
 		_outlineColor = color;
 		_dropShadowColor = -1;
 	}
@@ -83,7 +93,12 @@
 		_outlineColor = -1;
 		_dropShadowColor = color;
 	}
-
+	
+	void setTextXY(int16 x, int16 y) {
+		_textX = x;
+		_textY = y;
+	}
+	
 	uint16 updateChannel(uint16 channelIndex);
 	void deleteChannel(uint16 channelIndex);
 	int16 getChannelType(uint16 channelIndex);
@@ -117,10 +132,14 @@
 	void show();
 	void flash(int count);
 	
-	void setFont(int16 fontIndex);
-	void printChar(char c, int16 x, int16 y, byte color);
-	
+	void setFont(int16 fontNum);
+	void printChar(uint c, int16 x, int16 y, byte color);
+	void printText(const char *text);
+	void printTextEx(const char *text, int16 x, int16 y, int16 fontNum, int16 textColor, int16 outlineColor, const ClipInfo &clipInfo);
+	void printObjectText(int16 objectIndex, int16 x, int16 y, int16 fontNum, int16 textColor, int16 outlineColor, const ClipInfo &clipInfo);
+	int16 getTextWidth(int16 fontNum, const char *text);
 
+
 protected:
 	MadeEngine *_vm;
 	
@@ -131,13 +150,13 @@
 	byte _palette[768], _newPalette[768], _fxPalette[768];
 	int _paletteColorCount, _oldPaletteColorCount;
 	bool _paletteInitialized, _needPalette;
-	uint16 _currentFont;
 	int16 _textColor;
 	int16 _outlineColor;
 	int16 _dropShadowColor;
 
 	int16 _textX, _textY;
-	int16 _currentFontIndex;
+	Common::Rect _textRect;
+	int16 _currentFontNum;
 	FontResource *_font;
 	ClipInfo _fontDrawCtx;
 

Modified: scummvm/trunk/engines/made/scriptfuncs.cpp
===================================================================
--- scummvm/trunk/engines/made/scriptfuncs.cpp	2008-04-28 09:42:29 UTC (rev 31755)
+++ scummvm/trunk/engines/made/scriptfuncs.cpp	2008-04-28 10:56:21 UTC (rev 31756)
@@ -165,23 +165,22 @@
 #undef External
 
 int16 ScriptFunctionsRtz::o1_SYSTEM(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_SYSTEM");
+	// This opcode is empty.
 	return 0;
 }
 
 int16 ScriptFunctionsRtz::o1_INITGRAF(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_INITGRAF");
+	// This opcode is empty.
 	return 0;
 }
 
 int16 ScriptFunctionsRtz::o1_RESTOREGRAF(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_RESTOREGRAF");
+	// This opcode is empty.
 	return 0;
 }
 
 int16 ScriptFunctionsRtz::o1_DRAWPIC(int16 argc, int16 *argv) {
-	int16 channel = _vm->_screen->drawPic(argv[4], argv[3], argv[2], argv[1], argv[0]);
-	return channel;
+	return _vm->_screen->drawPic(argv[4], argv[3], argv[2], argv[1], argv[0]);
 }
 
 int16 ScriptFunctionsRtz::o1_CLS(int16 argc, int16 *argv) {
@@ -252,7 +251,6 @@
 	}
 
 	_vm->_system->updateScreen();
-	//g_system->delayMillis(10);
 
 	return eventNum;
 }
@@ -275,18 +273,18 @@
 }
 
 int16 ScriptFunctionsRtz::o1_PLAYSND(int16 argc, int16 *argv) {
-	int soundId = argv[0];
+	int soundNum = argv[0];
 	bool loop = false;
 
 	if (argc > 1) {
-		soundId = argv[1];
+		soundNum = argv[1];
 		loop = (argv[0] == 1);
 	}
 
-	if (soundId > 0) {
+	if (soundNum > 0) {
 		if (!_vm->_mixer->isSoundHandleActive(_audioStreamHandle)) {
 			_vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, 
-										 _vm->_res->getSound(soundId)->getAudioStream(_vm->_soundRate, loop));
+										 _vm->_res->getSound(soundNum)->getAudioStream(_vm->_soundRate, loop));
 		}
 	}
 
@@ -294,9 +292,9 @@
 }
 
 int16 ScriptFunctionsRtz::o1_PLAYMUS(int16 argc, int16 *argv) {
-	int16 musicId = argv[0];
-	if (musicId > 0) {
-		XmidiResource *xmidi = _vm->_res->getXmidi(musicId);
+	int16 musicNum = argv[0];
+	if (musicNum > 0) {
+		XmidiResource *xmidi = _vm->_res->getXmidi(musicNum);
 		_vm->_music->play(xmidi);
 		_vm->_res->freeResource(xmidi);
 	}
@@ -317,6 +315,8 @@
 
 int16 ScriptFunctionsRtz::o1_TEXTPOS(int16 argc, int16 *argv) {
 	warning("Unimplemented opcode: o1_TEXTPOS");
+	// This seems to be some kind of low-level opcode.
+	// The original engine calls int 10h to set the VGA cursor position.
 	return 0;
 }
 
@@ -421,16 +421,14 @@
 }
 
 int16 ScriptFunctionsRtz::o1_FONT(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_FONT");
-
-	uint16 fontID = argv[0];
-	printf("Set font to %i\n", fontID);
-	_vm->_screen->setFont(fontID);
+	_vm->_screen->setFont(argv[0]);
 	return 0;
 }
 
 int16 ScriptFunctionsRtz::o1_DRAWTEXT(int16 argc, int16 *argv) {
 	warning("Unimplemented opcode: o1_DRAWTEXT");
+	Object *obj = _vm->_dat->getObject(argv[argc - 1]);
+	warning("argc = %d; drawText = %s", argc, obj->getString());
 	return 0;
 }
 
@@ -441,26 +439,20 @@
 
 int16 ScriptFunctionsRtz::o1_TEXTRECT(int16 argc, int16 *argv) {
 	warning("Unimplemented opcode: o1_TEXTRECT");
-
-	int16 x1 = CLIP<int16>(argv[0], 1, 318);
-	int16 y1 = CLIP<int16>(argv[1], 1, 198);
+	int16 x1 = CLIP<int16>(argv[4], 1, 318);
+	int16 y1 = CLIP<int16>(argv[3], 1, 198);
 	int16 x2 = CLIP<int16>(argv[2], 1, 318);
-	int16 y2 = CLIP<int16>(argv[3], 1, 198);
-	int16 textValue = argv[4];
-
-	printf("Text rect: %i, %i, %i, %i - text value: %i\n", x1, y1, x2, y2, textValue);
-	// TODO: set text rect
-
+	int16 y2 = CLIP<int16>(argv[1], 1, 198);
+	int16 textValue = argv[0];
+	// TODO: textValue
+	_vm->_screen->setTextRect(Common::Rect(x1, y1, x2, y2));
 	return 0;
 }
 
 int16 ScriptFunctionsRtz::o1_TEXTXY(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_TEXTXY");
-
-	int16 x = CLIP<int16>(argv[0], 1, 318);
-	int16 y = CLIP<int16>(argv[1], 1, 198);
-
-	printf("Text: x = %i, y = %i\n", x, y);
+	int16 x = CLIP<int16>(argv[1], 1, 318);
+	int16 y = CLIP<int16>(argv[0], 1, 198);
+	_vm->_screen->setTextXY(x, y);
 	return 0;
 }
 
@@ -574,6 +566,7 @@
 int16 ScriptFunctionsRtz::o1_SNDENERGY(int16 argc, int16 *argv) {
 	// This is called while in-game voices are played
 	// Not sure what it's used for
+	// -> It's used to animate mouths when NPCs are talking
 	// Commented out to reduce spam
 	//warning("Unimplemented opcode: o1_SNDENERGY");
 	return 0;
@@ -590,11 +583,13 @@
 }
 
 int16 ScriptFunctionsRtz::o1_TEXTWIDTH(int16 argc, int16 *argv) {
-	Object *obj = _vm->_dat->getObject(argv[1]);
-	const char *text = obj->getString();
-	debug(4, "text = %s\n", text);
-	// TODO
-	return 0;
+	int16 width = 0;
+	if (argv[1] > 0) {
+		Object *obj = _vm->_dat->getObject(argv[1]);
+		const char *text = obj->getString();
+		width = _vm->_screen->getTextWidth(argv[0], text);
+	}
+	return width;
 }
 
 int16 ScriptFunctionsRtz::o1_PLAYMOVIE(int16 argc, int16 *argv) {
@@ -645,10 +640,7 @@
 }
 
 int16 ScriptFunctionsRtz::o1_PLACETEXT(int16 argc, int16 *argv) {
-	Object *obj = _vm->_dat->getObject(argv[5]);
-	const char *text = obj->getString();
-	debug(4, "text = %s\n", text); fflush(stdout);
-	return 0;
+	return _vm->_screen->placeText(argv[6], argv[5], argv[4], argv[3], argv[2], argv[1], argv[0]);
 }
 
 int16 ScriptFunctionsRtz::o1_DELETECHANNEL(int16 argc, int16 *argv) {


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