diff options
Diffstat (limited to 'engines/m4/animation.cpp')
-rw-r--r-- | engines/m4/animation.cpp | 535 |
1 files changed, 0 insertions, 535 deletions
diff --git a/engines/m4/animation.cpp b/engines/m4/animation.cpp deleted file mode 100644 index 4f315dd396..0000000000 --- a/engines/m4/animation.cpp +++ /dev/null @@ -1,535 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "common/textconsole.h" - -#include "m4/assets.h" -#include "m4/animation.h" -#include "m4/compression.h" -#include "m4/mads_scene.h" - -namespace M4 { - -// TODO: this code needs cleanup - -MadsAnimation::MadsAnimation(MadsM4Engine *vm, MadsView *view): Animation(vm), _view(view) { - _font = NULL; - _resetFlag = false; - _freeFlag = false; - _skipLoad = false; - _unkIndex = -1; - _messageCtr= 0; - _field12 = 0; - - _currentFrame = 0; - _oldFrameEntry = 0; - _nextFrameTimer = _madsVm->_currentTimer; - _nextScrollTimer = 0; -} - -MadsAnimation::~MadsAnimation() { - for (uint i = 0; i < _messages.size(); ++i) { - if (_messages[i].kernelMsgIndex >= 0) - _view->_kernelMessages.remove(_messages[i].kernelMsgIndex); - } - - // Further deletion logic - if (_field12) { - _view->_spriteSlots.deleteSprites(_spriteListIndexes[_spriteListIndex]); - } -} - -#define FILENAME_SIZE 13 - -/** - * Initializes and loads the data of an animation - */ -void MadsAnimation::initialize(const Common::String &filename, uint16 flags, M4Surface *surface, M4Surface *depthSurface) { - MadsPack anim(filename.c_str(), _vm); - bool madsRes = filename[0] == '*'; - char buffer[20]; - int streamIndex = 1; - - // Chunk 1: header - // header - - Common::SeekableReadStream *animStream = anim.getItemStream(0); - - int spriteListCount = animStream->readUint16LE(); - int miscEntriesCount = animStream->readUint16LE(); - int frameEntryCount = animStream->readUint16LE(); - int messagesCount = animStream->readUint16LE(); - animStream->skip(1); - _flags = animStream->readByte(); - - animStream->skip(2); - _animMode = animStream->readUint16LE(); - _roomNumber = animStream->readUint16LE(); - animStream->skip(2); - _field12 = animStream->readUint16LE() != 0; - _spriteListIndex = animStream->readUint16LE(); - _scrollX = animStream->readSint16LE(); - _scrollY = animStream->readSint16LE(); - _scrollTicks = animStream->readUint16LE(); - animStream->skip(8); - - animStream->read(buffer, FILENAME_SIZE); - buffer[FILENAME_SIZE] = '\0'; - _interfaceFile = Common::String(buffer); - - for (int i = 0; i < 10; ++i) { - animStream->read(buffer, FILENAME_SIZE); - buffer[FILENAME_SIZE] = '\0'; - _spriteSetNames[i] = Common::String(buffer); - } - - animStream->skip(81); - animStream->read(buffer, FILENAME_SIZE); - buffer[FILENAME_SIZE] = '\0'; - _lbmFilename = Common::String(buffer); - - animStream->skip(365); - animStream->read(buffer, FILENAME_SIZE); - buffer[FILENAME_SIZE] = '\0'; - _spritesFilename = Common::String(buffer); - - animStream->skip(48); - animStream->read(buffer, FILENAME_SIZE); - buffer[FILENAME_SIZE] = '\0'; - _soundName = Common::String(buffer); - - animStream->skip(13); - animStream->read(buffer, FILENAME_SIZE); - buffer[FILENAME_SIZE] = '\0'; - _dsrName = Common::String(buffer); - - animStream->read(buffer, FILENAME_SIZE); - buffer[FILENAME_SIZE] = '\0'; - Common::String fontResource(buffer); - - if (_animMode == 4) - flags |= 0x4000; - if (flags & 0x100) - loadInterface(surface, depthSurface); - - // Initialize the reference list - for (int i = 0; i < spriteListCount; ++i) - _spriteListIndexes.push_back(-1); - - delete animStream; - - if (messagesCount > 0) { - // Chunk 2 - // Following is a list of any messages for the animation - - animStream = anim.getItemStream(streamIndex++); - - for (int i = 0; i < messagesCount; ++i) { - AnimMessage rec; - rec.soundId = animStream->readSint16LE(); - animStream->read(rec.msg, 64); - animStream->skip(4); - rec.pos.x = animStream->readSint16LE(); - rec.pos.y = animStream->readSint16LE(); - rec.flags = animStream->readUint16LE(); - rec.rgb1.r = animStream->readByte() << 2; - rec.rgb1.g = animStream->readByte() << 2; - rec.rgb1.b = animStream->readByte() << 2; - rec.rgb2.r = animStream->readByte() << 2; - rec.rgb2.g = animStream->readByte() << 2; - rec.rgb2.b = animStream->readByte() << 2; - animStream->skip(2); // Space for kernelMsgIndex - rec.kernelMsgIndex = -1; - animStream->skip(6); - rec.startFrame = animStream->readUint16LE(); - rec.endFrame = animStream->readUint16LE(); - animStream->skip(2); - - _messages.push_back(rec); - } - - delete animStream; - } - - if (frameEntryCount > 0) { - // Chunk 3: animation frame info - animStream = anim.getItemStream(streamIndex++); - - for (int i = 0; i < frameEntryCount; i++) { - AnimFrameEntry rec; - rec.frameNumber = animStream->readUint16LE(); - rec.seqIndex = animStream->readByte(); - rec.spriteSlot.spriteListIndex = animStream->readByte(); - rec.spriteSlot.frameNumber = animStream->readUint16LE(); - rec.spriteSlot.xp = animStream->readSint16LE(); - rec.spriteSlot.yp = animStream->readSint16LE(); - rec.spriteSlot.depth = animStream->readSByte(); - rec.spriteSlot.scale = (int8)animStream->readByte(); - - _frameEntries.push_back(rec); - } - - delete animStream; - } - - if (miscEntriesCount > 0) { - // Chunk 4: Misc Data - animStream = anim.getItemStream(streamIndex); - - for (int i = 0; i < miscEntriesCount; ++i) { - AnimMiscEntry rec; - rec.soundNum = animStream->readByte(); - rec.msgIndex = animStream->readSByte(); - rec.numTicks = animStream->readUint16LE(); - rec.posAdjust.x = animStream->readUint16LE(); - rec.posAdjust.y = animStream->readUint16LE(); - animStream->readUint16LE(); - - _miscEntries.push_back(rec); - } - - delete animStream; - } - - // If the animation specifies a font, then load it for access - if (_flags & ANIM_CUSTOM_FONT) { - Common::String fontName; - if (madsRes) - fontName += "*"; - fontName += fontResource; - - if (fontName != "") - _font = _vm->_font->getFont(fontName.c_str()); - else - warning("Attempted to set a font with an empty name"); - } - - // If a speech file is specified, then load it - if (!_dsrName.empty()) - _vm->_sound->loadDSRFile(_dsrName.c_str()); - - // Load all the sprite sets for the animation - for (int i = 0; i < spriteListCount; ++i) { - if (_field12 && (i == _spriteListIndex)) - // Skip over field, since it's manually loaded - continue; - - _spriteListIndexes[i] = _view->_spriteSlots.addSprites(_spriteSetNames[i].c_str()); - } - - - if (_field12) { - Common::String resName; - if (madsRes) - resName += "*"; - resName += _spriteSetNames[_spriteListIndex]; - - _spriteListIndexes[_spriteListIndex] = _view->_spriteSlots.addSprites(resName.c_str()); - } - - // TODO: Unknown section about handling sprite set list combined with messages size - - // TODO: The original has two separate loops for the loop below based on _animMode == 4. Is it - // perhaps that in that mode the sprite frames has a different format..? - - // Remap the sprite list index fields from the initial value to the indexes of the loaded - // sprite sets for the animation - for (uint i = 0; i < _frameEntries.size(); ++i) { - int idx = _frameEntries[i].spriteSlot.spriteListIndex; - _frameEntries[i].spriteSlot.spriteListIndex = _spriteListIndexes[idx]; - } - - if (hasScroll()) - _nextScrollTimer = _madsVm->_currentTimer + _scrollTicks; -} - -/** - * Loads an animation file for display - */ -void MadsAnimation::load(const Common::String &filename, int abortTimers) { - initialize(filename, 0, NULL, NULL); - _messageCtr = 0; - _skipLoad = true; - -/* TODO: figure out extra stuff in this routine - if (_field12) { - _unkIndex = -1; - int listIndex = _spriteListIndexes[_spriteListIndex]; - SpriteAsset &spriteSet = _view->_spriteSlots.getSprite(listIndex); - ..?.. - } -*/ - - // Initialize miscellaneous fields - _currentFrame = 0; - _oldFrameEntry = 0; - _nextFrameTimer = _madsVm->_currentTimer; - _abortTimers = abortTimers; - _abortMode = _madsVm->scene()->_abortTimersMode2; - - if (_madsVm->_scene) - _actionNouns = _madsVm->scene()->_action._action; - - // Initialize kernel message list - for (uint i = 0; i < _messages.size(); ++i) - _messages[i].kernelMsgIndex = -1; -} - -void MadsAnimation::update() { - if (_field12) { - int spriteListIndex = _spriteListIndexes[_spriteListIndex]; - int newIndex = -1; - - for (uint idx = _oldFrameEntry; idx < _frameEntries.size(); ++idx) { - if (_frameEntries[idx].frameNumber > _currentFrame) - break; - if (_frameEntries[idx].spriteSlot.spriteListIndex == spriteListIndex) - newIndex = _frameEntries[idx].spriteSlot.frameNumber; - } - - if (newIndex >= 0) - load1(newIndex); - } - - // Check for scroll change - bool screenChanged = false; - - // Handle any scrolling of the screen surface - if (hasScroll() && (_madsVm->_currentTimer >= _nextScrollTimer)) { - _view->_bgSurface->scrollX(_scrollX); - _view->_bgSurface->scrollY(_scrollY); - - _nextScrollTimer = _madsVm->_currentTimer + _scrollTicks; - screenChanged = true; - } - - // If it's not time for the next frame, then exit - if (_madsVm->_currentTimer < _nextFrameTimer) { - if (screenChanged) - _view->_spriteSlots.fullRefresh(); - return; - } - - // Loop checks for any prior animation sprite slots to be expired - for (int slotIndex = 0; slotIndex < _view->_spriteSlots.startIndex; ++slotIndex) { - if (_view->_spriteSlots[slotIndex].seqIndex >= 0x80) { - // Flag the frame as animation sprite slot - _view->_spriteSlots[slotIndex].spriteType = EXPIRED_SPRITE; - } - } - - // Validate the current frame - if (_currentFrame >= (int)_miscEntries.size()) { - // Is the animation allowed to be repeated? - if (_resetFlag) { - _currentFrame = 0; - _oldFrameEntry = 0; - } else { - _freeFlag = true; - return; - } - } - - // Handle starting any sound for this frame - AnimMiscEntry &misc = _miscEntries[_currentFrame]; - if (misc.soundNum) - _vm->_sound->playSound(misc.soundNum); - - // Handle any offset adjustment for sprites as of this frame - if (_view->_posAdjust.x != misc.posAdjust.x) { - _view->_posAdjust.x = misc.posAdjust.x; - screenChanged = true; - } - if (_view->_posAdjust.y != misc.posAdjust.y) { - _view->_posAdjust.y = misc.posAdjust.y; - screenChanged = true; - } - - - if (screenChanged) { - // Signal the entire screen needs refreshing - _view->_spriteSlots.fullRefresh(); - } - - int spriteSlotsMax = _view->_spriteSlots.startIndex; - - // Main frame animation loop - frames get animated by being placed, as necessary, into the - // main sprite slot array - while ((uint)_oldFrameEntry < _frameEntries.size()) { - if (_frameEntries[_oldFrameEntry].frameNumber > _currentFrame) - break; - else if (_frameEntries[_oldFrameEntry].frameNumber == _currentFrame) { - // Found the correct frame - int spriteSlotIndex = 0; - int index = 0; - - for (;;) { - if ((spriteSlotIndex == 0) && (index < spriteSlotsMax)) { - int seqIndex = _frameEntries[_oldFrameEntry].seqIndex - _view->_spriteSlots[index].seqIndex; - if (seqIndex == 0x80) { - if (_view->_spriteSlots[index] == _frameEntries[_oldFrameEntry].spriteSlot) { - _view->_spriteSlots[index].spriteType = SPRITE_ZERO; - spriteSlotIndex = -1; - } - } - ++index; - continue; - } - - if (spriteSlotIndex == 0) { - int slotIndex = _view->_spriteSlots.getIndex(); - MadsSpriteSlot &slot = _view->_spriteSlots[slotIndex]; - slot.copy(_frameEntries[_oldFrameEntry].spriteSlot); - slot.seqIndex = _frameEntries[_oldFrameEntry].seqIndex + 0x80; - - SpriteAsset &spriteSet = _view->_spriteSlots.getSprite( - _view->_spriteSlots[slotIndex].spriteListIndex); - slot.spriteType = spriteSet.isBackground() ? BACKGROUND_SPRITE : FOREGROUND_SPRITE; - } - break; - } - } - - ++_oldFrameEntry; - } - - // Handle the display of any messages - for (uint idx = 0; idx < _messages.size(); ++idx) { - if (_messages[idx].kernelMsgIndex >= 0) { - // Handle currently active message - if ((_currentFrame < _messages[idx].startFrame) || (_currentFrame > _messages[idx].endFrame)) { - _view->_kernelMessages.remove(_messages[idx].kernelMsgIndex); - _messages[idx].kernelMsgIndex = -1; - --_messageCtr; - } - } else if ((_currentFrame >= _messages[idx].startFrame) && (_currentFrame <= _messages[idx].endFrame)) { - // Start displaying the message - AnimMessage &me = _messages[idx]; - - // The color index to use is dependant on how many messages are currently on-screen - uint8 colIndex; - switch (_messageCtr) { - case 1: - colIndex = 252; - break; - case 2: - colIndex = 16; - break; - default: - colIndex = 250; - break; - } - - _vm->_palette->setEntry(colIndex, me.rgb1.r, me.rgb1.g, me.rgb1.b); - _vm->_palette->setEntry(colIndex + 1, me.rgb2.r, me.rgb2.g, me.rgb2.b); - - // Add a kernel message to display the given text - me.kernelMsgIndex = _view->_kernelMessages.add(me.pos, colIndex * 0x101 + 0x100, 0, 0, INDEFINITE_TIMEOUT, me.msg); - assert(me.kernelMsgIndex >= 0); - - // Play the associated sound, if it exists - if (me.soundId > 0) - _vm->_sound->playDSRSound(me.soundId - 1, 255, false); - ++_messageCtr; - } - } - - // Move to the next frame - _currentFrame++; - if (_currentFrame >= (int)_miscEntries.size()) { - // Animation is complete - if (_abortTimers != 0) { - _view->_abortTimers = _abortTimers; - _view->_abortTimersMode = _abortMode; - - if (_abortMode != ABORTMODE_1) { - // Copy the noun list - if (_madsVm->_scene) - _madsVm->scene()->_action._action = _actionNouns; - } - } - } - - int frameNum = MIN(_currentFrame, (int)_miscEntries.size() - 1); - _nextFrameTimer = _madsVm->_currentTimer + _miscEntries[frameNum].numTicks; -} - -void MadsAnimation::setCurrentFrame(int frameNumber) { - _currentFrame = frameNumber; - _oldFrameEntry = 0; - _freeFlag = false; - - _nextScrollTimer = _nextFrameTimer = _madsVm->_currentTimer; -} - -int MadsAnimation::getCurrentFrame() { - return _currentFrame; -} - -void MadsAnimation::load1(int frameNumber) { - if (_skipLoad) - return; - - Common::Point pt; - int listIndex = _spriteListIndexes[_spriteListIndex]; - SpriteAsset &spriteSet = _view->_spriteSlots.getSprite(listIndex); - - if (_unkIndex < 0) { - M4Surface *frame = spriteSet.getFrame(0); - pt.x = frame->bounds().left; - pt.y = frame->bounds().top; - } else { - pt.x = _unkList[_unkIndex].x; - pt.y = _unkList[_unkIndex].y; - _unkIndex = 1 - _unkIndex; - } - - if (proc1(spriteSet, pt, frameNumber)) - error("proc1 failure"); -} - -bool MadsAnimation::proc1(SpriteAsset &spriteSet, const Common::Point &pt, int frameNumber) { - return 0; -} - -void MadsAnimation::loadInterface(M4Surface *&interfaceSurface, M4Surface *&depthSurface) { - if (_animMode <= 2) { - MadsSceneResources sceneResources; - sceneResources.load(_roomNumber, _interfaceFile.c_str(), 0, depthSurface, interfaceSurface); - - } else if (_animMode == 4) { - // Load a scene interface - interfaceSurface->madsLoadInterface(_interfaceFile); - } else { - // This mode allocates two large surfaces for the animation - // TODO: Are these ever properly freed? -error("Anim mode %d - need to check free logic", _animMode); - assert(!interfaceSurface); - assert(!depthSurface); - depthSurface = new M4Surface(MADS_SURFACE_WIDTH, MADS_SCREEN_HEIGHT); - interfaceSurface = new M4Surface(MADS_SURFACE_WIDTH, MADS_SCREEN_HEIGHT); - depthSurface->clear(); - interfaceSurface->clear(); - } -} - -} // End of namespace M4 |