From dc40f028afb38c970868d469005bd651df9f7b87 Mon Sep 17 00:00:00 2001 From: Bendegúz Nagy Date: Tue, 30 Aug 2016 21:08:13 +0200 Subject: DM: Add message area scroller --- engines/dm/TODOs/todo.txt | 2 +- engines/dm/gfx.cpp | 2 ++ engines/dm/text.cpp | 44 +++++++++++++++++++++++++++++++++++--------- engines/dm/text.h | 15 ++++++++++----- 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/engines/dm/TODOs/todo.txt b/engines/dm/TODOs/todo.txt index 4d4fef17c9..958375b5b7 100644 --- a/engines/dm/TODOs/todo.txt +++ b/engines/dm/TODOs/todo.txt @@ -14,7 +14,7 @@ Todo: I forgot to add a bunch of warning for show/hide mouse pointer and other mouse functions Code stuff todo: - Complete stub methods(blitShrink, blitmask, scroller) + Complete stub methods(blitShrink, blitmask) Add proper save header, add error handling to it Add translations to f433_processCommand140_saveGame 'LOAD' \ No newline at end of file diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp index 264fa29e8e..3163b8c454 100644 --- a/engines/dm/gfx.cpp +++ b/engines/dm/gfx.cpp @@ -38,6 +38,7 @@ #include "champion.h" #include "eventman.h" #include "lzw.h" +#include "text.h" namespace DM { DisplayMan::DisplayMan(DMEngine *dmEngine) : _vm(dmEngine) { @@ -914,6 +915,7 @@ byte *DisplayMan::getExplosionBitmap(uint16 explosionAspIndex, uint16 scale, int } void DisplayMan::updateScreen() { + _vm->_textMan->updateMessageArea(); // apply copper for (uint32 i = 320 * 30; i < 320 * 170; ++i) _bitmapScreen[i] += 16; diff --git a/engines/dm/text.cpp b/engines/dm/text.cpp index 6dd906c9e3..80a115cb5b 100644 --- a/engines/dm/text.cpp +++ b/engines/dm/text.cpp @@ -26,6 +26,7 @@ */ #include "text.h" +#include namespace DM { @@ -36,17 +37,21 @@ TextMan::TextMan(DMEngine* vm) : _vm(vm) { for (uint16 i = 0; i < 4; ++i) _messageAreaRowExpirationTime[i] = 0; _bitmapMessageAreaNewRow = new byte[320 * 7]; + _isScrolling = false; + _startedScrollingAt = -1; + _messageAreaCopy = new byte[320 * 7 * 4]; } TextMan::~TextMan() { delete[] _bitmapMessageAreaNewRow; + delete[] _messageAreaCopy; } #define k5_LetterWidth 5 #define k6_LetterHeight 6 void TextMan::printTextToBitmap(byte* destBitmap, uint16 destByteWidth, int16 destX, int16 destY, - Color textColor, Color bgColor, const char* text, uint16 destHeight) { + Color textColor, Color bgColor, const char* text, uint16 destHeight) { if ((destX -= 1) < 0) // fixes missalignment, to be checked destX = 0; if ((destY -= 4) < 0) // fixes missalignment, to be checked @@ -76,7 +81,7 @@ void TextMan::printTextToBitmap(byte* destBitmap, uint16 destByteWidth, int16 de Box box((nextX == destX) ? (nextX + 1) : nextX, nextX + k5_LetterWidth + 1, nextY, nextY + k6_LetterHeight - 1); _vm->_displayMan->blitToBitmap(srcBitmap, destBitmap, box, (nextX == destX) ? (srcX + 1) : srcX, 0, 6 * 128 / 2, destByteWidth, kM1_ColorNoTransparency, - k6_LetterHeight, destHeight); + k6_LetterHeight, destHeight); nextX += k5_LetterWidth + 1; } @@ -91,7 +96,7 @@ void TextMan::printToViewport(int16 posX, int16 posY, Color textColor, const cha } void TextMan::printWithTrailingSpaces(byte* destBitmap, int16 destByteWidth, int16 destX, int16 destY, Color textColor, - Color bgColor, const char* text, int16 requiredTextLength, int16 destHeight) { + Color bgColor, const char* text, int16 requiredTextLength, int16 destHeight) { Common::String str = text; for (int16 i = str.size(); i < requiredTextLength; ++i) str += ' '; @@ -102,7 +107,7 @@ void TextMan::printLineFeed() { printMessage(k0_ColorBlack, "\n"); } -void TextMan::printMessage(Color color, const char* string) { +void TextMan::printMessage(Color color, const char* string, bool printWithScroll) { uint16 L0031_ui_CharacterIndex; char L0033_ac_String[54]; @@ -118,7 +123,7 @@ void TextMan::printMessage(Color color, const char* string) { if (*string == ' ') { string++; if (_messageAreaCursorColumn != 53) { - printString(color, " "); // TODO: I'm not sure this is like the original + printString(color, " "); // I'm not sure if this is like the original } } else { L0031_ui_CharacterIndex = 0; @@ -142,6 +147,7 @@ void TextMan::createNewRow() { if (_messageAreaCursorRow == 3) { isTextScrolling(&_textScroller, true); memset(_bitmapMessageAreaNewRow, k0_ColorBlack, 320 * 7); + _isScrolling = true; setScrollerCommand(&_textScroller, 1); for (L0029_ui_RowIndex = 0; L0029_ui_RowIndex < 3; L0029_ui_RowIndex++) { @@ -158,9 +164,10 @@ void TextMan::printString(Color color, const char* string) { L0030_i_StringLength = strlen(string); if (isTextScrolling(&_textScroller, false)) { - printToLogicalScreen(_messageAreaCursorColumn * 6, (_messageAreaCursorRow * 7 - 6) + 177, color, k0_ColorBlack, string); + printToLogicalScreen(_messageAreaCursorColumn * 6, (_messageAreaCursorRow * 7 - 1) + 177, color, k0_ColorBlack, string); } else { - printTextToBitmap(_bitmapMessageAreaNewRow, k160_byteWidthScreen, _messageAreaCursorColumn * 6, 5, color, k0_ColorBlack, string, 7); + printTextToBitmap(_bitmapMessageAreaNewRow, k160_byteWidthScreen, _messageAreaCursorColumn * 6, 0, color, k0_ColorBlack, string, 7); + _isScrolling = true; if (isTextScrolling(&_textScroller, false)) setScrollerCommand(&_textScroller, 1); } @@ -204,7 +211,7 @@ void TextMan::clearExpiredRows() { L0028_s_Box._x2 = 319; for (L0026_ui_RowIndex = 0; L0026_ui_RowIndex < 4; L0026_ui_RowIndex++) { L0027_l_ExpirationTime = _messageAreaRowExpirationTime[L0026_ui_RowIndex]; - if ((L0027_l_ExpirationTime == -1) || (L0027_l_ExpirationTime > _vm->_gameTime)) + if ((L0027_l_ExpirationTime == -1) || (L0027_l_ExpirationTime > _vm->_gameTime) || _isScrolling) continue; L0028_s_Box._y2 = (L0028_s_Box._y1 = 172 + (L0026_ui_RowIndex * 7)) + 6; isTextScrolling(&_textScroller, true); @@ -236,11 +243,30 @@ void TextMan::clearAllRows() { Box tmpBox(0, 319, 169, 199); _vm->_displayMan->fillScreenBox(tmpBox, k0_ColorBlack); - + _messageAreaCursorRow = 3; _messageAreaCursorColumn = 0; for (L0023_i_RowIndex = 0; L0023_i_RowIndex < 4; L0023_i_RowIndex++) { _messageAreaRowExpirationTime[L0023_i_RowIndex] = -1; } } + +void TextMan::updateMessageArea() { + if (_isScrolling) { + if (_startedScrollingAt == -1) { + _startedScrollingAt = _vm->_system->getMillis(); + memcpy(_messageAreaCopy, _vm->_displayMan->_bitmapScreen + (200 - 7 * 4) * 320, 320 * 7 * 4); + } + int linesToCopy = (_vm->_system->getMillis() - _startedScrollingAt) / 50; + if (linesToCopy >= 7) { + linesToCopy = 7; + _startedScrollingAt = -1; + _isScrolling = false; + } + memcpy(_vm->_displayMan->_bitmapScreen + (200 - 7 * 4) * 320, _messageAreaCopy + linesToCopy * 320, + 320 * (7 * 4 - linesToCopy)); + memcpy(_vm->_displayMan->_bitmapScreen + (200 - linesToCopy) * 320, _bitmapMessageAreaNewRow, 320 * linesToCopy); + } +} + } diff --git a/engines/dm/text.h b/engines/dm/text.h index b6049d7659..d157c9bbeb 100644 --- a/engines/dm/text.h +++ b/engines/dm/text.h @@ -43,6 +43,11 @@ class TextMan { int16 _messageAreaCursorRow; // @ G0358_i_MessageAreaCursorRow int32 _messageAreaRowExpirationTime[4]; // @ G0360_al_MessageAreaRowExpirationTime byte *_bitmapMessageAreaNewRow; // @ G0356_puc_Bitmap_MessageAreaNewRow + + // for scrolling 'em messages + bool _isScrolling; + int64 _startedScrollingAt; + byte *_messageAreaCopy; public: TextScroller _textScroller; @@ -56,18 +61,18 @@ public: void printWithTrailingSpaces(byte *destBitmap, int16 destByteWidth, int16 destX, int16 destY, Color textColor, Color bgColor, const char *text, int16 strLenght, int16 destHeight); // @ F0041_TEXT_PrintWithTrailingSpaces void printLineFeed(); // @ F0051_TEXT_MESSAGEAREA_PrintLineFeed - void printMessage(Color color, const char *string); // @ F0047_TEXT_MESSAGEAREA_PrintMessage + void printMessage(Color color, const char *string, bool printWithScroll = true); // @ F0047_TEXT_MESSAGEAREA_PrintMessage void createNewRow(); // @ F0045_TEXT_MESSAGEAREA_CreateNewRow void printString(Color color, const char* string);// @ F0046_TEXT_MESSAGEAREA_PrintString void initialize(); // @ F0054_TEXT_Initialize void moveCursor(int16 column, int16 row); // @ F0042_TEXT_MESSAGEAREA_MoveCursor void clearExpiredRows(); // @ F0044_TEXT_MESSAGEAREA_ClearExpiredRows void printEndGameString(int16 x, int16 y, Color textColor, char *text); // @ F0443_STARTEND_EndgamePrintString - bool isTextScrolling(TextScroller *scroller, bool waitEndOfScrolling) { - warning("STUB METHOD: isTextScrolling"); return true; - } // @ F0561_SCROLLER_IsTextScrolling - void setScrollerCommand(TextScroller *scroller, int16 command) { warning("STUB METHOD: f560_SCROLLER_setCommand"); } // @ F0560_SCROLLER_SetCommand + bool isTextScrolling(TextScroller *scroller, bool waitEndOfScrolling) { return false; } // @ F0561_SCROLLER_IsTextScrolling + void setScrollerCommand(TextScroller *scroller, int16 command) { } // @ F0560_SCROLLER_SetCommand void clearAllRows(); // @ F0043_TEXT_MESSAGEAREA_ClearAllRows + + void updateMessageArea(); }; } -- cgit v1.2.3