reorg/clenup, changed main loop in smush code
svn-id: r6817
This commit is contained in:
parent
ee26752d2e
commit
06ef80fa61
32 changed files with 1491 additions and 2487 deletions
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
void Codec47Decoder::init(int width, int height) {
|
||||
deinit();
|
||||
_width = width;
|
||||
_height = height;
|
||||
makeTables37(4);
|
||||
makeTables37(8);
|
||||
|
||||
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;
|
||||
_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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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];
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
489
scumm/smush/smush_font.cpp
Normal file
489
scumm/smush/smush_font.cpp
Normal file
|
@ -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;
|
||||
}
|
67
scumm/smush/smush_font.h
Normal file
67
scumm/smush/smush_font.h
Normal file
|
@ -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
|
166
scumm/smush/smush_mixer.cpp
Normal file
166
scumm/smush/smush_mixer.cpp
Normal file
|
@ -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;
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
||||
#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
|
||||
class SmushChannel;
|
||||
|
||||
class SmushMixer {
|
||||
private:
|
||||
|
||||
#endif
|
||||
SoundMixer *_mixer;
|
||||
struct {
|
||||
int id;
|
||||
SmushChannel *chan;
|
||||
bool first;
|
||||
int mixer_index;
|
||||
} _channels[SoundMixer::NUM_CHANNELS];
|
||||
|
||||
int _nextIndex;
|
||||
int _soundFrequency;
|
||||
|
||||
public:
|
||||
|
||||
SmushMixer(SoundMixer *);
|
||||
virtual ~SmushMixer();
|
||||
SmushChannel *findChannel(int32 track);
|
||||
bool addChannel(SmushChannel *c);
|
||||
bool handleFrame();
|
||||
bool stop();
|
||||
bool update();
|
||||
bool _silentMixer;
|
||||
};
|
File diff suppressed because it is too large
Load diff
105
scumm/smush/smush_player.h
Normal file
105
scumm/smush/smush_player.h
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue