/* 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