diff options
author | Paul Gilbert | 2010-05-24 12:12:27 +0000 |
---|---|---|
committer | Paul Gilbert | 2010-05-24 12:12:27 +0000 |
commit | 6bda3e15db6baaa3af3d479e86dad2dd4f95084f (patch) | |
tree | 030bffb63865244c80e6a900ce734bebf146555a | |
parent | 55e29af78a52a13269d9905c6410e70f56b5920d (diff) | |
download | scummvm-rg350-6bda3e15db6baaa3af3d479e86dad2dd4f95084f.tar.gz scummvm-rg350-6bda3e15db6baaa3af3d479e86dad2dd4f95084f.tar.bz2 scummvm-rg350-6bda3e15db6baaa3af3d479e86dad2dd4f95084f.zip |
Implemented the bulk of the logic for displaying timed on-screen messages
svn-id: r49180
-rw-r--r-- | engines/m4/mads_logic.cpp | 11 | ||||
-rw-r--r-- | engines/m4/mads_logic.h | 1 | ||||
-rw-r--r-- | engines/m4/mads_scene.cpp | 54 | ||||
-rw-r--r-- | engines/m4/mads_views.cpp | 152 | ||||
-rw-r--r-- | engines/m4/mads_views.h | 21 |
5 files changed, 167 insertions, 72 deletions
diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp index 1fe5f4beb3..ee65d3be5c 100644 --- a/engines/m4/mads_logic.cpp +++ b/engines/m4/mads_logic.cpp @@ -245,4 +245,15 @@ void MadsSceneLogic::doAction() { } +void MadsSceneLogic::sceneStep() { + // FIXME: Temporary code to display a message on-screen + static bool tempBool = false; + if (!tempBool) { + tempBool = true; + + _madsVm->scene()->_kernelMessages.add(Common::Point(63, 100), 0x1110, 0, 0, 240, + _madsVm->globals()->getQuote(49)); + } +} + } diff --git a/engines/m4/mads_logic.h b/engines/m4/mads_logic.h index a589556a21..774ed016a6 100644 --- a/engines/m4/mads_logic.h +++ b/engines/m4/mads_logic.h @@ -54,6 +54,7 @@ public: void setupScene(); void enterScene(); void doAction(); + void sceneStep(); }; } diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp index 4f28cdc6da..1b8e44b581 100644 --- a/engines/m4/mads_scene.cpp +++ b/engines/m4/mads_scene.cpp @@ -302,7 +302,9 @@ void MadsScene::update() { } void MadsScene::updateState() { + _sceneLogic.sceneStep(); _sequenceList.tick(); + _kernelMessages.update(); } int MadsScene::loadSceneSpriteSet(const char *setName) { @@ -653,56 +655,4 @@ void MadsSceneResources::load(int sId) { /*--------------------------------------------------------------------------*/ -/** - * Adds a new entry to the timed on-screen text display list - */ -/* -void MadsScreenText::draw(M4Surface *surface) { -} - -void MadsScreenText::timedDisplay() { - for (int idx = 0; !_abortTimedText && (idx < OLD_TEXT_DISPLAY_SIZE); ++idx) { - if (((_timedText[idx].flags & TEXTFLAG_ACTIVE) != 0) && - (_timedText[idx].frameTimer <= g_system->getMillis())) - // Add the specified entry - addTimedText(&_timedText[idx]); - } -} - -void MadsScreenText::addTimedText(TimedText *entry) { - if ((entry->flags & TEXTFLAG_40) != 0) { - this->setActive2(entry->textDisplayIndex); - entry->flags &= 0x7F; - return; - } - - if ((entry->flags & TEXTFLAG_8) == 0) - // FIXME: Adjust timeouts for ScumVM's milli counter - entry->timeout -= 3; - - if ((entry->flags & TEXTFLAG_4) != 0) { - Text4A &rec = _text4A[entry->unk4AIndex]; - if ((rec.field25 != 0) || (rec.active == 0)) - entry->timeout = 0; - } - - if ((entry->timeout == 0) && !_abortTimedText) { - entry->flags |= TEXTFLAG_40; - - if (entry->field_1C) { - _abortTimedText = entry->field_1C; - //word_84208 = entry->field_1D; - - if (entry->field_1D != 1) { - // Restore the action list - for (int i = 0; i < 3; ++i) - _madsVm->scene()->actionNouns[i] = entry->actionNouns[i]; - } - } - } - - // TODO: code from 'loc_244ec' onwards -} -*/ - } // End of namespace M4 diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp index e82a9976a5..7a71509041 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -324,12 +324,13 @@ void MadsTextDisplay::cleanUp() { MadsKernelMessageList::MadsKernelMessageList(MadsView &owner): _owner(owner) { for (int i = 0; i < TIMED_TEXT_SIZE; ++i) { - MadsKernelMessageListEntry rec; + MadsKernelMessageEntry rec; _entries.push_back(rec); } _owner._textSpacing = -1; _talkFont = _vm->_font->getFont(FONT_CONVERSATION_MADS); + word_8469E = 0; } void MadsKernelMessageList::clear() { @@ -352,8 +353,8 @@ int MadsKernelMessageList::add(const Common::Point &pt, uint fontColour, uint8 f error("MadsKernelList overflow"); } - MadsKernelMessageListEntry &rec = _entries[idx]; - rec.msg = msg; + MadsKernelMessageEntry &rec = _entries[idx]; + strcpy(rec.msg, msg); rec.flags = flags | KMSG_ACTIVE; rec.colour1 = fontColour & 0xff; rec.colour2 = fontColour >> 8; @@ -378,13 +379,13 @@ int MadsKernelMessageList::addQuote(int quoteId, int v2, uint32 timeout) { return add(Common::Point(0, 0), 0x1110, KMSG_2 | KMSG_20, v2, timeout, quoteStr); } -void MadsKernelMessageList::unk1(int msgIndex, int v1, int v2) { +void MadsKernelMessageList::unk1(int msgIndex, int numTicks, int v2) { if (msgIndex < 0) return; _entries[msgIndex].flags |= (v2 == 0) ? KMSG_8 : (KMSG_8 | KMSG_1); _entries[msgIndex].msgOffset = 0; - _entries[msgIndex].field_E = v1; + _entries[msgIndex].numTicks = numTicks; _entries[msgIndex].frameTimer2 = _madsVm->_currentTimer; const char *msgP = _entries[msgIndex].msg; @@ -405,7 +406,7 @@ void MadsKernelMessageList::setSeqIndex(int msgIndex, int seqIndex) { } void MadsKernelMessageList::remove(int msgIndex) { - MadsKernelMessageListEntry &rec = _entries[msgIndex]; + MadsKernelMessageEntry &rec = _entries[msgIndex]; if (rec.flags & KMSG_ACTIVE) { if (rec.flags & KMSG_8) { @@ -427,6 +428,135 @@ void MadsKernelMessageList::reset() { // sub_20454 } +void MadsKernelMessageList::update() { + uint32 currentTimer = _madsVm->_currentTimer; + + for (uint i = 0; i < _entries.size(); ++i) { + if (((_entries[i].flags & KMSG_ACTIVE) != 0) && (currentTimer >= _entries[i].frameTimer)) + processText(i); + } +} + +void MadsKernelMessageList::processText(int msgIndex) { + MadsKernelMessageEntry &msg = _entries[msgIndex]; + uint32 currentTimer = _madsVm->_currentTimer; + bool flag = false; + + if ((msg.flags & KMSG_40) != 0) { + _owner._textDisplay.expire(msg.textDisplayIndex); + msg.flags &= !KMSG_ACTIVE; + return; + } + + if ((msg.flags & KMSG_8) == 0) { + msg.timeout -= 3; + } + + if (msg.flags & KMSG_4) { + MadsSequenceEntry &seqEntry = _owner._sequenceList[msg.sequenceIndex]; + if (seqEntry.doneFlag || !seqEntry.active) + msg.timeout = 0; + } + + if ((msg.timeout <= 0) && (_owner._abortTimers == 0)) { + msg.flags |= KMSG_40; + if (msg.field_1C != 0) { + _owner._abortTimers = msg.field_1C; + _owner._abortTimersMode = msg.abortMode; + + if (_owner._abortTimersMode != ABORTMODE_1) { + for (int i = 0; i < 3; ++i) + _madsVm->scene()->actionNouns[i] = msg.actionNouns[i]; + } + } + } + + msg.frameTimer = currentTimer + 3; + int x1 = 0, y1 = 0; + + if (msg.flags & KMSG_4) { + MadsSequenceEntry &seqEntry = _owner._sequenceList[msg.sequenceIndex]; + if (seqEntry.field_12) { + SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(seqEntry.spriteListIndex); + M4Sprite *frame = spriteSet.getFrame(seqEntry.frameIndex - 1); + x1 = frame->bounds().left; + y1 = frame->bounds().top; + } else { + x1 = seqEntry.msgPos.x; + y1 = seqEntry.msgPos.y; + } + } + + if (msg.flags & KMSG_2) { + if (word_8469E != 0) { + // TODO: Figure out various flags + } else { + x1 = 160; + y1 = 78; + } + } + + x1 += msg.position.x; + y1 += msg.position.y; + + if ((msg.flags & KMSG_8) && (msg.frameTimer >= currentTimer)) { + msg.msg[msg.msgOffset] = msg.asciiChar; + char *msgP = &msg.msg[++msg.msgOffset]; + *msgP = msg.asciiChar2; + + msg.asciiChar = *msgP; + msg.asciiChar2 = *(msgP + 1); + + if (!msg.asciiChar) { + *msgP = '\0'; + msg.flags &= ~KMSG_8; + } else if (msg.flags & KMSG_1) { + *msgP = '"'; + *(msgP + 1) = '\0'; + } + + msg.frameTimer = msg.frameTimer2 = currentTimer + msg.numTicks; + flag = true; + } + + int strWidth = _talkFont->getWidth(msg.msg, _owner._textSpacing); + + if (msg.flags & KMSG_30) { + x1 -= (msg.flags & KMSG_20) ? strWidth / 2 : strWidth; + } + + // Make sure text appears entirely on-screen + int x2 = x1 + strWidth; + if (x2 > MADS_SURFACE_WIDTH) + x1 -= x2 - MADS_SURFACE_WIDTH; + if (x1 > (MADS_SURFACE_WIDTH - 1)) + x1 = MADS_SURFACE_WIDTH - 1; + if (x1 < 0) + x1 = 0; + + if (y1 > (MADS_SURFACE_HEIGHT - 1)) + y1 = MADS_SURFACE_HEIGHT - 1; + if (y1 < 0) + y1 = 0; + + if (msg.textDisplayIndex >= 0) { + MadsTextDisplayEntry textEntry = _owner._textDisplay[msg.textDisplayIndex]; + + if (flag || (textEntry.bounds.left != x1) || (textEntry.bounds.top != y1)) { + // Mark the associated text entry as deleted, so it can be re-created + _owner._textDisplay.expire(msg.textDisplayIndex); + msg.textDisplayIndex = -1; + } + } + + if (msg.textDisplayIndex < 0) { + // Need to create a new text display entry for this message + int idx = _owner._textDisplay.add(x1, y1, msg.colour1 | (msg.colour2 << 8), _owner._textSpacing, msg.msg, _talkFont); + if (idx >= 0) + msg.textDisplayIndex = idx; + } +} + //-------------------------------------------------------------------------- /** @@ -725,7 +855,7 @@ bool MadsSequenceList::addSubEntry(int index, SequenceSubEntryMode mode, int fra } int MadsSequenceList::add(int spriteListIndex, int v0, int frameIndex, int triggerCountdown, int delayTicks, int extraTicks, int numTicks, - int height, int width, char field_12, char scale, uint8 depth, int frameInc, SpriteAnimType animType, int numSprites, + int msgX, int msgY, char field_12, char scale, uint8 depth, int frameInc, SpriteAnimType animType, int numSprites, int frameStart) { // Find a free slot @@ -754,8 +884,8 @@ int MadsSequenceList::add(int spriteListIndex, int v0, int frameIndex, int trigg _entries[timerIndex].depth = depth; _entries[timerIndex].scale = scale; _entries[timerIndex].field_12 = field_12; - _entries[timerIndex].width = width; - _entries[timerIndex].height = height; + _entries[timerIndex].msgPos.x = msgX; + _entries[timerIndex].msgPos.y = msgY; _entries[timerIndex].numTicks = numTicks; _entries[timerIndex].extraTicks = extraTicks; @@ -796,8 +926,8 @@ void MadsSequenceList::setSpriteSlot(int timerIndex, MadsSpriteSlot &spriteSlot) spriteSlot.scale = timerEntry.scale; if (timerEntry.field_12 == 0) { - spriteSlot.xp = timerEntry.width; - spriteSlot.yp = timerEntry.height; + spriteSlot.xp = timerEntry.msgPos.x; + spriteSlot.yp = timerEntry.msgPos.y; } else { spriteSlot.xp = sprite.getFrame(timerEntry.frameIndex - 1)->x; spriteSlot.yp = sprite.getFrame(timerEntry.frameIndex - 1)->y; diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h index 3b64cc77f2..52388a99e0 100644 --- a/engines/m4/mads_views.h +++ b/engines/m4/mads_views.h @@ -139,9 +139,10 @@ public: #define TIMED_TEXT_SIZE 10 #define TEXT_4A_SIZE 30 -enum KernelMessageFlags {KMSG_1 = 1, KMSG_2 = 2, KMSG_4 = 4, KMSG_8 = 8, KMSG_20 = 0x20, KMSG_40 = 0x40, KMSG_ACTIVE = 0x80}; +enum KernelMessageFlags {KMSG_1 = 1, KMSG_2 = 2, KMSG_4 = 4, KMSG_8 = 8, KMSG_20 = 0x20, KMSG_30 = 0x30, + KMSG_40 = 0x40, KMSG_ACTIVE = 0x80}; -class MadsKernelMessageListEntry { +class MadsKernelMessageEntry { public: uint8 flags; int sequenceIndex; @@ -152,22 +153,24 @@ public: Common::Point position; int textDisplayIndex; int msgOffset; - int field_E; + int numTicks; uint32 frameTimer2; uint32 frameTimer; uint32 timeout; bool field_1C; AbortTimerMode abortMode; uint16 actionNouns[3]; - const char *msg; + char msg[100]; }; class MadsKernelMessageList { private: MadsView &_owner; - Common::Array<MadsKernelMessageListEntry> _entries; + Common::Array<MadsKernelMessageEntry> _entries; Font *_talkFont; public: + int word_8469E; +public: MadsKernelMessageList(MadsView &owner); void clear(); @@ -177,6 +180,8 @@ public: void setSeqIndex(int msgIndex, int seqIndex); void remove(int msgIndex); void reset(); + void update(); + void processText(int msgIndex); }; class ScreenObjectEntry { @@ -311,9 +316,7 @@ struct MadsSequenceEntry { int field_12; int field_13; - int width; - int height; - + Common::Point msgPos; int triggerCountdown; bool doneFlag; MadsSequenceSubEntries entries; @@ -338,7 +341,7 @@ public: void clear(); bool addSubEntry(int index, SequenceSubEntryMode mode, int frameIndex, int abortVal); int add(int spriteListIndex, int v0, int v1, int triggerCountdown, int delayTicks, int extraTicks, int numTicks, - int height, int width, char field_12, char scale, uint8 depth, int frameInc, SpriteAnimType animType, + int msgX, int msgY, char field_12, char scale, uint8 depth, int frameInc, SpriteAnimType animType, int numSprites, int frameStart); void remove(int timerIndex); void setSpriteSlot(int timerIndex, MadsSpriteSlot &spriteSlot); |