scummvm/engines/m4/animation.cpp
2008-04-20 14:47:37 +00:00

211 lines
5.5 KiB
C++

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