diff options
| author | Paul Gilbert | 2010-05-15 00:28:44 +0000 | 
|---|---|---|
| committer | Paul Gilbert | 2010-05-15 00:28:44 +0000 | 
| commit | e91df69eb64d9e3ef7d02aa2423e3fbc96dc8aef (patch) | |
| tree | 96fd8554b8052a4ee18998573cadb5061ae5b39a | |
| parent | 6d38cf8b8f164b6d8e03715540b1d9bcfdad1ce7 (diff) | |
| download | scummvm-rg350-e91df69eb64d9e3ef7d02aa2423e3fbc96dc8aef.tar.gz scummvm-rg350-e91df69eb64d9e3ef7d02aa2423e3fbc96dc8aef.tar.bz2 scummvm-rg350-e91df69eb64d9e3ef7d02aa2423e3fbc96dc8aef.zip  | |
Decoded further fields in the SequenceList class, and started implementation of kernel message display
svn-id: r49034
| -rw-r--r-- | engines/m4/font.h | 6 | ||||
| -rw-r--r-- | engines/m4/mads_logic.cpp | 5 | ||||
| -rw-r--r-- | engines/m4/mads_scene.cpp | 42 | ||||
| -rw-r--r-- | engines/m4/mads_scene.h | 21 | ||||
| -rw-r--r-- | engines/m4/mads_views.cpp | 215 | ||||
| -rw-r--r-- | engines/m4/mads_views.h | 71 | 
6 files changed, 248 insertions, 112 deletions
diff --git a/engines/m4/font.h b/engines/m4/font.h index d675cb6d47..e64f80b70d 100644 --- a/engines/m4/font.h +++ b/engines/m4/font.h @@ -61,6 +61,12 @@ class Font {  public:  	Font(MadsM4Engine *vm);  	~Font(); + +	Font *getFont(const char *filename) { +		// TODO: Proper separation of font instances +		setFont(filename); +		return this; +	}  	void setFont(const char *filename);  	void setColor(uint8 color);  	void setColors(uint8 alt1, uint8 alt2, uint8 foreground); diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp index 24d225a2a6..9d6c4e169b 100644 --- a/engines/m4/mads_logic.cpp +++ b/engines/m4/mads_logic.cpp @@ -164,7 +164,8 @@ void MadsSceneLogic::selectScene(int sceneNum) {  void MadsSceneLogic::setupScene() {  	// FIXME: This is the hardcoded logic for Rex scene 101 only -	//const char *animName = formAnimName('A', -1); +	const char *animName = formAnimName('A', -1); +	warning("anim - %s", animName);  //	sub_1e754(animName, 3); @@ -187,7 +188,7 @@ void MadsSceneLogic::enterScene() {  	_spriteIndexes[16] = startSpriteSequence(_spriteIndexes[1], 0, 4, 0, 1, 0);  	_spriteIndexes[17] = startSpriteSequence(_spriteIndexes[2], 0, 4, 0, 1, 0); -	_madsVm->scene()->_sequenceList.unk2(0, 2, 7, 0x46); +	_madsVm->scene()->_sequenceList.addSubEntry(0, SM_FRAME_INDEX, 7, 70);  	_spriteIndexes[18] = startCycledSpriteSequence(_spriteIndexes[3], 0, 10, 0, 0, 60);  	_spriteIndexes[19] = startSpriteSequence(_spriteIndexes[4], 0, 5, 0, 1, 0); diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp index 39279573de..efb495e823 100644 --- a/engines/m4/mads_scene.cpp +++ b/engines/m4/mads_scene.cpp @@ -57,6 +57,12 @@ MadsScene::~MadsScene() {   * Secondary scene loading code   */  void MadsScene::loadScene2(const char *aaName) { +	// TODO: Completely finish + +	_spriteSlots.clear(); +	_sequenceList.clear(); +	_kernelMessages.clear(); +  	// Load up the properties for the scene  	_sceneResources.load(_currentScene); @@ -652,42 +658,6 @@ void MadsSceneResources::load(int sId) {   * 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; -	while ((idx < TIMED_TEXT_SIZE) && ((_timedText[idx].flags & TEXTFLAG_ACTIVE) != 0)) -		++idx; -	if (idx == TIMED_TEXT_SIZE) { -		if (vUnknown == 0) -			return -1; - -		error("Ran out of timed text display slots"); -	} - -	// Set up the entry values -	_timedText[idx].flags = flags | TEXTFLAG_ACTIVE; -	strcpy(_timedText[idx].message, message); -	_timedText[idx].colour1 = fontColours & 0xff; -	_timedText[idx].colour2 = fontColours >> 8; -	_timedText[idx].position.x = destPos.x; -	_timedText[idx].position.y = destPos.y; -	_timedText[idx].textDisplayIndex = -1; -	_timedText[idx].timeout = timeout; -	_timedText[idx].frameTimer = g_system->getMillis(); -	_timedText[idx].field_1C = vUnknown; -	_timedText[idx].field_1D = 0; // word_84206 - -	// Copy the current action noun list -	for (int i = 0; i < 3; ++i) -		_timedText[idx].actionNouns[i] = _madsVm->scene()->actionNouns[i]; - -	if (flags & TEXTFLAG_2) { -		warning("word_844b8 and dword_845a0 not yet implemented"); -	} - -	return idx; -} -  void MadsScreenText::draw(M4Surface *surface) {  } diff --git a/engines/m4/mads_scene.h b/engines/m4/mads_scene.h index 43a90b621f..f7625bb761 100644 --- a/engines/m4/mads_scene.h +++ b/engines/m4/mads_scene.h @@ -66,27 +66,6 @@ public:  	void load(int sceneId);	  }; -#define TIMED_TEXT_SIZE 10 -#define TEXT_4A_SIZE 30 - -enum TalkTextFlags {TEXTFLAG_2 = 2, TEXTFLAG_4 = 4, TEXTFLAG_8 = 8, TEXTFLAG_40 = 0x40, -		TEXTFLAG_ACTIVE = 0x80}; - -struct TimedText { -	uint8 flags; -	int colour1; -	int colour2; -	Common::Point position; -	int textDisplayIndex; -	int timerIndex; -	uint32 timeout; -	uint32 frameTimer; -	bool field_1C; -	uint8 field_1D; -	uint16 actionNouns[3]; -	char message[100]; -}; -  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}; diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp index 57dd3523d4..a99976338b 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -240,6 +240,108 @@ void MadsTextDisplay::cleanUp() {  //-------------------------------------------------------------------------- +MadsKernelMessageList::MadsKernelMessageList(MadsView &owner): _owner(owner) { +	for (int i = 0; i < TIMED_TEXT_SIZE; ++i) { +		MadsKernelMessageListEntry rec; +		_entries.push_back(rec); +	} + +	_owner._textSpacing = -1; +	_talkFont = _vm->_font->getFont(FONT_CONVERSATION_MADS); +} + +void MadsKernelMessageList::clear() { +	for (uint i = 0; i < _entries.size(); ++i) +		_entries[i].flags = 0; + +	_owner._textSpacing = -1; +	_talkFont = _vm->_font->getFont(FONT_CONVERSATION_MADS); +} + +int MadsKernelMessageList::add(const Common::Point &pt, uint fontColour, uint8 flags, uint8 v2, uint32 timeout, char *msg) { +	// Find a free slot +	uint idx = 0; +	while ((idx < _entries.size()) && ((_entries[idx].flags & KMSG_ACTIVE) != 0)) +		++idx; +	if (idx == _entries.size()) { +		if (v2 == 0) +			return -1; + +		error("MadsKernelList overflow"); +	} + +	MadsKernelMessageListEntry &rec = _entries[idx]; +	rec.msg = msg; +	rec.flags = flags | KMSG_ACTIVE; +	rec.colour1 = fontColour & 0xff; +	rec.colour2 = fontColour >> 8; +	rec.position = pt; +	rec.textDisplayIndex = -1; +	rec.timeout = timeout; +	rec.frameTimer = _madsVm->_currentTimer; +	rec.field_1C = v2; +	rec.abortMode = _owner._abortTimersMode2; +	 +	for (int i = 0; i < 3; ++i) +		rec.actionNouns[i] = _madsVm->scene()->actionNouns[i]; + +	if (flags & KMSG_2) +		rec.frameTimer = _owner._ticksAmount + _owner._newTimeout; + +	return idx; +} + +void MadsKernelMessageList::unk1(int msgIndex, int v1, 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].frameTimer2 = _madsVm->_currentTimer; + +	const char *msgP = _entries[msgIndex].msg; +	_entries[msgIndex].asciiChar = *msgP; +	_entries[msgIndex].asciiChar2 = *(msgP + 1); + +	if (_entries[msgIndex].flags & KMSG_2) +		_entries[msgIndex].frameTimer2 = _owner._ticksAmount + _owner._newTimeout; + +	_entries[msgIndex].frameTimer = _entries[msgIndex].frameTimer2; +} + +void MadsKernelMessageList::setSeqIndex(int msgIndex, int seqIndex) { +	if (msgIndex >= 0) { +		_entries[msgIndex].flags |= KMSG_4; +		_entries[msgIndex].sequenceIndex = seqIndex; +	} +} + +void MadsKernelMessageList::remove(int msgIndex) { +	MadsKernelMessageListEntry &rec = _entries[msgIndex]; + +	if (rec.flags & KMSG_ACTIVE) { +		if (rec.flags & KMSG_8) { +			*(rec.msg + rec.msgOffset) = rec.asciiChar; +			*(rec.msg + rec.msgOffset + 1) = rec.asciiChar2; +		} + +		if (rec.textDisplayIndex >= 0) +			_owner._textDisplay.expire(rec.textDisplayIndex); + +		rec.flags &= ~KMSG_ACTIVE; +	} +} + +void MadsKernelMessageList::reset() { +	for (uint i = 0; i < _entries.size(); ++i) +		remove(i); + +	// sub_20454 +} + +//-------------------------------------------------------------------------- +  /**   * Clears the entries list   */ @@ -375,14 +477,21 @@ MadsSequenceList::MadsSequenceList(MadsView &owner): _owner(owner) {  	}  } -bool MadsSequenceList::unk2(int index, int v1, int v2, int v3) { -	if (_entries[index].len27 >= TIMER_ENTRY_SUBSET_MAX) +void MadsSequenceList::clear() { +	for (uint i = 0; i < _entries.size(); ++i) { +		_entries[i].active = 0; +		_entries[i].dynamicHotspotIndex = -1; +	} +} + +bool MadsSequenceList::addSubEntry(int index, SequenceSubEntryMode mode, int frameIndex, int abortVal) { +	if (_entries[index].entries.count >= TIMER_ENTRY_SUBSET_MAX)  		return true; -	int subIndex = _entries[index].len27++; -	_entries[index].fld27[subIndex] = v1; -	_entries[index].fld2C[subIndex] = v2; -	_entries[index].fld36[subIndex] = v3; +	int subIndex = _entries[index].entries.count++; +	_entries[index].entries.mode[subIndex] = mode; +	_entries[index].entries.frameIndex[subIndex] = frameIndex; +	_entries[index].entries.abortVal[subIndex] = abortVal;  	return false;  } @@ -428,8 +537,8 @@ int MadsSequenceList::add(int spriteListIndex, int v0, int frameIndex, char fiel  	_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 +	_entries[timerIndex].entries.count = 0; +	_entries[timerIndex].abortMode = _owner._abortTimersMode2;  	for (int i = 0; i < 3; ++i)  		_entries[timerIndex].actionNouns[i] = _madsVm->scene()->actionNouns[i]; @@ -469,37 +578,37 @@ void MadsSequenceList::setSpriteSlot(int timerIndex, MadsSpriteSlot &spriteSlot)  }  bool MadsSequenceList::loadSprites(int timerIndex) { -	MadsSequenceEntry &timerEntry = _entries[timerIndex]; +	MadsSequenceEntry &seqEntry = _entries[timerIndex];  	int slotIndex;  	bool result = false;  	int idx = -1;  	_owner._spriteSlots.deleteTimer(timerIndex); -	if (timerEntry.field_25 != 0) { +	if (seqEntry.field_25 != 0) {  		remove(timerIndex);  		return false;  	} -	if (timerEntry.spriteListIndex == -1) { -		timerEntry.field_25 = -1; +	if (seqEntry.spriteListIndex == -1) { +		seqEntry.field_25 = -1;  	} else if ((slotIndex = _owner._spriteSlots.getIndex()) >= 0) {  		MadsSpriteSlot &spriteSlot = _owner._spriteSlots[slotIndex];  		setSpriteSlot(timerIndex, spriteSlot);  		int x2 = 0, y2 = 0; -		if ((timerEntry.field_13 != 0) || (timerEntry.dynamicHotspotIndex >= 0)) { -			SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(timerEntry.spriteListIndex); -			M4Sprite *frame = spriteSet.getFrame(timerEntry.frameIndex - 1); -			int width = frame->width() * timerEntry.scale / 200; -			int height = frame->height() * timerEntry.scale / 100; +		if ((seqEntry.field_13 != 0) || (seqEntry.dynamicHotspotIndex >= 0)) { +			SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(seqEntry.spriteListIndex); +			M4Sprite *frame = spriteSet.getFrame(seqEntry.frameIndex - 1); +			int width = frame->width() * seqEntry.scale / 200; +			int height = frame->height() * seqEntry.scale / 100;  			warning("frame size %d x %d", width, height);  			// TODO: Missing stuff here, and I'm not certain about the dynamic hotspot stuff below -			if (timerEntry.dynamicHotspotIndex >= 0) { -				DynamicHotspot &dynHotspot = _owner._dynamicHotspots[timerEntry.dynamicHotspotIndex]; +			if (seqEntry.dynamicHotspotIndex >= 0) { +				DynamicHotspot &dynHotspot = _owner._dynamicHotspots[seqEntry.dynamicHotspotIndex];  				dynHotspot.bounds.left = MAX(x2 - width, 0);  				dynHotspot.bounds.right = MAX(x2 - width, 319) - dynHotspot.bounds.left + 1; @@ -511,62 +620,70 @@ bool MadsSequenceList::loadSprites(int timerIndex) {  		}  		// Frame adjustments -		if (timerEntry.frameStart != timerEntry.numSprites) -			timerEntry.frameIndex += timerEntry.frameInc; +		if (seqEntry.frameStart != seqEntry.numSprites) +			seqEntry.frameIndex += seqEntry.frameInc; -		if (timerEntry.frameIndex >= timerEntry.frameStart) { -			if (timerEntry.frameIndex > timerEntry.numSprites) { +		if (seqEntry.frameIndex >= seqEntry.frameStart) { +			if (seqEntry.frameIndex > seqEntry.numSprites) {  				result = true; -				if (timerEntry.animType != ANIMTYPE_CYCLED) { +				if (seqEntry.animType != ANIMTYPE_CYCLED) {  					// Keep index from exceeding maximum allowed -					timerEntry.frameIndex = timerEntry.frameStart; +					seqEntry.frameIndex = seqEntry.frameStart;  				} else {  					// Switch into reverse -					timerEntry.frameIndex = timerEntry.numSprites - 1; -					timerEntry.frameInc = -1; +					seqEntry.frameIndex = seqEntry.numSprites - 1; +					seqEntry.frameInc = -1;  				}  			}  		} else {  			// Currently in reverse mode  			result = true; -			if (timerEntry.animType == ANIMTYPE_CYCLED) +			if (seqEntry.animType == ANIMTYPE_CYCLED)  			{  				// Switch back to forward direction again -				timerEntry.frameIndex = timerEntry.frameStart + 1; -				timerEntry.frameInc = 1; +				seqEntry.frameIndex = seqEntry.frameStart + 1; +				seqEntry.frameInc = 1;  			} else {  				// Otherwise reset back to last sprite for further reverse animating -				timerEntry.frameIndex = timerEntry.numSprites;		 +				seqEntry.frameIndex = seqEntry.numSprites;		  			}  		} -		if (result && (timerEntry.field_24 != 0)) { -			if (--timerEntry.field_24 != 0) -				timerEntry.field_25 = -1; +		if (result && (seqEntry.field_24 != 0)) { +			if (--seqEntry.field_24 != 0) +				seqEntry.field_25 = -1;  		}  	} else {  		// Out of sprite slots -		timerEntry.field_25 = -1; +		seqEntry.field_25 = -1;  	} -	if (timerEntry.len27 > 0) { -		for (int i = 0; i <= timerEntry.len27; ++i) { -			if ((!timerEntry.fld27[i] && (timerEntry.field_25 != 0)) || -				((timerEntry.fld27[i] == 1) && result)) { +	if (seqEntry.entries.count > 0) { +		for (int i = 0; i <= seqEntry.entries.count; ++i) { +			switch (seqEntry.entries.mode[i]) { +			case SM_0: +			case SM_1: +				if (((seqEntry.entries.mode[i] == SM_0) && (seqEntry.field_25 != 0)) || +					((seqEntry.entries.mode[i] == SM_1) && result))  				idx = i; -			} else if (timerEntry.fld27[i] > 1) { -				int v = timerEntry.fld2C[i]; -				if ((v == timerEntry.frameIndex) || (v == 0)) +				break; + +			case SM_FRAME_INDEX: { +				int v = seqEntry.entries.frameIndex[i]; +				if ((v == seqEntry.frameIndex) || (v == 0))  					idx = i;  			} + +			default: +				break; +			}  		}  	}  	if (idx >= 0) { -		//_owner._abortTimers = timerEntry.fld36[idx]; -		 -		// TODO: Figure out word_84208, timerEntry.field_3B[] +		_owner._abortTimers = seqEntry.entries.abortVal[idx]; +		_owner._abortTimersMode = seqEntry.abortMode;  	}  	return result; @@ -606,9 +723,15 @@ void MadsSequenceList::delay(uint32 v1, uint32 v2) {  //-------------------------------------------------------------------------- -MadsView::MadsView(View *view): _view(view), _dynamicHotspots(*this), _sequenceList(*this) { +MadsView::MadsView(View *view): _view(view), _dynamicHotspots(*this), _sequenceList(*this), +		_kernelMessages(*this) { +	_textSpacing = -1; +	_ticksAmount = 3; +	_newTimeout = 0;  	_abortTimers = 0;  	_abortTimers2 = 0; +	_abortTimersMode = ABORTMODE_0; +	_abortTimersMode2 = ABORTMODE_0;  }  void MadsView::refresh() { diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h index 50ce9e1aab..37c797b931 100644 --- a/engines/m4/mads_views.h +++ b/engines/m4/mads_views.h @@ -40,6 +40,8 @@ namespace M4 {  class MadsView; +enum AbortTimerMode {ABORTMODE_0 = 0, ABORTMODE_1 = 1, ABORTMODE_2 = 2}; +  class MadsSpriteSlot {  public:  	int spriteId; @@ -126,6 +128,48 @@ public:  	void cleanUp();  }; +#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_40 = 0x40, KMSG_ACTIVE = 0x80}; + +class MadsKernelMessageListEntry { +public: +	uint8 flags; +	int sequenceIndex; +	char asciiChar; +	char asciiChar2; +	int colour1; +	int colour2; +	Common::Point position; +	int textDisplayIndex; +	int msgOffset; +	int field_E; +	uint32 frameTimer2; +	uint32 frameTimer; +	uint32 timeout; +	bool field_1C; +	AbortTimerMode abortMode; +	uint16 actionNouns[3]; +	char *msg; +}; + +class MadsKernelMessageList { +private: +	MadsView &_owner; +	Common::Array<MadsKernelMessageListEntry> _entries; +	Font *_talkFont; +public: +	MadsKernelMessageList(MadsView &owner); + +	void clear(); +	int add(const Common::Point &pt, uint fontColour, uint8 flags, uint8 v2, uint32 timeout, char *msg); +	void unk1(int msgIndex, int v1, int v2); +	void setSeqIndex(int msgIndex, int seqIndex); +	void remove(int msgIndex); +	void reset(); +}; +  class ScreenObjectEntry {  public:  	Common::Rect bounds; @@ -191,9 +235,18 @@ public:  	void reset();  }; +enum SpriteAnimType {ANIMTYPE_SINGLE_DIRECTION = 1, ANIMTYPE_CYCLED = 2}; + +enum SequenceSubEntryMode {SM_0 = 0, SM_1 = 1, SM_FRAME_INDEX = 2}; +  #define TIMER_ENTRY_SUBSET_MAX 5 -enum SpriteAnimType {ANIMTYPE_SINGLE_DIRECTION = 1, ANIMTYPE_CYCLED = 2}; +struct MadsSequenceSubEntries { +	int count; +	SequenceSubEntryMode mode[TIMER_ENTRY_SUBSET_MAX]; +	int16 frameIndex[TIMER_ENTRY_SUBSET_MAX]; +	int8 abortVal[TIMER_ENTRY_SUBSET_MAX]; +};  struct MadsSequenceEntry {  	int8 active; @@ -220,11 +273,8 @@ struct MadsSequenceEntry {  	int field_24;  	int field_25; -	int len27; -	int8 fld27[TIMER_ENTRY_SUBSET_MAX]; -	int16 fld2C[TIMER_ENTRY_SUBSET_MAX]; -	int8 fld36[TIMER_ENTRY_SUBSET_MAX]; -	int field_3B; +	MadsSequenceSubEntries entries; +	AbortTimerMode abortMode;  	uint16 actionNouns[3];  	int numTicks; @@ -242,7 +292,8 @@ public:  	MadsSequenceList(MadsView &owner);  	MadsSequenceEntry &operator[](int index) { return _entries[index]; }	 -	bool unk2(int index, int v1, int v2, int v3); +	void clear(); +	bool addSubEntry(int index, SequenceSubEntryMode mode, int frameIndex, int abortVal);  	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 frameInc, SpriteAnimType animType,   		int numSprites, int frameStart); @@ -259,12 +310,18 @@ private:  public:  	MadsSpriteSlots _spriteSlots;  	MadsTextDisplay _textDisplay; +	MadsKernelMessageList _kernelMessages;  	ScreenObjects _screenObjects;  	MadsDynamicHotspots _dynamicHotspots;  	MadsSequenceList _sequenceList; +	int _textSpacing; +	int _ticksAmount; +	uint32 _newTimeout;  	int _abortTimers;  	int8 _abortTimers2; +	AbortTimerMode _abortTimersMode; +	AbortTimerMode _abortTimersMode2;  public:  	MadsView(View *view);  | 
