diff options
Diffstat (limited to 'engines/m4')
-rw-r--r-- | engines/m4/mads_logic.cpp | 95 | ||||
-rw-r--r-- | engines/m4/mads_logic.h | 7 | ||||
-rw-r--r-- | engines/m4/mads_scene.cpp | 151 | ||||
-rw-r--r-- | engines/m4/mads_scene.h | 87 | ||||
-rw-r--r-- | engines/m4/mads_views.cpp | 4 | ||||
-rw-r--r-- | engines/m4/mads_views.h | 4 | ||||
-rw-r--r-- | engines/m4/scene.cpp | 2 | ||||
-rw-r--r-- | engines/m4/scene.h | 3 |
8 files changed, 237 insertions, 116 deletions
diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp index e69e8c38ca..472db1a2b0 100644 --- a/engines/m4/mads_logic.cpp +++ b/engines/m4/mads_logic.cpp @@ -77,6 +77,74 @@ uint16 MadsSceneLogic::loadSpriteSet(uint16 suffixNum, uint16 sepChar) { return _madsVm->scene()->loadSceneSpriteSet(resName); } +uint16 MadsSceneLogic::startSpriteSequence(uint16 srcSpriteIdx, int v0, int numTicks, int fld24, int timeoutTicks, int extraTicks) { + M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(1); + uint8 pixel = *_madsVm->scene()->getWalkSurface()->getBasePtr(spriteFrame->x + (spriteFrame->width() / 2), + spriteFrame->y + (spriteFrame->height() / 2)); + + return _madsVm->scene()->_timerList.add(srcSpriteIdx, v0, 1, fld24, timeoutTicks, extraTicks, numTicks, 0, 0, + -1, 100, (int)pixel - 1, 1, 1, 0, 0); +} + +uint16 MadsSceneLogic::startSpriteSequence2(uint16 srcSpriteIdx, int v0, int numTicks, int fld24, int timeoutTicks, int extraTicks) { + M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(1); + uint8 pixel = *_madsVm->scene()->getWalkSurface()->getBasePtr(spriteFrame->x + (spriteFrame->width() / 2), + spriteFrame->y + (spriteFrame->height() / 2)); + + return _madsVm->scene()->_timerList.add(srcSpriteIdx, v0, 1, fld24, timeoutTicks, extraTicks, numTicks, 0, 0, + -1, 100, (int)pixel - 1, 1, 2, 0, 0); +} + +uint16 MadsSceneLogic::startSpriteSequence3(uint16 srcSpriteIdx, int v0, int numTicks, int fld24, int timeoutTicks, int extraTicks) { + M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(1); + uint8 pixel = *_madsVm->scene()->getWalkSurface()->getBasePtr(spriteFrame->x + (spriteFrame->width() / 2), + spriteFrame->y + (spriteFrame->height() / 2)); + + return _madsVm->scene()->_timerList.add(srcSpriteIdx, v0, 1, fld24, timeoutTicks, extraTicks, numTicks, 0, 0, + -1, 100, (int)pixel - 1, -1, 1, 0, 0); +} + +void MadsSceneLogic::activateHotspot(int idx, bool active) { + // TODO: +} + +void MadsSceneLogic::lowRoomsEntrySound() { + if (!_madsVm->globals()->_config.musicFlag) { + _madsVm->_sound->playSound(2); + } else { + // Play different sounds for each of the rooms + switch (_madsVm->globals()->sceneNumber) { + case 101: + _madsVm->_sound->playSound(11); + break; + case 102: + _madsVm->_sound->playSound(12); + break; + case 103: + _madsVm->_sound->playSound(3); + _madsVm->_sound->playSound(25); + break; + case 104: + _madsVm->_sound->playSound(10); + break; + case 105: + if ((_madsVm->globals()->previousScene < 104) || (_madsVm->globals()->previousScene > 108)) + _madsVm->_sound->playSound(10); + break; + case 106: + _madsVm->_sound->playSound(13); + break; + case 107: + _madsVm->_sound->playSound(3); + break; + case 108: + _madsVm->_sound->playSound(15); + break; + default: + break; + } + } +} /*--------------------------------------------------------------------------*/ @@ -114,6 +182,33 @@ void MadsSceneLogic::enterScene() { _spriteIndexes[11] = loadSpriteSet(1, 'a'); _spriteIndexes[12] = loadSpriteSet(8, 'x'); _spriteIndexes[13] = loadSpriteSet(0, 'x'); + + _spriteIndexes[15] = startSpriteSequence(_spriteIndexes[0], 0, 5, 0, 0, 25); + _spriteIndexes[16] = startSpriteSequence(_spriteIndexes[1], 0, 4, 0, 1, 0); + _spriteIndexes[17] = startSpriteSequence(_spriteIndexes[2], 0, 4, 0, 1, 0); + + _madsVm->scene()->_timerList.unk2(0, 2, 7, 0x46); + + _spriteIndexes[18] = startSpriteSequence2(_spriteIndexes[3], 0, 10, 0, 0, 60); + _spriteIndexes[19] = startSpriteSequence(_spriteIndexes[4], 0, 5, 0, 1, 0); + _spriteIndexes[20] = startSpriteSequence(_spriteIndexes[5], 0, 10, 0, 2, 0); + _spriteIndexes[21] = startSpriteSequence(_spriteIndexes[6], 0, 6, 0, 0, 0); + + _spriteIndexes[23] = startSpriteSequence(_spriteIndexes[8], 0, 6, 0, 10, 4); + _spriteIndexes[24] = startSpriteSequence(_spriteIndexes[9], 0, 6, 0, 32, 47); + + activateHotspot(0x137, false); // SHIELD MODULATOR + // shield_panel_opened = 0; + + if (_madsVm->globals()->previousScene != -1) + _madsVm->globals()->_globals[10] = 0; + if (_madsVm->globals()->previousScene != -2) { + //playerPos = (100, 152); + } + + // TODO: EXTRA STUFF + + lowRoomsEntrySound(); } void MadsSceneLogic::doAction() { diff --git a/engines/m4/mads_logic.h b/engines/m4/mads_logic.h index 2514f4e3f4..88f8c6e928 100644 --- a/engines/m4/mads_logic.h +++ b/engines/m4/mads_logic.h @@ -35,9 +35,14 @@ class MadsSceneLogic { private: // Library interface methods uint16 loadSpriteSet(uint16 suffixNum, uint16 sepChar); + uint16 startSpriteSequence(uint16 srcSpriteIdx, int v0, int numTicks, int fld24, int timeoutTicks, int extraTicks); + uint16 startSpriteSequence2(uint16 srcSpriteIdx, int v0, int numTicks, int fld24, int timeoutTicks, int extraTicks); + uint16 startSpriteSequence3(uint16 srcSpriteIdx, int v0, int numTicks, int fld24, int timeoutTicks, int extraTicks); + void activateHotspot(int idx, bool active); + void lowRoomsEntrySound(); private: int _sceneNumber; - uint16 _spriteIndexes[50]; + int16 _spriteIndexes[50]; // Support functions const char *formAnimName(char sepChar, int16 suffixNum); diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp index 53f232472d..26acafa521 100644 --- a/engines/m4/mads_scene.cpp +++ b/engines/m4/mads_scene.cpp @@ -44,7 +44,6 @@ MadsScene::MadsScene(MadsEngine *vm): _sceneResources(), Scene(vm, &_sceneResour _vm = vm; _interfaceSurface = new MadsInterfaceView(vm); - _spriteSlotsStart = 0; for (int i = 0; i < 3; ++i) actionNouns[i] = 0; } @@ -158,11 +157,6 @@ void MadsScene::leaveScene() { delete _sceneResources.hotspots; delete _sceneResources.props; - - // Delete the sprites - for (uint i = 0; i <_sceneSprites.size(); ++i) delete _sceneSprites[i]; - _sceneSprites.clear(); - delete _walkSurface; Scene::leaveScene(); @@ -269,12 +263,8 @@ void MadsScene::setAction(int action, int objectId) { * Draws all the elements of the scene */ void MadsScene::drawElements() { - // Display animations - for (int idx = 0; idx < _spriteSlotsStart; ++idx) { - - } - + _spriteSlots.draw(this); // Text display _textDisplay.draw(this); @@ -283,17 +273,6 @@ void MadsScene::drawElements() { _interfaceSurface->copyTo(this, 0, this->height() - _interfaceSurface->height()); /* - // At this point, in the original engine, the dirty/changed areas were copied to the screen. At the moment, - // the current M4 engine framework doesn't support dirty areas, but this is being kept in case that ever changes - for (int idx = 0; idx < DIRTY_AREA_SIZE; ++idx) { - if (_dirtyAreas[idx].active && _dirtyAreas[idx].active2 && - (_dirtyAreas[idx].bounds.width() > 0) && (_dirtyAreas[idx].bounds.height() > 0)) { - // Copy changed area to screen - - } - } -*/ - // Some kind of copying over of slot entries for (int idx = 0, idx2 = 0; idx < _spriteSlotsStart; ++idx) { if (_spriteSlots[idx].spriteId >= 0) { @@ -303,7 +282,7 @@ void MadsScene::drawElements() { } ++idx2; } - } + }*/ } @@ -330,7 +309,7 @@ void MadsScene::update() { } //***DEBUG*** - _sceneSprites[0]->getFrame(1)->copyTo(this, 120, 90, 0); + _spriteSlots.getSprite(0).getFrame(1)->copyTo(this, 120, 90, 0); } int MadsScene::loadSceneSpriteSet(const char *setName) { @@ -341,13 +320,7 @@ int MadsScene::loadSceneSpriteSet(const char *setName) { if (!strchr(resName, '.')) strcat(resName, ".SS"); - Common::SeekableReadStream *data = _vm->res()->get(resName); - SpriteAsset *spriteSet = new SpriteAsset(_vm, data, data->size(), resName); - spriteSet->translate(_vm->_palette); - _vm->res()->toss(resName); - - _sceneSprites.push_back(spriteSet); - return _sceneSprites.size() - 1; + return _spriteSlots.addSprites(resName); } void MadsScene::loadPlayerSprites(const char *prefix) { @@ -646,6 +619,79 @@ void MadsAction::set() { /*--------------------------------------------------------------------------*/ +MadsTimerList::MadsTimerList() { + for (int i = 0; i < TIMER_LIST_SIZE; ++i) { + MadsTimerEntry rec; + rec.active = 0; + rec.walkObjectIndex = -1; + _entries.push_back(rec); + } +} + +bool MadsTimerList::unk2(int index, int v1, int v2, int v3) { + if (_entries[index].len27 >= TIMER_ENTRY_SUBSET_MAX) + return true; + + int subIndex = _entries[index].len27++; + _entries[index].fld27[subIndex] = v1; + _entries[index].fld2C[subIndex] = v2; + _entries[index].field36 = v3; + + return false; +} + +int MadsTimerList::add(int spriteListIndex, int v0, int frameIndex, char field_24, int timeoutTicks, int extraTicks, int numTicks, + int height, int width, char field_12, char scale, char depth, int field_C, int field_A, int numSprites, + int spriteNum) { + + // Find a free slot + uint timerIndex = 0; + while ((timerIndex < _entries.size()) && (_entries[timerIndex].active)) + ++timerIndex; + if (timerIndex == _entries.size()) + error("TimerList full"); + + if (spriteNum <= 0) + spriteNum = 1; + if (numSprites == 0) + numSprites = _madsVm->scene()->_spriteSlots.getSprite(spriteListIndex).getCount(); + if (spriteNum == numSprites) + field_C = 0; + + // Set the list entry fields + _entries[timerIndex].active = true; + _entries[timerIndex].spriteListIndex = spriteListIndex; + _entries[timerIndex].field_2 = v0; + _entries[timerIndex].frameIndex = frameIndex; + _entries[timerIndex].spriteNum = spriteNum; + _entries[timerIndex].numSprites = numSprites; + _entries[timerIndex].field_A = field_A; + _entries[timerIndex].field_C = field_C; + _entries[timerIndex].depth = depth; + _entries[timerIndex].scale = scale; + _entries[timerIndex].field_12 = field_12; + _entries[timerIndex].width = width; + _entries[timerIndex].height = height; + _entries[timerIndex].numTicks = numTicks; + _entries[timerIndex].extraTicks = extraTicks; + + _entries[timerIndex].timeout = g_system->getMillis() + timeoutTicks * GAME_FRAME_DELAY; + + _entries[timerIndex].field_24 = field_24; + _entries[timerIndex].field_25 = 0; + _entries[timerIndex].field_13 = 0; + _entries[timerIndex].walkObjectIndex = -1; + _entries[timerIndex].len27 = 0; + _entries[timerIndex].field_3B = 0; //word_84206 + + for (int i = 0; i < 3; ++i) + _entries[timerIndex].actionNouns[i] = _madsVm->scene()->actionNouns[i]; + + return timerIndex; +} + +/*--------------------------------------------------------------------------*/ + void MadsSceneResources::load(int sId) { const char *sceneInfoStr = MADSResourceManager::getResourceName(RESPREFIX_RM, sId, ".DAT"); Common::SeekableReadStream *rawStream = _vm->_resourceManager->get(sceneInfoStr); @@ -687,45 +733,10 @@ void MadsSceneResources::load(int sId) { /*--------------------------------------------------------------------------*/ -MadsScreenText::MadsScreenText() { - for (int i = 0; i < OLD_TEXT_DISPLAY_SIZE; ++i) - _textDisplay[i].active = false; - for (int i = 0; i < TIMED_TEXT_SIZE; ++i) - _timedText[i].flags = 0; - _abortTimedText = false; -} - -/** - * Adds the specified string to the list of on-screen display text - */ -int MadsScreenText::add(const Common::Point &destPos, uint fontColours, int widthAdjust, const char *msg, Font *font) { - // Find a free slot - int idx = 0; - while ((idx < OLD_TEXT_DISPLAY_SIZE) && _textDisplay[idx].active) - ++idx; - if (idx == OLD_TEXT_DISPLAY_SIZE) - error("Ran out of text display slots"); - - // Set up the entry values - _textDisplay[idx].active = true; - _textDisplay[idx].active2 = 1; - _textDisplay[idx].bounds.left = destPos.x; - _textDisplay[idx].bounds.top = destPos.y; - _textDisplay[idx].bounds.setWidth(font->getWidth(msg, widthAdjust)); - _textDisplay[idx].bounds.setHeight(font->getHeight()); - _textDisplay[idx].font = font; - strncpy(_textDisplay[idx].message, msg, 100); - _textDisplay[idx].message[99] = '\0'; - _textDisplay[idx].colour1 = fontColours & 0xff; - _textDisplay[idx].colour2 = fontColours >> 8; - _textDisplay[idx].spacing = widthAdjust; - - return idx; -} - /** * Adds a new entry to the timed on-screen text display list */ +/* int MadsScreenText::addTimed(const Common::Point &destPos, uint fontColours, uint flags, int vUnknown, uint32 timeout, const char *message) { // Find a free slot int idx = 0; @@ -749,7 +760,7 @@ int MadsScreenText::addTimed(const Common::Point &destPos, uint fontColours, uin _timedText[idx].timeout = timeout; _timedText[idx].frameTimer = g_system->getMillis(); _timedText[idx].field_1C = vUnknown; - _timedText[idx].field_1D = 0; /* word_84206 */ + _timedText[idx].field_1D = 0; // word_84206 // Copy the current action noun list for (int i = 0; i < 3; ++i) @@ -762,9 +773,6 @@ int MadsScreenText::addTimed(const Common::Point &destPos, uint fontColours, uin return idx; } -/** - * Draws any text display entries to the screen - */ void MadsScreenText::draw(M4Surface *surface) { } @@ -811,5 +819,6 @@ void MadsScreenText::addTimedText(TimedText *entry) { // TODO: code from 'loc_244ec' onwards } +*/ } // End of namespace M4 diff --git a/engines/m4/mads_scene.h b/engines/m4/mads_scene.h index 317b5fb93c..06f039d4e2 100644 --- a/engines/m4/mads_scene.h +++ b/engines/m4/mads_scene.h @@ -65,29 +65,18 @@ public: }; #define TIMED_TEXT_SIZE 10 -#define OLD_TEXT_DISPLAY_SIZE 40 #define TEXT_4A_SIZE 30 enum TalkTextFlags {TEXTFLAG_2 = 2, TEXTFLAG_4 = 4, TEXTFLAG_8 = 8, TEXTFLAG_40 = 0x40, TEXTFLAG_ACTIVE = 0x80}; -struct TextDisplay { - bool active; - int spacing; - int16 active2; - Common::Rect bounds; - int colour1, colour2; - Font *font; - char message[100]; -}; - struct TimedText { uint8 flags; int colour1; int colour2; Common::Point position; int textDisplayIndex; - int unk4AIndex; + int timerIndex; uint32 timeout; uint32 frameTimer; bool field_1C; @@ -96,30 +85,58 @@ struct TimedText { char message[100]; }; -struct Text4A { - uint8 active; - uint8 field25; +#define TIMER_ENTRY_SUBSET_MAX 5 + +struct MadsTimerEntry { + int8 active; + int8 spriteListIndex; + + int field_2; + + int frameIndex; + int spriteNum; + int numSprites; + + int field_A; + int field_C; + + int depth; + int scale; + int walkObjectIndex; + + int field_12; + int field_13; + + int width; + int height; + + int field_24; + int field_25; + int len27; + int8 fld27[TIMER_ENTRY_SUBSET_MAX]; + int16 fld2C[TIMER_ENTRY_SUBSET_MAX]; + int8 field36; + int field_3B; + + uint16 actionNouns[3]; + int numTicks; + int extraTicks; + int32 timeout; }; -class MadsScreenText { -private: - TextDisplay _textDisplay[OLD_TEXT_DISPLAY_SIZE]; - TimedText _timedText[TIMED_TEXT_SIZE]; - Text4A _text4A[TEXT_4A_SIZE]; - bool _abortTimedText; +#define TIMER_LIST_SIZE 30 - void addTimedText(TimedText *entry); +class MadsTimerList { +private: + Common::Array<MadsTimerEntry> _entries; public: - MadsScreenText(); + MadsTimerList(); - // TextDisplay list - int add(const Common::Point &destPos, uint fontColours, int widthAdjust, const char *msg, Font *font); - void setActive2(int16 idx) { _textDisplay[idx].active2 = -1; } - // TimedText list - int addTimed(const Common::Point &destPos, uint fontColours, uint flags, int vUnknown, uint32 timeout, const char *message); - - void draw(M4Surface *surface); - void timedDisplay(); + MadsTimerEntry &operator[](int index) { return _entries[index]; } + bool unk2(int index, int v1, int v2, int v3); + int add(int spriteListIndex, int v0, int v1, char field_24, int timeoutTicks, int extraTicks, int numTicks, + int height, int width, char field_12, char scale, char depth, int field_C, int field_A, + int numSprites, int spriteNum); }; enum MadsActionMode {ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, ACTMODE_TALK = 6}; @@ -157,9 +174,6 @@ public: const char *statusText() const { return _statusText; } }; -typedef Common::Array<SpriteAsset *> SpriteAssetArray; - -#define SPRITE_SLOTS_SIZE 50 #define DIRTY_AREA_SIZE 90 class MadsScene : public Scene { @@ -170,11 +184,7 @@ private: MadsSceneLogic _sceneLogic; SpriteAsset *_playerSprites; - SpriteAssetArray _sceneSprites; - SpriteSlot _spriteSlots[50]; - MadsScreenText _textDisplay; DirtyArea _dirtyAreas[DIRTY_AREA_SIZE]; - int _spriteSlotsStart; void drawElements(); void loadScene2(const char *aaName); @@ -186,6 +196,7 @@ private: public: char _aaName[100]; uint16 actionNouns[3]; + MadsTimerList _timerList; public: MadsScene(MadsEngine *vm); virtual ~MadsScene(); diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp index e8a5aa6f4f..fdfbf16f9e 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -47,7 +47,7 @@ int MadsSpriteSlots::getIndex() { return startIndex++; } -void MadsSpriteSlots::addSprites(const char *resName) { +int MadsSpriteSlots::addSprites(const char *resName) { // Get the sprite set Common::SeekableReadStream *data = _vm->res()->get(resName); SpriteAsset *spriteSet = new SpriteAsset(_vm, data, data->size(), resName); @@ -56,7 +56,7 @@ void MadsSpriteSlots::addSprites(const char *resName) { _sprites.push_back(SpriteList::value_type(spriteSet)); _vm->res()->toss(resName); - // Translate the sprite set to the current palette + return _sprites.size() - 1; } class DepthEntry { diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h index 7dd991ffd6..bb151d7078 100644 --- a/engines/m4/mads_views.h +++ b/engines/m4/mads_views.h @@ -76,7 +76,7 @@ public: } int getIndex(); - void addSprites(const char *resName); + int addSprites(const char *resName); void clear() { startIndex = 0; _sprites.clear(); @@ -155,7 +155,7 @@ public: class MadsView: public View { -protected: +public: MadsSpriteSlots _spriteSlots; MadsTextDisplay _textDisplay; ScreenObjects _screenObjects; diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp index 15c68f276c..72e24767a9 100644 --- a/engines/m4/scene.cpp +++ b/engines/m4/scene.cpp @@ -39,7 +39,7 @@ namespace M4 { -Scene::Scene(MadsM4Engine *vm, SceneResources *res): View(vm, Common::Rect(0, 0, vm->_screen->width(), +Scene::Scene(MadsM4Engine *vm, SceneResources *res): MadsView(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())), _sceneResources(res) { _screenType = VIEWID_SCENE; diff --git a/engines/m4/scene.h b/engines/m4/scene.h index 5dafb138db..e0a72fe848 100644 --- a/engines/m4/scene.h +++ b/engines/m4/scene.h @@ -76,7 +76,7 @@ class M4Engine; class MadsEngine; class InterfaceView; -class Scene : public View { +class Scene : public MadsView { private: HotSpotList _sceneHotspots; protected: @@ -113,6 +113,7 @@ public: void hideInterface(); GameInterfaceView *getInterface() { return _interfaceSurface; } SceneResources &getSceneResources() { return *_sceneResources; } + M4Surface *getWalkSurface() const { return _walkSurface; } void onRefresh(RectList *rects, M4Surface *destSurface); bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents); |