diff options
author | Paul Gilbert | 2010-04-23 10:28:30 +0000 |
---|---|---|
committer | Paul Gilbert | 2010-04-23 10:28:30 +0000 |
commit | 328d571bba73525174531edcb2f68d28417e9aac (patch) | |
tree | b8b336fa271a3d212b73fbecd6cf609dbf6ac6bb /engines/m4 | |
parent | 1243217547de55a9a83a2fadf88e73406b2769c6 (diff) | |
download | scummvm-rg350-328d571bba73525174531edcb2f68d28417e9aac.tar.gz scummvm-rg350-328d571bba73525174531edcb2f68d28417e9aac.tar.bz2 scummvm-rg350-328d571bba73525174531edcb2f68d28417e9aac.zip |
Implemented extra timer methods and a DynamicHotspots class
svn-id: r48776
Diffstat (limited to 'engines/m4')
-rw-r--r-- | engines/m4/mads_scene.cpp | 73 | ||||
-rw-r--r-- | engines/m4/mads_scene.h | 55 | ||||
-rw-r--r-- | engines/m4/mads_views.cpp | 229 | ||||
-rw-r--r-- | engines/m4/mads_views.h | 100 |
4 files changed, 328 insertions, 129 deletions
diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp index 499ea880af..ad6370e08f 100644 --- a/engines/m4/mads_scene.cpp +++ b/engines/m4/mads_scene.cpp @@ -619,79 +619,6 @@ 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); diff --git a/engines/m4/mads_scene.h b/engines/m4/mads_scene.h index 775c2bf766..864f7428a4 100644 --- a/engines/m4/mads_scene.h +++ b/engines/m4/mads_scene.h @@ -87,60 +87,6 @@ struct TimedText { char message[100]; }; -#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; -}; - -#define TIMER_LIST_SIZE 30 - -class MadsTimerList { -private: - Common::Array<MadsTimerEntry> _entries; -public: - MadsTimerList(); - - 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}; enum MAdsActionMode2 {ACTMODE2_0 = 0, ACTMODE2_2 = 2, ACTMODE2_5 = 5}; @@ -198,7 +144,6 @@ 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 4e6dae7742..8e4004f75e 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -59,6 +59,16 @@ int MadsSpriteSlots::addSprites(const char *resName) { return _sprites.size() - 1; } +/* + * Deletes the sprite slot with the given timer entry + */ +void MadsSpriteSlots::deleteTimer(int timerIndex) { + for (int idx = 0; idx < startIndex; ++idx) { + if (_entries[idx].timerIndex == timerIndex) + _entries[idx].spriteId = -1; + } +} + class DepthEntry { public: int depth; @@ -235,8 +245,227 @@ void ScreenObjects::setActive(int category, int idx, bool active) { } } +/*--------------------------------------------------------------------------*/ + +DynamicHotspots::DynamicHotspots(MadsView &owner): _owner(owner) { + for (int i = 0; HITBOX_AREA_SIZE; ++i) { + DynamicHotspot rec; + rec.active = false; + } + _flag = true; + _count = 0; +} + +int DynamicHotspots::add(int descId, int field14, int timerIndex, const Common::Rect &bounds) { + // Find a free slot + uint idx = 0; + while ((idx < _entries.size()) && !_entries[idx].active) + ++idx; + if (idx == _entries.size()) + error("DynamicHotspots overflow"); + + _entries[idx].active = true; + _entries[idx].descId = descId; + _entries[idx].bounds = bounds; + _entries[idx].pos.x = -3; + _entries[idx].pos.y = 0; + _entries[idx].facing = 5; + _entries[idx].field_14 = field14; + _entries[idx].articleNumber = 6; + _entries[idx].field_17 = 0; + + ++_count; + _flag = true; + _owner._timerList[timerIndex].dynamicHotspotIndex = idx; + + return idx; +} + +int DynamicHotspots::setPosition(int index, int xp, int yp, int facing) { + if (index >= 0) { + _entries[index].pos.x = xp; + _entries[index].pos.y = yp; + _entries[index].facing = facing; + } + + return index; +} + +int DynamicHotspots::set17(int index, int v) { + if (index >= 0) + _entries[index].field_17 = v; + + return index; +} + +void DynamicHotspots::remove(int index) { + if (_entries[index].active) { + if (_entries[index].timerIndex >= 0) + _owner._timerList[_entries[index].timerIndex].dynamicHotspotIndex = -1; + _entries[index].active = false; + + --_count; + _flag = true; + } +} + +void DynamicHotspots::reset() { + for (uint i = 0; i < _entries.size(); ++i) + _entries[i].active = false; + + _count = 0; + _flag = false; +} + +/*--------------------------------------------------------------------------*/ + +MadsTimerList::MadsTimerList(MadsView &owner): _owner(owner) { + for (int i = 0; i < TIMER_LIST_SIZE; ++i) { + MadsTimerEntry rec; + rec.active = 0; + rec.dynamicHotspotIndex = -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].dynamicHotspotIndex = -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 MadsTimerList::remove(int timerIndex) { + if (_entries[timerIndex].active) { + if (_entries[timerIndex].dynamicHotspotIndex >= 0) + _owner._dynamicHotspots.remove(_entries[timerIndex].dynamicHotspotIndex); + } + + _entries[timerIndex].active = false; + _owner._spriteSlots.deleteTimer(timerIndex); +} + +void MadsTimerList::setSpriteSlot(int timerIndex, MadsSpriteSlot &spriteSlot) { + MadsTimerEntry &timerEntry = _entries[timerIndex]; + SpriteAsset &sprite = _owner._spriteSlots.getSprite(timerEntry.spriteListIndex); + + // TODO: Figure out logic for spriteId value based on SPRITE_SLOT.field_0 + spriteSlot.spriteId = (0 /*field 0*/ == 1) ? 0xFFFC : 1; + spriteSlot.timerIndex = timerIndex; + spriteSlot.spriteListIndex = timerEntry.spriteListIndex; + spriteSlot.frameNumber = ((timerEntry.field_2 == 1) ? 0x8000 : 0) | timerEntry.frameIndex; + spriteSlot.depth = timerEntry.depth; + spriteSlot.scale = timerEntry.scale; + + if (timerEntry.field_12 == 0) { + spriteSlot.xp = timerEntry.width; + spriteSlot.yp = timerEntry.height; + } else { + spriteSlot.xp = sprite.getFrame(timerEntry.frameIndex)->x; + spriteSlot.yp = sprite.getFrame(timerEntry.frameIndex)->y; + } +} + +bool MadsTimerList::loadSprites(int timerIndex) { + MadsTimerEntry &timerEntry = _entries[timerIndex]; + + _owner._spriteSlots.deleteTimer(timerIndex); + if (timerEntry.field_25 != 0) { + remove(timerIndex); + return false; + } + + // TODO: Rest of method + + return true; +} + +/** + * Handles counting down entries in the timer list for action + */ +void MadsTimerList::tick() { + for (uint idx = 0; idx < _entries.size(); ++idx) { + if ((_owner._abortTimers2 == 0) && (_owner._abortTimers != 0)) + break; + + MadsTimerEntry &timerEntry = _entries[idx]; + uint32 currentTimer = g_system->getMillis(); + + if (!timerEntry.active || (currentTimer < timerEntry.timeout)) + continue; + + // Set the next timeout for the timer entry + timerEntry.timeout = currentTimer + timerEntry.numTicks; + + // Action the sprite + if (loadSprites(idx)) { + timerEntry.timeout += timerEntry.extraTicks; + } + } +} + //-------------------------------------------------------------------------- +MadsView::MadsView(View *view): _view(view), _dynamicHotspots(*this), _timerList(*this) { + _abortTimers = 0; + _abortTimers2 = 0; +} + void MadsView::refresh(RectList *rects) { // Draw any sprites _spriteSlots.draw(_view); diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h index f1c23dc27b..cf449c2880 100644 --- a/engines/m4/mads_views.h +++ b/engines/m4/mads_views.h @@ -38,6 +38,7 @@ namespace M4 { #define MADS_SCREEN_HEIGHT 200 #define MADS_Y_OFFSET ((MADS_SCREEN_HEIGHT - MADS_SURFACE_HEIGHT) / 2) +class MadsView; class MadsSpriteSlot { public: @@ -81,6 +82,7 @@ public: startIndex = 0; _sprites.clear(); } + void deleteTimer(int timerIndex); void draw(View *view); }; @@ -152,7 +154,98 @@ public: void setActive(int category, int idx, bool active); }; +class DynamicHotspot { +public: + bool active; + int timerIndex; + Common::Rect bounds; + Common::Point pos; + int facing; + int descId; + int field_14; + int articleNumber; + int field_17; + + DynamicHotspot() { active = false; } +}; + +#define HITBOX_AREA_SIZE 8 + +class DynamicHotspots { +private: + MadsView &_owner; + Common::Array<DynamicHotspot> _entries; + bool _flag; + int _count; +public: + DynamicHotspots(MadsView &owner); + + DynamicHotspot &operator[](uint idx) { return _entries[idx]; } + int add(int descId, int field14, int timerIndex, const Common::Rect &bounds); + int setPosition(int index, int xp, int yp, int facing); + int set17(int index, int v); + void remove(int index); + void reset(); +}; +#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 dynamicHotspotIndex; + + 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; + uint32 timeout; +}; + +#define TIMER_LIST_SIZE 30 + +class MadsTimerList { +private: + MadsView &_owner; + Common::Array<MadsTimerEntry> _entries; +public: + MadsTimerList(MadsView &owner); + + 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); + void remove(int timerIndex); + void setSpriteSlot(int timerIndex, MadsSpriteSlot &spriteSlot); + bool loadSprites(int timerIndex); + void tick(); +}; class MadsView { private: @@ -161,8 +254,13 @@ public: MadsSpriteSlots _spriteSlots; MadsTextDisplay _textDisplay; ScreenObjects _screenObjects; + DynamicHotspots _dynamicHotspots; + MadsTimerList _timerList; + + int _abortTimers; + int8 _abortTimers2; public: - MadsView(View *view): _view(view) {} + MadsView(View *view); void refresh(RectList *rects); }; |