diff options
| author | Benjamin Haisch | 2008-04-28 10:56:21 +0000 | 
|---|---|---|
| committer | Benjamin Haisch | 2008-04-28 10:56:21 +0000 | 
| commit | fc6fe46951f999d7fc14bf4bedcce7bfe728a77d (patch) | |
| tree | 3d373e2c69567fd77dc61702857711ecea98bbff | |
| parent | 6d3a7e4f6b90b4e24119af735b976031a6c9c7e7 (diff) | |
| download | scummvm-rg350-fc6fe46951f999d7fc14bf4bedcce7bfe728a77d.tar.gz scummvm-rg350-fc6fe46951f999d7fc14bf4bedcce7bfe728a77d.tar.bz2 scummvm-rg350-fc6fe46951f999d7fc14bf4bedcce7bfe728a77d.zip | |
Implemented text drawing and cleanup.
svn-id: r31756
| -rw-r--r-- | engines/made/resource.cpp | 16 | ||||
| -rw-r--r-- | engines/made/resource.h | 7 | ||||
| -rw-r--r-- | engines/made/screen.cpp | 198 | ||||
| -rw-r--r-- | engines/made/screen.h | 33 | ||||
| -rw-r--r-- | engines/made/scriptfuncs.cpp | 76 | 
5 files changed, 266 insertions, 64 deletions
| diff --git a/engines/made/resource.cpp b/engines/made/resource.cpp index cfab28cca5..1eb04f6211 100644 --- a/engines/made/resource.cpp +++ b/engines/made/resource.cpp @@ -225,7 +225,7 @@ int FontResource::getHeight() const {  	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 @@ int FontResource::getCharWidth(char c) const {  		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 @@ byte *FontResource::getChar(char c) const {  		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); diff --git a/engines/made/resource.h b/engines/made/resource.h index 93c57818bd..e2ddd228e5 100644 --- a/engines/made/resource.h +++ b/engines/made/resource.h @@ -118,12 +118,13 @@ public:  	~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 { diff --git a/engines/made/screen.cpp b/engines/made/screen.cpp index dc08bc0a88..ad1627c6df 100644 --- a/engines/made/screen.cpp +++ b/engines/made/screen.cpp @@ -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 @@ Screen::Screen(MadeEngine *vm) : _vm(vm) {  	_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 @@ void Screen::drawSpriteChannels(const ClipInfo &clipInfo, int16 includeStateMask  				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 @@ int16 Screen::getAnimFrameCount(uint16 animIndex) {  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 @@ void Screen::show() {  		return;  	drawSpriteChannels(_clipInfo1, 3, 0); -	  	memcpy(_screen2->pixels, _screen1->pixels, 64000);  	drawSpriteChannels(_clipInfo2, 1, 2); @@ -499,16 +560,16 @@ void Screen::flash(int flashCount) {  	}  } -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::printChar(char c, int16 x, int16 y, byte color) {  } +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 diff --git a/engines/made/screen.h b/engines/made/screen.h index d5dc1bb3e2..0ca28086f9 100644 --- a/engines/made/screen.h +++ b/engines/made/screen.h @@ -74,7 +74,17 @@ public:  	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 @@ public:  		_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,9 +132,13 @@ public:  	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 @@ protected:  	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; diff --git a/engines/made/scriptfuncs.cpp b/engines/made/scriptfuncs.cpp index c0f699dee6..ff6bf4b79c 100644 --- a/engines/made/scriptfuncs.cpp +++ b/engines/made/scriptfuncs.cpp @@ -165,23 +165,22 @@ void ScriptFunctionsRtz::setupExternalsTable() {  #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 @@ int16 ScriptFunctionsRtz::o1_EVENT(int16 argc, int16 *argv) {  	}  	_vm->_system->updateScreen(); -	//g_system->delayMillis(10);  	return eventNum;  } @@ -275,18 +273,18 @@ int16 ScriptFunctionsRtz::o1_VISUALFX(int16 argc, int16 *argv) {  }  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_PLAYSND(int16 argc, int16 *argv) {  }  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_ISMUS(int16 argc, int16 *argv) {  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_PALETTELOCK(int16 argc, int16 *argv) {  }  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_HOMETEXT(int16 argc, int16 *argv) {  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_MONOCLS(int16 argc, int16 *argv) {  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_ANIMTEXT(int16 argc, int16 *argv) {  }  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_PLACESPRITE(int16 argc, int16 *argv) {  }  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) { | 
