mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-27 04:07:05 +00:00
7ca439f410
svn-id: r31600
211 lines
5.5 KiB
C++
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
|