diff options
| author | Paul Gilbert | 2014-04-07 22:37:22 -0400 | 
|---|---|---|
| committer | Paul Gilbert | 2014-04-07 22:37:22 -0400 | 
| commit | 7e13f488abeb6a7530d591bae880fdb185c8fef1 (patch) | |
| tree | f761b8479267909be151dbefe0f4f7176b23b3c1 | |
| parent | f6a6ea974117cd8401a2caecdba9ef553821d41a (diff) | |
| download | scummvm-rg350-7e13f488abeb6a7530d591bae880fdb185c8fef1.tar.gz scummvm-rg350-7e13f488abeb6a7530d591bae880fdb185c8fef1.tar.bz2 scummvm-rg350-7e13f488abeb6a7530d591bae880fdb185c8fef1.zip | |
MADS: Implement loading logic for UI background animations
| -rw-r--r-- | engines/mads/animation.cpp | 72 | ||||
| -rw-r--r-- | engines/mads/animation.h | 32 | ||||
| -rw-r--r-- | engines/mads/game.cpp | 1 | ||||
| -rw-r--r-- | engines/mads/game.h | 1 | ||||
| -rw-r--r-- | engines/mads/mads.cpp | 1 | ||||
| -rw-r--r-- | engines/mads/mads.h | 1 | ||||
| -rw-r--r-- | engines/mads/palette.h | 13 | ||||
| -rw-r--r-- | engines/mads/scene.cpp | 22 | ||||
| -rw-r--r-- | engines/mads/scene.h | 2 | ||||
| -rw-r--r-- | engines/mads/scene_data.h | 5 | ||||
| -rw-r--r-- | engines/mads/screen.cpp | 6 | ||||
| -rw-r--r-- | engines/mads/user_interface.cpp | 76 | ||||
| -rw-r--r-- | engines/mads/user_interface.h | 14 | 
13 files changed, 206 insertions, 40 deletions
| diff --git a/engines/mads/animation.cpp b/engines/mads/animation.cpp index b557a598ed..40abdbe26b 100644 --- a/engines/mads/animation.cpp +++ b/engines/mads/animation.cpp @@ -108,15 +108,24 @@ void AnimMessage::load(Common::SeekableReadStream *f) {  	f->skip(2);  } -void AnimFrameEntry::load(Common::SeekableReadStream *f) { -	_frameNumber = f->readUint16LE(); -	_seqIndex = f->readByte(); -	_spriteSlot._spritesIndex = f->readByte(); -	_spriteSlot._frameNumber = f->readUint16LE(); -	_spriteSlot._position.x = f->readSint16LE(); -	_spriteSlot._position.y = f->readSint16LE(); -	_spriteSlot._depth = f->readSByte(); -	_spriteSlot._scale = (int8)f->readByte(); +void AnimFrameEntry::load(Common::SeekableReadStream *f, bool uiFlag) { +	if (uiFlag) { +		f->skip(2); +		_seqIndex = f->readByte(); +		_spriteSlot._spritesIndex = f->readByte(); +		_spriteSlot._frameNumber = f->readUint16LE(); +		_spriteSlot._position.x = f->readSint16LE(); +		_spriteSlot._position.y = f->readSint16LE(); +	} else { +		_frameNumber = f->readUint16LE(); +		_seqIndex = f->readByte(); +		_spriteSlot._spritesIndex = f->readByte(); +		_spriteSlot._frameNumber = f->readUint16LE(); +		_spriteSlot._position.x = f->readSint16LE(); +		_spriteSlot._position.y = f->readSint16LE(); +		_spriteSlot._depth = f->readSByte(); +		_spriteSlot._scale = (int8)f->readByte(); +	}  }  /*------------------------------------------------------------------------*/ @@ -132,6 +141,22 @@ void AnimMiscEntry::load(Common::SeekableReadStream *f) {  /*------------------------------------------------------------------------*/ +void AnimUIEntry::load(Common::SeekableReadStream *f) { +	_probability = f->readUint16LE(); +	_imageCount = f->readUint16LE(); +	_firstImage = f->readUint16LE(); +	_lastImage = f->readUint16LE(); +	_counter = f->readSint16LE(); +	for (int i = 0; i < ANIM_SPAWN_COUNT; ++i) +		_spawn[i] = f->readByte(); +	for (int i = 0; i < ANIM_SPAWN_COUNT; ++i) +		_spawnFrame[i] = f->readUint16LE(); +	_sound = f->readUint16LE() & 0xFF; +	_soundFrame = f->readUint16LE(); +} + +/*------------------------------------------------------------------------*/ +  Animation *Animation::init(MADSEngine *vm, Scene *scene) {  	return new Animation(vm, scene);  } @@ -149,7 +174,7 @@ Animation::~Animation() {  	if (_header._manualFlag)  		scene._sprites.remove(_spriteListIndexes[_header._spritesIndex]); -	for (uint idx = 0; idx < _header._spriteSetsCount; ++idx) { +	for (int idx = 0; idx < _header._spriteSetsCount; ++idx) {  		if (!_header._manualFlag || _header._spritesIndex != idx)  			scene._sprites.remove(_spriteListIndexes[idx]);  	} @@ -195,12 +220,12 @@ void Animation::load(UserInterface &interfaceSurface, MSurface &depthSurface,  	delete stream;  	if (_header._animMode == 4) -		flags |= 0x4000; +		flags |= PALFLAG_RESERVED; -	if (flags & 0x100) { +	if (flags & ANIMFLAG_LOAD_BACKGROUND) {  		loadInterface(interfaceSurface, depthSurface, _header, flags, palAnimData, sceneInfo);  	} -	if (flags & 0x200) { +	if (flags & ANIMFLAG_LOAD_BACKGROUND_ONLY) {  		// No data  		_header._messagesCount = 0;  		_header._frameEntriesCount = 0; @@ -234,7 +259,7 @@ void Animation::load(UserInterface &interfaceSurface, MSurface &depthSurface,  		for (int i = 0; i < _header._frameEntriesCount; i++) {  			AnimFrameEntry rec; -			rec.load(frameStream); +			rec.load(frameStream, flags & ANIMFLAG_LOAD_BACKGROUND);  			_frameEntries.push_back(rec);  		} @@ -242,14 +267,23 @@ void Animation::load(UserInterface &interfaceSurface, MSurface &depthSurface,  	}  	_miscEntries.clear(); +	_uiEntries.clear();  	if (_header._miscEntriesCount > 0) {  		// Chunk 4: Misc Data  		Common::SeekableReadStream *miscStream = madsPack.getItemStream(streamIndex++); -		for (int i = 0; i < _header._miscEntriesCount; ++i) { -			AnimMiscEntry rec; -			rec.load(miscStream); -			_miscEntries.push_back(rec); +		if (flags & ANIMFLAG_LOAD_BACKGROUND) { +			for (int i = 0; i < _header._miscEntriesCount; ++i) { +				AnimUIEntry rec; +				rec.load(miscStream); +				_uiEntries.push_back(rec); +			} +		} else { +			for (int i = 0; i < _header._miscEntriesCount; ++i) { +				AnimMiscEntry rec; +				rec.load(miscStream); +				_miscEntries.push_back(rec); +			}  		}  		delete miscStream; @@ -257,7 +291,7 @@ void Animation::load(UserInterface &interfaceSurface, MSurface &depthSurface,  	// If the animation specifies a font, then load it for access  	delete _font; -	if (_header._flags & ANIM_CUSTOM_FONT) { +	if (_header._flags & ANIMFLAG_CUSTOM_FONT) {  		Common::String fontName = "*" + _header._fontResource;  		_font = _vm->_font->getFont(fontName.c_str());  	} else { diff --git a/engines/mads/animation.h b/engines/mads/animation.h index 8095bec5e0..75f14a52b3 100644 --- a/engines/mads/animation.h +++ b/engines/mads/animation.h @@ -33,7 +33,12 @@  namespace MADS { -enum AnimFlag { ANIM_CUSTOM_FONT = 0x20 }; +enum AnimFlag {  +	ANIMFLAG_DITHER				= 0x0001,	// Dither to 16 colors +	ANIMFLAG_CUSTOM_FONT		= 0x0020,	// Load ccustom font  +	ANIMFLAG_LOAD_BACKGROUND	= 0x0100,	// Load background +	ANIMFLAG_LOAD_BACKGROUND_ONLY = 0x0200	// Load background only +};  class MADSEngine;  class Scene; @@ -63,7 +68,7 @@ public:  	/**  	 * Loads data for the record  	 */ -	void load(Common::SeekableReadStream *f); +	void load(Common::SeekableReadStream *f, bool uiFlag);  };  class AnimMiscEntry { @@ -80,6 +85,26 @@ public:  	void load(Common::SeekableReadStream *f);  }; +#define ANIM_SPAWN_COUNT 2 + +class AnimUIEntry { +public: +	int _probability; +	int _imageCount; +	int _firstImage; +	int _lastImage; +	int _counter; +	int _spawn[ANIM_SPAWN_COUNT]; +	int _spawnFrame[ANIM_SPAWN_COUNT]; +	int _sound; +	int _soundFrame; + +	/** +	 * Loads the data for the record +	 */ +	void load(Common::SeekableReadStream *f); +}; +  class AAHeader {  public:  	int _spriteSetsCount; @@ -115,7 +140,6 @@ private:  	Common::Array<int> _spriteListIndexes;  	Common::Array<AnimMessage> _messages; -	Common::Array<AnimFrameEntry> _frameEntries;  	Common::Array<AnimMiscEntry> _miscEntries;  	Common::Array<SpriteAsset *> _spriteSets;  	Font *_font; @@ -153,6 +177,8 @@ private:  protected:  	Animation(MADSEngine *vm, Scene *scene);  public: +	Common::Array<AnimFrameEntry> _frameEntries; +	Common::Array<AnimUIEntry> _uiEntries;  	bool _resetFlag;  	static Animation *init(MADSEngine *vm, Scene *scene); diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp index 90ea105bd1..fd0294161d 100644 --- a/engines/mads/game.cpp +++ b/engines/mads/game.cpp @@ -52,7 +52,6 @@ Game::Game(MADSEngine *vm): _vm(vm), _surface(nullptr), _objects(vm),  	_priorSectionNumber = 0;  	_currentSectionNumber = -1;  	_kernelMode = KERNEL_GAME_LOAD; -	_v2 = 0;  	_quoteEmergency = false;  	_vocabEmergency = false;  	_aaName = "*I0.AA"; diff --git a/engines/mads/game.h b/engines/mads/game.h index f41e7d248c..e4880091cc 100644 --- a/engines/mads/game.h +++ b/engines/mads/game.h @@ -131,7 +131,6 @@ public:  	VisitedScenes _visitedScenes;  	Scene _scene;  	KernelMode _kernelMode; -	int _v2;  	int _trigger;  	ScreenTransition _fx;  	TriggerMode _triggerMode; diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp index 68d8579dc4..229d3fcef8 100644 --- a/engines/mads/mads.cpp +++ b/engines/mads/mads.cpp @@ -43,6 +43,7 @@ MADSEngine::MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc) :  	_textWindowStill = false;  	_screenFade = SCREEN_FADE_SMOOTH;  	_musicFlag = false; +	_dithering = false;  	_debugger = nullptr;  	_dialogs = nullptr; diff --git a/engines/mads/mads.h b/engines/mads/mads.h index cf8046f8f6..4ea0758f88 100644 --- a/engines/mads/mads.h +++ b/engines/mads/mads.h @@ -104,6 +104,7 @@ public:  	bool _textWindowStill;  	ScreenFade _screenFade;  	bool _musicFlag; +	bool _dithering;  public:  	MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc);  	virtual ~MADSEngine(); diff --git a/engines/mads/palette.h b/engines/mads/palette.h index dd5eaf6c2b..cceef09417 100644 --- a/engines/mads/palette.h +++ b/engines/mads/palette.h @@ -32,6 +32,19 @@ class MADSEngine;  #define PALETTE_USAGE_COUNT 4 +/** + * Palette mapping options + */ +enum { +	PALFLAG_BACKGROUND		= 0x8000,  // Loading initial background        +	PALFLAG_RESERVED		= 0x4000,  // Enable mapping reserved colors  +	PALFLAG_ANY_TO_CLOSEST	= 0x2000,  // Any color can map to closest      +	PALFLAG_ALL_TO_CLOSEST	= 0x1000,  // Any colors that can map must map  +	PALFLAG_TOP_COLORS		= 0x0800,  // Allow mapping to high four colors  +	PALFLAG_DEFINE_RESERVED	= 0x0400,  // Define initial reserved color     +	PALFLAG_MASK			= 0xfc00   // Mask for all the palette flags    +}; +  struct RGB4 {  	byte r;  	byte g; diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp index b178de5839..ac57e0bcbf 100644 --- a/engines/mads/scene.cpp +++ b/engines/mads/scene.cpp @@ -123,8 +123,12 @@ void Scene::loadScene(int sceneId, const Common::String &prefix, bool palFlag) {  	_kernelMessages.clear();  	// TODO: palletteUsage reset?  setPalette(_nullPalette); +	int flags = SCENEFLAG_LOAD_SHADOW; +	if (_vm->_dithering) +		flags |= SCENEFLAG_DITHER; +  	_sceneInfo = SceneInfo::init(_vm); -	_sceneInfo->load(_currentSceneId, _variant, Common::String(), _vm->_game->_v2 ? 17 : 16, +	_sceneInfo->load(_currentSceneId, _variant, Common::String(), flags,  		_depthSurface, _backgroundSurface);  	// Initialise palette animation for the scene @@ -143,10 +147,12 @@ void Scene::loadScene(int sceneId, const Common::String &prefix, bool palFlag) {  	_vm->_palette->_paletteUsage.load(1, 0xF);  	// Load interface -	int flags = _vm->_game->_v2 ? 0x4101 : 0x4100; -	if (!_vm->_textWindowStill) -		flags |= 0x200; - +	flags = PALFLAG_RESERVED | ANIMFLAG_LOAD_BACKGROUND; +	if (_vm->_dithering) +		flags |= ANIMFLAG_DITHER; +	if (_vm->_textWindowStill) +		flags |= ANIMFLAG_LOAD_BACKGROUND_ONLY; +		  	_animationData = Animation::init(_vm, this);  	MSurface depthSurface;  	_animationData->load(_userInterface, depthSurface, prefix, flags, nullptr, nullptr); @@ -513,7 +519,7 @@ void Scene::loadAnimation(const Common::String &resName, int abortTimers) {  	_activeAnimation = Animation::init(_vm, this);  	_activeAnimation->load(interfaceSurface, depthSurface, resName,  -		_vm->_game->_v2 ? 1 : 0, nullptr, nullptr); +		_vm->_dithering ? ANIMFLAG_DITHER : 0, nullptr, nullptr);  	_activeAnimation->startAnimation(abortTimers);  } @@ -585,8 +591,4 @@ void Scene::resetScene() {  	_sequences.clear();  } -void Scene::backgroundAnimation() { -	warning("TODO: Scene::backgroundAnimation"); -} -  } // End of namespace MADS diff --git a/engines/mads/scene.h b/engines/mads/scene.h index b0ecf111e6..f449ededfc 100644 --- a/engines/mads/scene.h +++ b/engines/mads/scene.h @@ -213,8 +213,6 @@ public:  	void resetScene(); -	void backgroundAnimation(); -  	/**  	* Removes all the scene specific sprites fromt the sprites list,   	* leaving any player sprites list in place at the start of the list. diff --git a/engines/mads/scene_data.h b/engines/mads/scene_data.h index 2a6032a507..73ca21d092 100644 --- a/engines/mads/scene_data.h +++ b/engines/mads/scene_data.h @@ -52,6 +52,11 @@ class SpriteSlot;  #define TEXT_DISPLAY_MAX_SIZE 40  #define DIRTY_AREAS_SIZE (SPRITE_SLOTS_MAX_SIZE + TEXT_DISPLAY_MAX_SIZE) +enum {  +	SCENEFLAG_DITHER		= 0x01,     // Dither to 16 colors +	SCENEFLAG_LOAD_SHADOW	= 0x10		// Load hard shadows +}; +  class VerbInit {  public:  	int _id; diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp index 25623bc215..683a56705a 100644 --- a/engines/mads/screen.cpp +++ b/engines/mads/screen.cpp @@ -354,10 +354,10 @@ void ScreenObjects::check(bool scanFlag) {  					slot._flags = IMG_ERASE;  		} -		// Any background animation -		scene.backgroundAnimation(); +		// Any background animation in the user interface +		userInterface.doBackgroundAnimation(); -		// Handle animating the selected inventory animation +		// Handle animating the selected inventory item  		userInterface.inventoryAnim();  		// Set the base time diff --git a/engines/mads/user_interface.cpp b/engines/mads/user_interface.cpp index c371f3d837..d7f198f3ce 100644 --- a/engines/mads/user_interface.cpp +++ b/engines/mads/user_interface.cpp @@ -48,7 +48,7 @@ void UISlots::add(const Common::Point &pt, int frameNumber, int spritesIndex) {  	assert(size() < 50);  	UISlot ie; -	ie._flags = -3; +	ie._flags = IMG_OVERPRINT;  	ie._segmentId = IMG_TEXT_UPDATE;  	ie._position = pt;  	ie._frameNumber = frameNumber; @@ -57,6 +57,20 @@ void UISlots::add(const Common::Point &pt, int frameNumber, int spritesIndex) {  	push_back(ie);  } +void UISlots::add(const AnimFrameEntry &frameEntry) { +	assert(size() < 50); + +	UISlot ie; +	ie._flags = IMG_UPDATE; +	ie._segmentId = frameEntry._seqIndex; +	ie._spritesIndex = frameEntry._spriteSlot._spritesIndex; +	ie._frameNumber = frameEntry._frameNumber; +	ie._position = frameEntry._spriteSlot._position; + +	push_back(ie); +} + +  void UISlots::draw(bool updateFlag, bool delFlag) {  	Scene &scene = _vm->_game->_scene;  	UserInterface &userInterface = scene._userInterface; @@ -633,6 +647,66 @@ void UserInterface::inventoryAnim() {  	_uiSlots.push_back(slot);  } +void UserInterface::doBackgroundAnimation() { +	Scene &scene = _vm->_game->_scene; +	Common::Array<AnimUIEntry> &uiEntries = scene._animationData->_uiEntries; +	Common::Array<AnimFrameEntry> &frameEntries = scene._animationData->_frameEntries; + +	_noSegmentsActive = !_someSegmentsActive; +	_someSegmentsActive = false; + +	for (int idx = 0; idx < uiEntries.size(); ++idx) { +		AnimUIEntry &uiEntry = uiEntries[idx]; + +		if (uiEntry._counter < 0) { +			if (uiEntry._counter == -1) { +				int probabilityRandom = _vm->getRandomNumber(1, 30000); +				int probability = uiEntry._probability; +				if (uiEntry._probability > 30000) { +					if (_noSegmentsActive) { +						probability -= 30000; +					} else { +						probability = -1; +					} +				} +				if (probabilityRandom <= probability) { +					uiEntry._counter = uiEntry._firstImage; +					_someSegmentsActive = true; +				} +			} else { +				uiEntry._counter = uiEntry._firstImage; +				_someSegmentsActive = true; +			} +		} else { +			for (int idx2 = 0; idx2 < ANIM_SPAWN_COUNT; idx2++) { +				if (uiEntry._spawnFrame[idx2] == (uiEntry._counter - uiEntry._firstImage)) { +					int tempIndex = uiEntry._spawn[idx2]; +					if (idx >= tempIndex) { +						uiEntries[tempIndex]._counter = uiEntries[tempIndex]._firstImage; +					} else { +						uiEntries[tempIndex]._counter = -2; +					} +					_someSegmentsActive = true; +				} +			} + +			++uiEntry._counter; +			if (uiEntry._counter > uiEntry._lastImage) { +				uiEntry._counter = -1; +			} else { +				_someSegmentsActive = true; +			} +		} +	} + +	for (int idx = 0; idx < uiEntries.size(); ++idx) { +		int imgScan = uiEntries[idx]._counter; +		if (imgScan >= 0) { +			_uiSlots.add(frameEntries[imgScan]); +		} +	} +} +  void UserInterface::categoryChanged() {  	_highlightedItemIndex = -1;  	_vm->_events->initVars(); diff --git a/engines/mads/user_interface.h b/engines/mads/user_interface.h index 445cd1e487..86b5622a03 100644 --- a/engines/mads/user_interface.h +++ b/engines/mads/user_interface.h @@ -33,6 +33,8 @@ namespace MADS {  enum { IMG_SPINNING_OBJECT = 200, IMG_TEXT_UPDATE = 201 }; +class AnimFrameEntry; +  class UISlot {  public:  	int _flags; @@ -62,6 +64,11 @@ public:  	void add(const Common::Point &pt, int frameNumber, int spritesIndex);  	/** +	 * Loads the data from an aimation frame entry +	 */ +	void add(const AnimFrameEntry &frameEntry); + +	/**  	 * Adds a special entry for full refresh of the user interface  	 */  	void fullRefresh(); @@ -83,6 +90,8 @@ private:  	int _invFrameNumber;  	uint32 _scrollMilli;  	bool _scrollFlag; +	int _noSegmentsActive; +	int _someSegmentsActive;  	/**  	 * Loads the elements of the user interface @@ -183,6 +192,11 @@ public:  	void noInventoryAnim();  	/** +	 * Handles any animation that occurs in the background of the user interface +	 */ +	void doBackgroundAnimation(); + +	/**  	* Handles queuing a new frame of an inventory animation for drawing  	*/  	void inventoryAnim(); | 
