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) { |