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 | |
| 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
| -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);  };  | 
