aboutsummaryrefslogtreecommitdiff
path: root/scumm/smush
diff options
context:
space:
mode:
authorPaweł Kołodziejski2003-03-17 12:28:50 +0000
committerPaweł Kołodziejski2003-03-17 12:28:50 +0000
commit06ef80fa6170bec33f9ac117400fa86f965c4aa7 (patch)
tree70c978c3f0f8bda24e5f2aae221ac88ac4d2fc2d /scumm/smush
parentee26752d2e83ba3ae0a51a170f39894d8a78a14b (diff)
downloadscummvm-rg350-06ef80fa6170bec33f9ac117400fa86f965c4aa7.tar.gz
scummvm-rg350-06ef80fa6170bec33f9ac117400fa86f965c4aa7.tar.bz2
scummvm-rg350-06ef80fa6170bec33f9ac117400fa86f965c4aa7.zip
reorg/clenup, changed main loop in smush code
svn-id: r6817
Diffstat (limited to 'scumm/smush')
-rw-r--r--scumm/smush/brenderer.cpp77
-rw-r--r--scumm/smush/brenderer.h81
-rw-r--r--scumm/smush/channel.h70
-rw-r--r--scumm/smush/chunk.cpp77
-rw-r--r--scumm/smush/chunk.h72
-rw-r--r--scumm/smush/codec1.cpp29
-rw-r--r--scumm/smush/codec1.h48
-rw-r--r--scumm/smush/codec37.cpp72
-rw-r--r--scumm/smush/codec37.h35
-rw-r--r--scumm/smush/codec44.cpp62
-rw-r--r--scumm/smush/codec44.h34
-rw-r--r--scumm/smush/codec47.cpp69
-rw-r--r--scumm/smush/codec47.h27
-rw-r--r--scumm/smush/color.cpp37
-rw-r--r--scumm/smush/color.h55
-rw-r--r--scumm/smush/decoder.h51
-rw-r--r--scumm/smush/frenderer.cpp399
-rw-r--r--scumm/smush/frenderer.h165
-rw-r--r--scumm/smush/imuse_channel.cpp18
-rw-r--r--scumm/smush/mixer.h58
-rw-r--r--scumm/smush/palette.h57
-rw-r--r--scumm/smush/player.h109
-rw-r--r--scumm/smush/renderer.h125
-rw-r--r--scumm/smush/saud_channel.cpp52
-rw-r--r--scumm/smush/scumm_renderer.cpp320
-rw-r--r--scumm/smush/scumm_renderer.h65
-rw-r--r--scumm/smush/smush_font.cpp489
-rw-r--r--scumm/smush/smush_font.h67
-rw-r--r--scumm/smush/smush_mixer.cpp166
-rw-r--r--scumm/smush/smush_mixer.h (renamed from scumm/smush/config.h)42
-rw-r--r--scumm/smush/smush_player.cpp (renamed from scumm/smush/player.cpp)827
-rw-r--r--scumm/smush/smush_player.h105
32 files changed, 1482 insertions, 2478 deletions
diff --git a/scumm/smush/brenderer.cpp b/scumm/smush/brenderer.cpp
deleted file mode 100644
index 45bd5be167..0000000000
--- a/scumm/smush/brenderer.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#include <stdafx.h>
-#include "brenderer.h"
-
-#include "common/engine.h" // for debug, warning, error
-
-#include <assert.h>
-
-void BaseRenderer::clean() {
- if(_data) {
- delete[] _data;
- _data = 0;
- _width = _height = 0;
- }
-}
-
-BaseRenderer::BaseRenderer() :
- _data(0),
- _frame(0),
- _nbframes(0),
- _width(0),
- _height(0) {
-}
-
-BaseRenderer::~BaseRenderer() {
- clean();
-}
-
-bool BaseRenderer::initFrame(const Point &p) {
- clean();
- _width = p.getX();
- _height = p.getY();
- assert(_width && _height);
- _data = new byte[_width * _height];
- if(!_data) error("base_renderer unable to allocate frame buffer");
- return true;
-}
-
-byte *BaseRenderer::lockFrame(int32 frame) {
- _frame = frame;
- if(!_data) error("no allocated image buffer in lock_frame");
- return _data;
-}
-
-bool BaseRenderer::unlockFrame() {
- return true;
-}
-
-bool BaseRenderer::flipFrame() {
- save();
- return true;
-}
-
-bool BaseRenderer::setPalette(const Palette & pal) {
- _pal = pal;
- return true;
-}
diff --git a/scumm/smush/brenderer.h b/scumm/smush/brenderer.h
deleted file mode 100644
index 9fd616552e..0000000000
--- a/scumm/smush/brenderer.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#ifndef BRENDERER_H
-#define BRENDERER_H
-
-#include "config.h"
-
-#include "renderer.h"
-#include "palette.h"
-
-/*! @brief base class for easily creating ::renderer instances
-
- This class implements some function available in the ::renderer abstract class, so that
- creation of subclasses of ::renderer is easier.
-*/
-class BaseRenderer : public Renderer {
-protected:
- Palette _pal; //!< The current palette
- byte *_data; //!< The current frame buffer
- int32 _frame; //!< The current frame number
- int32 _nbframes; //!< The number of frames in the animation
- int32 _width; //!< The current frame's width
- int32 _height; //!< The current frame's height
- const char *_fname; //!< The filename of the animation being played
-protected:
- virtual void save() = 0;
-
-protected:
- const char *getFilename() const { return _fname; }; //!< accessor for animation filename
- int32 getNbframes() const { return _nbframes; }; //!< accessor for number of frames
- void clean(); //!< memory cleanup (deletes frame buffer)
- void setFrame(int32 f) { _frame = f; }; //!< allows to change the frame number
-public:
- int32 getFrame() const { return _frame; }; //!< accessor for current frame number
- BaseRenderer();
- virtual ~BaseRenderer();
-
- virtual bool initFrame(const Point &size);
- virtual byte *lockFrame(int32 frame);
- virtual bool unlockFrame();
- virtual bool flipFrame();
- virtual bool setPalette(const Palette &pal);
- virtual bool startDecode(const char *fname, int32 version, int32 nbframes) { _fname = fname; _nbframes = nbframes; return true; }
- virtual Mixer *getMixer() { return 0; };
- virtual bool prematureClose() { return false; };
-};
-
-/*! @brief A null ::renderer
-
- This class completely implements ::renderer, without actually doing anything.
- This class is useful for performance measurements.
-*/
-class NullRenderer : public BaseRenderer {
-protected:
- void save() {};
-public:
- NullRenderer() {};
- virtual ~NullRenderer() {};
- bool wait(int32 ms) { return true; };
-};
-
-#endif
diff --git a/scumm/smush/channel.h b/scumm/smush/channel.h
index 03b93280ee..c0ce8ca7fb 100644
--- a/scumm/smush/channel.h
+++ b/scumm/smush/channel.h
@@ -19,63 +19,47 @@
*
*/
-#ifndef CHANNEL_H
-#define CHANNEL_H
+#ifndef SMUSH_CHANNEL_H
+#define SMUSH_CHANNEL_H
-#include "config.h"
-#include "common/engine.h" // for debug, warning, error
-
-#ifdef DEBUG
-# ifndef NO_DEBUG_CHANNEL
-# define DEBUG_CHANNEL
-# endif
-#else
-# ifdef DEBUG_CHANNEL
-# error DEBUG_CHANNEL defined without DEBUG
-# endif
-#endif
+#include "common/engine.h"
class Chunk;
class ContChunk;
-/*! @brief int32erface for a sound channel (a track)
-
- This is the int32erface for sound channels.
-*/
-class _Channel {
+class SmushChannel {
public:
- virtual ~_Channel() {};
- // called by the smush_player
+
+ virtual ~SmushChannel() {};
virtual bool appendData(Chunk &b, int32 size) = 0;
virtual bool setParameters(int32, int32, int32, int32) = 0;
virtual bool checkParameters(int32, int32, int32, int32, int32) = 0;
- // called by the mixer
virtual bool isTerminated() const = 0;
virtual int32 availableSoundData() const = 0;
- virtual void getSoundData(int16 *sound_buffer, int32 size) = 0; // size is in sample
+ virtual void getSoundData(int16 *sound_buffer, int32 size) = 0;
virtual void getSoundData(int8 *sound_buffer, int32 size) = 0;
virtual int32 getRate() = 0;
virtual bool getParameters(int32 &rate, bool &stereo, bool &is_16bit) = 0;
virtual int32 getTrackIdentifier() const = 0;
};
-class SaudChannel : public _Channel {
+class SaudChannel : public SmushChannel {
private:
- int32 _track; //!< The track identifier
- int32 _nbframes; //!< number of frames of the track (unused)
- int32 _dataSize; //!< the size of the sound buffer
- int32 _frequency; //!< the frequency target of the track (always 22050)
- bool _inData; //!< are we processing data ?
- bool _markReached; //!< set to \c true when the SMRK tag is reached
- int32 _flags; //!< current flags of the track (unused)
- int32 _volume; //!< the current track volume
- int32 _balance; //!< the current track balance
- int32 _index; //!< the current PSAD index (for coherency checking)
- int16 _voltable[2][256]; //!< the precalculated volume table (stereo 16 bits)
- byte *_tbuffer; //!< data temporary buffer
- int32 _tbufferSize; //!< temporary buffer size
- byte *_sbuffer; //!< sound buffer
- int32 _sbufferSize; //!< sound buffer size
+ int32 _track;
+ int32 _nbframes;
+ int32 _dataSize;
+ int32 _frequency;
+ bool _inData;
+ bool _markReached;
+ int32 _flags;
+ int32 _volume;
+ int32 _balance;
+ int32 _index;
+ int16 _voltable[2][256];
+ byte *_tbuffer;
+ int32 _tbufferSize;
+ byte *_sbuffer;
+ int32 _sbufferSize;
protected:
void handleStrk(Chunk &c);
@@ -105,13 +89,7 @@ public:
virtual int32 getTrackIdentifier() const { return _track; };
};
-/*! @brief class for a IACT sound ::channel (a The Dig track)
-
- This class implements a channel specifically for The Dig.
-
- \bug for unknown reason, some sound have a too long duration, or repeat themselves.
-*/
-class ImuseChannel : public _Channel {
+class ImuseChannel : public SmushChannel {
private:
int32 _track; //!< the track number
byte *_tbuffer; //!< data temporary buffer
diff --git a/scumm/smush/chunk.cpp b/scumm/smush/chunk.cpp
index f35e91fffa..0f3bfbf734 100644
--- a/scumm/smush/chunk.cpp
+++ b/scumm/smush/chunk.cpp
@@ -22,35 +22,34 @@
#include <stdafx.h>
#include "chunk.h"
-#include "common/engine.h" // for debug, warning, error
+#include "common/engine.h"
#include "common/file.h"
#include "common/str.h"
-#include <stdio.h> // for FILE, fopen, fclose, fseek and ftell
-#include <string.h> // for memcpy
-
-/*! @brief very small and fast wrapper for a ifstream.
-
- implements reference counting, so that ::file_Chunk does not leak memory !
-*/
class FilePtr {
ScummVM::String _filename;
File _ifs;
int32 _refcount;
int32 _curPos;
public:
- FilePtr(const char *fname, const char *directory) : _filename(fname), _refcount(1), _curPos(0) {
- debug(9, "FilePtr created for %s", fname);
- _ifs.open(fname, directory);
- if(_ifs.isOpen() == false) error("FilePtr unable to read file %s", fname);
- }
+ FilePtr(const char *fname, const char *directory) :
+ _filename(fname),
+ _refcount(1),
+ _curPos(0) {
+ debug(9, "FilePtr created for %s", fname);
+ _ifs.open(fname, directory);
+ if(_ifs.isOpen() == false) error("FilePtr unable to read file %s", fname);
+ }
+
~FilePtr() {
debug(9, "FilePtr destroyed for %s", _filename.c_str());
_ifs.close();
}
+
int32 tell() {
return _curPos;
}
+
bool seek(int32 pos) {
if(pos != _curPos) {
_ifs.seek(pos, SEEK_SET);
@@ -58,14 +57,17 @@ public:
}
return true;
}
+
bool read(void *ptr, int32 size) {
_ifs.read(ptr, size);
_curPos += size;
return true;
}
+
void incRef() {
_refcount++;
}
+
void decRef() {
if(--_refcount == 0)
delete this;
@@ -82,11 +84,16 @@ const char *Chunk::ChunkString(Chunk::type t) {
return data;
}
-FileChunk::FileChunk() : _data(0), _type(0), _size(0), _curPos(0) {
+FileChunk::FileChunk() :
+ _data(0),
+ _type(0),
+ _size(0),
+ _curPos(0) {
}
FileChunk::~FileChunk() {
- if(_data) _data->decRef();
+ if(_data)
+ _data->decRef();
}
FileChunk::FileChunk(const char *fname, const char *directory) {
@@ -137,11 +144,15 @@ bool FileChunk::seek(int32 delta, seek_type dir) {
_curPos += delta;
break;
case seek_start:
- if(delta < 0) error("invalid seek request");
+ if(delta < 0)
+ error("invalid seek request");
+
_curPos = (uint32)delta;
break;
case seek_end:
- if(delta > 0 || (_size + delta) < 0) error("invalid seek request");
+ if(delta > 0 || (_size + delta) < 0)
+ error("invalid seek request");
+
_curPos = (uint32)(_size + delta);
break;
}
@@ -154,6 +165,7 @@ bool FileChunk::seek(int32 delta, seek_type dir) {
bool FileChunk::read(void *buffer, uint32 size) {
if(size <= 0 || (_curPos + size) > _size)
error("invalid buffer read request");
+
_data->seek(_offset + _curPos);
_data->read(buffer, size);
_curPos += size;
@@ -163,6 +175,7 @@ bool FileChunk::read(void *buffer, uint32 size) {
int8 FileChunk::getChar() {
if(_curPos >= _size)
error("invalid char read request");
+
_data->seek(_offset + _curPos);
int8 buffer;
_data->read(&buffer, sizeof(buffer));
@@ -173,6 +186,7 @@ int8 FileChunk::getChar() {
byte FileChunk::getByte() {
if(_curPos >= _size)
error("invalid byte read request");
+
_data->seek(_offset + _curPos);
byte buffer;
_data->read(&buffer, sizeof(buffer));
@@ -188,6 +202,7 @@ int16 FileChunk::getShort() {
uint16 FileChunk::getWord() {
if(_curPos >= _size - 1)
error("invalid word read request");
+
_data->seek(_offset + _curPos);
uint16 buffer;
_data->read(&buffer, sizeof(buffer));
@@ -198,6 +213,7 @@ uint16 FileChunk::getWord() {
uint32 FileChunk::getDword() {
if(_curPos >= _size - 3)
error("invalid dword read request");
+
_data->seek(_offset + _curPos);
uint32 buffer;
_data->read(&buffer, sizeof(buffer));
@@ -207,7 +223,8 @@ uint32 FileChunk::getDword() {
ContChunk::ContChunk(byte *data) {
if(data == 0)
- error("Chunk() called with NULL point32er");
+ error("Chunk() called with NULL pointer");
+
_type = (Chunk::type)READ_BE_UINT32(data);
_size = READ_BE_UINT32(data + 4);
_data = data + sizeof(Chunk::type) + sizeof(uint32);
@@ -257,39 +274,51 @@ bool ContChunk::seek(int32 delta, seek_type dir) {
}
bool ContChunk::read(void *buffer, uint32 size) {
- if(size <= 0 || (_curPos + size) > _size) error("invalid buffer read request");
+ if(size <= 0 || (_curPos + size) > _size)
+ error("invalid buffer read request");
+
memcpy(buffer, _data + _curPos, size);
_curPos += size;
return true;
}
int8 ContChunk::getChar() {
- if(_curPos >= _size) error("invalid char read request");
+ if(_curPos >= _size)
+ error("invalid char read request");
+
return _data[_curPos++];
}
byte ContChunk::getByte() {
- if(_curPos >= _size) error("invalid byte read request");
+ if(_curPos >= _size)
+ error("invalid byte read request");
+
byte *ptr = (byte *)(_data + _curPos);
_curPos += 1;
return *ptr;
}
int16 ContChunk::getShort() {
- if(_curPos >= _size - 1) error("invalid int16 read request");
+ if(_curPos >= _size - 1)
+ error("invalid int16 read request");
+
int16 buffer = getWord();
return *((int16 *)&buffer);
}
uint16 ContChunk::getWord() {
- if(_curPos >= _size - 1) error("invalid word read request");
+ if(_curPos >= _size - 1)
+ error("invalid word read request");
+
uint16 *ptr = (uint16 *)(_data + _curPos);
_curPos += 2;
return READ_LE_UINT16(ptr);
}
uint32 ContChunk::getDword() {
- if(_curPos >= _size - 3) error("invalid dword read request");
+ if(_curPos >= _size - 3)
+ error("invalid dword read request");
+
uint32 *ptr = (uint32 *)(_data + _curPos);
_curPos += 4;
return READ_LE_UINT32(ptr);
diff --git a/scumm/smush/chunk.h b/scumm/smush/chunk.h
index 44a9150392..0549c88716 100644
--- a/scumm/smush/chunk.h
+++ b/scumm/smush/chunk.h
@@ -22,69 +22,54 @@
#ifndef CHUNK_H
#define CHUNK_H
-#include "config.h"
+#include "common/scummsys.h"
-/*! @brief Interface for Chunk handling
-
- This class is an interface for reading from a Chunk.
-
- \todo handle big endian system.
-*/
class Chunk {
public:
- enum seek_type { seek_start, seek_end, seek_cur };
+
virtual ~Chunk() {};
- typedef uint32 type; //!< type of a Chunk (i.e. The first 4byte field of the Chunk structure).
- /*! @brief convert a type to a string
-
- Utility function that convert a type to a string.
-
- @param t the type to convert to a string
-
- @return the converted string
- */
- static const char * ChunkString(type t);
-
- virtual type getType() const = 0; //!< return the type of the Chunk
- virtual uint32 getSize() const = 0; //!< return the size of the Chunk
- virtual Chunk * subBlock() = 0; //!< extract a subChunk from the current read position
- virtual bool eof() const = 0; //!< is the Chunk completely read ?
- virtual uint32 tell() const = 0; //!< get the Chunk current read position
- virtual bool seek(int32 delta, seek_type dir = seek_cur) = 0; //!< move the current read position inside the Chunk
- virtual bool read(void * buffer, uint32 size) = 0; //!< read some data for the current read position
- virtual int8 getChar() = 0; //!< extract the character at the current read position
- virtual byte getByte() = 0; //!< extract the byte at the current read position
- virtual int16 getShort() = 0; //!< extract the short at the current read position
- virtual uint16 getWord() = 0; //!< extract the word at the current read position
- virtual uint32 getDword()= 0; //!< extract the dword at the current read position
+ enum seek_type { seek_start, seek_end, seek_cur };
+ typedef uint32 type;
+ static const char *ChunkString(type t);
+ virtual type getType() const = 0;
+ virtual uint32 getSize() const = 0;
+ virtual Chunk *subBlock() = 0;
+ virtual bool eof() const = 0;
+ virtual uint32 tell() const = 0;
+ virtual bool seek(int32 delta, seek_type dir = seek_cur) = 0;
+ virtual bool read(void *buffer, uint32 size) = 0;
+ virtual int8 getChar() = 0;
+ virtual byte getByte() = 0;
+ virtual int16 getShort() = 0;
+ virtual uint16 getWord() = 0;
+ virtual uint32 getDword()= 0;
};
class FilePtr;
-/*! @brief file based ::Chunk
-
- This class is an implementation of ::Chunk that handles file.
-
-*/
class FileChunk : public Chunk {
private:
- FilePtr * _data;
+ FilePtr *_data;
type _type;
uint32 _size;
uint32 _offset;
uint32 _curPos;
+
protected:
+
FileChunk();
+
public:
- FileChunk(const char * fname, const char * directory);
+
+ FileChunk(const char *fname, const char *directory);
virtual ~FileChunk();
type getType() const;
uint32 getSize() const;
- Chunk * subBlock();
+ Chunk *subBlock();
bool eof() const;
uint32 tell() const;
bool seek(int32 delta, seek_type dir = seek_cur);
- bool read(void * buffer, uint32 size);
+ bool read(void *buffer, uint32 size);
int8 getChar();
byte getByte();
short getShort();
@@ -92,17 +77,16 @@ public:
uint32 getDword();
};
-/*! @brief memory based ::Chunk
-
- This class is an implementation of ::Chunk that handles a memory buffer.
-*/
class ContChunk : public Chunk {
private:
+
byte *_data;
Chunk::type _type;
uint32 _size;
uint32 _curPos;
+
public:
+
ContChunk(byte *data);
Chunk::type getType() const;
uint32 getSize() const;
diff --git a/scumm/smush/codec1.cpp b/scumm/smush/codec1.cpp
index 589ec2ee51..673a9c1d0e 100644
--- a/scumm/smush/codec1.cpp
+++ b/scumm/smush/codec1.cpp
@@ -20,44 +20,28 @@
*/
#include <stdafx.h>
-#include "codec1.h"
+#include "common/scummsys.h"
-Codec1Decoder::~Codec1Decoder() {
-}
-
-bool Codec1Decoder::decode(byte *dst, const byte *src, int) {
- byte val;
- int32 size_line;
- int32 code, length;
- int32 h, height = getRect().height();
+void smush_decode_codec1(byte *dst, byte *src, int height) {
+ byte val, code;
+ int32 length;
+ int h = height, size_line;
for(h = 0; h < height; h++) {
- size_line = READ_LE_UINT16(src); // size of compressed line !
+ size_line = READ_LE_UINT16(src);
src += 2;
-#ifdef DEBUG_CODEC1
- debug(7, "codec1 : h == %d, size_line == %d", h, size_line);
-#endif
while(size_line > 0) {
code = *src++;
size_line--;
length = (code >> 1) + 1;
-#ifdef DEBUG_CODEC1
- debug(7, "codec1 : length == %d", length);
-#endif
if(code & 1) {
val = *src++;
size_line--;
if (val)
memset(dst, val, length);
dst += length;
-#ifdef DEBUG_CODEC1
- debug(7, "codec1 : blitting %d times %d", length, val);
-#endif
} else {
size_line -= length;
-#ifdef DEBUG_CODEC1
- debug(7, "codec1 : blitting %d entries", length);
-#endif
while(length--) {
val = *src++;
if (val)
@@ -67,5 +51,4 @@ bool Codec1Decoder::decode(byte *dst, const byte *src, int) {
}
}
}
- return true;
}
diff --git a/scumm/smush/codec1.h b/scumm/smush/codec1.h
deleted file mode 100644
index ee2b806868..0000000000
--- a/scumm/smush/codec1.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#ifndef CODEC1_H
-#define CODEC1_H
-
-#include "config.h"
-
-#ifdef DEBUG
-# ifndef NO_DEBUG_CODEC1
-# define DEBUG_CODEC1
-# endif
-#else
-# ifdef DEBUG_CODEC1
-# error DEBUG_CODEC1 defined without DEBUG
-# endif
-#endif
-
-#include "decoder.h"
-
-/*! @brief ::decoder for codec 1 and 3.
-
-*/
-class Codec1Decoder : public Decoder {
-public:
- virtual ~Codec1Decoder();
- bool decode(byte *dst, const byte *src, int length);
-};
-
-#endif
diff --git a/scumm/smush/codec37.cpp b/scumm/smush/codec37.cpp
index 03a23410e2..a2087c4b51 100644
--- a/scumm/smush/codec37.cpp
+++ b/scumm/smush/codec37.cpp
@@ -24,35 +24,24 @@
#include "common/engine.h"
-#include <assert.h>
-#include <string.h>
-
-bool Codec37Decoder::initSize(const Point &p, const Rect &r) {
- if(r.width() != getRect().width() && r.height() != getRect().height()) {
- if(
- (r.width() != 320 || r.height() != 200) &&
- (r.width() != 384 || r.height() != 242) &&
- (r.width() != 640 || r.height() != 480)
- )
- return false;
- Decoder::initSize(p, r);
- clean();
- int32 frame_size = getRect().width() * getRect().height();
- _deltaSize = frame_size * 3 + 0x13600;
- _deltaBuf = new byte[_deltaSize];
- memset(_deltaBuf, 0, _deltaSize);
- if(_deltaBuf == 0) error("unable to allocate decoder buffer");
- _deltaBufs[0] = _deltaBuf + 0x4D80;
- _deltaBufs[1] = _deltaBuf + 0xE880 + frame_size;
- _offsetTable = new int16[255];
- _curtable = 0;
- if(_offsetTable == 0)
- error("unable to allocate decoder offset table");
- _tableLastPitch = -1;
- _tableLastIndex = -1;
- return true;
- }
- return false;
+void Codec37Decoder::init(int width, int height) {
+ deinit();
+ _width = width;
+ _height = height;
+ _frameSize = _width * _height;
+ _deltaSize = _frameSize * 3 + 0x13600;
+ _deltaBuf = new byte[_deltaSize];
+ memset(_deltaBuf, 0, _deltaSize);
+ if(_deltaBuf == 0)
+ error("unable to allocate decoder buffer");
+ _deltaBufs[0] = _deltaBuf + 0x4D80;
+ _deltaBufs[1] = _deltaBuf + 0xE880 + _frameSize;
+ _offsetTable = new int16[255];
+ _curtable = 0;
+ if(_offsetTable == 0)
+ error("unable to allocate decoder offset table");
+ _tableLastPitch = -1;
+ _tableLastIndex = -1;
}
Codec37Decoder::Codec37Decoder() {
@@ -67,7 +56,7 @@ Codec37Decoder::Codec37Decoder() {
_prevSeqNb = 0;
}
-void Codec37Decoder::clean() {
+void Codec37Decoder::deinit() {
if(_offsetTable) {
delete []_offsetTable;
_offsetTable = 0;
@@ -84,10 +73,10 @@ void Codec37Decoder::clean() {
}
Codec37Decoder::~Codec37Decoder() {
- clean();
+ deinit();
}
-void Codec37Decoder::maketable(int32 pitch, int32 index) {
+void Codec37Decoder::maketable(int pitch, int index) {
static const int8 maketable_bytes[] = {
0, 0, 1, 0, 2, 0, 3, 0, 5, 0,
8, 0, 13, 0, 21, 0, -1, 0, -2, 0,
@@ -246,6 +235,7 @@ void Codec37Decoder::maketable(int32 pitch, int32 index) {
if (_tableLastPitch == pitch && _tableLastIndex == index)
return;
+
_tableLastPitch = pitch;
_tableLastIndex = index;
index *= 255;
@@ -368,7 +358,7 @@ void Codec37Decoder::bompDecode(byte *dst, const byte *src, int len) {
dst += 4; \
} while(0)
-void Codec37Decoder::proc3WithFDFE(byte *dst, const byte *src, int32 next_offs, int32 bw, int32 bh, int32 pitch, int16 *offset_table) {
+void Codec37Decoder::proc3WithFDFE(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
do {
int32 i = bw;
do {
@@ -388,7 +378,7 @@ void Codec37Decoder::proc3WithFDFE(byte *dst, const byte *src, int32 next_offs,
} while (--bh);
}
-void Codec37Decoder::proc3WithoutFDFE(byte *dst, const byte *src, int32 next_offs, int32 bw, int32 bh, int32 pitch, int16 *offset_table) {
+void Codec37Decoder::proc3WithoutFDFE(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
do {
int32 i = bw;
do {
@@ -404,7 +394,7 @@ void Codec37Decoder::proc3WithoutFDFE(byte *dst, const byte *src, int32 next_off
} while (--bh);
}
-void Codec37Decoder::proc4WithFDFE(byte *dst, const byte *src, int32 next_offs, int32 bw, int32 bh, int32 pitch, int16 *offset_table) {
+void Codec37Decoder::proc4WithFDFE(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
do {
int32 i = bw;
do {
@@ -440,7 +430,7 @@ void Codec37Decoder::proc4WithFDFE(byte *dst, const byte *src, int32 next_offs,
} while (--bh);
}
-void Codec37Decoder::proc4WithoutFDFE(byte *dst, const byte *src, int32 next_offs, int32 bw, int32 bh, int32 pitch, int16 *offset_table) {
+void Codec37Decoder::proc4WithoutFDFE(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
do {
int32 i = bw;
do {
@@ -472,10 +462,8 @@ void Codec37Decoder::proc4WithoutFDFE(byte *dst, const byte *src, int32 next_off
} while (--bh);
}
-bool Codec37Decoder::decode(byte *dst, const byte *src, int length) {
- int32 width = getRect().width();
- int32 height = getRect().height();
- int32 bw = (width + 3) >> 2, bh = (height + 3) >> 2;
+void Codec37Decoder::decode(byte *dst, const byte *src) {
+ int32 bw = (_width + 3) >> 2, bh = (_height + 3) >> 2;
int32 pitch = bw << 2;
int16 seq_nb = READ_LE_UINT16(src + 2);
@@ -543,8 +531,6 @@ bool Codec37Decoder::decode(byte *dst, const byte *src, int length) {
}
_prevSeqNb = seq_nb;
- memcpy(dst, _deltaBufs[_curtable], width * height);
-
- return true;
+ memcpy(dst, _deltaBufs[_curtable], _frameSize);
}
diff --git a/scumm/smush/codec37.h b/scumm/smush/codec37.h
index 0773f50f22..52f4504665 100644
--- a/scumm/smush/codec37.h
+++ b/scumm/smush/codec37.h
@@ -19,36 +19,39 @@
*
*/
-#ifndef CODEC37_H
-#define CODEC37_H
+#ifndef SMUSH_CODEC37_H
+#define SMUSH_CODEC37_H
-#include "decoder.h"
+#include "common/scummsys.h"
-class Codec37Decoder : public Decoder {
+class Codec37Decoder {
private:
+
int32 _deltaSize;
byte *_deltaBufs[2];
byte *_deltaBuf;
int16 *_offsetTable;
- int32 _curtable;
+ int _curtable;
uint16 _prevSeqNb;
- int32 _tableLastPitch;
- int32 _tableLastIndex;
+ int _tableLastPitch;
+ int _tableLastIndex;
+ int32 _frameSize;
+ int _width, _height;
public:
- bool initSize(const Point &, const Rect &);
Codec37Decoder();
- void clean();
- virtual ~Codec37Decoder();
+ ~Codec37Decoder();
+ void init(int width, int height);
+ void deinit();
protected:
- void maketable(int32, int32);
+ void maketable(int, int);
void bompDecode(byte *dst, const byte *src, int len);
- void proc3WithFDFE(byte *dst, const byte *src, int32, int32, int32, int32, int16 *);
- void proc3WithoutFDFE(byte *dst, const byte *src, int32, int32, int32, int32, int16 *);
- void proc4WithFDFE(byte *dst, const byte *src, int32, int32, int32, int32, int16 *);
- void proc4WithoutFDFE(byte *dst, const byte *src, int32, int32, int32, int32, int16 *);
+ void proc3WithFDFE(byte *dst, const byte *src, int32, int, int, int, int16 *);
+ void proc3WithoutFDFE(byte *dst, const byte *src, int32, int, int, int, int16 *);
+ void proc4WithFDFE(byte *dst, const byte *src, int32, int, int, int, int16 *);
+ void proc4WithoutFDFE(byte *dst, const byte *src, int32, int, int, int, int16 *);
public:
- bool decode(byte *dst, const byte *src, int length);
+ void decode(byte *dst, const byte *src);
};
#endif
diff --git a/scumm/smush/codec44.cpp b/scumm/smush/codec44.cpp
deleted file mode 100644
index dae835bb55..0000000000
--- a/scumm/smush/codec44.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#include <stdafx.h>
-#include "codec44.h"
-
-bool Codec44Decoder::decode(byte *dst, const byte *src, int length) {
- int32 size_line, num;
- int32 width = getRect().width();
- int32 height = getRect().height();
- const byte *src2 = src;
- byte *dst2 = _buffer;
- byte val;
-
- do {
- size_line = READ_LE_UINT16(src2);
- src2 += 2;
- length -= 2;
-
- while (size_line != 0) {
- num = *src2++;
- val = *src2++;
- memset(dst2, val, num);
- dst2 += num;
- length -= 2;
- size_line -= 2;
- if (size_line != 0) {
- num = READ_LE_UINT16(src2) + 1;
- src2 += 2;
- memcpy(dst2, src2, num);
- dst2 += num;
- src2 += num;
- length -= num + 2;
- size_line -= num + 2;
- }
- }
- dst2--;
-
- } while (length > 1);
-
- memcpy(dst, _buffer, width * height);
-
- return true;
-}
diff --git a/scumm/smush/codec44.h b/scumm/smush/codec44.h
deleted file mode 100644
index b4ecd7fbc1..0000000000
--- a/scumm/smush/codec44.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#ifndef CODEC44_H
-#define CODEC44_H
-
-#include "decoder.h"
-
-class Codec44Decoder : public Decoder {
- byte _buffer[1000];
-
-public:
- bool decode(byte *dst, const byte *src, int length);
-};
-
-#endif
diff --git a/scumm/smush/codec47.cpp b/scumm/smush/codec47.cpp
index 30983412c3..a7a98b7289 100644
--- a/scumm/smush/codec47.cpp
+++ b/scumm/smush/codec47.cpp
@@ -601,16 +601,16 @@ void Codec47Decoder::level1(byte *d_dst) {
}
}
-void Codec47Decoder::decode2(byte *dst, const byte *src, int32 width, int32 height, const byte *param_ptr) {
+void Codec47Decoder::decode2(byte *dst, const byte *src, int width, int height, const byte *param_ptr) {
_d_src = src;
_paramPtr = param_ptr - 0xf8;
- int32 bw = (width + 7) >> 3;
- int32 bh = (height + 7) >> 3;
- int32 next_line = width * 7;
+ int bw = (width + 7) >> 3;
+ int bh = (height + 7) >> 3;
+ int next_line = width * 7;
_d_pitch = width;
do {
- int32 tmp_bw = bw;
+ int tmp_bw = bw;
do {
level1(dst);
dst += 8;
@@ -619,35 +619,26 @@ void Codec47Decoder::decode2(byte *dst, const byte *src, int32 width, int32 heig
} while (--bh);
}
-bool Codec47Decoder::initSize(const Point &p, const Rect &r) {
- if(r.width() != getRect().width() && r.height() != getRect().height()) {
- if(
- (r.width() != 640 || r.height() != 480)
- )
- return false;
- Decoder::initSize(p, r);
- clean();
-
- makeTables37(4);
- makeTables37(8);
-
- int32 frame_size = getRect().width() * getRect().height();
- _deltaSize = frame_size * 3;
- _deltaBuf = new byte[_deltaSize];
- _deltaBufs[0] = _deltaBuf;
- _deltaBufs[1] = _deltaBuf + frame_size;
- _curBuf = _deltaBuf + frame_size * 2;
-
- return true;
- }
- return false;
+void Codec47Decoder::init(int width, int height) {
+ deinit();
+ _width = width;
+ _height = height;
+ makeTables37(4);
+ makeTables37(8);
+
+ _frameSize = _width * _height;
+ _deltaSize = _frameSize * 3;
+ _deltaBuf = new byte[_deltaSize];
+ _deltaBufs[0] = _deltaBuf;
+ _deltaBufs[1] = _deltaBuf + _frameSize;
+ _curBuf = _deltaBuf + _frameSize * 2;
}
Codec47Decoder::Codec47Decoder() {
_deltaBuf = 0;
}
-void Codec47Decoder::clean() {
+void Codec47Decoder::deinit() {
_lastTableWidth = -1;
if(_deltaBuf) {
delete []_deltaBuf;
@@ -659,12 +650,10 @@ void Codec47Decoder::clean() {
}
Codec47Decoder::~Codec47Decoder() {
- clean();
+ deinit();
}
-bool Codec47Decoder::decode(byte *dst, const byte *src, int length) {
- int32 width = getRect().width();
- int32 height = getRect().height();
+bool Codec47Decoder::decode(byte *dst, const byte *src) {
_offset1 = _deltaBufs[1] - _curBuf;
_offset2 = _deltaBufs[0] - _curBuf;
@@ -674,9 +663,9 @@ bool Codec47Decoder::decode(byte *dst, const byte *src, int length) {
byte *tmp_ptr;
if (seq_nb == 0) {
- makeTables47(width);
- memset(_deltaBufs[0], src[12], width * height);
- memset(_deltaBufs[1], src[13], width * height);
+ makeTables47(_width);
+ memset(_deltaBufs[0], src[12], _frameSize);
+ memset(_deltaBufs[1], src[13], _frameSize);
_prevSeqNb = -1;
}
@@ -686,28 +675,28 @@ bool Codec47Decoder::decode(byte *dst, const byte *src, int length) {
switch(src[2]) {
case 0:
- memcpy(_curBuf, gfx_data, width * height);
+ memcpy(_curBuf, gfx_data, _frameSize);
break;
case 1:
warning("codec47: not implemented decode1 proc");
break;
case 2:
if (seq_nb == _prevSeqNb + 1) {
- decode2(_curBuf, gfx_data, width, height, src + 8);
+ decode2(_curBuf, gfx_data, _width, _height, src + 8);
}
break;
case 3:
- memcpy(_curBuf, _deltaBufs[1], width * height);
+ memcpy(_curBuf, _deltaBufs[1], _frameSize);
break;
case 4:
- memcpy(_curBuf, _deltaBufs[0], width * height);
+ memcpy(_curBuf, _deltaBufs[0], _frameSize);
break;
case 5:
bompDecode(_curBuf, gfx_data, READ_LE_UINT32(src + 14));
break;
}
- memcpy(dst, _curBuf, width * height);
+ memcpy(dst, _curBuf, _frameSize);
if (seq_nb == _prevSeqNb + 1) {
if (src[3] == 1) {
diff --git a/scumm/smush/codec47.h b/scumm/smush/codec47.h
index c1a395289d..425f0daacf 100644
--- a/scumm/smush/codec47.h
+++ b/scumm/smush/codec47.h
@@ -19,27 +19,28 @@
*
*/
-#ifndef CODEC_47_H
-#define CODEC_47_H
+#ifndef SMUSH_CODEC_47_H
+#define SMUSH_CODEC_47_H
-#include "config.h"
+#include "common/scummsys.h"
-#include "decoder.h"
-
-class Codec47Decoder : public Decoder {
+class Codec47Decoder {
private:
+
int32 _deltaSize;
byte *_deltaBufs[2];
byte *_deltaBuf;
byte *_curBuf;
int32 _prevSeqNb;
- int32 _lastTableWidth;
+ int _lastTableWidth;
const byte *_d_src, *_paramPtr;
- int32 _d_pitch;
+ int _d_pitch;
int32 _offset1, _offset2;
byte _tableBig[99328];
byte _tableSmall[32768];
int16 _table[256];
+ int32 _frameSize;
+ int _width, _height;
void makeTables47(int32 width);
void makeTables37(int32 param);
@@ -47,14 +48,14 @@ private:
void level1(byte *d_dst);
void level2(byte *d_dst);
void level3(byte *d_dst);
- void decode2(byte *dst, const byte *src, int32 width, int32 height, const byte *param_ptr);
+ void decode2(byte *dst, const byte *src, int width, int height, const byte *param_ptr);
public:
Codec47Decoder();
- virtual ~Codec47Decoder();
- bool initSize(const Point &, const Rect &);
- void clean();
- bool decode(byte *dst, const byte *src, int length);
+ ~Codec47Decoder();
+ void init(int width, int height);
+ void deinit();
+ bool decode(byte *dst, const byte *src);
};
#endif
diff --git a/scumm/smush/color.cpp b/scumm/smush/color.cpp
deleted file mode 100644
index 601f312def..0000000000
--- a/scumm/smush/color.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#include <stdafx.h>
-#include "color.h"
-
-#define UPDATE_COLOR(c, inc) (((int32)((c)) << 7) + (c) + (inc)) >> 7
-#define CHECK_BOUNDS(c) (((c) > 255) ? 255 : (((c) < 0) ? 0 : (c)))
-
-void Color::delta(int16 * ptr) {
- // This is a very specific method for XPALs.
- int16 t;
- t = UPDATE_COLOR(_r, ptr[0]);
- _r = CHECK_BOUNDS(t);
- t = UPDATE_COLOR(_g, ptr[1]);
- _g = CHECK_BOUNDS(t);
- t = UPDATE_COLOR(_b, ptr[2]);
- _b = CHECK_BOUNDS(t);
-}
diff --git a/scumm/smush/color.h b/scumm/smush/color.h
deleted file mode 100644
index 78e82a461b..0000000000
--- a/scumm/smush/color.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#ifndef COLOR_H
-#define COLOR_H
-
-#include "config.h"
-
-/*! @brief simple class for handling a Chunk.
-
- This small class is an helper for Chunks.
-*/
-class Color {
-public:
- typedef byte value_type; //!< The type of the Chunk components.
-private:
- value_type _r; //!< The red component.
- value_type _g; //!< The green component.
- value_type _b; //!< The blue component.
-public:
- Color() : _r(0), _g(0), _b(0) {}
- Color(value_type r, value_type g, value_type b) : _r(r), _g(g), _b(b) {}
-
- inline value_type red() const { return _r; }
- inline value_type green() const { return _g; }
- inline value_type blue() const { return _b; }
- /*! @brief handle delta palette modification
-
- This method is used specifically by player::handleDeltaPalette().
- It updates the Chunk component using delta values given as short.
-
- @param ptr pointer to a table of 3 shorts that contain delta values to use.
- */
- void delta(int16 * ptr);
-};
-
-#endif
diff --git a/scumm/smush/decoder.h b/scumm/smush/decoder.h
deleted file mode 100644
index ebf9645dcd..0000000000
--- a/scumm/smush/decoder.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#ifndef DECODER_H
-#define DECODER_H
-
-#include "config.h"
-
-#include "common/rect.h"
-
-using ScummVM::Point;
-using ScummVM::Rect;
-
-/*! @brief base class for codec decompression.
-
- This class provides an interface for codec decompression.
-
-*/
-class Decoder {
-private:
- Rect _r; //!< current size of the frame object to decode
- Point _p; //!< position of the frame object to decode
-protected:
- const Rect & getRect() const{ return _r; }
- const Point & getSize() const { return _p; }
-public:
- Decoder() {};
- virtual ~Decoder() {};
- virtual bool initSize(const Point &p, const Rect &r) { _p = p; _r = r; return true; };
- virtual bool decode(byte *dst, const byte *src, int length) = 0;
-};
-
-#endif
diff --git a/scumm/smush/frenderer.cpp b/scumm/smush/frenderer.cpp
deleted file mode 100644
index 212ad8f7c0..0000000000
--- a/scumm/smush/frenderer.cpp
+++ /dev/null
@@ -1,399 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#include <stdafx.h>
-#include "common/util.h"
-#include "common/engine.h" // for debug, warning, error
-#include "scumm/scumm.h"
-
-#include "frenderer.h"
-
-#include <assert.h>
-#include <string.h>
-
-FontRenderer::FontRenderer(bool use_original_colors) :
- _nbChars(0),
- _color(-1),
- _original(use_original_colors) {
-}
-
-FontRenderer::~FontRenderer() {
- for(int32 i = 0; i < _nbChars; i++) {
- if(_chars[i].chr) delete []_chars[i].chr;
- }
-}
-
-void FontRenderer::save() {
- _chars[_nbChars].width = _width;
- _chars[_nbChars].height = _height;
- int size = _width * _height;
- _chars[_nbChars].chr = new byte[size];
- memcpy(_chars[_nbChars].chr, _data, size);
- _nbChars++;
-}
-
-int32 FontRenderer::charWidth(int32 v) const {
- if(v < 0) v = 256 + v;
- if(v < 0 || v >= _nbChars) error("invalid character in FontRenderer::charWidth : %d (%d)", v, _nbChars);
- return _chars[v].width;
-}
-
-int32 FontRenderer::charHeight(int32 v) const {
- if(v < 0) v = 256 + v;
- if(v < 0 || v >= _nbChars) error("invalid character in FontRenderer::charHeight : %d (%d)", v, _nbChars);
- return _chars[v].height;
-}
-
-int32 FontRenderer::stringWidth(const char *str) const {
- int32 ret = 0;
-
- while(*str) {
- ret += charWidth(*str++);
- }
-
- return ret;
-}
-
-int32 FontRenderer::stringHeight(const char *str) const {
- int32 ret = 0;
-
- for(int32 i = 0; str[i] != 0; i++) {
- int32 h = charHeight(str[i]);
- ret = MAX(ret, h);
- }
-
- return ret;
-}
-
-int32 FontRenderer::drawChar(byte *buffer, const Point &size, int32 x, int32 y, int32 chr) const {
- int32 w = _chars[chr].width;
- int32 h = _chars[chr].height;
- byte *src = _chars[chr].chr;
- byte *dst = buffer + size.getX() * y + x;
-
- if(_original) {
- for(int32 j = 0; j < h; j++) {
- for(int32 i = 0; i < w; i++) {
- char value = *src++;
- if(value) dst[i] = value;
- }
- dst += size.getX();
- }
- } else {
- char color = (_color != -1) ? _color : 1;
- if (g_scumm->_gameId == GID_CMI) {
- for(int32 j = 0; j < h; j++) {
- for(int32 i = 0; i < w; i++) {
- char value = *src++;
- if(value == -color) {
- dst[i] = 0xFF;
- } else if(value == -31) {
- dst[i] = 0;
- } else if(value) {
- dst[i] = value;
- }
- }
- dst += size.getX();
- }
- } else {
- for(int32 j = 0; j < h; j++) {
- for(int32 i = 0; i < w; i++) {
- char value = *src++;
- if(value == 1) {
- dst[i] = color;
- } else if(value) {
- dst[i] = 0;
- }
- }
- dst += size.getX();
- }
- }
- }
- return w;
-}
-
-static char **split(const char *str, char sep) {
- char **ret = new char *[62];
- int32 n = 0;
- const char *i = str, *j = strchr(i, sep);
-
- while(j != NULL) {
- assert(n < 60);
- ret[n] = new char[j - i + 1];
- memcpy(ret[n], i, j - i);
- ret[n++][j - i] = 0;
- i = j+1;
- j = strchr(i, sep);
- }
-
- ret[n] = new char[strlen(i) + 1];
- memcpy(ret[n], i, strlen(i));
- ret[n++][strlen(i)] = 0;
- ret[n] = 0;
- return ret;
-}
-
-void FontRenderer::drawSubstring(const byte *str, byte *buffer, const Point &size, int32 x, int32 y) const {
- for(int32 i = 0; str[i] != 0; i++)
- x += drawChar(buffer, size, x, y, str[i]);
-}
-
-bool FontRenderer::drawStringAbsolute(const char *str, byte *buffer, const Point &size, int32 x, int32 y) const {
- debug(9, "FontRenderer::drawStringAbsolute(%s, %d, %d)", str, x, y);
- while(str) {
- char line[256];
- char *pos = strchr(str, '\n');
- if(pos) {
- memcpy(line, str, pos - str - 1);
- line[pos - str - 1] = 0;
- str = pos + 1;
- } else {
- strcpy(line, str);
- str = 0;
- }
- drawSubstring((const byte *)line, buffer, size, x, y);
- y += stringHeight(line);
- }
- return true;
-}
-
-bool FontRenderer::drawStringCentered(const char *str, byte *buffer, const Point &size, int32 y, int32 xmin, int32 width, int32 offset) const {
- debug(9, "FontRenderer::drawStringCentered(%s, %d, %d)", str, xmin, y);
- if ((strchr(str, '\n') != 0)) {
- char *j = strchr(str, '\n');
- *j = 0;
- }
- char **words = split(str, ' ');
- int32 nb_sub = 0;
-
- while(words[nb_sub]) nb_sub++;
-
- int32 *sizes = new int32[nb_sub];
- int32 i = 0, max_width = 0, height = 0, nb_subs = 0;
-
- for(i = 0; i < nb_sub; i++)
- sizes[i] = stringWidth(words[i]);
-
- char **substrings = new char *[nb_sub];
- int32 *substr_widths = new int32[nb_sub];
- int32 space_width = charWidth(' ');
-
- i = 0;
- while(i < nb_sub) {
- int32 substr_width = sizes[i];
- char *substr = new char[1000];
- strcpy(substr, words[i]);
- int32 j = i + 1;
-
- while(j < nb_sub && (substr_width + space_width + sizes[j]) < width) {
- substr_width += sizes[j++] + space_width;
- }
-
- for(int32 k = i + 1; k < j; k++) {
- strcat(substr, " ");
- strcat(substr, words[k]);
- }
-
- substrings[nb_subs] = substr;
- substr_widths[nb_subs++] = substr_width;
- if(substr_width > max_width)
- max_width = substr_width;
- i = j;
- height += stringHeight(substr);
- }
-
- delete []sizes;
- for(i = 0; i < nb_sub; i++) {
- delete []words[i];
- }
- delete []words;
-
- max_width = (max_width + 1) >> 1;
- // we have a box from 0 -> max_width
- // we want a box from (xmin + offset) - max_width / 2, (xmin + offset) + max_width / 2
- int x = xmin + width / 2;
- x += offset - size.getX() / 2;
-
- if(x < max_width) x = max_width;
- if(x + max_width > size.getX()) {
- x = size.getX() - max_width;
- }
-
- if(y + height > size.getY()) {
- y = size.getY() - height;
- }
-
- for(i = 0; i < nb_subs; i++) {
- int32 substr_width = substr_widths[i];
- drawSubstring((const byte *)substrings[i], buffer, size, x - substr_width / 2, y);
- y += stringHeight(substrings[i]);
- delete []substrings[i];
- }
-
- delete []substr_widths;
- delete []substrings;
- return true;
-}
-
-bool FontRenderer::drawStringWrap(const char *str, byte *buffer, const Point &size, int32 x, int32 y, int32 width) const {
- debug(9, "FontRenderer::drawStringWrap(%s, %d, %d)", str, x, y);
- if ((strchr(str, '\n') != 0)) {
- char *j = strchr(str, '\n');
- *j = 0;
- }
- char * * words = split(str, ' ');
- int32 nb_sub = 0;
-
- while(words[nb_sub]) nb_sub++;
-
- int32 *sizes = new int32[nb_sub];
- int32 i = 0, max_width = 0, height = 0, nb_subs = 0, left_x;
-
- for(i = 0; i < nb_sub; i++)
- sizes[i] = stringWidth(words[i]);
-
- char **substrings = new char *[nb_sub];
- int32 *substr_widths = new int32[nb_sub];
- int32 space_width = charWidth(' ');
-
- i = 0;
- while(i < nb_sub) {
- int32 substr_width = sizes[i];
- char *substr = new char[1000];
- strcpy(substr, words[i]);
- int32 j = i + 1;
-
- while(j < nb_sub && (substr_width + space_width + sizes[j]) < width) {
- substr_width += sizes[j++] + space_width;
- }
-
- for(int32 k = i + 1; k < j; k++) {
- strcat(substr, " ");
- strcat(substr, words[k]);
- }
-
- substrings[nb_subs] = substr;
- substr_widths[nb_subs++] = substr_width;
- i = j;
- height += stringHeight(substr);
- }
-
- delete []sizes;
- for(i = 0; i < nb_sub; i++) {
- delete []words[i];
- }
- delete []words;
-
- if(y + height > size.getY()) {
- y = size.getY() - height;
- }
-
- for(i = 0; i < nb_subs; i++)
- max_width = MAX(max_width, substr_widths[i]);
-
- if(max_width + x > size.getX())
- left_x = size.getX() - max_width + charWidth(' ');
- else
- left_x = x;
-
- if(max_width + left_x > size.getX())
- left_x = size.getX() - max_width;
-
- for(i = 0; i < nb_subs; i++) {
- drawSubstring((const byte *)substrings[i], buffer, size, left_x, y);
- y += stringHeight(substrings[i]);
- delete []substrings[i];
- }
-
- delete []substr_widths;
- delete []substrings;
- return true;
-}
-
-bool FontRenderer::drawStringWrapCentered(const char *str, byte *buffer, const Point &size, int32 x, int32 y, int32 width) const {
- int32 max_substr_width = 0;
- debug(9, "FontRenderer::drawStringWrapCentered(%s, %d, %d)", str, x, y);
- if ((strchr(str, '\n') != 0)) {
- char *j = strchr(str, '\n');
- *j = 0;
- }
- char **words = split(str, ' ');
- int32 nb_sub = 0;
-
- while(words[nb_sub]) nb_sub++;
-
- int32 *sizes = new int32[nb_sub];
- int32 i = 0, height = 0, nb_subs = 0;
-
- for(i = 0; i < nb_sub; i++)
- sizes[i] = stringWidth(words[i]);
-
- char **substrings = new char *[nb_sub];
- int32 *substr_widths = new int32[nb_sub];
- int32 space_width = charWidth(' ');
-
- i = 0;
- width = MIN(width, size.getX());
- while(i < nb_sub) {
- int32 substr_width = sizes[i];
- char *substr = new char[1000];
- strcpy(substr, words[i]);
- int32 j = i + 1;
-
- while(j < nb_sub && (substr_width + space_width + sizes[j]) < width) {
- substr_width += sizes[j++] + space_width;
- }
-
- for(int32 k = i + 1; k < j; k++) {
- strcat(substr, " ");
- strcat(substr, words[k]);
- }
-
- substrings[nb_subs] = substr;
- substr_widths[nb_subs++] = substr_width;
- max_substr_width = MAX(substr_width, max_substr_width);
- i = j;
- height += stringHeight(substr);
- }
-
- delete []sizes;
- for(i = 0; i < nb_sub; i++) {
- delete []words[i];
- }
- delete []words;
-
- if(y + height > size.getY()) {
- y = size.getY() - height;
- }
-
- x = (size.getX() - max_substr_width) / 2;
-
- for(i = 0; i < nb_subs; i++) {
- int32 substr_width = substr_widths[i];
- drawSubstring((const byte *)substrings[i], buffer, size, x + (max_substr_width - substr_width) / 2, y);
- y += stringHeight(substrings[i]);
- delete []substrings[i];
- }
-
- delete []substr_widths;
- delete []substrings;
- return true;
-}
diff --git a/scumm/smush/frenderer.h b/scumm/smush/frenderer.h
deleted file mode 100644
index 93f3b95400..0000000000
--- a/scumm/smush/frenderer.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#ifndef FRENDERER_H
-#define FRENDERER_H
-
-#include "config.h"
-
-#ifdef DEBUG
-# ifndef NO_DEBUG_FONT_RENDERER
-# define DEBUG_FONT_RENDERER
-# endif
-#else
-# ifdef DEBUG_FONT_RENDERER
-# error DEBUG_FONT_RENDERER defined without DEBUG
-# endif
-#endif
-
-#include "brenderer.h"
-#include "common/util.h"
-
-/*! @brief ::renderer implementation specifically designed for font files.
-
- This class is a valid ::renderer implementation. The frames are kept in memory, as bitmap representing characters, so that
- they can be rendered again in another frame as strings.
-
- This class also contains some functions useful for printing strings. This is used to show subtitles and more generally texts
- in animations.
-
- @todo update the mehod to use the ::blitter class, instead of direct pointers.
-*/
-class FontRenderer : public BaseRenderer {
-private:
- int32 _nbChars; //!< The number of frames in the font
- int32 _color; //!< A color parameter used for font printing.
- bool _original; //!< flag for color selection
- struct {
- int32 width;
- int32 height;
- byte *chr;
- } _chars[256]; //!< array that contains the size of the different frames (i.e. characters) of the font.
-public:
- /*! @brief font_renderer constructor
-
- @param use_original_colors flag to indicate if the font use it's own color, or if the base color are set at runtime.
- */
- FontRenderer(bool use_original_colors = false);
- virtual ~FontRenderer();
- virtual bool wait(int32 ms) { return true; };
-protected:
- virtual void save();
- /*! @brief get the width of a character.
-
- @param c the character we want the width from.
-
- @return the width of the character
- */
- int32 charWidth(int32 c) const;
- /*! @brief get the width of a string.
-
- @param str the string we want the width from.
-
- @return the complete width of the string
- */
- int32 stringWidth(const char *str) const;
- /*! @brief get the height of a character.
-
- @param c the character we want the height from.
-
- @return the height of the character
- */
- int32 charHeight(int32 c) const;
- /*! @brief get the height of a string.
-
- @param str the string we want the height from.
-
- @return the complete height of the string
- */
- int32 stringHeight(const char *str) const;
- /*! @brief draw a character in the given frame buffer.
-
- @param buffer the frame buffer to draw into.
- @param size the size of the frame buffer.
- @param x the horizontal position of the topleft corner of the character.
- @param y the vertical position of the topleft corner of the character.
- @param c the character to draw.
-
- @bug This method does not clip. This is not really a bug, as it should always be correctly called, but some asserts would be welcome.
-
- @return the width of the character
- */
- int32 drawChar(byte *buffer, const Point &size, int32 x, int32 y, int32 c) const;
- /*! @brief draw a string in the given frame buffer.
-
- @param str the string to draw.
- @param buffer the frame buffer to draw into.
- @param size the size of the frame buffer.
- @param x the horizontal position of the topleft corner of the string.
- @param y the vertical position of the topleft corner of the string.
-
- @bug This method does not clip. This is not really a bug, as it should always be correctly called, but some asserts would be welcome.
- */
- void drawSubstring(const byte *str, byte *buffer, const Point &size, int32 x, int32 y) const;
-public:
- /*! @brief change the programmable color of the font.
-
- @param c the new color to use.
-
- @return \c true if everything went fine, \c false otherwise
- */
- bool setColor(int32 c) { _color = c; return true; }
- /*! @brief draw a centered and possibly using multiple lines string.
-
- This method performs calculation of the string size before choosing where to draw it.
- As I still not have figured out exactly what is the meaning of the fields in the TRES Chunk,
- the real meaning of the parameters can be quite difficult to understand.
-
- @remark The current implementation is incorrect in the sense that it does not conform to the original game.
- @todo rewrite and rethink this to better match the original implementation.
-
- @param str the string to draw.
- @param buffer the frame buffer to draw into.
- @param size the size of the frame buffer.
- @param y the vertical position of the topleft corner of the string. This position may be changed if it is too low to be correctly drawn.
- @param xmin the minimum horizontal position of the topleft corner of the string.
- @param width the maximum width of the string. If the string is too long, it will wrap.
- @param offset offset to give to the horizontal position.
-
- @return \c true if everything went fine, \c false otherwise
- */
- bool drawStringCentered(const char *str, byte *buffer, const Point &size, int32 y, int32 xmin, int32 width, int32 offset) const;
- bool drawStringWrap(const char *str, byte *buffer, const Point &size, int32 x, int32 y, int32 width) const;
- bool drawStringWrapCentered(const char *str, byte *buffer, const Point &size, int32 x, int32 y, int32 width) const;
- /*! @brief draw a string at an absolute position.
-
- @param str the string to draw.
- @param buffer the frame buffer to draw into.
- @param size the size of the frame buffer.
- @param x the horizontal position of the topleft corner of the string.
- @param y the vertical position of the topleft corner of the string. This position may be changed if it is too low to be correctly drawn.
-
- @return \c true if everything went fine, \c false otherwise
- */
- bool drawStringAbsolute(const char *str, byte *buffer, const Point &size, int32 x, int32 y) const;
-};
-
-#endif
diff --git a/scumm/smush/imuse_channel.cpp b/scumm/smush/imuse_channel.cpp
index f857bf19c3..064b662a33 100644
--- a/scumm/smush/imuse_channel.cpp
+++ b/scumm/smush/imuse_channel.cpp
@@ -24,9 +24,6 @@
#include "chunk.h"
#include "chunk_type.h"
-#include <assert.h>
-#include <string.h>
-
ImuseChannel::ImuseChannel(int32 track, int32 freq) :
_track(track),
_tbuffer(0),
@@ -73,7 +70,7 @@ bool ImuseChannel::checkParameters(int32 index, int32 nbframes, int32 size, int3
}
bool ImuseChannel::appendData(Chunk &b, int32 size) {
- if(_dataSize == -1) { // First call
+ if(_dataSize == -1) {
assert(size > 8);
Chunk::type imus_type = b.getDword(); imus_type = SWAP_BYTES(imus_type);
uint32 imus_size = b.getDword(); imus_size = SWAP_BYTES(imus_size);
@@ -86,9 +83,9 @@ bool ImuseChannel::appendData(Chunk &b, int32 size) {
if(!_tbuffer)
error("imuse_channel failed to allocate memory");
b.read(_tbuffer, size);
- _dataSize = -2; // even if _in_data does not get set, this won't be called again
+ _dataSize = -2;
} else {
- if(_tbuffer) { // remaining from last call
+ if(_tbuffer) {
byte *old = _tbuffer;
int32 new_size = size + _tbufferSize;
_tbuffer = new byte[new_size];
@@ -223,7 +220,7 @@ bool ImuseChannel::handleSubTags(int32 &offset) {
handleMap(c);
}
break;
- case TYPE_DATA: // Sound data !!!
+ case TYPE_DATA:
_inData = true;
_dataSize = size;
offset += 8;
@@ -254,7 +251,6 @@ bool ImuseChannel::handleSubTags(int32 &offset) {
}
bool ImuseChannel::processBuffer() {
- // see comments in saud_channel::processBuffer for an explanation
assert(_tbuffer != 0);
assert(_tbufferSize != 0);
assert(_sbuffer == 0);
@@ -266,7 +262,7 @@ bool ImuseChannel::processBuffer() {
while(handleSubTags(offset));
_sbufferSize = _dataSize;
_sbuffer = _tbuffer;
- if(offset < _tbufferSize) { // there is still some unprocessed data
+ if(offset < _tbufferSize) {
int32 new_size = _tbufferSize - offset;
_tbuffer = new byte[new_size];
if(!_tbuffer) error("imuse_channel failed to allocate memory");
@@ -277,12 +273,10 @@ bool ImuseChannel::processBuffer() {
_tbufferSize = 0;
}
if(_sbufferSize == 0) {
- // this never happened yet, but who knows
delete []_sbuffer;
_sbuffer = 0;
}
} else {
- // easy, swap the buffer
_sbufferSize = _tbufferSize;
_sbuffer = _tbuffer;
_tbufferSize = 0;
@@ -301,7 +295,7 @@ bool ImuseChannel::processBuffer() {
_tbuffer = 0;
_tbufferSize = 0;
} else {
- if(offset) { // maybe I should assert() this to avoid a lock...
+ if(offset) {
byte * old = _tbuffer;
int32 new_size = _tbufferSize - offset;
_tbuffer = new byte[new_size];
diff --git a/scumm/smush/mixer.h b/scumm/smush/mixer.h
deleted file mode 100644
index 2375c523c0..0000000000
--- a/scumm/smush/mixer.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#ifndef SMUSH_MIXER_H
-#define SMUSH_MIXER_H
-
-#include "config.h"
-
-#ifdef DEBUG
-# ifndef NO_DEBUG_MIXER
-# define DEBUG_MIXER
-# endif
-#else
-# ifdef DEBUG_MIXER
-# error DEBUG_MIXER defined without DEBUG
-# endif
-#endif
-
-class _Channel;
-
-class SoundRenderer;
-
-/*! @brief The class for the player's sound mixer
-
- This class is used for sound mixing.
- It contains a list of current track and request them to mix.
- It then sends the mixed sound samples to the sound renderer.
-
-*/
-class Mixer {
-public:
- virtual ~Mixer() {};
- virtual bool init() = 0;
- virtual _Channel * findChannel(int32 track) = 0;
- virtual bool addChannel(_Channel * c) = 0;
- virtual bool handleFrame() = 0;
- virtual bool stop() = 0;
-};
-
-#endif
diff --git a/scumm/smush/palette.h b/scumm/smush/palette.h
deleted file mode 100644
index ea9df037c0..0000000000
--- a/scumm/smush/palette.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#ifndef SMUSH_PALETTE_H
-#define SMUSH_PALETTE_H
-
-#include "config.h"
-
-#include "color.h"
-
-/*! @brief simple class for handling a palette.
-
- This small class is an helper for palettes.
-*/
-class Palette {
-private:
- Color _colors[256];
-public:
- Palette() {}
- Palette(byte *ptr)
- {
- for(int32 i = 0; i < 256; i++) {
- _colors[i] = Color(ptr[3 * i + 0], ptr[3 * i + 1], ptr[3 * i + 2]);
- }
-
- }
- const Color & operator[](int32 a) const
- {
- assert(a >= 0 && a < 256);
- return _colors[a];
- }
- Color & operator[](int32 a)
- {
- assert(a >= 0 && a < 256);
- return _colors[a];
- }
-};
-
-#endif
diff --git a/scumm/smush/player.h b/scumm/smush/player.h
deleted file mode 100644
index 60311b88f7..0000000000
--- a/scumm/smush/player.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#ifndef PLAYER_H
-#define PLAYER_H
-
-#include "config.h"
-
-#include "common/util.h"
-#include "chunk.h"
-#include "palette.h"
-#include "codec1.h"
-#include "codec37.h"
-#include "codec44.h"
-#include "codec47.h"
-
-class FontRenderer;
-class Mixer;
-class Renderer;
-class StringResource;
-
-/*! @brief the SMUSH player class
-
- This class is the player itself.
-*/
-class SmushPlayer {
-private:
- char *_fname; //!< the name of the animation file being played
- int32 _version; //!< the version of the animation file being played
- int32 _secondaryVersion; //!< the secondary version number of the animation file being played
- int32 _soundFrequency; //!< the sound frequency of the animation file being played
- int32 _nbframes; //!< the number of frames in the animation file
- Mixer *_mixer; //!< the sound mixer
- Palette _pal; //!< the current palette
- int16 _deltaPal[768]; //!< the delta palette information set by an xpal
- Renderer *_renderer; //!< pointer to the ::renderer
- StringResource *_strings; //!< pointer to the string resources associated with the animation
- FontRenderer *_fr[5]; //!< pointers to the fonts for the animation
- Codec1Decoder _codec1; //!< the ::decoder for codec 1 and 3
- Codec37Decoder _codec37; //!< the ::decoder for codec 37
- Codec47Decoder _codec47; //!< the ::decoder for codec 47
- Codec44Decoder _codec44; //!< the ::decoder for codec 21 and 44
- Point _frameSize; //!< the current frame size of the animation
- int32 _frame; //!< the current frame number of the animation
- bool _outputSound; //!< should we handle sound ?
- bool _wait; //!< should we synchronise the player ?
- bool _alreadyInit; //!< has the player already been initialized for the current frame
- bool _codec37Called; //!< has the codec 37 already been called once for this animation
- bool _skipNext; //!< should the player skip the next frame object ?
- bool _subtitles; //!< should the player handle subtitles ?
- bool _bgmusic; //!< should the player output the background music ?
- bool _voices; //!< should the player output the voice ?
- bool _skips[37]; //!< mapping of frame object identifier to show or hide
- byte *_curBuffer; //!< pointer to the current frame
- int32 _IACTchannel;
- byte _IACToutput[4096];
- int32 _IACTpos;
- bool _storeFrame;
- byte *_frameBuffer;
-
-public:
- SmushPlayer(Renderer *, bool wait = true, bool output_sound = true);
- virtual ~SmushPlayer();
- bool play(const char *, const char *directory);
- void updatePalette(void);
- void show(const char *);
- void hide(const char *);
-protected:
- bool readString(const char *file, const char *directory, bool &);
- void clean();
- void checkBlock(const Chunk &, Chunk::type, uint32 = 0);
- void handleAnimHeader(Chunk &);
- void handleFrame(Chunk &);
- void handleNewPalette(Chunk &);
- void handleFrameObject(Chunk &);
- void handleSoundBuffer(int32, int32, int32, int32, int32, int32, Chunk &, int32);
- void handleImuseBuffer(int32, int32, int32, int32, int32, int32, Chunk &, int32);
- void handleSoundFrame(Chunk &);
- void handleSkip(Chunk &);
- void handleStore(Chunk &);
- void handleFetch(Chunk &);
- void handleImuseAction8(Chunk &, int32 flags, int32 unknown, int32 track_id);
- void handleImuseAction(Chunk &);
- void handleTextResource(Chunk &);
- void handleDeltaPalette(Chunk &);
- void decodeCodec(Chunk &, const Rect &, Decoder &);
- void readPalette(Palette &, Chunk &);
- void initSize(const Rect &, bool, bool);
-};
-
-#endif
diff --git a/scumm/smush/renderer.h b/scumm/smush/renderer.h
deleted file mode 100644
index 724b0eb6d1..0000000000
--- a/scumm/smush/renderer.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#ifndef RENDERER_H
-#define RENDERER_H
-
-#include "config.h"
-
-#include "palette.h"
-#include "common/rect.h"
-
-using ScummVM::Point;
-using ScummVM::Rect;
-class Mixer;
-
-/*! @brief interface for general output (rendering)
-
- This is the interface for frame output.
- Several implementations of these interface exist, each having a particular
- application.
-*/
-class Renderer {
-public:
- virtual ~Renderer() {};
- /*! @brief start of animation output
-
- This is called by the animation player when output is going to start.
-
- @param fname name of the animation being played.
- @param version version number of the animation
- @param nbframes total number of frames of the animation.
-
- @return true if initialisation was ok, false otherwise
- */
- virtual bool startDecode(const char *fname, int32 version, int32 nbframes) = 0;
- /*! @brief start of animation output
-
- This is called by the animation player when the frame size is changing.
-
- @param size new size of the frames.
-
- @return true if everything went fine, false otherwise
- */
- virtual bool initFrame(const Point & size) = 0;
- /*! @brief set a new palette
-
- This is called by the animation player when the palette is changing.
-
- @param pal new palette.
-
- @return true if everything went fine, false otherwise
- */
- virtual bool setPalette(const Palette & pal) = 0;
- /*! @brief lock a frame buffer
-
- This is called by the animation player when a frame is going to be decoded.
-
- @param frame the frame number.
-
- @return a pointer to the frame buffer to output data to.
- */
- virtual byte *lockFrame(int32 frame) = 0;
- /*! @brief unlock a frame buffer
-
- This is called by the animation player when a frame has been decoded.
-
- @return true if everything went fine, false otherwise
- */
- virtual bool unlockFrame() = 0;
- /*! @brief flip a frame buffer
-
- This is called by the animation player when the current frame should be shown.
-
- @return true if everything went fine, false otherwise
- */
- virtual bool flipFrame() = 0;
- /*! @brief wait for some time
-
- This is called by the animation player when the animation should stay idle.
-
- @param ms number of millisecond to wait.
-
- @return true if everything went fine, false otherwise
- */
- virtual bool wait(int32 ms) = 0;
- /*! @brief does the renderer want a premature end of the animation ?
-
- This is called by the animation player after each frame.
-
- @return true if playing should be stopped, false otherwise.
- */
- virtual bool prematureClose() = 0;
- /*! @brief request for a mixer
-
- This is called by the animation player when sound output is required by the animation.
-
- @return a valid pointer to an uninitialized mixer instance, or null if none is available.
- */
- virtual Mixer *getMixer() = 0;
- /*! @brief debugging function : do not use
-
- @return true if everything went fine, false otherwise
- */
- virtual bool saveCurrent() { return false; };
-};
-
-#endif
diff --git a/scumm/smush/saud_channel.cpp b/scumm/smush/saud_channel.cpp
index d49c63bc44..3ab0f03faa 100644
--- a/scumm/smush/saud_channel.cpp
+++ b/scumm/smush/saud_channel.cpp
@@ -25,9 +25,6 @@
#include "chunk.h"
#include "chunk_type.h"
-#include <assert.h>
-#include <string.h>
-
void SaudChannel::handleStrk(Chunk &b) {
int32 size = b.getSize();
if(size != 14 && size != 10) {
@@ -41,7 +38,8 @@ void SaudChannel::handleSmrk(Chunk &b) {
void SaudChannel::handleShdr(Chunk &b) {
int32 size = b.getSize();
- if(size != 4) warning("SMRK has a invalid size : %d", size);
+ if(size != 4)
+ warning("SMRK has a invalid size : %d", size);
}
bool SaudChannel::handleSubTags(int32 &offset) {
@@ -93,12 +91,6 @@ bool SaudChannel::handleSubTags(int32 &offset) {
}
bool SaudChannel::processBuffer() {
- // At the start of this function, we have _tbuffer[0.._tbuffersize] containing possible data...
- // and _sbuffer is 0
- // At the end we have :
- // if(sound data) _sbuffer[0.._sbuffer_size] contains the sound data
- // the unprocessed data is kept in _tbuffer[0.._tbuffersize] (which may have changed)
- // if no unprocessed data, then _tbuffer is 0
assert(_tbuffer != 0);
assert(_tbufferSize != 0);
assert(_sbuffer == 0);
@@ -106,12 +98,11 @@ bool SaudChannel::processBuffer() {
if(_inData) {
if(_dataSize < _tbufferSize) {
- // I can't assume that the channel is finished after data is received... (this assumption failed in realride.san)
int32 offset = _dataSize;
while(handleSubTags(offset));
_sbufferSize = _dataSize;
_sbuffer = _tbuffer;
- if(offset < _tbufferSize) { // there is still some unprocessed data
+ if(offset < _tbufferSize) {
int new_size = _tbufferSize - offset;
_tbuffer = new byte[new_size];
if(!_tbuffer) error("SaudChannel failed to allocate memory");
@@ -122,12 +113,10 @@ bool SaudChannel::processBuffer() {
_tbufferSize = 0;
}
if(_sbufferSize == 0) {
- // this never happened yet, but who knows
delete []_sbuffer;
_sbuffer = 0;
}
} else {
- // easy, swap the buffer
_sbufferSize = _tbufferSize;
_sbuffer = _tbuffer;
_tbufferSize = 0;
@@ -140,17 +129,19 @@ bool SaudChannel::processBuffer() {
_sbufferSize = _tbufferSize - offset;
assert(_sbufferSize);
_sbuffer = new byte[_sbufferSize];
- if(!_sbuffer) error("saud_channel failed to allocate memory");
+ if(!_sbuffer)
+ error("saud_channel failed to allocate memory");
memcpy(_sbuffer, _tbuffer + offset, _sbufferSize);
delete []_tbuffer;
_tbuffer = 0;
_tbufferSize = 0;
} else {
- if(offset) { // maybe I should assert() this to avoid a lock...
- unsigned char *old = _tbuffer;
+ if(offset) {
+ byte *old = _tbuffer;
int32 new_size = _tbufferSize - offset;
_tbuffer = new byte[new_size];
- if(!_tbuffer) error("SaudChannel failed to allocate memory");
+ if(!_tbuffer)
+ error("SaudChannel failed to allocate memory");
memcpy(_tbuffer, old + offset, new_size);
_tbufferSize = new_size;
delete []old;
@@ -197,10 +188,14 @@ void SaudChannel::recalcVolumeTable() {
int32 right_multiplier = MAX_BALANCE + _balance;
volume_left = _volume * left_multiplier / (MAX_BALANCE * 2);
volume_right = _volume * right_multiplier / (MAX_BALANCE * 2);
- if(volume_left < 0) volume_left = 0;
- if(volume_left > 128) volume_left = 128;
- if(volume_right < 0) volume_right = 0;
- if(volume_right > 128) volume_right = 128;
+ if(volume_left < 0)
+ volume_left = 0;
+ if(volume_left > 128)
+ volume_left = 128;
+ if(volume_right < 0)
+ volume_right = 0;
+ if(volume_right > 128)
+ volume_right = 128;
for(int32 i = 0; i < 256; i++) {
int16 value = volume_left * (int8)i;
_voltable[0][i] = TO_BE_16(value);
@@ -220,9 +215,12 @@ bool SaudChannel::setParameters(int32 nb, int32 flags, int32 volume, int32 balan
}
bool SaudChannel::checkParameters(int32 index, int32 nb, int32 flags, int32 volume, int32 balance) {
- if(++_index != index) error("invalid index in SaudChannel::checkParameters()");
- if(_nbframes != nb) error("invalid duration in SaudChannel::checkParameters()");
- if(_flags != flags) error("invalid flags in SaudChannel::checkParameters()");
+ if(++_index != index)
+ error("invalid index in SaudChannel::checkParameters()");
+ if(_nbframes != nb)
+ error("invalid duration in SaudChannel::checkParameters()");
+ if(_flags != flags)
+ error("invalid flags in SaudChannel::checkParameters()");
if(_volume != volume || _balance != balance) {
_volume = volume;
_balance = balance;
@@ -232,13 +230,13 @@ bool SaudChannel::checkParameters(int32 index, int32 nb, int32 flags, int32 volu
}
bool SaudChannel::appendData(Chunk &b, int32 size) {
- if(_dataSize == -1) { // First call
+ if(_dataSize == -1) {
assert(size > 8);
Chunk::type saud_type = b.getDword(); saud_type = SWAP_BYTES(saud_type);
uint32 saud_size = b.getDword(); saud_size = SWAP_BYTES(saud_size);
if(saud_type != TYPE_SAUD) error("Invalid Chunk for SaudChannel : %X", saud_type);
size -= 8;
- _dataSize = -2; // We don't get here again...
+ _dataSize = -2;
}
if(_tbuffer) {
byte *old = _tbuffer;
diff --git a/scumm/smush/scumm_renderer.cpp b/scumm/smush/scumm_renderer.cpp
deleted file mode 100644
index 88fc955883..0000000000
--- a/scumm/smush/scumm_renderer.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#include <stdafx.h>
-#include "common/util.h"
-#include "scumm_renderer.h"
-#include "channel.h"
-#include "mixer.h"
-#include "sound/mixer.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/imuse.h"
-
-class ScummMixer : public Mixer {
-private:
- SoundMixer *_mixer; //!< pointer to the SoundMixer instance
- struct {
- int id;
- _Channel *chan;
- bool first;
- int mixer_index;
- } _channels[SoundMixer::NUM_CHANNELS]; //!< The map of track and channels
- int _nextIndex;
-public:
- ScummMixer(SoundMixer *);
- virtual ~ScummMixer();
- bool init();
- _Channel *findChannel(int32 track);
- bool addChannel(_Channel *c);
- bool handleFrame();
- bool stop();
- bool update();
- bool _silentMixer;
-};
-
-ScummMixer::ScummMixer(SoundMixer *m) : _mixer(m), _nextIndex(_mixer->_beginSlots) {
- for(int32 i = _mixer->_beginSlots; i < SoundMixer::NUM_CHANNELS; i++) {
- _channels[i].id = -1;
- _channels[i].chan = 0;
- _channels[i].first = true;
- }
-}
-
-ScummMixer::~ScummMixer() {
-}
-
-bool ScummMixer::init() {
- debug(9, "ScummMixer::init()");
- return true;
-}
-
-_Channel *ScummMixer::findChannel(int32 track) {
- debug(9, "scumm_mixer::findChannel(%d)", track);
- for(int32 i = _mixer->_beginSlots; i < SoundMixer::NUM_CHANNELS; i++) {
- if(_channels[i].id == track)
- return _channels[i].chan;
- }
- return 0;
-}
-
-bool ScummMixer::addChannel(_Channel *c) {
- int32 track = c->getTrackIdentifier();
- int i;
-
- debug(9, "ScummMixer::addChannel(%d)", track);
-
- for(i = _mixer->_beginSlots; i < SoundMixer::NUM_CHANNELS; i++) {
- if(_channels[i].id == track)
- warning("mixer::addChannel(%d) : channel already exist !", track);
- }
- if(_nextIndex >= SoundMixer::NUM_CHANNELS) _nextIndex = _mixer->_beginSlots;
-
- for(i = _nextIndex; i < SoundMixer::NUM_CHANNELS; i++) {
- if(_channels[i].chan == 0 || _channels[i].id == -1) {
- _channels[i].chan = c;
- _channels[i].id = track;
- _channels[i].first = true;
- _nextIndex = i + 1;
- return true;
- }
- }
-
- for(i = _mixer->_beginSlots; i < _nextIndex; i++) {
- if(_channels[i].chan == 0 || _channels[i].id == -1) {
- _channels[i].chan = c;
- _channels[i].id = track;
- _channels[i].first = true;
- _nextIndex = i + 1;
- return true;
- }
- }
-
- fprintf(stderr, "_nextIndex == %d\n", _nextIndex);
-
- for(i = _mixer->_beginSlots; i < SoundMixer::NUM_CHANNELS; i++) {
- fprintf(stderr, "channel %d : %p(%d, %d) %d %d\n", i, (void *)_channels[i].chan,
- _channels[i].chan ? _channels[i].chan->getTrackIdentifier() : -1,
- _channels[i].chan ? _channels[i].chan->isTerminated() : 1,
- _channels[i].first, _channels[i].mixer_index);
- }
-
- error("mixer::add_channel() : no more channel available");
- return false;
-}
-
-bool ScummMixer::handleFrame() {
- debug(9, "ScummMixer::handleFrame()");
- for(int i = _mixer->_beginSlots; i < SoundMixer::NUM_CHANNELS; i++) {
- if(_channels[i].id != -1) {
- debug(9, "updating channel %d (%p)", _channels[i].id, _channels[i].chan);
- if(_channels[i].chan->isTerminated()) {
- debug(9, "channel %d has terminated (%p)", _channels[i].id, _channels[i].chan);
- delete _channels[i].chan;
- _channels[i].id = -1;
- _channels[i].chan = 0;
- } else {
- int32 rate;
- bool stereo, is_short;
-
- _channels[i].chan->getParameters(rate, stereo, is_short);
- int32 size = _channels[i].chan->availableSoundData();
- debug(9, "channel %d : %d, %s, %d bits, %d", _channels[i].id, rate, stereo ? "stereo" : "mono", is_short ? 16 : 8, size);
- int32 flags = stereo ? SoundMixer::FLAG_STEREO : 0;
-
- if(is_short) {
- // FIXME this is one more data copy... we could get rid of it...
- short *data = new int16[size * (stereo ? 2 : 1) * 2];
- _channels[i].chan->getSoundData(data, size);
- if(_channels[i].chan->getRate() == 11025) size *= 2;
- size *= stereo ? 4 : 2;
-
- if(_silentMixer == false) {
- // append to _sound
- if(_channels[i].first) {
- _channels[i].mixer_index = _mixer->playStream(NULL, -1, data, size, rate, flags | SoundMixer::FLAG_16BITS);
- debug(5, "channel %d bound to mixer_index %d", _channels[i].id, _channels[i].mixer_index);
- _channels[i].first = false;
- } else {
- _mixer->append(_channels[i].mixer_index, data, size, rate, flags | SoundMixer::FLAG_16BITS);
- }
- }
-
- delete []data;
- } else {
- int8 *data = new int8[size * (stereo ? 2 : 1) * 2];
- _channels[i].chan->getSoundData(data, size);
- if(_channels[i].chan->getRate() == 11025) size *= 2;
- size *= stereo ? 2 : 1;
-
- if(_silentMixer == false) {
- // append to _sound
- if(_channels[i].first) {
- _channels[i].mixer_index = _mixer->playStream(NULL, -1, data, size, rate, flags | SoundMixer::FLAG_UNSIGNED);
- _channels[i].first = false;
- } else {
- _mixer->append(_channels[i].mixer_index, data, size, rate, flags | SoundMixer::FLAG_UNSIGNED);
- }
- }
-
- delete []data;
- }
- }
- }
- }
- return true;
-}
-
-bool ScummMixer::stop() {
- debug(9, "ScummMixer::stop()");
- for(int i = _mixer->_beginSlots; i < SoundMixer::NUM_CHANNELS; i++) {
- if(_channels[i].id != -1) {
- delete _channels[i].chan;
- _channels[i].id = -1;
- _channels[i].chan = 0;
- }
- }
- return true;
-}
-
-ScummRenderer::ScummRenderer(Scumm *scumm, uint32 speed) :
- _scumm(scumm),
- _smixer(0),
- _insaneSpeed(speed),
- _pending_updates(0) {
-}
-
-static ScummRenderer *s_renderer;
-
-static void smush_handler(void *engine) {
- s_renderer->update();
-}
-
-bool ScummRenderer::initFrame(const Point &p) {
- clean();
- _width = p.getX();
- _height = p.getY();
- assert(_width && _height);
- _data = _scumm->virtscr[0].screenPtr + _scumm->virtscr[0].xstart;
- return true;
-}
-
-void ScummRenderer::clean() {
- _data = 0;
- _width = _height = 0;
-}
-
-byte *ScummRenderer::lockFrame(int32 frame) {
- _frame = frame;
- if(!_data) error("no allocated image buffer in lock_frame");
- return _data;
-}
-
-Mixer *ScummRenderer::getMixer() {
- if(_smixer == 0) {
- _smixer = new ScummMixer(_scumm->_mixer);
- if(!_smixer) error("unable to allocate a smush mixer");
- _smixer->_silentMixer = _scumm->_silentDigitalImuse;
- s_renderer = this;
- _scumm->_timer->installProcedure(&smush_handler, _insaneSpeed);
- }
- return _smixer;
-}
-
-ScummRenderer::~ScummRenderer() {
- clean();
- _scumm->_insaneState = false;
- _scumm->exitCutscene();
- if(_smixer) {
- _scumm->_timer->releaseProcedure(&smush_handler);
- delete _smixer;
- _smixer = 0;
- }
- if (_scumm->_imuseDigital) {
- _scumm->_imuseDigital->pause(false);
- }
- _scumm->_sound->pauseBundleMusic(false);
-
- _scumm->_fullRedraw = 1;
-}
-
-bool ScummRenderer::wait(int32 ms) {
- // Because waitForTimer() also is the function that checks for user
- // input we always want to call it at least once between frames, or
- // the user may become unable to interrupt the movie.
- do {
- _scumm->waitForTimer(1);
- } while(_pending_updates <= 0);
- return true;
-}
-
-bool ScummRenderer::startDecode(const char *fname, int32 version, int32 nbframes) {
- if (_scumm->_imuseDigital) {
- _scumm->_imuseDigital->pause(true);
- }
- _scumm->_sound->pauseBundleMusic(true);
- _scumm->_videoFinished = false;
- _scumm->_insaneState = true;
- return true;
-}
-
-bool ScummRenderer::setPalette(const Palette &pal) {
- int i;
- byte palette_colors[1024];
- byte *p = palette_colors;
-
- for (i = 0; i < 256; i++, p += 4) {
- p[0] = pal[i].red();
- p[1] = pal[i].green();
- p[2] = pal[i].blue();
- p[3] = 0;
- }
-
- _scumm->_system->set_palette(palette_colors, 0, 256);
- _scumm->setDirtyColors(0, 255);
- return BaseRenderer::setPalette(pal); // For compatibility with possible subclass...
-}
-
-void ScummRenderer::save() {
- int width = MIN(_width, _scumm->_realWidth);
- int height = MIN(_height, _scumm->_realHeight);
-
- // In theory, this will always be true. In reality, there may be
- // several pending updates because the computer wasn't fast enough to
- // process them all. In that case, skip the frame to catch up.
- if (--_pending_updates <= 0) {
- _scumm->_system->copy_rect(_data, _width, 0, 0, width, height);
- _scumm->_system->update_screen();
- } else {
- warning("ScummRenderer: Skipping frame %d to catch up", getFrame());
- }
- _scumm->processKbd();
-}
-
-bool ScummRenderer::prematureClose() {
- return _scumm->_videoFinished || _scumm->_saveLoadFlag;
-}
-
-bool ScummRenderer::update() {
- _pending_updates++;
- return true;
-}
-
diff --git a/scumm/smush/scumm_renderer.h b/scumm/smush/scumm_renderer.h
deleted file mode 100644
index 1432cd8af8..0000000000
--- a/scumm/smush/scumm_renderer.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#ifndef SCUMM_RENDERER_H
-#define SCUMM_RENDERER_H
-
-#include "config.h"
-
-#ifdef DEBUG
-# ifndef NO_DEBUG_SCUMM_RENDERER
-# define DEBUG_SCUMM_RENDERER
-# endif
-#else
-# ifdef DEBUG_SCUMM_RENDERER
-# error DEBUG_SCUMM_RENDERER defined without DEBUG
-# endif
-#endif
-
-#include "brenderer.h"
-
-class ScummMixer;
-class Scumm;
-class Mixer;
-
-class ScummRenderer : public BaseRenderer {
-private:
- Scumm *_scumm;
- ScummMixer *_smixer;
- uint32 _insaneSpeed;
- volatile int _pending_updates;
-public:
- ScummRenderer(Scumm *scumm, uint32 speed);
- virtual ~ScummRenderer();
- virtual bool wait(int32 ms);
- bool update();
-protected:
- virtual bool initFrame(const Point &size);
- virtual byte *lockFrame(int32 frame);
- virtual void clean();
- virtual bool startDecode(const char *fname, int32 version, int32 nbframes);
- virtual bool setPalette(const Palette & pal);
- virtual void save();
- virtual Mixer *getMixer();
- virtual bool prematureClose();
-};
-
-#endif
diff --git a/scumm/smush/smush_font.cpp b/scumm/smush/smush_font.cpp
new file mode 100644
index 0000000000..2e1207be38
--- /dev/null
+++ b/scumm/smush/smush_font.cpp
@@ -0,0 +1,489 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include <stdafx.h>
+#include "common/util.h"
+#include "common/engine.h"
+#include "common/file.h"
+#include "scumm/scumm.h"
+
+#include "smush_font.h"
+
+SmushFont::SmushFont(bool use_original_colors, bool new_colors) :
+ _nbChars(0),
+ _color(-1),
+ _new_colors(new_colors),
+ _original(use_original_colors) {
+ for(int i = 0; i < 256; i++)
+ _chars[i].chr = NULL;
+}
+
+SmushFont::~SmushFont() {
+ for(int i = 0; i < _nbChars; i++) {
+ if(_chars[i].chr)
+ delete []_chars[i].chr;
+ }
+}
+
+bool SmushFont::loadFont(const char *filename, const char *directory) {
+ debug(2, "SmushFont::loadFont() called");
+
+ File file;
+ file.open(filename, directory);
+ if (file.isOpen() == false) {
+ warning("SmushFont::loadFont() Can't open font file: %s/%s", directory, filename);
+ return false;
+ }
+
+ uint32 tag = file.readUint32BE();
+ if (tag != 'ANIM') {
+ debug(2, "SmushFont::loadFont() there is no ANIM chunk in font header");
+ return false;
+ }
+
+ if (_dataSrc != NULL) {
+ free(_dataSrc);
+ _dataSrc = NULL;
+ }
+
+ uint32 length = file.readUint32BE();
+ _dataSrc = (byte *)malloc(length);
+ file.read(_dataSrc, length);
+ file.close();
+
+ if (READ_BE_UINT32(_dataSrc) != 'AHDR') {
+ debug(2, "SmushFont::loadFont() there is no AHDR chunk in font header");
+ free(_dataSrc);
+ _dataSrc = NULL;
+ return false;
+ }
+
+ _nbChars = READ_LE_UINT16(_dataSrc + 10);
+ int32 offset = READ_BE_UINT32(_dataSrc + 4) + 8;
+ for (int l = 0; l < _nbChars; l++) {
+ if (READ_BE_UINT32(_dataSrc + offset) == 'FRME') {
+ offset += 8;
+ if (READ_BE_UINT32(_dataSrc + offset) == 'FOBJ') {
+ _chars[l].width = READ_LE_UINT16(_dataSrc + offset + 14);
+ _chars[l].height = READ_LE_UINT16(_dataSrc + offset + 16);
+ _chars[l].chr = new byte[_chars[l].width * _chars[l].height + 1000];
+ decodeCodec(_chars[l].chr, _dataSrc + offset + 22, READ_BE_UINT32(_dataSrc + offset + 4) - 14);
+ offset += READ_BE_UINT32(_dataSrc + offset + 4) + 8;
+ } else {
+ debug(2, "SmushFont::loadFont(%s, %s) there is no FOBJ chunk in FRME chunk %d (offset %x)", filename, directory, l, offset);
+ break;
+ }
+ } else {
+ debug(2, "SmushFont::loadFont(%s, %s) there is no FRME chunk %d (offset %x)", filename, directory, l, offset);
+ break;
+ }
+ }
+
+ free(_dataSrc);
+ _dataSrc = NULL;
+ return true;
+}
+
+int SmushFont::getCharWidth(byte v) {
+ if(v >= _nbChars)
+ error("invalid character in SmushFont::charWidth : %d (%d)", v, _nbChars);
+
+ return _chars[v].width;
+}
+
+int SmushFont::getCharHeight(byte v) {
+ if(v >= _nbChars)
+ error("invalid character in SmushFont::charHeight : %d (%d)", v, _nbChars);
+
+ return _chars[v].height;
+}
+
+int SmushFont::getStringWidth(char *str) {
+ int ret = 0;
+
+ while(*str) {
+ ret += getCharWidth(*str++);
+ }
+
+ return ret;
+}
+
+int SmushFont::getStringHeight(char *str) {
+ int ret = 0;
+
+ for(int i = 0; str[i] != 0; i++) {
+ int h = getCharHeight(str[i]);
+ ret = MAX(ret, h);
+ }
+
+ return ret;
+}
+
+void SmushFont::decodeCodec(byte *dst, byte *src, int length) {
+ int size_line, num;
+ byte *src2 = src;
+ byte *dst2 = dst;
+ byte val;
+
+ do {
+ size_line = READ_LE_UINT16(src2);
+ src2 += 2;
+ length -= 2;
+
+ while (size_line != 0) {
+ num = *src2++;
+ val = *src2++;
+ memset(dst2, val, num);
+ dst2 += num;
+ length -= 2;
+ size_line -= 2;
+ if (size_line != 0) {
+ num = READ_LE_UINT16(src2) + 1;
+ src2 += 2;
+ memcpy(dst2, src2, num);
+ dst2 += num;
+ src2 += num;
+ length -= num + 2;
+ size_line -= num + 2;
+ }
+ }
+ dst2--;
+
+ } while (length > 1);
+}
+
+int SmushFont::drawChar(byte *buffer, int dst_width, int x, int y, byte chr) {
+ int w = _chars[chr].width;
+ int h = _chars[chr].height;
+ byte *src = _chars[chr].chr;
+ byte *dst = buffer + dst_width * y + x;
+
+ if(_original) {
+ for(int32 j = 0; j < h; j++) {
+ for(int32 i = 0; i < w; i++) {
+ char value = *src++;
+ if(value) dst[i] = value;
+ }
+ dst += dst_width;
+ }
+ } else {
+ char color = (_color != -1) ? _color : 1;
+ if (_new_colors == true) {
+ for(int j = 0; j < h; j++) {
+ for(int i = 0; i < w; i++) {
+ char value = *src++;
+ if(value == -color) {
+ dst[i] = 0xFF;
+ } else if(value == -31) {
+ dst[i] = 0;
+ } else if(value) {
+ dst[i] = value;
+ }
+ }
+ dst += dst_width;
+ }
+ } else {
+ for(int j = 0; j < h; j++) {
+ for(int i = 0; i < w; i++) {
+ char value = *src++;
+ if(value == 1) {
+ dst[i] = color;
+ } else if(value) {
+ dst[i] = 0;
+ }
+ }
+ dst += dst_width;
+ }
+ }
+ }
+ return w;
+}
+
+static char **split(char *str, char sep) {
+ char **ret = new char *[62];
+ int n = 0;
+ const char *i = str;
+ char *j = strchr(i, sep);
+
+ while(j != NULL) {
+ assert(n < 60);
+ ret[n] = new char[j - i + 1];
+ memcpy(ret[n], i, j - i);
+ ret[n++][j - i] = 0;
+ i = j + 1;
+ j = strchr(i, sep);
+ }
+
+ ret[n] = new char[strlen(i) + 1];
+ memcpy(ret[n], i, strlen(i));
+ ret[n++][strlen(i)] = 0;
+ ret[n] = 0;
+
+ return ret;
+}
+
+void SmushFont::drawSubstring(char *str, byte *buffer, int dst_width, int x, int y) {
+ for(int i = 0; str[i] != 0; i++)
+ x += drawChar(buffer, dst_width, x, y, str[i]);
+}
+
+void SmushFont::drawStringAbsolute(char *str, byte *buffer, int dst_width, int x, int y) {
+ debug(9, "SmushFont::drawStringAbsolute(%s, %d, %d)", str, x, y);
+
+ while(str) {
+ char line[256];
+ char *pos = strchr(str, '\n');
+ if(pos) {
+ memcpy(line, str, pos - str - 1);
+ line[pos - str - 1] = 0;
+ str = pos + 1;
+ } else {
+ strcpy(line, str);
+ str = 0;
+ }
+ drawSubstring(line, buffer, dst_width, x, y);
+ y += getStringHeight(line);
+ }
+}
+
+void SmushFont::drawStringCentered(char *str, byte *buffer, int dst_width, int dst_height, int y, int xmin, int width, int offset) {
+ debug(9, "SmushFont::drawStringCentered(%s, %d, %d)", str, xmin, y);
+
+ if ((strchr(str, '\n') != 0)) {
+ char *z = strchr(str, '\n');
+ *z = 0;
+ }
+ char **words = split(str, ' ');
+ int nb_sub = 0;
+
+ while(words[nb_sub])
+ nb_sub++;
+
+ int *sizes = new int[nb_sub];
+ int i = 0, max_width = 0, height = 0, nb_subs = 0;
+
+ for(i = 0; i < nb_sub; i++)
+ sizes[i] = getStringWidth(words[i]);
+
+ char **substrings = new char *[nb_sub];
+ int *substr_widths = new int[nb_sub];
+ int space_width = getCharWidth(' ');
+
+ i = 0;
+ while(i < nb_sub) {
+ int substr_width = sizes[i];
+ char *substr = new char[1000];
+ strcpy(substr, words[i]);
+ int j = i + 1;
+
+ while(j < nb_sub && (substr_width + space_width + sizes[j]) < width) {
+ substr_width += sizes[j++] + space_width;
+ }
+
+ for(int k = i + 1; k < j; k++) {
+ strcat(substr, " ");
+ strcat(substr, words[k]);
+ }
+
+ substrings[nb_subs] = substr;
+ substr_widths[nb_subs++] = substr_width;
+ if(substr_width > max_width)
+ max_width = substr_width;
+ i = j;
+ height += getStringHeight(substr);
+ }
+
+ delete []sizes;
+ for(i = 0; i < nb_sub; i++) {
+ delete []words[i];
+ }
+ delete []words;
+
+ max_width = (max_width + 1) >> 1;
+ int x = xmin + width / 2;
+ x += offset - dst_width / 2;
+
+ if(x < max_width) x = max_width;
+ if(x + max_width > dst_width) {
+ x = dst_width - max_width;
+ }
+
+ if(y + height > dst_height) {
+ y = dst_height - height;
+ }
+
+ for(i = 0; i < nb_subs; i++) {
+ int substr_width = substr_widths[i];
+ drawSubstring(substrings[i], buffer, dst_width, x - substr_width / 2, y);
+ y += getStringHeight(substrings[i]);
+ delete []substrings[i];
+ }
+
+ delete []substr_widths;
+ delete []substrings;
+}
+
+void SmushFont::drawStringWrap(char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width) {
+ debug(9, "SmushFont::drawStringWrap(%s, %d, %d)", str, x, y);
+
+ if ((strchr(str, '\n') != 0)) {
+ char *z = strchr(str, '\n');
+ *z = 0;
+ }
+ char ** words = split(str, ' ');
+ int nb_sub = 0;
+
+ while(words[nb_sub])
+ nb_sub++;
+
+ int *sizes = new int[nb_sub];
+ int i = 0, max_width = 0, height = 0, nb_subs = 0, left_x;
+
+ for(i = 0; i < nb_sub; i++)
+ sizes[i] = getStringWidth(words[i]);
+
+ char **substrings = new char *[nb_sub];
+ int *substr_widths = new int[nb_sub];
+ int space_width = getCharWidth(' ');
+
+ i = 0;
+ while(i < nb_sub) {
+ int substr_width = sizes[i];
+ char *substr = new char[1000];
+ strcpy(substr, words[i]);
+ int j = i + 1;
+
+ while(j < nb_sub && (substr_width + space_width + sizes[j]) < width) {
+ substr_width += sizes[j++] + space_width;
+ }
+
+ for(int k = i + 1; k < j; k++) {
+ strcat(substr, " ");
+ strcat(substr, words[k]);
+ }
+
+ substrings[nb_subs] = substr;
+ substr_widths[nb_subs++] = substr_width;
+ i = j;
+ height += getStringHeight(substr);
+ }
+
+ delete []sizes;
+ for(i = 0; i < nb_sub; i++) {
+ delete []words[i];
+ }
+ delete []words;
+
+ if(y + height > dst_height) {
+ y = dst_height - height;
+ }
+
+ for(i = 0; i < nb_subs; i++)
+ max_width = MAX(max_width, substr_widths[i]);
+
+ if(max_width + x > dst_width)
+ left_x = dst_width - max_width + getCharWidth(' ');
+ else
+ left_x = x;
+
+ if(max_width + left_x > dst_height)
+ left_x = dst_width - max_width;
+
+ for(i = 0; i < nb_subs; i++) {
+ drawSubstring(substrings[i], buffer, dst_width, left_x, y);
+ y += getStringHeight(substrings[i]);
+ delete []substrings[i];
+ }
+
+ delete []substr_widths;
+ delete []substrings;
+}
+
+void SmushFont::drawStringWrapCentered(char *str, byte *buffer, int dst_width, int dst_height, int x, int32 y, int width) {
+ debug(9, "SmushFont::drawStringWrapCentered(%s, %d, %d)", str, x, y);
+
+ int max_substr_width = 0;
+ if ((strchr(str, '\n') != 0)) {
+ char *z = strchr(str, '\n');
+ *z = 0;
+ }
+ char **words = split(str, ' ');
+ int nb_sub = 0;
+
+ while(words[nb_sub])
+ nb_sub++;
+
+ int *sizes = new int[nb_sub];
+ int i = 0, height = 0, nb_subs = 0;
+
+ for(i = 0; i < nb_sub; i++)
+ sizes[i] = getStringWidth(words[i]);
+
+ char **substrings = new char *[nb_sub];
+ int *substr_widths = new int[nb_sub];
+ int space_width = getCharWidth(' ');
+
+ i = 0;
+ width = MIN(width, dst_width);
+ while(i < nb_sub) {
+ int substr_width = sizes[i];
+ char *substr = new char[1000];
+ strcpy(substr, words[i]);
+ int j = i + 1;
+
+ while(j < nb_sub && (substr_width + space_width + sizes[j]) < width) {
+ substr_width += sizes[j++] + space_width;
+ }
+
+ for(int k = i + 1; k < j; k++) {
+ strcat(substr, " ");
+ strcat(substr, words[k]);
+ }
+
+ substrings[nb_subs] = substr;
+ substr_widths[nb_subs++] = substr_width;
+ max_substr_width = MAX(substr_width, max_substr_width);
+ i = j;
+ height += getStringHeight(substr);
+ }
+
+ delete []sizes;
+ for(i = 0; i < nb_sub; i++) {
+ delete []words[i];
+ }
+ delete []words;
+
+ if(y + height > dst_height) {
+ y = dst_height - height;
+ }
+
+ x = (dst_width - max_substr_width) / 2;
+
+ for(i = 0; i < nb_subs; i++) {
+ int substr_width = substr_widths[i];
+ drawSubstring(substrings[i], buffer, dst_width, x + (max_substr_width - substr_width) / 2, y);
+ y += getStringHeight(substrings[i]);
+ delete []substrings[i];
+ }
+
+ delete []substr_widths;
+ delete []substrings;
+}
diff --git a/scumm/smush/smush_font.h b/scumm/smush/smush_font.h
new file mode 100644
index 0000000000..39ecd939f9
--- /dev/null
+++ b/scumm/smush/smush_font.h
@@ -0,0 +1,67 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef SMUSH_FONT_H
+#define SMUSH_FONT_H
+
+#include "common/scummsys.h"
+
+class SmushFont {
+private:
+
+ int _nbChars;
+ byte _color;
+ bool _new_colors;
+ bool _original;
+ byte *_dataSrc;
+
+ struct {
+ int width;
+ int height;
+ byte *chr;
+ } _chars[256];
+
+public:
+
+ SmushFont(bool use_original_colors, bool new_colors);
+ ~SmushFont();
+
+protected:
+
+ int getCharWidth(byte c);
+ int getStringWidth(char *str);
+ int getCharHeight(byte c);
+ int getStringHeight(char *str);
+ int drawChar(byte *buffer, int dst_width, int x, int y, byte chr);
+ void drawSubstring(char *str, byte *buffer, int dst_width, int x, int y);
+ void decodeCodec(byte *dst, byte *src, int length);
+
+public:
+
+ bool loadFont(const char *filename, const char *directory);
+ void setColor(byte c) { _color = c; }
+ void drawStringCentered(char *str, byte *buffer, int dst_width, int dst_height, int y, int xmin, int width, int offset);
+ void drawStringWrap(char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width);
+ void drawStringWrapCentered(char *str, byte *buffer, int dst_width, int dst_height, int x, int32 y, int width);
+ void drawStringAbsolute(char *str, byte *buffer, int dst_width, int x, int y);
+};
+
+#endif
diff --git a/scumm/smush/smush_mixer.cpp b/scumm/smush/smush_mixer.cpp
new file mode 100644
index 0000000000..c7ed4708b6
--- /dev/null
+++ b/scumm/smush/smush_mixer.cpp
@@ -0,0 +1,166 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include <stdafx.h>
+#include "common/util.h"
+#include "smush_mixer.h"
+#include "channel.h"
+#include "sound/mixer.h"
+#include "scumm/scumm.h"
+#include "scumm/sound.h"
+#include "scumm/imuse.h"
+
+SmushMixer::SmushMixer(SoundMixer *m) :
+ _mixer(m),
+ _soundFrequency(22050),
+ _nextIndex(_mixer->_beginSlots) {
+ for(int32 i = _mixer->_beginSlots; i < SoundMixer::NUM_CHANNELS; i++) {
+ _channels[i].id = -1;
+ _channels[i].chan = NULL;
+ _channels[i].first = true;
+ }
+}
+
+SmushMixer::~SmushMixer() {
+}
+
+SmushChannel *SmushMixer::findChannel(int32 track) {
+ debug(9, "SmushMixer::findChannel(%d)", track);
+ for(int32 i = _mixer->_beginSlots; i < SoundMixer::NUM_CHANNELS; i++) {
+ if(_channels[i].id == track)
+ return _channels[i].chan;
+ }
+ return NULL;
+}
+
+bool SmushMixer::addChannel(SmushChannel *c) {
+ int32 track = c->getTrackIdentifier();
+ int i;
+
+ debug(9, "SmushMixer::addChannel(%d)", track);
+
+ for(i = _mixer->_beginSlots; i < SoundMixer::NUM_CHANNELS; i++) {
+ if(_channels[i].id == track)
+ warning("SmushMixer::addChannel(%d) : channel already exist !", track);
+ }
+ if(_nextIndex >= SoundMixer::NUM_CHANNELS)
+ _nextIndex = _mixer->_beginSlots;
+
+ for(i = _nextIndex; i < SoundMixer::NUM_CHANNELS; i++) {
+ if(_channels[i].chan == NULL || _channels[i].id == -1) {
+ _channels[i].chan = c;
+ _channels[i].id = track;
+ _channels[i].first = true;
+ _nextIndex = i + 1;
+ return true;
+ }
+ }
+
+ for(i = _mixer->_beginSlots; i < _nextIndex; i++) {
+ if(_channels[i].chan == NULL || _channels[i].id == -1) {
+ _channels[i].chan = c;
+ _channels[i].id = track;
+ _channels[i].first = true;
+ _nextIndex = i + 1;
+ return true;
+ }
+ }
+
+ warning("_nextIndex == %d\n", _nextIndex);
+
+ for(i = _mixer->_beginSlots; i < SoundMixer::NUM_CHANNELS; i++) {
+ warning("channel %d : %p(%d, %d) %d %d\n", i, (void *)_channels[i].chan,
+ _channels[i].chan ? _channels[i].chan->getTrackIdentifier() : -1,
+ _channels[i].chan ? _channels[i].chan->isTerminated() : 1,
+ _channels[i].first, _channels[i].mixer_index);
+ }
+
+ error("SmushMixer::add_channel() : no more channel available");
+ return false;
+}
+
+bool SmushMixer::handleFrame() {
+ debug(9, "SmushMixer::handleFrame()");
+ for(int i = _mixer->_beginSlots; i < SoundMixer::NUM_CHANNELS; i++) {
+ if(_channels[i].id != -1) {
+ if(_channels[i].chan->isTerminated()) {
+ delete _channels[i].chan;
+ _channels[i].id = -1;
+ _channels[i].chan = NULL;
+ } else {
+ int32 rate;
+ bool stereo, is_short;
+
+ _channels[i].chan->getParameters(rate, stereo, is_short);
+ int32 size = _channels[i].chan->availableSoundData();
+ int32 flags = stereo ? SoundMixer::FLAG_STEREO : 0;
+
+ if(is_short) {
+ short *data = new int16[size * (stereo ? 2 : 1) * 2];
+ _channels[i].chan->getSoundData(data, size);
+ if(_channels[i].chan->getRate() == 11025) size *= 2;
+ size *= stereo ? 4 : 2;
+
+ if(_silentMixer == false) {
+ if(_channels[i].first) {
+ _channels[i].mixer_index = _mixer->playStream(NULL, -1, data, size, rate, flags | SoundMixer::FLAG_16BITS);
+ _channels[i].first = false;
+ } else {
+ _mixer->append(_channels[i].mixer_index, data, size, rate, flags | SoundMixer::FLAG_16BITS);
+ }
+ }
+
+ delete []data;
+ } else {
+ int8 *data = new int8[size * (stereo ? 2 : 1) * 2];
+ _channels[i].chan->getSoundData(data, size);
+ if(_channels[i].chan->getRate() == 11025) size *= 2;
+ size *= stereo ? 2 : 1;
+
+ if(_silentMixer == false) {
+ if(_channels[i].first) {
+ _channels[i].mixer_index = _mixer->playStream(NULL, -1, data, size, rate, flags | SoundMixer::FLAG_UNSIGNED);
+ _channels[i].first = false;
+ } else {
+ _mixer->append(_channels[i].mixer_index, data, size, rate, flags | SoundMixer::FLAG_UNSIGNED);
+ }
+ }
+
+ delete []data;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+bool SmushMixer::stop() {
+ debug(9, "SmushMixer::stop()");
+ for(int i = _mixer->_beginSlots; i < SoundMixer::NUM_CHANNELS; i++) {
+ if(_channels[i].id != -1) {
+ delete _channels[i].chan;
+ _channels[i].id = -1;
+ _channels[i].chan = NULL;
+ }
+ }
+ return true;
+}
+
diff --git a/scumm/smush/config.h b/scumm/smush/smush_mixer.h
index 6ba4341e07..ea446a228e 100644
--- a/scumm/smush/config.h
+++ b/scumm/smush/smush_mixer.h
@@ -19,24 +19,34 @@
*
*/
-#ifndef SMUSH_CONFIG_H
-#define SMUSH_CONFIG_H
-
#include <stdafx.h>
-#include <scummsys.h>
-#ifndef NDEBUG
-#define DEBUG
-#endif
+#include "sound/mixer.h"
+
+class SmushChannel;
+
+class SmushMixer {
+private:
+
+ SoundMixer *_mixer;
+ struct {
+ int id;
+ SmushChannel *chan;
+ bool first;
+ int mixer_index;
+ } _channels[SoundMixer::NUM_CHANNELS];
-#define NO_DEBUG_MIXER
-#define NO_DEBUG_CHANNEL
-#define NO_DEBUG_CLIPPER
-#define NO_DEBUG_CODEC1
-#define NO_DEBUG_CODEC37
-#define NO_DEBUG_CODEC44
-#define NO_DEBUG_WIN32
-#define NO_DEBUG_FONT_RENDERER
+ int _nextIndex;
+ int _soundFrequency;
+public:
-#endif
+ SmushMixer(SoundMixer *);
+ virtual ~SmushMixer();
+ SmushChannel *findChannel(int32 track);
+ bool addChannel(SmushChannel *c);
+ bool handleFrame();
+ bool stop();
+ bool update();
+ bool _silentMixer;
+};
diff --git a/scumm/smush/player.cpp b/scumm/smush/smush_player.cpp
index 437cdbe645..d114718d7e 100644
--- a/scumm/smush/player.cpp
+++ b/scumm/smush/smush_player.cpp
@@ -22,39 +22,38 @@
#include <stdafx.h>
#include "common/file.h"
#include "common/util.h"
-#include "common/engine.h" // for debug, warning, error
+#include "common/engine.h"
#include "scumm/scumm.h"
+#include "scumm/sound.h"
+#include "scumm/imuse.h"
#include "sound/mixer.h"
-
-#include "player.h"
-
-#include "mixer.h"
-#include "renderer.h"
-#include "frenderer.h"
+#include "smush_player.h"
+#include "smush_mixer.h"
+#include "smush_font.h"
#include "channel.h"
+#include "chunk.h"
#include "chunk_type.h"
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-const int WAIT = 100;
-
-const int32 MAX_STRINGS = 200;
+const int MAX_STRINGS = 200;
class StringResource {
private:
+
struct {
- int32 id;
+ int id;
char *string;
} _strings[MAX_STRINGS];
- int32 _nbStrings;
- int32 _lastId;
+
+ int _nbStrings;
+ int _lastId;
char *_lastString;
+
public:
- StringResource() : _nbStrings(0), _lastId(-1) {};
+
+ StringResource() :
+ _nbStrings(0),
+ _lastId(-1) {
+ };
~StringResource() {
for(int32 i = 0; i < _nbStrings; i++) {
delete []_strings[i].string;
@@ -62,22 +61,22 @@ public:
}
bool init(char *buffer, int32 length) {
-#ifdef DEBUG
- debug(9, "parsing string resources...");
-#endif
char *def_start = strchr(buffer, '#');
while(def_start != NULL) {
char *def_end = strchr(def_start, '\n');
assert(def_end != NULL);
+
char *id_end = def_end;
while(id_end >= def_start && !isdigit(*(id_end-1))) {
id_end--;
}
+
assert(id_end > def_start);
char *id_start = id_end;
while(isdigit(*(id_start - 1))) {
id_start--;
}
+
char idstring[32];
memcpy(idstring, id_start, id_end - id_start);
idstring[id_end - id_start] = 0;
@@ -120,9 +119,6 @@ public:
memmove(line_end, line_start, strlen(line_start)+1);
}
}
-#ifdef DEBUG
- debug(9, "Inserting (%s)%d == \"%s\"", idstring, id, value);
-#endif
_strings[_nbStrings].id = id;
_strings[_nbStrings].string = value;
_nbStrings ++;
@@ -131,7 +127,7 @@ public:
return true;
}
- const char *get(int32 id) {
+ char *get(int id) {
if(id == _lastId) {
return _lastString;
}
@@ -149,85 +145,136 @@ public:
}
};
-void SmushPlayer::show(const char *p) {
- if(strcmp(p, "subtitles") == 0) {
- _subtitles = true;
- } else if(strcmp(p, "bgmusic") == 0) {
- _bgmusic = true;
- } else if(strcmp(p, "voices") == 0) {
- _voices = true;
- } else {
- int id = atoi(p);
- if(id < 0 || id > 36) {
- error("invalid parameter to show");
- }
- _skips[id] = true;
+static StringResource *getStrings(const char *file, const char *directory, bool is_encoded) {
+ debug(7, "trying to read text ressources from %s", file);
+ File theFile;
+
+ theFile.open(file, directory);
+ if (!theFile.isOpen()) {
+ return 0;
}
-}
+ int32 length = theFile.size();
+ char *filebuffer = new char [length + 1];
+ assert(filebuffer);
+ theFile.read(filebuffer, length);
+ filebuffer[length] = 0;
-void SmushPlayer::hide(const char *p) {
- if(strcmp(p, "subtitles") == 0) {
- _subtitles = false;
- } else if(strcmp(p, "bgmusic") == 0) {
- _bgmusic = false;
- } else if(strcmp(p, "voices") == 0) {
- _voices = false;
- } else {
- int32 id = atoi(p);
- if(id < 0 || id > 36) {
- error("invalid parameter to hide");
+ if(is_encoded) {
+ static const int32 ETRS_HEADER_LENGTH = 16;
+ assert(length > ETRS_HEADER_LENGTH);
+ Chunk::type type = READ_BE_UINT32(filebuffer);
+
+ if(type != TYPE_ETRS) {
+ delete [] filebuffer;
+ return getStrings(file, directory, false);
}
- _skips[id] = false;
+
+ char *old = filebuffer;
+ filebuffer = new char[length - ETRS_HEADER_LENGTH + 1];
+ for(int32 i = ETRS_HEADER_LENGTH; i < length; i++) {
+ filebuffer[i - ETRS_HEADER_LENGTH] = old[i] ^ 0xCC;
+ }
+ filebuffer[length - ETRS_HEADER_LENGTH] = '\0';
+ delete []old;
+ length -= ETRS_HEADER_LENGTH;
}
+ StringResource *sr = new StringResource;
+ assert(sr);
+ sr->init(filebuffer, length);
+ delete []filebuffer;
+ return sr;
}
-SmushPlayer::SmushPlayer(Renderer * renderer, bool wait, bool sound) :
- _version(-1),
- _secondaryVersion(0),
- _soundFrequency(0),
- _nbframes(0),
- _mixer(0),
- _renderer(renderer),
- _strings(0),
- _frameSize(-1, -1),
- _frame(0),
- _outputSound(sound),
- _wait(wait),
- _alreadyInit(false),
- _codec37Called(false),
- _skipNext(false),
- _subtitles(true),
- _bgmusic(true),
- _voices(true),
- _curBuffer(0),
- _IACTchannel(-1),
- _IACTpos(0),
- _storeFrame(false),
- _frameBuffer(NULL) {
- _fr[0] = _fr[1] = _fr[2] = _fr[3] = _fr[4] = 0;
- assert(_renderer != 0);
+SmushPlayer *player;
+
+void smush_callback(void *ptr) {
+ player->_smushProcessFrame = true;
+ player->parseNextFrame();
+ player->_smushProcessFrame = false;
+}
+
+SmushPlayer::SmushPlayer(Scumm *scumm, int speed, bool subtitles) {
+ player = this;
+ _version = -1;
+ _nbframes = 0;
+ _smixer = 0;
+ _strings = NULL;
+ _skipNext = false;
+ _data = NULL;
+ _storeFrame = false;
+ _width = 0;
+ _height = 0;
+ _frameBuffer = NULL;
+ _sf[0] = NULL;
+ _sf[1] = NULL;
+ _sf[2] = NULL;
+ _sf[3] = NULL;
+ _sf[4] = NULL;
+ _scumm = scumm;
+ _IACTchannel = -1,
+ _IACTpos = 0;
+ _soundFrequency = 22050;
+ _speed = speed;
+ _subtitles = subtitles;
+ _smushProcessFrame = false;
}
SmushPlayer::~SmushPlayer() {
- clean();
+ deinit();
}
-void SmushPlayer::updatePalette(void) {
- _renderer->setPalette(_pal);
+void SmushPlayer::init() {
+
+ _frame = 0;
+
+ _scumm->_sound->pauseBundleMusic(true);
+ if (_scumm->_imuseDigital) {
+ _scumm->_imuseDigital->pause(true);
+ }
+ _scumm->_videoFinished = false;
+ _scumm->_insaneState = true;
+
+ _smixer = new SmushMixer(_scumm->_mixer);
+
+ _scumm->setDirtyColors(0, 255);
+ _smixer->_silentMixer = _scumm->_silentDigitalImuse;
+ _scumm->_smushPlay = true;
+ _data = _scumm->virtscr[0].screenPtr + _scumm->virtscr[0].xstart;
+ _scumm->_timer->installProcedure(&smush_callback, _speed);
+
+ _alreadyInit = false;
}
-void SmushPlayer::clean() {
- if(_strings)
+void SmushPlayer::deinit() {
+ _scumm->_smushPlay = false;
+ _scumm->_timer->releaseProcedure(&smush_callback);
+ while (_smushProcessFrame) {}
+
+ for(int i = 0; i < 5; i++) {
+ if (_sf[i]) {
+ delete _sf[i];
+ _sf[i] = NULL;
+ }
+ }
+
+ if(_strings) {
delete _strings;
- if(_fr[0]) delete _fr[0];
- if(_fr[1]) delete _fr[1];
- if(_fr[2]) delete _fr[2];
- if(_fr[3]) delete _fr[3];
- if(_fr[4]) delete _fr[4];
+ _strings = NULL;
+ }
- if (_frameBuffer != NULL) {
- free(_frameBuffer);
+ if(_smixer) {
+ _smixer->stop();
+ delete _smixer;
+ _smixer = NULL;
+ }
+
+ _scumm->_insaneState = false;
+ _scumm->exitCutscene();
+ if (_scumm->_imuseDigital) {
+ _scumm->_imuseDigital->pause(false);
}
+ _scumm->_sound->pauseBundleMusic(false);
+ _scumm->_fullRedraw = 1;
}
void SmushPlayer::checkBlock(const Chunk &b, Chunk::type type_expected, uint32 min_size) {
@@ -235,22 +282,22 @@ void SmushPlayer::checkBlock(const Chunk &b, Chunk::type type_expected, uint32 m
error("Chunk type is different from expected : %d != %d", b.getType(), type_expected);
}
if(min_size > b.getSize()) {
- error( "Chunk size is inferior than minimum required size : %d < %d", b.getSize(), min_size);
+ error("Chunk size is inferior than minimum required size : %d < %d", b.getSize(), min_size);
}
}
void SmushPlayer::handleSoundBuffer(int32 track_id, int32 index, int32 max_frames, int32 flags, int32 vol, int32 bal, Chunk &b, int32 size) {
- debug(6, "smush_player::handleSoundBuffer(%d)", track_id);
- if(!_voices && (flags & 128) == 128) {
- return;
- }
- if(!_bgmusic && (flags & 64) == 64) {
- return;
- }
- _Channel *c = _mixer->findChannel(track_id);
- if(c == 0) {
+ debug(6, "SmushPlayer::handleSoundBuffer(%d)", track_id);
+// if((flags & 128) == 128) {
+// return;
+// }
+// if((flags & 64) == 64) {
+// return;
+// }
+ SmushChannel *c = _smixer->findChannel(track_id);
+ if(c == NULL) {
c = new SaudChannel(track_id, _soundFrequency);
- _mixer->addChannel(c);
+ _smixer->addChannel(c);
}
if(index == 0) {
c->setParameters(max_frames, flags, vol, bal);
@@ -263,9 +310,7 @@ void SmushPlayer::handleSoundBuffer(int32 track_id, int32 index, int32 max_frame
void SmushPlayer::handleSoundFrame(Chunk &b) {
checkBlock(b, TYPE_PSAD);
debug(6, "SmushPlayer::handleSoundFrame()");
- if(!_outputSound) {
- return;
- }
+
int32 track_id = b.getWord();
int32 index = b.getWord();
int32 max_frames = b.getWord();
@@ -292,31 +337,27 @@ void SmushPlayer::handleSkip(Chunk &b) {
}
void SmushPlayer::handleStore(Chunk &b) {
+ debug(6, "SmushPlayer::handleStore()");
checkBlock(b, TYPE_STOR, 4);
_storeFrame = true;
- debug(6, "SmushPlayer::handleStore()");
}
void SmushPlayer::handleFetch(Chunk &b) {
- checkBlock(b, TYPE_FTCH, 6);
debug(6, "SmushPlayer::handleFetch()");
-
- if(_curBuffer == NULL) {
- _curBuffer = _renderer->lockFrame(_frame);
- }
+ checkBlock(b, TYPE_FTCH, 6);
if (_frameBuffer != NULL) {
- memcpy(_curBuffer, _frameBuffer, _frameSize.getX() * _frameSize.getY());
+ memcpy(_data, _frameBuffer, _width * _height);
}
}
void SmushPlayer::handleImuseBuffer(int32 track_id, int32 index, int32 nbframes, int32 size, int32 unk1, int32 track_flags, Chunk &b, int32 bsize) {
int32 track = (track_flags << 16) | track_id;
- _Channel *c = _mixer->findChannel(track);
+ SmushChannel *c = _smixer->findChannel(track);
if(c == 0) {
c = new ImuseChannel(track, _soundFrequency);
- _mixer->addChannel(c);
+ _smixer->addChannel(c);
}
if(index == 0)
c->setParameters(nbframes, size, track_flags, unk1);
@@ -325,13 +366,22 @@ void SmushPlayer::handleImuseBuffer(int32 track_id, int32 index, int32 nbframes,
c->appendData(b, bsize);
}
-void SmushPlayer::handleImuseAction8(Chunk &b, int32 flags, int32 unknown, int32 track_flags) {
+void SmushPlayer::handleImuseAction(Chunk &b) {
+ checkBlock(b, TYPE_IACT, 8);
+ debug(6, "SmushPlayer::handleImuseAction()");
+
+ int code = b.getWord();
+ int flags = b.getWord();
+ int unknown = b.getShort();
+ int track_flags = b.getWord();
+
assert(flags == 46 && unknown == 0);
- int32 track_id = b.getWord();
- int32 index = b.getWord();
- int32 nbframes = b.getWord();
+ int track_id = b.getWord();
+ int index = b.getWord();
+ int nbframes = b.getWord();
int32 size = b.getDword();
int32 bsize = b.getSize() - 18;
+
if (g_scumm->_gameId != GID_CMI) {
handleImuseBuffer(track_id, index, nbframes, size, unknown, track_flags, b, bsize);
} else {
@@ -382,10 +432,10 @@ void SmushPlayer::handleImuseAction8(Chunk &b, int32 flags, int32 unknown, int32
} while (--count);
if (_IACTchannel == -1) {
- _IACTchannel = g_scumm->_mixer->playStream(NULL, -1, output_data, 0x1000, 22050,
+ _IACTchannel = _scumm->_mixer->playStream(NULL, -1, output_data, 0x1000, 22050,
SoundMixer::FLAG_STEREO | SoundMixer::FLAG_16BITS, -1, 200000);
} else {
- g_scumm->_mixer->append(_IACTchannel, output_data, 0x1000, 22050,
+ _scumm->_mixer->append(_IACTchannel, output_data, 0x1000, 22050,
SoundMixer::FLAG_STEREO | SoundMixer::FLAG_16BITS);
}
@@ -419,53 +469,23 @@ void SmushPlayer::handleImuseAction8(Chunk &b, int32 flags, int32 unknown, int32
}
}
-void SmushPlayer::handleImuseAction(Chunk &b) {
- checkBlock(b, TYPE_IACT, 8);
- debug(6, "SmushPlayer::handleImuseAction()");
- if(!_outputSound) {
- return;
- }
- int32 code = b.getWord();
- int32 flags = b.getWord();
- int32 unknown = b.getShort();
- int32 track_flags = b.getWord();
-#ifdef DEBUG
- debug(5, "handleImuseAction(%d, %d, %d, %d)", code, flags, unknown, track_flags);
-#endif
- switch(code) {
- case 8:
- handleImuseAction8(b, flags, unknown, track_flags);
- break;
-#ifdef DEBUG
- default: {
- debug(9, "%5.5d %d %8.8d %4.4d", track_flags, flags, unknown);
- }
-#endif
- }
-}
-
void SmushPlayer::handleTextResource(Chunk &b) {
- int32 pos_x = b.getShort();
- int32 pos_y = b.getShort();
- int32 flags = b.getShort();
- int32 left = b.getShort();
- int32 top = b.getShort();
- int32 width = b.getShort();
+ int pos_x = b.getShort();
+ int pos_y = b.getShort();
+ int flags = b.getShort();
+ int left = b.getShort();
+ int top = b.getShort();
+ int width = b.getShort();
/*int32 height =*/ b.getShort();
/*int32 unk2 =*/ b.getWord();
- const char *str;
- char *string = NULL;
- char *string2 = NULL;
+ char *str, *string = NULL, *string2 = NULL;
if (b.getType() == TYPE_TEXT) {
- string = (char*)malloc(b.getSize() - 16);
+ string = (char *)malloc(b.getSize() - 16);
str = string;
b.read(string, b.getSize() - 16);
} else {
- int32 string_id = b.getWord();
-#ifdef DEBUG
- debug(6, "SmushPlayer::handleTextResource(%d)", string_id);
-#endif
+ int string_id = b.getWord();
if(!_strings)
return;
str = _strings->get(string_id);
@@ -475,16 +495,16 @@ void SmushPlayer::handleTextResource(Chunk &b) {
if((!_subtitles) && ((flags & 8) == 8))
return;
- FontRenderer *fr = _fr[0];
- int32 color = 15;
+ SmushFont *sf = _sf[0];
+ int color = 15;
while(*str == '/') {
str++; // For Full Throttle text resources
}
- if (g_scumm->_gameId == GID_CMI) {
- g_scumm->translateText((byte *)str - 1, g_scumm->_transText);
+ if (_scumm->_gameId == GID_CMI) {
+ _scumm->translateText((byte*)str - 1, _scumm->_transText);
while(*str++ != '/');
- string2 = (char*)g_scumm->_transText;
+ string2 = (char *)_scumm->_transText;
// If string2 contains formatting information there probably
// wasn't any translation for it in the language.tab file. In
@@ -499,7 +519,7 @@ void SmushPlayer::handleTextResource(Chunk &b) {
{
int id = str[3] - '0';
str += 4;
- fr = _fr[id];
+ sf = _sf[id];
}
break;
case 'c':
@@ -512,18 +532,16 @@ void SmushPlayer::handleTextResource(Chunk &b) {
error("invalid escape code in text string");
}
}
- assert(fr != 0);
- fr->setColor(color);
- if(!_curBuffer) {
- _curBuffer = _renderer->lockFrame(_frame);
- }
- if (g_scumm->_gameId != GID_CMI) {
- string2 = (char *)str;
+ assert(sf != NULL);
+ sf->setColor(color);
+
+ if (_scumm->_gameId != GID_CMI) {
+ string2 = str;
}
- if (g_scumm->_gameId == GID_CMI) {
+ if (_scumm->_gameId == GID_CMI) {
if (string2[0] == 0) {
- string2 = (char *)str;
+ string2 = str;
}
}
@@ -534,28 +552,28 @@ void SmushPlayer::handleTextResource(Chunk &b) {
// bit 3 - wrap around 8
switch (flags) {
case 0:
- fr->drawStringAbsolute(string2, _curBuffer, _frameSize, pos_x, pos_y);
+ sf->drawStringAbsolute(string2, _data, _width, pos_x, pos_y);
break;
case 1:
- fr->drawStringCentered(string2, _curBuffer, _frameSize, MAX(pos_y, top), left, width, pos_x);
+ sf->drawStringCentered(string2, _data, _width, _height, MAX(pos_y, top), left, width, pos_x);
break;
case 4:
- fr->drawStringAbsolute(string2, _curBuffer, _frameSize, pos_x, pos_y);
+ sf->drawStringAbsolute(string2, _data, _width, pos_x, pos_y);
break;
case 5:
- fr->drawStringCentered(string2, _curBuffer, _frameSize, MAX(pos_y, top), left, width, pos_x);
+ sf->drawStringCentered(string2, _data, _width, _height, MAX(pos_y, top), left, width, pos_x);
break;
case 8:
- fr->drawStringWrap(string2, _curBuffer, _frameSize, pos_x, MAX(pos_y, top), width);
+ sf->drawStringWrap(string2, _data, _width, _height, pos_x, MAX(pos_y, top), width);
break;
case 9:
- fr->drawStringCentered(string2, _curBuffer, _frameSize, MAX(pos_y, top), left, width, pos_x);
+ sf->drawStringCentered(string2, _data, _width, _height, MAX(pos_y, top), left, width, pos_x);
break;
case 12:
- fr->drawStringWrap(string2, _curBuffer, _frameSize, pos_x, MAX(pos_y, top), width);
+ sf->drawStringWrap(string2, _data, _width, _height, pos_x, MAX(pos_y, top), width);
break;
case 13:
- fr->drawStringWrapCentered(string2, _curBuffer, _frameSize, pos_x, MAX(pos_y, top), width);
+ sf->drawStringWrapCentered(string2, _data, _width, _height, pos_x, MAX(pos_y, top), width);
break;
default:
warning("SmushPlayer::handleTextResource. Not handled flags: %d\n", flags);
@@ -566,92 +584,79 @@ void SmushPlayer::handleTextResource(Chunk &b) {
}
}
-void SmushPlayer::readPalette(Palette &out, Chunk &in) {
- byte buffer[768];
- in.read(buffer, 768);
- out = Palette(buffer);
+bool SmushPlayer::readString(const char *file, const char *directory) {
+ const char *i = strrchr(file, '.');
+ if(i == NULL) {
+ error("invalid filename : %s", file);
+ }
+ char fname[260];
+ memcpy(fname, file, i - file);
+ strcpy(fname + (i - file), ".trs");
+ if((_strings = getStrings(fname, directory, false)) != 0) {
+ return true;
+ }
+
+ if((_strings = getStrings("digtxt.trs", directory, true)) != 0) {
+ return true;
+ }
+ return false;
+}
+
+void SmushPlayer::readPalette(byte *out, Chunk &in) {
+ in.read(out, 0x300);
+}
+
+static byte delta_color(byte org_color, int16 delta_color) {
+ int16 t;
+ t = (((int32)(org_color) << 7) + org_color + delta_color) >> 7;
+ if (t > 255)
+ t = 255;
+ if (t < 0)
+ t = 0;
+ return (byte)t;
}
void SmushPlayer::handleDeltaPalette(Chunk &b) {
checkBlock(b, TYPE_XPAL);
debug(6, "SmushPlayer::handleDeltaPalette()");
- if(b.getSize() == 768 * 3 + 4) {
- int32 unk1, num;
- unk1 = b.getWord();
- num = b.getWord();
- for(int32 i = 0; i < 768; i++) {
+
+ if(b.getSize() == 0x300 * 3 + 4) {
+
+ b.getWord();
+ b.getWord();
+
+ for(int i = 0; i < 0x300; i++) {
_deltaPal[i] = b.getWord();
}
readPalette(_pal, b);
- updatePalette();
+ setPalette(_pal);
} else if(b.getSize() == 6) {
- int32 unk1, num, unk2;
- unk1 = b.getWord();
- num = b.getWord();
- unk2 = b.getWord();
- for(int32 i = 0; i < 256; i++) {
- _pal[i].delta(_deltaPal + 3 * i);
+
+ b.getWord();
+ b.getWord();
+ b.getWord();
+
+ for(int i = 0; i < 0x300; i++) {
+ _pal[i] = delta_color(_pal[i], _deltaPal[i]);
}
- updatePalette();
+ setPalette(_pal);
} else {
- error("wrong size for DeltaPalette");
+ error("SmushPlayer::handleDeltaPalette() Wrong size for DeltaPalette");
}
}
void SmushPlayer::handleNewPalette(Chunk &b) {
- checkBlock(b, TYPE_NPAL, 768);
+ checkBlock(b, TYPE_NPAL, 0x300);
debug(6, "SmushPlayer::handleNewPalette()");
+
readPalette(_pal, b);
- updatePalette();
+ setPalette(_pal);
}
-void SmushPlayer::decodeCodec(Chunk &src, const Rect &r, Decoder &codec) {
- assert(_curBuffer);
-
- int32 chunk_size = src.getSize() - 14;
- byte *chunk_buffer = (byte *)malloc(chunk_size);
- assert(chunk_buffer);
- src.read(chunk_buffer, chunk_size);
- codec.decode((byte *)_curBuffer, chunk_buffer, chunk_size);
- free(chunk_buffer);
-
- if (_storeFrame == true) {
- if (_frameBuffer == NULL) {
- _frameBuffer = (byte *)malloc(_frameSize.getX() * _frameSize.getY());
- }
- memcpy(_frameBuffer, _curBuffer, _frameSize.getX() * _frameSize.getY());
- _storeFrame = false;
- }
+void SmushPlayer::initCodecs() {
}
-void SmushPlayer::initSize(const Rect &r, bool always, bool transparent) {
- if(_codec37Called) _alreadyInit = true;
-
- if(!_alreadyInit || _frameSize.getX() < r.right() || _frameSize.getY() < r.bottom() || always) {
- if(_curBuffer) {
- _renderer->unlockFrame();
- _curBuffer = 0;
- }
- _frameSize = r.bottomRight();
- _renderer->initFrame(_frameSize);
- }
-
- if(_curBuffer) {
- _renderer->unlockFrame();
- _curBuffer = 0;
- }
-
- _curBuffer = _renderer->lockFrame(_frame);
- if(!_alreadyInit && transparent) {
- memset(_curBuffer, 0, _frameSize.getX() * _frameSize.getY());
- }
-
- _codec1.initSize(_frameSize, r);
- _codec37.initSize(_frameSize, r);
- _codec47.initSize(_frameSize, r);
- _codec44.initSize(_frameSize, r);
- _alreadyInit = true;
-}
+extern void smush_decode_codec1(byte *dst, byte *src, int height);
void SmushPlayer::handleFrameObject(Chunk &b) {
checkBlock(b, TYPE_FOBJ, 14);
@@ -659,53 +664,75 @@ void SmushPlayer::handleFrameObject(Chunk &b) {
_skipNext = false;
return;
}
+
int codec = b.getWord();
- debug(6, "SmushPlayer::handleFrameObject(%d)", codec);
- uint16 left = b.getWord();
- uint16 top = b.getWord();
- uint16 width = b.getWord();
- uint16 height = b.getWord();
- Rect r(left, top, left + width, top + height);
- uint16 data[2];
- data[1] = b.getWord();
- data[0] = b.getWord();
-#ifdef DEBUG
- debug(5, "Frame pos : %d, %d", left, top);
- debug(5, "Frame size : %dx%d", width, height);
- debug(5, "Codec : %d", codec);
-#endif
+ b.getWord(); // left
+ b.getWord(); // top
+ int width = b.getWord();
+ int height = b.getWord();
+
+ // hack for spontanic changing resolution
+ // differ than width scumm screen, and pass only one width 384x242
+ if((height != _scumm->_realHeight) && (height != 242))
+ return;
+ if (height == 242)
+ return;
+ if((width != _scumm->_realWidth) && (width != 384))
+ return;
+ if (width == 384)
+ return;
+
+ if(_alreadyInit == false) {
+ _codec37.init(width, height);
+ _codec47.init(width, height);
+ _alreadyInit = true;
+ }
+
+ _width = width;
+ _height = height;
+ b.getWord();
+ b.getWord();
+
+
+ int32 chunk_size = b.getSize() - 14;
+ byte *chunk_buffer = (byte *)malloc(chunk_size);
+ assert(chunk_buffer);
+ b.read(chunk_buffer, chunk_size);
+
switch (codec) {
- case 3:
case 1:
- initSize(r, false, true);
- decodeCodec(b, r, _codec1);
+ case 3:
+ smush_decode_codec1(_data, chunk_buffer, _height);
break;
case 37:
- initSize(r, true, false);
- decodeCodec(b, r, _codec37);
- _codec37Called = true;
+ _codec37.decode(_data, chunk_buffer);
break;
case 47:
- initSize(r, true, false);
- decodeCodec(b, r, _codec47);
- _codec37Called = true;
- break;
- case 21:
- case 44:
- initSize(r, true, true);
- decodeCodec(b, r, _codec44);
+ _codec47.decode(_data, chunk_buffer);
break;
default:
- error("Invalid codec for frame object : %d", (int32)codec);
+ error("Invalid codec for frame object : %d", (int)codec);
}
+
+ if (_storeFrame == true) {
+ if (_frameBuffer == NULL) {
+ _frameBuffer = (byte *)malloc(_width * _height);
+ }
+ memcpy(_frameBuffer, _data, _width * _height);
+ _storeFrame = false;
+ }
+
+ free(chunk_buffer);
}
void SmushPlayer::handleFrame(Chunk &b) {
checkBlock(b, TYPE_FRME);
debug(6, "SmushPlayer::handleFrame(%d)", _frame);
- _alreadyInit = false;
_skipNext = false;
+ uint32 start_time, curr_time, start_update, end_update;
+ start_time = _scumm->_system->get_msecs();
+
while(!b.eof()) {
Chunk *sub = b.subBlock();
if(sub->getSize() & 1) b.seek(1);
@@ -745,188 +772,126 @@ void SmushPlayer::handleFrame(Chunk &b) {
}
delete sub;
}
- if(_curBuffer) {
- _renderer->unlockFrame();
- _curBuffer = 0;
+
+ curr_time = _scumm->_system->get_msecs();
+
+ _smixer->handleFrame();
+
+ start_update = _scumm->_system->get_msecs();
+ if (curr_time < (start_time + _speed / 1000)) {
+ updateScreen();
+ } else {
+ warning("SmushPlayer: skipping update frame %d", _frame);
}
- if(_outputSound)
- _mixer->handleFrame();
-#ifdef DEBUG
- debug(5, "===================END OF FRAME========================");
-#endif
- _renderer->flipFrame();
- if(_wait)
- _renderer->wait(WAIT);
+ end_update = _scumm->_system->get_msecs();
+ debug(0, "Smush stats: FRME( %03d ),GFX_update( %03d ),FRME+GFX+SFX( %03d ),Limit(%d)",
+ curr_time - start_time, end_update - start_update,
+ end_update - start_time, _speed / 1000);
+
_frame++;
}
void SmushPlayer::handleAnimHeader(Chunk &b) {
- checkBlock(b, TYPE_AHDR, 774);
+ checkBlock(b, TYPE_AHDR, 0x300 + 6);
debug(6, "SmushPlayer::handleAnimHeader()");
+
_version = b.getWord();
_nbframes = b.getWord();
b.getWord();
- _renderer->startDecode(_fname, _version, _nbframes);
readPalette(_pal, b);
- updatePalette();
- if(_version == 2) {
- _secondaryVersion = b.getDword();
- b.getDword();
- if(_secondaryVersion != 10 && _secondaryVersion != 0 && _secondaryVersion != 12 && _secondaryVersion != 15 && _secondaryVersion != 14) {
- error("Wrong secondary version number for SMUSH animation");
+ setPalette(_pal);
+}
+
+void SmushPlayer::setupAnim(const char *file, const char *directory) {
+ _base = new FileChunk(file, directory);
+ Chunk *sub = _base->subBlock();
+ checkBlock(*sub, TYPE_AHDR);
+ handleAnimHeader(*sub);
+
+ readString(file, directory);
+
+ if (_scumm->_gameId == GID_FT) {
+ _sf[0] = new SmushFont(true, false);
+ _sf[2] = new SmushFont(true, false);
+ _sf[0]->loadFont("scummfnt.nut", directory);
+ _sf[2]->loadFont("titlfnt.nut", directory);
+ } else if (_scumm->_gameId == GID_DIG) {
+ for(int i = 0; i < 4; i++) {
+ char file_font[11];
+ sprintf((char *)&file_font, "font%d.nut", i);
+ _sf[i] = new SmushFont(i != 0, false);
+ _sf[i]->loadFont(file_font, directory);
}
- } else if(_version > 2) {
- error("Wrong primary version number for SMUSH animation");
- }
- if(_outputSound) {
- _soundFrequency = 22050;
- _mixer = _renderer->getMixer();
- if(_mixer) {
- _mixer->init();
- } else {
- _outputSound = false;
+ } else if (_scumm->_gameId == GID_CMI) {
+ for(int i = 0; i < 5; i++) {
+ char file_font[11];
+ sprintf((char *)&file_font, "font%d.nut", i);
+ _sf[i] = new SmushFont(false, true);
+ _sf[i]->loadFont(file_font, directory);
}
- }
+ } else {
+ error("SmushPlayer::init() Unknown font setup for game");
+ }
+
+ delete sub;
}
-static StringResource *getStrings(const char *file, const char *directory, bool is_encoded) {
- debug(7, "trying to read text ressources from %s", file);
- File theFile;
+void SmushPlayer::parseNextFrame() {
+ if (_scumm->_smushPlay == false)
+ return;
- theFile.open(file, directory);
- if (!theFile.isOpen()) {
- return 0;
+ Chunk *sub = _base->subBlock();
+ if (_base->eof()) {
+ _scumm->_videoFinished = true;
+ return;
}
- int32 length = theFile.size();
- char *filebuffer = new char [length + 1];
- assert(filebuffer);
- theFile.read(filebuffer, length);
- filebuffer[length] = 0;
-
- if(is_encoded) {
- static const int32 ETRS_HEADER_LENGTH = 16;
- assert(length > ETRS_HEADER_LENGTH);
- Chunk::type type = READ_BE_UINT32(filebuffer);
-
- if(type != TYPE_ETRS) {
- delete [] filebuffer;
- return getStrings(file, directory, false);
- }
- char *old = filebuffer;
- filebuffer = new char[length - ETRS_HEADER_LENGTH + 1];
- for(int32 i = ETRS_HEADER_LENGTH; i < length; i++) {
- filebuffer[i - ETRS_HEADER_LENGTH] = old[i] ^ 0xCC;
- }
- filebuffer[length - ETRS_HEADER_LENGTH] = '\0';
- delete []old;
- length -= ETRS_HEADER_LENGTH;
+ switch(sub->getType()) {
+ case TYPE_FRME:
+ handleFrame(*sub);
+ break;
+ default:
+ error("Unknown Chunk found : %d, %d", sub->getType(), sub->getSize());
}
- StringResource *sr = new StringResource;
- assert(sr);
- sr->init(filebuffer, length);
- delete []filebuffer;
- return sr;
+ delete sub;
}
-bool SmushPlayer::readString(const char *file, const char *directory, bool &ft) {
- const char *i = strrchr(file, '.');
- if(i == NULL) {
- error("invalid filename : %s", file);
- }
- char fname[260];
- memcpy(fname, file, i - file);
- strcpy(fname + (i - file), ".trs");
- if((_strings = getStrings(fname, directory, false)) != 0) {
- ft = true;
- return true;
- }
+void SmushPlayer::setPalette(byte *palette) {
+ byte palette_colors[1024];
+ byte *p = palette_colors;
+ byte *data = palette;
- if((_strings = getStrings("digtxt.trs", directory, true)) != 0) {
- ft = false;
- return true;
+ for (int i = 0; i != 256; i++, data += 3, p += 4) {
+ p[0] = data[0]; // red
+ p[1] = data[1]; // green
+ p[2] = data[2]; // blue
+ p[3] = 0;
}
- return false;
-}
-static FontRenderer *loadFont(const char *file, const char *directory, bool original = false) {
-#ifdef DEBUG
- debug(5, "loading font from \"%s\"", file);
-#endif
- FontRenderer *fr = new FontRenderer(original);
- SmushPlayer p(fr, false, false);
- p.play(file, directory);
- return fr;
+ _scumm->_system->set_palette(palette_colors, 0, 256);
}
-bool SmushPlayer::play(const char *file, const char *directory) {
-#ifdef DEBUG
- debug(5, "start of animation : %s", file);
-#endif
- clean();
-
- if(_wait) {
- bool isFullthrottle = false;
- if(!readString(file, directory, isFullthrottle)) {
-#ifdef DEBUG
- debug(2, "unable to read text information for \"%s\"", file);
-#endif
- }
- if((_strings) || (g_scumm->_gameId == GID_CMI)) {
- if(isFullthrottle) {
- _fr[0] = loadFont("scummfnt.nut", directory, true);
- _fr[2] = loadFont("titlfnt.nut", directory, true);
- } else {
- for(int i = 0; i < 4; i++) {
- char file_font[11];
- sprintf((char *)&file_font, "font%d.nut", i);
- _fr[i] = loadFont(file_font, directory, i != 0);
- }
- }
- }
- if(g_scumm->_gameId == GID_CMI) {
- for(int i = 0; i < 5; i++) {
- char file_font[11];
- sprintf((char *)&file_font, "font%d.nut", i);
- _fr[i] = loadFont(file_font, directory, false);
- }
- }
- }
+void SmushPlayer::updateScreen() {
+ int width = MIN(_width, _scumm->_realWidth);
+ int height = MIN(_height, _scumm->_realHeight);
- File test;
- test.open(file, directory);
- if (!test.isOpen()) {
- warning("Missing smush file %s", file);
- return true;
- }
- test.close();
-
- FileChunk base = FileChunk(file, directory);
+ _scumm->parseEvents();
+ _scumm->_system->copy_rect(_data, _width, 0, 0, width, height);
+ _scumm->_system->update_screen();
+}
- checkBlock(base, TYPE_ANIM);
+void SmushPlayer::play(const char *filename, const char *directory) {
+ setupAnim(filename, directory);
+ init();
- while(!base.eof()) {
- Chunk *sub = base.subBlock();
- switch(sub->getType()) {
- case TYPE_AHDR:
- handleAnimHeader(*sub);
- break;
- case TYPE_FRME:
- handleFrame(*sub);
- break;
- default:
- error("Unknown Chunk found : %d, %d", sub->getType(), sub->getSize());
- }
- delete sub;
- if(_renderer->prematureClose()) {
+ while (true) {
+ _scumm->processKbd();
+ _scumm->_system->delay_msecs(10);
+ if (_scumm->_videoFinished == true)
break;
- }
- }
-#ifdef DEBUG
- debug(5, "end of animation");
-#endif
- if(_outputSound) {
- _mixer->stop();
- }
- return true;
+ if (_scumm->_saveLoadFlag)
+ break;
+ };
+
+ deinit();
}
diff --git a/scumm/smush/smush_player.h b/scumm/smush/smush_player.h
new file mode 100644
index 0000000000..73aefb5664
--- /dev/null
+++ b/scumm/smush/smush_player.h
@@ -0,0 +1,105 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef SMUSH_PLAYER_H
+#define SMUSH_PLAYER_H
+
+#include "common/util.h"
+#include "chunk.h"
+#include "codec37.h"
+#include "codec47.h"
+
+class SmushFont;
+class SmushMixer;
+class StringResource;
+
+class SmushPlayer {
+private:
+
+ Scumm *_scumm;
+ int _version;
+ int32 _nbframes;
+ SmushMixer *_smixer;
+ int16 _deltaPal[0x300];
+ byte _pal[0x300];
+ StringResource *_strings;
+ SmushFont *_sf[5];
+ Codec37Decoder _codec37;
+ Codec47Decoder _codec47;
+ int dst_width, dst_height;
+ FileChunk *_base;
+ byte *_frameBuffer;
+
+ bool _codec37Called;
+ bool _skipNext;
+ bool _subtitles;
+ bool _skips[37];
+ int32 _frame;
+
+ int _IACTchannel;
+ byte _IACToutput[4096];
+ int32 _IACTpos;
+ bool _storeFrame;
+ int _soundFrequency;
+ bool _alreadyInit;
+ int _speed;
+ bool _outputSound;
+
+public:
+
+ int _width, _height;
+ byte *_data;
+ bool _smushProcessFrame;
+
+ SmushPlayer(Scumm *, int, bool);
+ ~SmushPlayer();
+ void updatePalette(void);
+ void parseNextFrame();
+ void init();
+ void deinit();
+ void setupAnim(const char *file, const char *directory);
+ void initCodecs();
+ void updateScreen();
+ void play(const char *filename, const char *directory);
+ void setPalette(byte *palette);
+
+protected:
+
+ bool readString(const char *file, const char *directory);
+ void clean();
+ void checkBlock(const Chunk &, Chunk::type, uint32 = 0);
+ void handleAnimHeader(Chunk &);
+ void handleFrame(Chunk &);
+ void handleNewPalette(Chunk &);
+ void handleFrameObject(Chunk &);
+ void handleSoundBuffer(int32, int32, int32, int32, int32, int32, Chunk &, int32);
+ void handleImuseBuffer(int32, int32, int32, int32, int32, int32, Chunk &, int32);
+ void handleSoundFrame(Chunk &);
+ void handleSkip(Chunk &);
+ void handleStore(Chunk &);
+ void handleFetch(Chunk &);
+ void handleImuseAction(Chunk &);
+ void handleTextResource(Chunk &);
+ void handleDeltaPalette(Chunk &);
+ void readPalette(byte *, Chunk &);
+};
+
+#endif