From 7ca439f410ac1c46a387567b30271ae4e4a2ed30 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sun, 20 Apr 2008 14:47:37 +0000 Subject: Initial import of the work in progress M4 engine svn-id: r31600 --- engines/m4/animation.cpp | 210 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 engines/m4/animation.cpp (limited to 'engines/m4/animation.cpp') diff --git a/engines/m4/animation.cpp b/engines/m4/animation.cpp new file mode 100644 index 0000000000..6c9d90a3d2 --- /dev/null +++ b/engines/m4/animation.cpp @@ -0,0 +1,210 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "m4/assets.h" +#include "m4/animation.h" +#include "m4/compression.h" + +namespace M4 { + +// TODO: this code needs cleanup + +Animation::Animation(M4Engine *vm) { + _vm = vm; + _playing = false; +} + +void Animation::loadFullScreen(const char *filename) { + _vm->_palette->deleteAllRanges(); + load(filename); +} + +void Animation::load(const char *filename) { + MadsPack anim(filename, _vm); + char buffer[20]; + + // Chunk 1: header + // header + // TODO: there are some unknown fields here, plus we don't read + // the entire chunk + Common::SeekableReadStream *animStream = anim.getItemStream(0); + Common::SeekableReadStream *spriteSeriesStream; + //printf("Chunk 0, size %i\n", animStream->size()); + _seriesCount = animStream->readUint16LE(); + _frameCount = animStream->readUint16LE(); + _frameEntryCount = animStream->readUint16LE(); + + // Unknown + for (int i = 0; i < 43; i++) + animStream->readByte(); + + _spriteSeriesNames = new Common::String[_seriesCount]; + printf("%i sprite series\n", _seriesCount); + + // TODO: for now, we only load the first sprite series + if (_seriesCount > 1) + printf("TODO: Anim has %i sprite series, for now, we only load the first one\n", _seriesCount); + _seriesCount = 1; // TODO + + for (int i = 0; i < _seriesCount; i++) { + animStream->read(buffer, 13); + _spriteSeriesNames[i] = Common::String(buffer); + //printf("%03d: %s\n", i, _spriteSeriesNames[i].c_str()); + + spriteSeriesStream = _vm->res()->get(_spriteSeriesNames[i].c_str()); + _spriteSeries = new SpriteAsset(_vm, spriteSeriesStream, + spriteSeriesStream->size(), _spriteSeriesNames[i].c_str()); + _vm->res()->toss(_spriteSeriesNames[i].c_str()); + + // Adjust the palette of the sprites in the sprite series + // so that they can be displayed on screen correctly + RGBList *palData = new RGBList(_spriteSeries->getColorCount(), _spriteSeries->getPalette(), true); + _vm->_palette->addRange(palData); + + for (int k = 0; k < _spriteSeries->getCount(); k++) { + M4Sprite *spr = _spriteSeries->getFrame(k); + spr->translate(palData); // sprite pixel translation + } + } + + //printf("End pos: %i\n", animStream->pos()); + + delete animStream; + + // ------------------ + + // Chunk 2: anim info + AnimationFrame frame; + animStream = anim.getItemStream(1); + //printf("Chunk 1, size %i\n", animStream->size()); + + _frameEntries = new AnimationFrame[_frameEntryCount]; + + for (int i = 0; i < _frameEntryCount; i++) { + + frame.animFrameIndex = animStream->readUint16LE(); + frame.u = animStream->readByte(); + frame.seriesIndex = animStream->readByte(); + frame.seriesFrameIndex = animStream->readUint16LE(); + frame.x = animStream->readUint16LE(); + frame.y = animStream->readUint16LE(); + frame.v = animStream->readByte(); + frame.w = animStream->readByte(); + + _frameEntries[i] = frame; + + /* + printf( + "animFrameIndex = %4d, " + "u = %3d, " + "seriesIndex = %3d, " + "seriesFrameIndex = %6d, " + "x = %3d, " + "y = %3d, " + "v = %3d, " + "w = %3d\n", + + frame.animFrameIndex, + frame.u, + frame.seriesIndex, + frame.seriesFrameIndex, + frame.x, + frame.y, + frame.v, + frame.w + ); + */ + } + //printf("End pos: %i\n", animStream->pos()); + + delete animStream; + + // Chunk 3: unknown (seems to be sound data?) + // TODO +} + +Animation::~Animation() { + //delete[] _spriteSeriesNames; + //delete[] _spriteSeries; + //delete[] _frameEntries; +} + +void Animation::start() { + _curFrame = 0; + _curFrameEntry = 0; + //for (int i = 0; i < _seriesCount; i++) { + //_spriteSeries[i] = new SpriteSeries((char*)_spriteSeriesNames[i].c_str()); + //} + _playing = true; + updateAnim(); +} + +bool Animation::updateAnim() { + if (!_playing) + return true; + + // Get the scene background surface + M4Surface *bg = _vm->_scene->getBackgroundSurface(); + + while (_frameEntries[_curFrameEntry].animFrameIndex == _curFrame) { + AnimationFrame *frame = &_frameEntries[_curFrameEntry]; + int seriesFrameIndex = (frame->seriesFrameIndex & 0x7FFF) - 1; + + // Write the sprite onto the screen + M4Sprite *spr = _spriteSeries->getFrame(seriesFrameIndex); + + // FIXME: We assume that the transparent color is the color of the top left pixel + byte *transparentColor = (byte *)spr->pixels; + + // FIXME: correct x, y + spr->copyTo(bg, frame->x, frame->y, (int)*transparentColor); + + // HACK: wait a bit + g_system->delayMillis(100); + + //printf("_curFrameEntry = %d\n", _curFrameEntry); + _curFrameEntry++; + } + + //printf("_curFrame = %d\n", _curFrame); + + _curFrame++; + if (_curFrame >= _frameCount) // anim done + stop(); + + return _curFrame >= _frameCount; +} + +void Animation::stop() { + _playing = false; + + for (int i = 0; i < _seriesCount; i++) { + // TODO: cleanup + //delete _spriteSeries[i]; + //_spriteSeries[i] = NULL; + } +} + +} // End of namespace M4 -- cgit v1.2.3