diff options
Diffstat (limited to 'engines/simon')
-rw-r--r-- | engines/simon/animation.cpp | 233 | ||||
-rw-r--r-- | engines/simon/animation.h | 58 | ||||
-rw-r--r-- | engines/simon/items.cpp | 13 | ||||
-rw-r--r-- | engines/simon/module.mk | 1 | ||||
-rw-r--r-- | engines/simon/simon.cpp | 1 | ||||
-rw-r--r-- | engines/simon/simon.h | 1 |
6 files changed, 305 insertions, 2 deletions
diff --git a/engines/simon/animation.cpp b/engines/simon/animation.cpp new file mode 100644 index 0000000000..1cbac3ccc9 --- /dev/null +++ b/engines/simon/animation.cpp @@ -0,0 +1,233 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001-2006 The ScummVM project + * + * 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 "common/stdafx.h" + +#include "common/endian.h" +#include "common/system.h" + +#include "simon/animation.h" + +#ifdef USE_ZLIB +#include <zlib.h> +#endif + +bool DXA_Player::open(const char *filename) { + bool opened = false; + char filename2[100]; + + _leftButtonDown = false; + _rightButtonDown = false; + + // Change file extension to dxa + strcpy(filename2, filename); + int len = strlen(filename2) - 4; + filename2[len++] = '.'; + filename2[len++] = 'd'; + filename2[len++] = 'x'; + filename2[len++] = 'a'; + + if (_fd.open(filename2)) { + uint32 tag = _fd.readUint32BE(); + if (tag == MKID_BE('DEXA')) { + _fd.readByte(); + _framesCount = _fd.readUint16BE(); + _frameTicks = _fd.readUint32BE(); + if (_frameTicks > 100) { + _frameTicks = 100; + } + _width = _fd.readUint16BE(); + _height = _fd.readUint16BE(); + debug(5, "frames_count %d width %d height %d ticks %d", _framesCount, _width, _height, _frameTicks); + _frameSize = _width * _height; + _frameBuffer1 = (uint8 *)malloc(_frameSize); + _frameBuffer2 = (uint8 *)malloc(_frameSize); + if (!_frameBuffer1 || !_frameBuffer2) { + error("error allocating frame tables, size %d\n", _frameSize); + close(); + } else { + tag = _fd.readUint32BE(); + if (tag == MKID_BE('WAVE')) { + uint32 size = _fd.readUint32BE(); + debug(5, "Wave_size = %d", size); + // TODO: Preload wave data + _fd.seek(size + 23); + } + _currentFrame = 0; + opened = true; + } + } + } + return opened; +} + +void DXA_Player::close() { + _fd.close(); + free(_frameBuffer1); + free(_frameBuffer2); +} + +void DXA_Player::play() { + g_system->clearScreen(); + + while (_currentFrame < _framesCount) { + handleNextFrame(); + ++_currentFrame; + } + + g_system->clearScreen(); +} + +void DXA_Player::handleNextFrame() { + uint32 tag = _fd.readUint32BE(); + if (tag == MKID_BE('CMAP')) { + uint8 rgb[768]; + byte palette[1024]; + byte *p = palette; + + _fd.read(rgb, ARRAYSIZE(rgb)); + for (int i = 0; i <= 256; i++) { + *p++ = rgb[i * 3 + 0]; + *p++ = rgb[i * 3 + 1]; + *p++ = rgb[i * 3 + 2]; + *p++ = 0; + } + g_system->setPalette(palette, 0, 256); + } + + tag = _fd.readUint32BE(); + if (tag == MKID_BE('FRAM')) { + uint8 type = _fd.readByte(); + uint32 size = _fd.readUint32BE(); + debug(5, "frame %d type %d size %d", _currentFrame, type, size); + _fd.read(_frameBuffer2, size); + switch (type) { + case 2: + case 3: + decodeZlib(_frameBuffer2, size, _frameSize); + break; + case 4: + case 5: + decode0(_frameBuffer2, size); + break; + case 6: + case 7: + decode2(_frameBuffer2, size, _frameSize); + break; + } + if (type == 2 || type == 4 || type == 6) { + memcpy(_frameBuffer1, _frameBuffer2, _frameSize); + } else { + for (int j = 0; j < _height; ++j) { + for (int i = 0; i < _width; ++i) { + const int offs = j * _width + i; + _frameBuffer1[offs] ^= _frameBuffer2[offs]; + } + } + } + } + + if (_width == 640 && _height == 480) + g_system->copyRectToScreen(_frameBuffer1, _width, 0, 0, _width, _height); + else + g_system->copyRectToScreen(_frameBuffer1, _width, 128, 100, _width, _height); + g_system->updateScreen(); + delay(_frameTicks); +} + +void DXA_Player::decodeZlib(uint8 *data, int size, int totalSize) { +#ifdef USE_ZLIB + uint8 *temp = (uint8 *)malloc(size); + if (temp) { + memcpy(temp, data, size); + z_stream d_stream; + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + d_stream.next_in = temp; + d_stream.avail_in = size; + d_stream.total_in = size; + d_stream.next_out = data; + d_stream.avail_out = totalSize; + inflateInit(&d_stream); + inflate(&d_stream, Z_FINISH); + inflateEnd(&d_stream); + free(temp); + } +#endif +} + +void DXA_Player::decode0(uint8 *data, int size) { + error("decode0"); +} + +void DXA_Player::decode2(uint8 *data, int size, int totalSize) { + error("decode2"); +} + +void DXA_Player::delay(uint amount) { + OSystem::Event event; + + uint32 start = g_system->getMillis(); + uint32 cur = start; + uint this_delay; + + do { + while (g_system->pollEvent(event)) { + switch (event.type) { + case OSystem::EVENT_LBUTTONDOWN: + _leftButtonDown = true; + break; + case OSystem::EVENT_RBUTTONDOWN: + _rightButtonDown = true; + break; + case OSystem::EVENT_LBUTTONUP: + _leftButtonDown = false; + break; + case OSystem::EVENT_RBUTTONUP: + _rightButtonDown = false; + break; + case OSystem::EVENT_QUIT: + g_system->quit(); + break; + default: + break; + } + } + + if (_leftButtonDown && _rightButtonDown) { + _currentFrame = _framesCount; + amount = 0; + } + + if (amount == 0) + break; + + { + this_delay = 20 * 1; + if (this_delay > amount) + this_delay = amount; + g_system->delayMillis(this_delay); + } + cur = g_system->getMillis(); + } while (cur < start + amount); +} diff --git a/engines/simon/animation.h b/engines/simon/animation.h new file mode 100644 index 0000000000..822cd7cc03 --- /dev/null +++ b/engines/simon/animation.h @@ -0,0 +1,58 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001-2006 The ScummVM project + * + * 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$ + * + */ + +#ifndef __DXA_PLAYER_H__ +#define __DXA_PLAYER_H__ + +#include "common/file.h" + +struct DXA_Player { + static const uint32 _tagDEXA; + static const uint32 _tagFRAM; + static const uint32 _tagWAVE; + static const uint32 _tagCMAP; + + bool _playing; + bool _leftButtonDown; + bool _rightButtonDown; + Common::File _fd; + uint8 *_frameBuffer1; + uint8 *_frameBuffer2; + uint16 _width; + uint16 _height; + uint32 _frameSize; + uint16 _framesCount; + uint16 _currentFrame; + uint32 _frameTicks; + + bool open(const char *filename); + void close(); + void play(); + void delay(uint amount); + + void handleNextFrame(); + void decodeZlib(uint8 *data, int size, int totalSize); + void decode0(uint8 *data, int size); + void decode2(uint8 *data, int size, int totalSize); +}; + +#endif // __DXA_PLAYER_H__ diff --git a/engines/simon/items.cpp b/engines/simon/items.cpp index aed8157bad..f93b586cd1 100644 --- a/engines/simon/items.cpp +++ b/engines/simon/items.cpp @@ -23,6 +23,8 @@ // Item script opcodes for Simon1/Simon2 #include "common/stdafx.h" + +#include "simon/animation.h" #include "simon/simon.h" #include "simon/intern.h" @@ -1923,12 +1925,19 @@ void SimonEngine::o3_mouseOff() { void SimonEngine::o3_loadSmack() { // 182: load video file - debug(0,"Load video file: %s", getStringPtrByID(getNextStringID())); + _videoName = getStringPtrByID(getNextStringID()); + debug(0,"Load video file: %s", _videoName); } void SimonEngine::o3_playSmack() { // 183: play video - debug(0, "Play video"); + debug(0, "Play video %s", _videoName); + + DXA_Player p; + if (p.open((const char *)_videoName)) { + p.play(); + p.close(); + } } void SimonEngine::o3_centreScroll() { diff --git a/engines/simon/module.mk b/engines/simon/module.mk index 3af9057f63..b0e88d9257 100644 --- a/engines/simon/module.mk +++ b/engines/simon/module.mk @@ -1,6 +1,7 @@ MODULE := engines/simon MODULE_OBJS := \ + animation.o \ charset.o \ cursor.o \ debug.o \ diff --git a/engines/simon/simon.cpp b/engines/simon/simon.cpp index c7331851d4..a6104c8aa1 100644 --- a/engines/simon/simon.cpp +++ b/engines/simon/simon.cpp @@ -194,6 +194,7 @@ SimonEngine::SimonEngine(OSystem *syst) _tblList = 0; _codePtr = 0; + _videoName = 0; _localStringtable = 0; _stringIdLocalMin = 1; diff --git a/engines/simon/simon.h b/engines/simon/simon.h index 80b5f508bb..3bd8354c6b 100644 --- a/engines/simon/simon.h +++ b/engines/simon/simon.h @@ -207,6 +207,7 @@ protected: byte *_tblList; const byte *_codePtr; + const byte *_videoName; byte **_localStringtable; uint _stringIdLocalMin, _stringIdLocalMax; |