Merge remote branch 'upstream/master' into pegasus

Conflicts:
	base/plugins.cpp
	configure
This commit is contained in:
Matthew Hoops 2012-04-19 08:16:08 -04:00
commit 9971e74c4c
59 changed files with 3573 additions and 17544 deletions

View file

@ -75,7 +75,7 @@ EXECUTABLE := $(EXEPRE)scummvm$(EXEEXT)
include $(srcdir)/Makefile.common include $(srcdir)/Makefile.common
# check if configure has been run or has been changed since last run # check if configure has been run or has been changed since last run
config.h config.mk: $(srcdir)/configure config.h config.mk: $(srcdir)/configure $(srcdir)/engines/configure.engines
ifeq "$(findstring config.mk,$(MAKEFILE_LIST))" "config.mk" ifeq "$(findstring config.mk,$(MAKEFILE_LIST))" "config.mk"
@echo "Running $(srcdir)/configure with the last specified parameters" @echo "Running $(srcdir)/configure with the last specified parameters"
@sleep 2 @sleep 2

File diff suppressed because it is too large Load diff

View file

@ -96,6 +96,45 @@ private:
uint32 _totalSamples, _samplesRead; uint32 _totalSamples, _samplesRead;
}; };
/**
* An AudioStream wrapper that forces audio to be played in mono.
* It currently just ignores the right channel if stereo.
*/
class ForcedMonoAudioStream : public AudioStream {
public:
ForcedMonoAudioStream(AudioStream *parentStream, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) :
_parentStream(parentStream), _disposeAfterUse(disposeAfterUse) {}
~ForcedMonoAudioStream() {
if (_disposeAfterUse == DisposeAfterUse::YES)
delete _parentStream;
}
int readBuffer(int16 *buffer, const int numSamples) {
if (!_parentStream->isStereo())
return _parentStream->readBuffer(buffer, numSamples);
int16 temp[2];
int samples = 0;
while (samples < numSamples && !endOfData()) {
_parentStream->readBuffer(temp, 2);
*buffer++ = temp[0];
samples++;
}
return samples;
}
bool endOfData() const { return _parentStream->endOfData(); }
bool isStereo() const { return false; }
int getRate() const { return _parentStream->getRate(); }
private:
AudioStream *_parentStream;
DisposeAfterUse::Flag _disposeAfterUse;
};
QuickTimeAudioDecoder::QuickTimeAudioDecoder() : Common::QuickTimeParser() { QuickTimeAudioDecoder::QuickTimeAudioDecoder() : Common::QuickTimeParser() {
} }
@ -495,7 +534,13 @@ void QuickTimeAudioDecoder::QuickTimeAudioTrack::enterNewEdit(const Timestamp &p
} }
void QuickTimeAudioDecoder::QuickTimeAudioTrack::queueStream(AudioStream *stream, const Timestamp &length) { void QuickTimeAudioDecoder::QuickTimeAudioTrack::queueStream(AudioStream *stream, const Timestamp &length) {
_queue->queueAudioStream(stream, DisposeAfterUse::YES); // If the samples are stereo and the container is mono, force the samples
// to be mono.
if (stream->isStereo() && !isStereo())
_queue->queueAudioStream(new ForcedMonoAudioStream(stream, DisposeAfterUse::YES), DisposeAfterUse::YES);
else
_queue->queueAudioStream(stream, DisposeAfterUse::YES);
_samplesQueued += length.convertToFramerate(getRate()).totalNumberOfFrames(); _samplesQueued += length.convertToFramerate(getRate()).totalNumberOfFrames();
} }

View file

@ -85,111 +85,7 @@ public:
// Iterate over all registered (static) plugins and load them. // Iterate over all registered (static) plugins and load them.
// Engine plugins // Engine plugins
#if PLUGIN_ENABLED_STATIC(SCUMM) #include "engines/plugins_table.h"
LINK_PLUGIN(SCUMM)
#endif
#if PLUGIN_ENABLED_STATIC(AGI)
LINK_PLUGIN(AGI)
#endif
#if PLUGIN_ENABLED_STATIC(AGOS)
LINK_PLUGIN(AGOS)
#endif
#if PLUGIN_ENABLED_STATIC(CGE)
LINK_PLUGIN(CGE)
#endif
#if PLUGIN_ENABLED_STATIC(CINE)
LINK_PLUGIN(CINE)
#endif
#if PLUGIN_ENABLED_STATIC(COMPOSER)
LINK_PLUGIN(COMPOSER)
#endif
#if PLUGIN_ENABLED_STATIC(CRUISE)
LINK_PLUGIN(CRUISE)
#endif
#if PLUGIN_ENABLED_STATIC(DRACI)
LINK_PLUGIN(DRACI)
#endif
#if PLUGIN_ENABLED_STATIC(DRASCULA)
LINK_PLUGIN(DRASCULA)
#endif
#if PLUGIN_ENABLED_STATIC(DREAMWEB)
LINK_PLUGIN(DREAMWEB)
#endif
#if PLUGIN_ENABLED_STATIC(GOB)
LINK_PLUGIN(GOB)
#endif
#if PLUGIN_ENABLED_STATIC(GROOVIE)
LINK_PLUGIN(GROOVIE)
#endif
#if PLUGIN_ENABLED_STATIC(HUGO)
LINK_PLUGIN(HUGO)
#endif
#if PLUGIN_ENABLED_STATIC(KYRA)
LINK_PLUGIN(KYRA)
#endif
#if PLUGIN_ENABLED_STATIC(LASTEXPRESS)
LINK_PLUGIN(LASTEXPRESS)
#endif
#if PLUGIN_ENABLED_STATIC(LURE)
LINK_PLUGIN(LURE)
#endif
#if PLUGIN_ENABLED_STATIC(MADE)
LINK_PLUGIN(MADE)
#endif
#if PLUGIN_ENABLED_STATIC(MOHAWK)
LINK_PLUGIN(MOHAWK)
#endif
#if PLUGIN_ENABLED_STATIC(PARALLACTION)
LINK_PLUGIN(PARALLACTION)
#endif
#if PLUGIN_ENABLED_STATIC(PEGASUS)
LINK_PLUGIN(PEGASUS)
#endif
#if PLUGIN_ENABLED_STATIC(QUEEN)
LINK_PLUGIN(QUEEN)
#endif
#if PLUGIN_ENABLED_STATIC(SAGA)
LINK_PLUGIN(SAGA)
#endif
#if PLUGIN_ENABLED_STATIC(SCI)
LINK_PLUGIN(SCI)
#endif
#if PLUGIN_ENABLED_STATIC(SKY)
LINK_PLUGIN(SKY)
#endif
#if PLUGIN_ENABLED_STATIC(SWORD1)
LINK_PLUGIN(SWORD1)
#endif
#if PLUGIN_ENABLED_STATIC(SWORD2)
LINK_PLUGIN(SWORD2)
#endif
#if PLUGIN_ENABLED_STATIC(SWORD25)
LINK_PLUGIN(SWORD25)
#endif
#if PLUGIN_ENABLED_STATIC(TEENAGENT)
LINK_PLUGIN(TEENAGENT)
#endif
#if PLUGIN_ENABLED_STATIC(TESTBED)
LINK_PLUGIN(TESTBED)
#endif
#if PLUGIN_ENABLED_STATIC(TINSEL)
LINK_PLUGIN(TINSEL)
#endif
#if PLUGIN_ENABLED_STATIC(TOLTECS)
LINK_PLUGIN(TOLTECS)
#endif
#if PLUGIN_ENABLED_STATIC(TOON)
LINK_PLUGIN(TOON)
#endif
#if PLUGIN_ENABLED_STATIC(TSAGE)
LINK_PLUGIN(TSAGE)
#endif
#if PLUGIN_ENABLED_STATIC(TOUCHE)
LINK_PLUGIN(TOUCHE)
#endif
#if PLUGIN_ENABLED_STATIC(TUCKER)
LINK_PLUGIN(TUCKER)
#endif
// Music plugins // Music plugins
// TODO: Use defines to disable or enable each MIDI driver as a // TODO: Use defines to disable or enable each MIDI driver as a

File diff suppressed because it is too large Load diff

View file

@ -25,12 +25,30 @@
namespace Common { namespace Common {
/** class CosineTable {
* Get a cosine table with the specified bit precision public:
* /**
* @param bits Precision of the table, which must be in range [4, 16] * Construct a cosine table with the specified bit precision
*/ *
const float *getCosineTable(int bits); * @param bitPrecision Precision of the table, which must be in range [4, 16]
*/
CosineTable(int bitPrecision);
~CosineTable();
/**
* Get pointer to table
*/
const float *getTable() { return _table; }
/**
* Get pointer to table
*/
int getPrecision() { return _bitPrecision; }
private:
float *_table;
int _bitPrecision;
};
} // End of namespace Common } // End of namespace Common

View file

@ -26,15 +26,14 @@
// Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> // Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
// Copyright (c) 2010 Vitor Sessak // Copyright (c) 2010 Vitor Sessak
#include "common/cosinetables.h"
#include "common/dct.h" #include "common/dct.h"
namespace Common { namespace Common {
DCT::DCT(int bits, TransformType trans) : _bits(bits), _trans(trans), _rdft(0) { DCT::DCT(int bits, TransformType trans) : _bits(bits), _cos(_bits + 2), _trans(trans), _rdft(0) {
int n = 1 << _bits; int n = 1 << _bits;
_tCos = getCosineTable(_bits + 2); _tCos = _cos.getTable();
_csc2 = new float[n / 2]; _csc2 = new float[n / 2];

View file

@ -33,6 +33,8 @@
#include "common/math.h" #include "common/math.h"
#include "common/rdft.h" #include "common/rdft.h"
#include "common/cosinetables.h"
namespace Common { namespace Common {
/** /**
@ -59,6 +61,7 @@ private:
int _bits; int _bits;
TransformType _trans; TransformType _trans;
CosineTable _cos;
const float *_tCos; const float *_tCos;
float *_csc2; float *_csc2;

View file

@ -29,6 +29,7 @@
#include "common/cosinetables.h" #include "common/cosinetables.h"
#include "common/fft.h" #include "common/fft.h"
#include "common/util.h" #include "common/util.h"
#include "common/textconsole.h"
namespace Common { namespace Common {
@ -45,6 +46,13 @@ FFT::FFT(int bits, int inverse) : _bits(bits), _inverse(inverse) {
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
_revTab[-splitRadixPermutation(i, n, _inverse) & (n - 1)] = i; _revTab[-splitRadixPermutation(i, n, _inverse) & (n - 1)] = i;
for (int i = 0; i < ARRAYSIZE(_cosTables); i++) {
if (i+4 <= _bits)
_cosTables[i] = new Common::CosineTable(i+4);
else
_cosTables[i] = 0;
}
} }
FFT::~FFT() { FFT::~FFT() {
@ -162,15 +170,7 @@ PASS(pass)
#define BUTTERFLIES BUTTERFLIES_BIG #define BUTTERFLIES BUTTERFLIES_BIG
PASS(pass_big) PASS(pass_big)
#define DECL_FFT(t, n, n2, n4) \ void FFT::fft4(Complex *z) {
static void fft##n(Complex *z) { \
fft##n2(z); \
fft##n4(z + n4 * 2); \
fft##n4(z + n4 * 3); \
pass(z, getCosineTable(t), n4 / 2);\
}
static void fft4(Complex *z) {
float t1, t2, t3, t4, t5, t6, t7, t8; float t1, t2, t3, t4, t5, t6, t7, t8;
BF(t3, t1, z[0].re, z[1].re); BF(t3, t1, z[0].re, z[1].re);
@ -183,7 +183,7 @@ static void fft4(Complex *z) {
BF(z[2].im, z[0].im, t2, t5); BF(z[2].im, z[0].im, t2, t5);
} }
static void fft8(Complex *z) { void FFT::fft8(Complex *z) {
float t1, t2, t3, t4, t5, t6, t7, t8; float t1, t2, t3, t4, t5, t6, t7, t8;
fft4(z); fft4(z);
@ -202,14 +202,15 @@ static void fft8(Complex *z) {
TRANSFORM(z[1], z[3], z[5], z[7], sqrthalf, sqrthalf); TRANSFORM(z[1], z[3], z[5], z[7], sqrthalf, sqrthalf);
} }
static void fft16(Complex *z) { void FFT::fft16(Complex *z) {
float t1, t2, t3, t4, t5, t6; float t1, t2, t3, t4, t5, t6;
fft8(z); fft8(z);
fft4(z + 8); fft4(z + 8);
fft4(z + 12); fft4(z + 12);
const float * const cosTable = getCosineTable(4); assert(_cosTables[0]);
const float * const cosTable = _cosTables[0]->getTable();
TRANSFORM_ZERO(z[0], z[4], z[8], z[12]); TRANSFORM_ZERO(z[0], z[4], z[8], z[12]);
TRANSFORM(z[2], z[6], z[10], z[14], sqrthalf, sqrthalf); TRANSFORM(z[2], z[6], z[10], z[14], sqrthalf, sqrthalf);
@ -217,27 +218,31 @@ static void fft16(Complex *z) {
TRANSFORM(z[3], z[7], z[11], z[15], cosTable[3], cosTable[1]); TRANSFORM(z[3], z[7], z[11], z[15], cosTable[3], cosTable[1]);
} }
DECL_FFT(5, 32, 16, 8) void FFT::fft(int n, int logn, Complex *z) {
DECL_FFT(6, 64, 32, 16) switch (logn) {
DECL_FFT(7, 128, 64, 32) case 2:
DECL_FFT(8, 256, 128, 64) fft4(z);
DECL_FFT(9, 512, 256, 128) break;
#define pass pass_big case 3:
DECL_FFT(10, 1024, 512, 256) fft8(z);
DECL_FFT(11, 2048, 1024, 512) break;
DECL_FFT(12, 4096, 2048, 1024) case 4:
DECL_FFT(13, 8192, 4096, 2048) fft16(z);
DECL_FFT(14, 16384, 8192, 4096) break;
DECL_FFT(15, 32768, 16384, 8192) default:
DECL_FFT(16, 65536, 32768, 16384) fft((n / 2), logn - 1, z);
fft((n / 4), logn - 2, z + (n / 4) * 2);
static void (* const fft_dispatch[])(Complex *) = { fft((n / 4), logn - 2, z + (n / 4) * 3);
fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024, assert(_cosTables[logn - 4]);
fft2048, fft4096, fft8192, fft16384, fft32768, fft65536, if (n > 1024)
}; pass_big(z, _cosTables[logn - 4]->getTable(), (n / 4) / 2);
else
pass(z, _cosTables[logn - 4]->getTable(), (n / 4) / 2);
}
}
void FFT::calc(Complex *z) { void FFT::calc(Complex *z) {
fft_dispatch[_bits - 2](z); fft(1 << _bits, _bits, z);
} }
} // End of namespace Common } // End of namespace Common

View file

@ -34,6 +34,8 @@
namespace Common { namespace Common {
class CosineTable;
/** /**
* (Inverse) Fast Fourier Transform. * (Inverse) Fast Fourier Transform.
* *
@ -64,13 +66,17 @@ private:
Complex *_expTab; Complex *_expTab;
Complex *_tmpBuf; Complex *_tmpBuf;
const float *_tSin;
const float *_tCos;
int _splitRadix; int _splitRadix;
int _permutation; int _permutation;
static int splitRadixPermutation(int i, int n, int inverse); static int splitRadixPermutation(int i, int n, int inverse);
CosineTable *_cosTables[13];
void fft4(Complex *z);
void fft8(Complex *z);
void fft16(Complex *z);
void fft(int n, int logn, Complex *z);
}; };
} // End of namespace Common } // End of namespace Common

View file

@ -41,7 +41,6 @@ MODULE_OBJS := \
xmlparser.o \ xmlparser.o \
zlib.o zlib.o
ifdef USE_BINK
MODULE_OBJS += \ MODULE_OBJS += \
cosinetables.o \ cosinetables.o \
dct.o \ dct.o \
@ -49,7 +48,6 @@ MODULE_OBJS += \
huffman.o \ huffman.o \
rdft.o \ rdft.o \
sinetables.o sinetables.o
endif
# Include common rules # Include common rules
include $(srcdir)/rules.mk include $(srcdir)/rules.mk

View file

@ -25,12 +25,10 @@
// Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot com> // Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot com>
#include "common/rdft.h" #include "common/rdft.h"
#include "common/cosinetables.h"
#include "common/sinetables.h"
namespace Common { namespace Common {
RDFT::RDFT(int bits, TransformType trans) : _bits(bits), _fft(0) { RDFT::RDFT(int bits, TransformType trans) : _bits(bits), _sin(bits), _cos(bits), _fft(0) {
assert ((_bits >= 4) && (_bits <= 16)); assert ((_bits >= 4) && (_bits <= 16));
_inverse = trans == IDFT_C2R || trans == DFT_C2R; _inverse = trans == IDFT_C2R || trans == DFT_C2R;
@ -40,8 +38,8 @@ RDFT::RDFT(int bits, TransformType trans) : _bits(bits), _fft(0) {
int n = 1 << bits; int n = 1 << bits;
_tSin = getSineTable(bits) + (trans == DFT_R2C || trans == DFT_C2R) * (n >> 2); _tSin = _sin.getTable() + (trans == DFT_R2C || trans == DFT_C2R) * (n >> 2);
_tCos = getCosineTable(bits); _tCos = _cos.getTable();
} }
RDFT::~RDFT() { RDFT::~RDFT() {

View file

@ -31,11 +31,17 @@
#include "common/math.h" #include "common/math.h"
#include "common/fft.h" #include "common/fft.h"
#include "common/cosinetables.h"
#include "common/sinetables.h"
namespace Common { namespace Common {
/** /**
* (Inverse) Real Discrete Fourier Transform. * (Inverse) Real Discrete Fourier Transform.
* *
* Used in audio:
* - QDM2
*
* Used in engines: * Used in engines:
* - scumm * - scumm
*/ */
@ -59,6 +65,8 @@ private:
int _inverse; int _inverse;
int _signConvention; int _signConvention;
SineTable _sin;
CosineTable _cos;
const float *_tSin; const float *_tSin;
const float *_tCos; const float *_tCos;

File diff suppressed because it is too large Load diff

View file

@ -25,12 +25,30 @@
namespace Common { namespace Common {
/** class SineTable {
* Get a sine table with the specified bit precision public:
* /**
* @param bits Precision of the table, which must be in range [4, 16] * Construct a sine table with the specified bit precision
*/ *
const float *getSineTable(int bits); * @param bitPrecision Precision of the table, which must be in range [4, 16]
*/
SineTable(int bitPrecision);
~SineTable();
/**
* Get pointer to table
*/
const float *getTable() { return _table; }
/**
* Get pointer to table
*/
int getPrecision() { return _bitPrecision; }
private:
float *_table;
int _bitPrecision;
};
} // End of namespace Common } // End of namespace Common

View file

@ -83,7 +83,7 @@ namespace Common {
* Print a hexdump of the data passed in. The number of bytes per line is * Print a hexdump of the data passed in. The number of bytes per line is
* customizable. * customizable.
* @param data the data to be dumped * @param data the data to be dumped
* @param len the lenght of that data * @param len the length of that data
* @param bytesPerLine number of bytes to print per line (default: 16) * @param bytesPerLine number of bytes to print per line (default: 16)
* @param startOffset shift the shown offsets by the starting offset (default: 0) * @param startOffset shift the shown offsets by the starting offset (default: 0)
*/ */

52
configure vendored
View file

@ -77,53 +77,10 @@ add_engine() {
done done
} }
add_engine scumm "SCUMM" yes "scumm_7_8 he" _srcdir=`dirname $0`
add_engine scumm_7_8 "v7 & v8 games" yes
add_engine he "HE71+ games" yes # Read list of engines
add_engine agi "AGI" yes . $_srcdir/engines/configure.engines
add_engine agos "AGOS" yes "agos2"
add_engine agos2 "AGOS 2 games" yes
add_engine cge "CGE" yes
add_engine cine "Cinematique evo 1" yes
add_engine composer "Magic Composer" no
add_engine cruise "Cinematique evo 2" yes
add_engine draci "Dragon History" yes
add_engine drascula "Drascula: The Vampire Strikes Back" yes
add_engine dreamweb "Dreamweb" no
add_engine gob "Gobli*ns" yes
add_engine groovie "Groovie" yes "groovie2"
add_engine groovie2 "Groovie 2 games" no
add_engine hugo "Hugo Trilogy" yes
add_engine kyra "Legend of Kyrandia" yes "lol eob"
add_engine lol "Lands of Lore" yes
add_engine eob "Eye of the Beholder" no
add_engine lastexpress "The Last Express" no
add_engine lure "Lure of the Temptress" yes
add_engine made "MADE" yes
add_engine mohawk "Mohawk" yes "cstime myst riven"
add_engine cstime "Where in Time is Carmen Sandiego?" no
add_engine riven "Riven: The Sequel to Myst" no
add_engine myst "Myst" no
add_engine parallaction "Parallaction" yes
add_engine pegasus "The Journeyman Project: Pegasus Prime" no
add_engine queen "Flight of the Amazon Queen" yes
add_engine saga "SAGA" yes "ihnm saga2"
add_engine ihnm "IHNM" yes
add_engine saga2 "SAGA 2 games" no
add_engine sci "SCI" yes "sci32"
add_engine sci32 "SCI32 games" no
add_engine sky "Beneath a Steel Sky" yes
add_engine sword1 "Broken Sword" yes
add_engine sword2 "Broken Sword II" yes
add_engine sword25 "Broken Sword 2.5" no
add_engine teenagent "Teen Agent" yes
add_engine testbed "TestBed: the Testing framework" no
add_engine tinsel "Tinsel" yes
add_engine toltecs "3 Skulls of the Toltecs" no
add_engine toon "Toonstruck" yes
add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes
add_engine tsage "TsAGE" yes
add_engine tucker "Bud Tucker in Double Trouble" yes
# #
# Default settings # Default settings
@ -230,7 +187,6 @@ _host_vendor=""
_host_os="" _host_os=""
_host_alias="" _host_alias=""
_srcdir=`dirname $0`
_port_mk="ports.mk" _port_mk="ports.mk"
# Use temp files in the build directory # Use temp files in the build directory

View file

@ -28,7 +28,6 @@
#define LIBS_DEFINE "SCUMMVM_LIBS" // Name of the include environment variable #define LIBS_DEFINE "SCUMMVM_LIBS" // Name of the include environment variable
#define REVISION_DEFINE "SCUMMVM_INTERNAL_REVISION" #define REVISION_DEFINE "SCUMMVM_INTERNAL_REVISION"
#define HAS_VIDEO_FOLDER 1
//#define ADDITIONAL_LIBRARY "" //#define ADDITIONAL_LIBRARY ""
#define NEEDS_RTTI 0 #define NEEDS_RTTI 0

View file

@ -575,7 +575,9 @@ int main(int argc, char *argv[]) {
globalWarnings.push_back("-Wwrite-strings"); globalWarnings.push_back("-Wwrite-strings");
// The following are not warnings at all... We should consider adding them to // The following are not warnings at all... We should consider adding them to
// a different list of parameters. // a different list of parameters.
#if !NEEDS_RTTI
globalWarnings.push_back("-fno-rtti"); globalWarnings.push_back("-fno-rtti");
#endif
globalWarnings.push_back("-fno-exceptions"); globalWarnings.push_back("-fno-exceptions");
globalWarnings.push_back("-fcheck-new"); globalWarnings.push_back("-fcheck-new");
@ -691,7 +693,7 @@ bool parseEngine(const std::string &line, EngineDesc &engine);
} // End of anonymous namespace } // End of anonymous namespace
EngineDescList parseConfigure(const std::string &srcDir) { EngineDescList parseConfigure(const std::string &srcDir) {
std::string configureFile = srcDir + "/configure"; std::string configureFile = srcDir + "/engines/configure.engines";
std::ifstream configure(configureFile.c_str()); std::ifstream configure(configureFile.c_str());
if (!configure) if (!configure)
@ -1213,9 +1215,7 @@ void ProjectProvider::createProject(const BuildSetup &setup) {
createModuleList(setup.srcDir + "/gui", setup.defines, in, ex); createModuleList(setup.srcDir + "/gui", setup.defines, in, ex);
createModuleList(setup.srcDir + "/audio", setup.defines, in, ex); createModuleList(setup.srcDir + "/audio", setup.defines, in, ex);
createModuleList(setup.srcDir + "/audio/softsynth/mt32", setup.defines, in, ex); createModuleList(setup.srcDir + "/audio/softsynth/mt32", setup.defines, in, ex);
#if HAS_VIDEO_FOLDER
createModuleList(setup.srcDir + "/video", setup.defines, in, ex); createModuleList(setup.srcDir + "/video", setup.defines, in, ex);
#endif
// Resource files // Resource files
in.push_back(setup.srcDir + "/icons/" + setup.projectName + ".ico"); in.push_back(setup.srcDir + "/icons/" + setup.projectName + ".ico");
@ -1225,6 +1225,8 @@ void ProjectProvider::createProject(const BuildSetup &setup) {
in.push_back(setup.srcDir + "/AUTHORS"); in.push_back(setup.srcDir + "/AUTHORS");
in.push_back(setup.srcDir + "/COPYING"); in.push_back(setup.srcDir + "/COPYING");
in.push_back(setup.srcDir + "/COPYING.LGPL"); in.push_back(setup.srcDir + "/COPYING.LGPL");
in.push_back(setup.srcDir + "/COPYING.BSD");
in.push_back(setup.srcDir + "/COPYING.FREEFONT");
in.push_back(setup.srcDir + "/COPYRIGHT"); in.push_back(setup.srcDir + "/COPYRIGHT");
in.push_back(setup.srcDir + "/NEWS"); in.push_back(setup.srcDir + "/NEWS");
in.push_back(setup.srcDir + "/README"); in.push_back(setup.srcDir + "/README");

View file

@ -20,6 +20,7 @@
* *
*/ */
#include "config.h"
#include "xcode.h" #include "xcode.h"
#include <fstream> #include <fstream>
@ -86,34 +87,34 @@ XCodeProvider::XCodeProvider(StringList &global_warnings, std::map<std::string,
void XCodeProvider::createWorkspace(const BuildSetup &setup) { void XCodeProvider::createWorkspace(const BuildSetup &setup) {
// Create project folder // Create project folder
std::string workspace = setup.outputDir + '/' + "scummvm.xcodeproj"; std::string workspace = setup.outputDir + '/' + PROJECT_NAME ".xcodeproj";
#if defined(_WIN32) || defined(WIN32) #if defined(_WIN32) || defined(WIN32)
if (!CreateDirectory(workspace.c_str(), NULL)) if (!CreateDirectory(workspace.c_str(), NULL))
if (GetLastError() != ERROR_ALREADY_EXISTS) if (GetLastError() != ERROR_ALREADY_EXISTS)
error("Could not create folder \"" + setup.outputDir + '/' + "scummvm.xcodeproj\""); error("Could not create folder \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj\"");
#else #else
if (mkdir(workspace.c_str(), 0777) == -1) { if (mkdir(workspace.c_str(), 0777) == -1) {
if (errno == EEXIST) { if (errno == EEXIST) {
// Try to open as a folder (might be a file / symbolic link) // Try to open as a folder (might be a file / symbolic link)
DIR *dirp = opendir(workspace.c_str()); DIR *dirp = opendir(workspace.c_str());
if (dirp == NULL) { if (dirp == NULL) {
error("Could not create folder \"" + setup.outputDir + '/' + "scummvm.xcodeproj\""); error("Could not create folder \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj\"");
} else { } else {
// The folder exists, just close the stream and return // The folder exists, just close the stream and return
closedir(dirp); closedir(dirp);
} }
} else { } else {
error("Could not create folder \"" + setup.outputDir + '/' + "scummvm.xcodeproj\""); error("Could not create folder \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj\"");
} }
} }
#endif #endif
// Setup global objects // Setup global objects
setupDefines(setup); setupDefines(setup);
_targets.push_back("ScummVM-iPhone"); _targets.push_back(PROJECT_DESCRIPTION "-iPhone");
_targets.push_back("ScummVM-OS X"); _targets.push_back(PROJECT_DESCRIPTION "-OS X");
_targets.push_back("ScummVM-Simulator"); _targets.push_back(PROJECT_DESCRIPTION "-Simulator");
setupCopyFilesBuildPhase(); setupCopyFilesBuildPhase();
setupFrameworksBuildPhase(); setupFrameworksBuildPhase();
@ -153,9 +154,9 @@ void XCodeProvider::createProjectFile(const std::string &, const std::string &,
// Main Project file // Main Project file
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void XCodeProvider::ouputMainProjectFile(const BuildSetup &setup) { void XCodeProvider::ouputMainProjectFile(const BuildSetup &setup) {
std::ofstream project((setup.outputDir + '/' + "scummvm.xcodeproj" + '/' + "project.pbxproj").c_str()); std::ofstream project((setup.outputDir + '/' + PROJECT_NAME ".xcodeproj" + '/' + "project.pbxproj").c_str());
if (!project) if (!project)
error("Could not open \"" + setup.outputDir + '/' + "scummvm.xcodeproj" + '/' + "project.pbxproj\" for writing"); error("Could not open \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj" + '/' + "project.pbxproj\" for writing");
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Header // Header
@ -392,8 +393,8 @@ void XCodeProvider::setupNativeTarget() {
target->addProperty("dependencies", "", "", SettingsNoValue|SettingsAsList); target->addProperty("dependencies", "", "", SettingsNoValue|SettingsAsList);
target->addProperty("name", _targets[i], "", SettingsNoValue|SettingsQuoteVariable); target->addProperty("name", _targets[i], "", SettingsNoValue|SettingsQuoteVariable);
target->addProperty("productName", "scummvm", "", SettingsNoValue); target->addProperty("productName", PROJECT_NAME, "", SettingsNoValue);
target->addProperty("productReference", getHash("PBXFileReference_ScummVM.app_" + _targets[i]), "ScummVM.app", SettingsNoValue); target->addProperty("productReference", getHash("PBXFileReference_" PROJECT_DESCRIPTION ".app_" + _targets[i]), PROJECT_DESCRIPTION ".app", SettingsNoValue);
target->addProperty("productType", "com.apple.product-type.application", "", SettingsNoValue|SettingsQuoteVariable); target->addProperty("productType", "com.apple.product-type.application", "", SettingsNoValue|SettingsQuoteVariable);
_nativeTarget.add(target); _nativeTarget.add(target);
@ -405,7 +406,7 @@ void XCodeProvider::setupProject() {
Object *project = new Object(this, "PBXProject", "PBXProject", "PBXProject", "", "Project object"); Object *project = new Object(this, "PBXProject", "PBXProject", "PBXProject", "", "Project object");
project->addProperty("buildConfigurationList", getHash("XCConfigurationList_scummvm"), "Build configuration list for PBXProject \"scummvm\"", SettingsNoValue); project->addProperty("buildConfigurationList", getHash("XCConfigurationList_scummvm"), "Build configuration list for PBXProject \"" PROJECT_NAME "\"", SettingsNoValue);
project->addProperty("compatibilityVersion", "Xcode 3.2", "", SettingsNoValue|SettingsQuoteVariable); project->addProperty("compatibilityVersion", "Xcode 3.2", "", SettingsNoValue|SettingsQuoteVariable);
project->addProperty("developmentRegion", "English", "", SettingsNoValue); project->addProperty("developmentRegion", "English", "", SettingsNoValue);
project->addProperty("hasScannedForEncodings", "1", "", SettingsNoValue); project->addProperty("hasScannedForEncodings", "1", "", SettingsNoValue);
@ -495,8 +496,8 @@ void XCodeProvider::setupResourcesBuildPhase() {
} }
// Add custom files depending on the target // Add custom files depending on the target
if (_targets[i] == "ScummVM-OS X") { if (_targets[i] == PROJECT_DESCRIPTION "-OS X") {
files.settings[getHash("PBXResources_scummvm.icns")] = Setting("", "scummvm.icns in Resources", SettingsNoValue, 0, 6); files.settings[getHash("PBXResources_" PROJECT_NAME ".icns")] = Setting("", PROJECT_NAME ".icns in Resources", SettingsNoValue, 0, 6);
// Remove 2 iphone icon files // Remove 2 iphone icon files
files.settings.erase(getHash("PBXResources_Default.png")); files.settings.erase(getHash("PBXResources_Default.png"));
@ -526,7 +527,7 @@ void XCodeProvider::setupBuildConfiguration() {
// ****************************************/ // ****************************************/
// Debug // Debug
Object *iPhone_Debug_Object = new Object(this, "XCBuildConfiguration_ScummVM-iPhone_Debug", _targets[0] /* ScummVM-iPhone */, "XCBuildConfiguration", "PBXNativeTarget", "Debug"); Object *iPhone_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-iPhone_Debug", _targets[0] /* ScummVM-iPhone */, "XCBuildConfiguration", "PBXNativeTarget", "Debug");
Property iPhone_Debug; Property iPhone_Debug;
ADD_SETTING_QUOTE(iPhone_Debug, "ARCHS", "$(ARCHS_UNIVERSAL_IPHONE_OS)"); ADD_SETTING_QUOTE(iPhone_Debug, "ARCHS", "$(ARCHS_UNIVERSAL_IPHONE_OS)");
ADD_SETTING_QUOTE(iPhone_Debug, "CODE_SIGN_IDENTITY", "iPhone Developer"); ADD_SETTING_QUOTE(iPhone_Debug, "CODE_SIGN_IDENTITY", "iPhone Developer");
@ -558,7 +559,7 @@ void XCodeProvider::setupBuildConfiguration() {
ADD_SETTING_LIST(iPhone_Debug, "LIBRARY_SEARCH_PATHS", iPhone_LibPaths, SettingsAsList, 5); ADD_SETTING_LIST(iPhone_Debug, "LIBRARY_SEARCH_PATHS", iPhone_LibPaths, SettingsAsList, 5);
ADD_SETTING(iPhone_Debug, "ONLY_ACTIVE_ARCH", "YES"); ADD_SETTING(iPhone_Debug, "ONLY_ACTIVE_ARCH", "YES");
ADD_SETTING(iPhone_Debug, "PREBINDING", "NO"); ADD_SETTING(iPhone_Debug, "PREBINDING", "NO");
ADD_SETTING(iPhone_Debug, "PRODUCT_NAME", "ScummVM"); ADD_SETTING(iPhone_Debug, "PRODUCT_NAME", PROJECT_DESCRIPTION);
ADD_SETTING_QUOTE(iPhone_Debug, "PROVISIONING_PROFILE", "EF590570-5FAC-4346-9071-D609DE2B28D8"); ADD_SETTING_QUOTE(iPhone_Debug, "PROVISIONING_PROFILE", "EF590570-5FAC-4346-9071-D609DE2B28D8");
ADD_SETTING_QUOTE_VAR(iPhone_Debug, "PROVISIONING_PROFILE[sdk=iphoneos*]", ""); ADD_SETTING_QUOTE_VAR(iPhone_Debug, "PROVISIONING_PROFILE[sdk=iphoneos*]", "");
ADD_SETTING(iPhone_Debug, "SDKROOT", "iphoneos4.0"); ADD_SETTING(iPhone_Debug, "SDKROOT", "iphoneos4.0");
@ -568,7 +569,7 @@ void XCodeProvider::setupBuildConfiguration() {
iPhone_Debug_Object->properties["buildSettings"] = iPhone_Debug; iPhone_Debug_Object->properties["buildSettings"] = iPhone_Debug;
// Release // Release
Object *iPhone_Release_Object = new Object(this, "XCBuildConfiguration_ScummVM-iPhone_Release", _targets[0] /* ScummVM-iPhone */, "XCBuildConfiguration", "PBXNativeTarget", "Release"); Object *iPhone_Release_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-iPhone_Release", _targets[0] /* ScummVM-iPhone */, "XCBuildConfiguration", "PBXNativeTarget", "Release");
Property iPhone_Release(iPhone_Debug); Property iPhone_Release(iPhone_Debug);
ADD_SETTING(iPhone_Release, "GCC_OPTIMIZATION_LEVEL", "3"); ADD_SETTING(iPhone_Release, "GCC_OPTIMIZATION_LEVEL", "3");
ADD_SETTING(iPhone_Release, "COPY_PHASE_STRIP", "YES"); ADD_SETTING(iPhone_Release, "COPY_PHASE_STRIP", "YES");
@ -586,7 +587,7 @@ void XCodeProvider::setupBuildConfiguration() {
****************************************/ ****************************************/
// Debug // Debug
Object *scummvm_Debug_Object = new Object(this, "XCBuildConfiguration_scummvm_Debug", "scummvm", "XCBuildConfiguration", "PBXProject", "Debug"); Object *scummvm_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_NAME "_Debug", PROJECT_NAME, "XCBuildConfiguration", "PBXProject", "Debug");
Property scummvm_Debug; Property scummvm_Debug;
ADD_SETTING(scummvm_Debug, "ALWAYS_SEARCH_USER_PATHS", "NO"); ADD_SETTING(scummvm_Debug, "ALWAYS_SEARCH_USER_PATHS", "NO");
ADD_SETTING_QUOTE(scummvm_Debug, "ARCHS", "$(ARCHS_STANDARD_32_BIT)"); ADD_SETTING_QUOTE(scummvm_Debug, "ARCHS", "$(ARCHS_STANDARD_32_BIT)");
@ -623,7 +624,7 @@ void XCodeProvider::setupBuildConfiguration() {
scummvm_Debug_Object->properties["buildSettings"] = scummvm_Debug; scummvm_Debug_Object->properties["buildSettings"] = scummvm_Debug;
// Release // Release
Object *scummvm_Release_Object = new Object(this, "XCBuildConfiguration_scummvm_Release", "scummvm", "XCBuildConfiguration", "PBXProject", "Release"); Object *scummvm_Release_Object = new Object(this, "XCBuildConfiguration_" PROJECT_NAME "_Release", PROJECT_NAME, "XCBuildConfiguration", "PBXProject", "Release");
Property scummvm_Release(scummvm_Debug); Property scummvm_Release(scummvm_Debug);
REMOVE_SETTING(scummvm_Release, "GCC_C_LANGUAGE_STANDARD"); // Not sure why we remove that, or any of the other warnings REMOVE_SETTING(scummvm_Release, "GCC_C_LANGUAGE_STANDARD"); // Not sure why we remove that, or any of the other warnings
REMOVE_SETTING(scummvm_Release, "GCC_WARN_ABOUT_RETURN_TYPE"); REMOVE_SETTING(scummvm_Release, "GCC_WARN_ABOUT_RETURN_TYPE");
@ -641,7 +642,7 @@ void XCodeProvider::setupBuildConfiguration() {
****************************************/ ****************************************/
// Debug // Debug
Object *scummvmOSX_Debug_Object = new Object(this, "XCBuildConfiguration_ScummVM-OSX_Debug", _targets[1] /* ScummVM-OS X */, "XCBuildConfiguration", "PBXNativeTarget", "Debug"); Object *scummvmOSX_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-OSX_Debug", _targets[1] /* ScummVM-OS X */, "XCBuildConfiguration", "PBXNativeTarget", "Debug");
Property scummvmOSX_Debug; Property scummvmOSX_Debug;
ADD_SETTING_QUOTE(scummvmOSX_Debug, "ARCHS", "$(NATIVE_ARCH)"); ADD_SETTING_QUOTE(scummvmOSX_Debug, "ARCHS", "$(NATIVE_ARCH)");
ADD_SETTING(scummvmOSX_Debug, "COMPRESS_PNG_FILES", "NO"); ADD_SETTING(scummvmOSX_Debug, "COMPRESS_PNG_FILES", "NO");
@ -687,13 +688,13 @@ void XCodeProvider::setupBuildConfiguration() {
scummvmOSX_LdFlags.push_back("-lz"); scummvmOSX_LdFlags.push_back("-lz");
ADD_SETTING_LIST(scummvmOSX_Debug, "OTHER_LDFLAGS", scummvmOSX_LdFlags, SettingsAsList, 5); ADD_SETTING_LIST(scummvmOSX_Debug, "OTHER_LDFLAGS", scummvmOSX_LdFlags, SettingsAsList, 5);
ADD_SETTING(scummvmOSX_Debug, "PREBINDING", "NO"); ADD_SETTING(scummvmOSX_Debug, "PREBINDING", "NO");
ADD_SETTING(scummvmOSX_Debug, "PRODUCT_NAME", "ScummVM"); ADD_SETTING(scummvmOSX_Debug, "PRODUCT_NAME", PROJECT_DESCRIPTION);
scummvmOSX_Debug_Object->addProperty("name", "Debug", "", SettingsNoValue); scummvmOSX_Debug_Object->addProperty("name", "Debug", "", SettingsNoValue);
scummvmOSX_Debug_Object->properties["buildSettings"] = scummvmOSX_Debug; scummvmOSX_Debug_Object->properties["buildSettings"] = scummvmOSX_Debug;
// Release // Release
Object *scummvmOSX_Release_Object = new Object(this, "XCBuildConfiguration_ScummVMOSX_Release", _targets[1] /* ScummVM-OS X */, "XCBuildConfiguration", "PBXNativeTarget", "Release"); Object *scummvmOSX_Release_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-OSX_Release", _targets[1] /* ScummVM-OS X */, "XCBuildConfiguration", "PBXNativeTarget", "Release");
Property scummvmOSX_Release(scummvmOSX_Debug); Property scummvmOSX_Release(scummvmOSX_Debug);
ADD_SETTING(scummvmOSX_Release, "COPY_PHASE_STRIP", "YES"); ADD_SETTING(scummvmOSX_Release, "COPY_PHASE_STRIP", "YES");
REMOVE_SETTING(scummvmOSX_Release, "GCC_DYNAMIC_NO_PIC"); REMOVE_SETTING(scummvmOSX_Release, "GCC_DYNAMIC_NO_PIC");
@ -711,7 +712,7 @@ void XCodeProvider::setupBuildConfiguration() {
****************************************/ ****************************************/
// Debug // Debug
Object *scummvmSimulator_Debug_Object = new Object(this, "XCBuildConfiguration_ScummVM-Simulator_Debug", _targets[2] /* ScummVM-Simulator */, "XCBuildConfiguration", "PBXNativeTarget", "Debug"); Object *scummvmSimulator_Debug_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-Simulator_Debug", _targets[2] /* ScummVM-Simulator */, "XCBuildConfiguration", "PBXNativeTarget", "Debug");
Property scummvmSimulator_Debug(iPhone_Debug); Property scummvmSimulator_Debug(iPhone_Debug);
ADD_SETTING_QUOTE(scummvmSimulator_Debug, "FRAMEWORK_SEARCH_PATHS", "$(inherited)"); ADD_SETTING_QUOTE(scummvmSimulator_Debug, "FRAMEWORK_SEARCH_PATHS", "$(inherited)");
ADD_SETTING_LIST(scummvmSimulator_Debug, "GCC_PREPROCESSOR_DEFINITIONS", scummvm_defines, SettingsNoQuote|SettingsAsList, 5); ADD_SETTING_LIST(scummvmSimulator_Debug, "GCC_PREPROCESSOR_DEFINITIONS", scummvm_defines, SettingsNoQuote|SettingsAsList, 5);
@ -722,7 +723,7 @@ void XCodeProvider::setupBuildConfiguration() {
scummvmSimulator_Debug_Object->properties["buildSettings"] = scummvmSimulator_Debug; scummvmSimulator_Debug_Object->properties["buildSettings"] = scummvmSimulator_Debug;
// Release // Release
Object *scummvmSimulator_Release_Object = new Object(this, "XCBuildConfiguration_ScummVM-Simulator_Release", _targets[2] /* ScummVM-Simulator */, "XCBuildConfiguration", "PBXNativeTarget", "Release"); Object *scummvmSimulator_Release_Object = new Object(this, "XCBuildConfiguration_" PROJECT_DESCRIPTION "-Simulator_Release", _targets[2] /* ScummVM-Simulator */, "XCBuildConfiguration", "PBXNativeTarget", "Release");
Property scummvmSimulator_Release(scummvmSimulator_Debug); Property scummvmSimulator_Release(scummvmSimulator_Debug);
ADD_SETTING(scummvmSimulator_Release, "COPY_PHASE_STRIP", "YES"); ADD_SETTING(scummvmSimulator_Release, "COPY_PHASE_STRIP", "YES");
REMOVE_SETTING(scummvmSimulator_Release, "GCC_DYNAMIC_NO_PIC"); REMOVE_SETTING(scummvmSimulator_Release, "GCC_DYNAMIC_NO_PIC");

View file

@ -801,6 +801,7 @@ balloon Putt-Putt and Pep's Balloon-O-Rama
145bd3373574feb668cc2eea2ec6cf86 -1 ru Windows HE 80 - - sev 145bd3373574feb668cc2eea2ec6cf86 -1 ru Windows HE 80 - - sev
27b2ef1653089fe5b897d9cc89ce784f -1 ru Windows HE 80 - - George Kormendi 27b2ef1653089fe5b897d9cc89ce784f -1 ru Windows HE 80 - - George Kormendi
2232b0b9411575b1f9961713ebc9de61 -1 All Windows HE 80 - ES and NL exiltd (ES), Ben Castricum (NL) 2232b0b9411575b1f9961713ebc9de61 -1 All Windows HE 80 - ES and NL exiltd (ES), Ben Castricum (NL)
a22af0ad0e3126d19d22707b0267a37d -1 nl Windows HE 80 - - Ben Castricum
a56a05c6b865b9956639f8c51269e5ab -1 nl Mac HE 80 - - Ben Castricum a56a05c6b865b9956639f8c51269e5ab -1 nl Mac HE 80 - - Ben Castricum
d7b247c26bf1f01f8f7daf142be84de3 -1 en Windows HE 99 Updated - iziku d7b247c26bf1f01f8f7daf142be84de3 -1 en Windows HE 99 Updated - iziku
8e3241ddd6c8dadf64305e8740d45e13 -1 en All HE 100 Updated - Kirben 8e3241ddd6c8dadf64305e8740d45e13 -1 en All HE 100 Updated - Kirben

View file

@ -14,10 +14,10 @@
0x0031,0x0000, 0x0031,0x0000,
0x0031,0x0000, 0x0031,0x0000,
[Vendor] [Vendor]
0x0073,0x0063,0x0075,0x006d,0x006d,0x0076,0x006d,0x002e,0x006f,0x0067,0x0000, 0x0073,0x0063,0x0075,0x006d,0x006d,0x0076,0x006d,0x002e,0x006f,0x0072,0x0067,0x0000,
0x0073,0x0063,0x0075,0x006d,0x006d,0x0076,0x006d,0x002e,0x006f,0x0067,0x0000, 0x0073,0x0063,0x0075,0x006d,0x006d,0x0076,0x006d,0x002e,0x006f,0x0072,0x0067,0x0000,
0x0073,0x0063,0x0075,0x006d,0x006d,0x0076,0x006d,0x002e,0x006f,0x0067,0x0000, 0x0073,0x0063,0x0075,0x006d,0x006d,0x0076,0x006d,0x002e,0x006f,0x0072,0x0067,0x0000,
0x0073,0x0063,0x0075,0x006d,0x006d,0x0076,0x006d,0x002e,0x006f,0x0067,0x0000, 0x0073,0x0063,0x0075,0x006d,0x006d,0x0076,0x006d,0x002e,0x006f,0x0072,0x0067,0x0000,
[Release_Date] [Release_Date]
0x0000, 0x0000,
0x0000, 0x0000,
@ -26,16 +26,16 @@
[Description] [Description]
0x0049,0x006e,0x0074,0x0065,0x0072,0x0070,0x0072,0x0065,0x0074,0x0065,0x0072,0x0020,0x0066,0x006F,0x0072,0x0020,0x00 0x0049,0x006e,0x0074,0x0065,0x0072,0x0070,0x0072,0x0065,0x0074,0x0065,0x0072,0x0020,0x0066,0x006F,0x0072,0x0020,0x00
73,0x0065,0x0076,0x0065,0x0072,0x0061,0x006C,0x0020,0x0061,0x0064,0x0076,0x0065,0x006E,0x0074,0x0075,0x0072,0x0065,0 73,0x0065,0x0076,0x0065,0x0072,0x0061,0x006C,0x0020,0x0061,0x0064,0x0076,0x0065,0x006E,0x0074,0x0075,0x0072,0x0065,0
x0020,,0x0067,0x0061,0x006D,0x0065,0x0073,,0x0000, x0020,0x0067,0x0061,0x006D,0x0065,0x0073,0x0000,
0x0049,0x006e,0x0074,0x0065,0x0072,0x0070,0x0072,0x0065,0x0074,0x0065,0x0072,0x0020,0x0066,0x006F,0x0072,0x0020,0x00 0x0049,0x006e,0x0074,0x0065,0x0072,0x0070,0x0072,0x0065,0x0074,0x0065,0x0072,0x0020,0x0066,0x006F,0x0072,0x0020,0x00
73,0x0065,0x0076,0x0065,0x0072,0x0061,0x006C,0x0020,0x0061,0x0064,0x0076,0x0065,0x006E,0x0074,0x0075,0x0072,0x0065,0 73,0x0065,0x0076,0x0065,0x0072,0x0061,0x006C,0x0020,0x0061,0x0064,0x0076,0x0065,0x006E,0x0074,0x0075,0x0072,0x0065,0
x0020,,0x0067,0x0061,0x006D,0x0065,0x0073,,0x0000, x0020,0x0067,0x0061,0x006D,0x0065,0x0073,0x0000,
0x0049,0x006e,0x0074,0x0065,0x0072,0x0070,0x0072,0x0065,0x0074,0x0065,0x0072,0x0020,0x0066,0x006F,0x0072,0x0020,0x00 0x0049,0x006e,0x0074,0x0065,0x0072,0x0070,0x0072,0x0065,0x0074,0x0065,0x0072,0x0020,0x0066,0x006F,0x0072,0x0020,0x00
73,0x0065,0x0076,0x0065,0x0072,0x0061,0x006C,0x0020,0x0061,0x0064,0x0076,0x0065,0x006E,0x0074,0x0075,0x0072,0x0065,0 73,0x0065,0x0076,0x0065,0x0072,0x0061,0x006C,0x0020,0x0061,0x0064,0x0076,0x0065,0x006E,0x0074,0x0075,0x0072,0x0065,0
x0020,,0x0067,0x0061,0x006D,0x0065,0x0073,,0x0000, x0020,0x0067,0x0061,0x006D,0x0065,0x0073,0x0000,
0x0049,0x006e,0x0074,0x0065,0x0072,0x0070,0x0072,0x0065,0x0074,0x0065,0x0072,0x0020,0x0066,0x006F,0x0072,0x0020,0x00 0x0049,0x006e,0x0074,0x0065,0x0072,0x0070,0x0072,0x0065,0x0074,0x0065,0x0072,0x0020,0x0066,0x006F,0x0072,0x0020,0x00
73,0x0065,0x0076,0x0065,0x0072,0x0061,0x006C,0x0020,0x0061,0x0064,0x0076,0x0065,0x006E,0x0074,0x0075,0x0072,0x0065,0 73,0x0065,0x0076,0x0065,0x0072,0x0061,0x006C,0x0020,0x0061,0x0064,0x0076,0x0065,0x006E,0x0074,0x0075,0x0072,0x0065,0
x0020,,0x0067,0x0061,0x006D,0x0065,0x0073,,0x0000, x0020,0x0067,0x0061,0x006D,0x0065,0x0073,0x0000,
[JoyStick_Support] [JoyStick_Support]
0 0
[icon_path] [icon_path]

View file

@ -1265,7 +1265,7 @@ protected:
virtual void doOutput(const byte *src, uint len); virtual void doOutput(const byte *src, uint len);
void clsCheck(WindowBlock *window); void clsCheck(WindowBlock *window);
void quickLoadOrSave(); virtual void quickLoadOrSave();
byte *vc10_uncompressFlip(const byte *src, uint16 w, uint16 h); byte *vc10_uncompressFlip(const byte *src, uint16 w, uint16 h);
byte *vc10_flip(const byte *src, uint16 w, uint16 h); byte *vc10_flip(const byte *src, uint16 w, uint16 h);
@ -2060,6 +2060,7 @@ protected:
void windowBackSpace(WindowBlock *window); void windowBackSpace(WindowBlock *window);
virtual char *genSaveName(int slot); virtual char *genSaveName(int slot);
virtual void quickLoadOrSave();
}; };
class AGOSEngine_FeebleDemo : public AGOSEngine_Feeble { class AGOSEngine_FeebleDemo : public AGOSEngine_Feeble {

View file

@ -136,12 +136,25 @@ char *AGOSEngine::genSaveName(int slot) {
return buf; return buf;
} }
#ifdef ENABLE_AGOS2
void AGOSEngine_Feeble::quickLoadOrSave() {
// Quick loading and saving isn't possible in The Feeble Files or Puzzle Pack.
}
#endif
void AGOSEngine::quickLoadOrSave() { void AGOSEngine::quickLoadOrSave() {
// Quick load & save is only supported complete version of Simon the Sorcerer 1/2 // The function uses segments of code from the original game scripts
if (getGameType() == GType_PP || getGameType() == GType_FF || // to allow quick loading and saving, but isn't perfect.
(getFeatures() & GF_DEMO)) { //
// Unfortuntely this allows loading and saving in locations,
// which aren't supported, and will not restore correctly:
// Any overhead maps in Simon the Sorcerer 2
// Various locations in Elvira 1/2 and Waxworks where saving
// was disabled
// The floppy disk demo of Simon the Sorcerer 1 doesn't work.
if (getFeatures() & GF_DEMO)
return; return;
}
bool success; bool success;
Common::String buf; Common::String buf;

48
engines/configure.engines Normal file
View file

@ -0,0 +1,48 @@
# This file is included from the main "configure" script
add_engine scumm "SCUMM" yes "scumm_7_8 he"
add_engine scumm_7_8 "v7 & v8 games" yes
add_engine he "HE71+ games" yes
add_engine agi "AGI" yes
add_engine agos "AGOS" yes "agos2"
add_engine agos2 "AGOS 2 games" yes
add_engine cge "CGE" yes
add_engine cine "Cinematique evo 1" yes
add_engine composer "Magic Composer" no
add_engine cruise "Cinematique evo 2" yes
add_engine draci "Dragon History" yes
add_engine drascula "Drascula: The Vampire Strikes Back" yes
add_engine dreamweb "Dreamweb" no
add_engine gob "Gobli*ns" yes
add_engine groovie "Groovie" yes "groovie2"
add_engine groovie2 "Groovie 2 games" no
add_engine hugo "Hugo Trilogy" yes
add_engine kyra "Legend of Kyrandia" yes "lol eob"
add_engine lol "Lands of Lore" yes
add_engine eob "Eye of the Beholder" no
add_engine lastexpress "The Last Express" no
add_engine lure "Lure of the Temptress" yes
add_engine made "MADE" yes
add_engine mohawk "Mohawk" yes "cstime myst riven"
add_engine cstime "Where in Time is Carmen Sandiego?" no
add_engine riven "Riven: The Sequel to Myst" no
add_engine myst "Myst" no
add_engine parallaction "Parallaction" yes
add_engine pegasus "The Journeyman Project: Pegasus Prime" no
add_engine queen "Flight of the Amazon Queen" yes
add_engine saga "SAGA" yes "ihnm saga2"
add_engine ihnm "IHNM" yes
add_engine saga2 "SAGA 2 games" no
add_engine sci "SCI" yes "sci32"
add_engine sci32 "SCI32 games" no
add_engine sky "Beneath a Steel Sky" yes
add_engine sword1 "Broken Sword" yes
add_engine sword2 "Broken Sword II" yes
add_engine sword25 "Broken Sword 2.5" no
add_engine teenagent "Teen Agent" yes
add_engine testbed "TestBed: the Testing framework" no
add_engine tinsel "Tinsel" yes
add_engine toltecs "3 Skulls of the Toltecs" no
add_engine toon "Toonstruck" yes
add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes
add_engine tsage "TsAGE" yes
add_engine tucker "Bud Tucker in Double Trouble" yes

View file

@ -23,6 +23,7 @@
#include "base/plugins.h" #include "base/plugins.h"
#include "engines/advancedDetector.h" #include "engines/advancedDetector.h"
#include "engines/savestate.h"
#include "common/file.h" #include "common/file.h"
#include "drascula/drascula.h" #include "drascula/drascula.h"
@ -271,6 +272,62 @@ public:
_guioptions = GUIO2(GUIO_NOMIDI, GUIO_NOLAUNCHLOAD); _guioptions = GUIO2(GUIO_NOMIDI, GUIO_NOLAUNCHLOAD);
} }
virtual bool hasFeature(MetaEngineFeature f) const {
return (f == kSupportsListSaves);
}
virtual SaveStateList listSaves(const char *target) const {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
Common::String pattern = Common::String::format("%s??", target);
// Get list of savefiles for target game
Common::StringArray filenames = saveFileMan->listSavefiles(pattern);
Common::Array<int> slots;
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
// Obtain the last 2 digits of the filename, since they correspond to the save slot
int slotNum = atoi(file->c_str() + file->size() - 2);
// Ensure save slot is within valid range
if (slotNum >= 1 && slotNum <= 10) {
slots.push_back(slotNum);
}
}
// Sort save slot ids
Common::sort<int>(slots.begin(), slots.end());
// Load save index
Common::String fileEpa = Common::String::format("%s.epa", target);
Common::InSaveFile *epa = saveFileMan->openForLoading(fileEpa);
// Get savegame names from index
Common::String saveDesc;
SaveStateList saveList;
int line = 1;
for (size_t i = 0; i < slots.size(); i++) {
// ignore lines corresponding to unused saveslots
for (; line < slots[i]; line++)
epa->readLine();
// copy the name in the line corresponding to the save slot and truncate to 22 characters
saveDesc = Common::String(epa->readLine().c_str(), 22);
// handle cases where the save directory and save index are detectably out of sync
if (saveDesc == "*")
saveDesc = "No name specified.";
// increment line number to keep it in sync with slot number
line++;
// Insert savegame name into list
saveList.push_back(SaveStateDescriptor(slots[i], saveDesc));
}
delete epa;
return saveList;
}
virtual const char *getName() const { virtual const char *getName() const {
return "Drascula"; return "Drascula";
} }

View file

@ -63,6 +63,20 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam
_channel1 = 0; _channel1 = 0;
_datafilePrefix = "DREAMWEB."; _datafilePrefix = "DREAMWEB.";
// ES and FR CD release use a different data file prefix
if (isCD()) {
switch(getLanguage()) {
case Common::ES_ESP:
_datafilePrefix = "DREAMWSP.";
break;
case Common::FR_FRA:
_datafilePrefix = "DREAMWFR.";
break;
default:
// Nothing to do
break;
}
}
_openChangeSize = kInventx+(4*kItempicsize); _openChangeSize = kInventx+(4*kItempicsize);
_quitRequested = false; _quitRequested = false;
@ -526,10 +540,54 @@ uint8 DreamWebEngine::modifyChar(uint8 c) const {
default: default:
return c; return c;
} }
case Common::FR_FRA:
switch(c) {
case 133:
return 'Z' + 1;
case 130:
return 'Z' + 2;
case 138:
return 'Z' + 3;
case 136:
return 'Z' + 4;
case 140:
return 'Z' + 5;
case 135:
return 'Z' + 6;
case 149:
return ',' - 1;
case 131:
return ',' - 2;
case 141:
return ',' - 3;
case 139:
return ',' - 4;
case 151:
return 'A' - 1;
case 147:
return 'A' - 3;
case 150:
return 'A' - 4;
default:
return c;
}
default: default:
return c; return c;
} }
} }
Common::String DreamWebEngine::modifyFileName(const char *name) {
Common::String fileName(name);
// Sanity check
if (!fileName.hasPrefix("DREAMWEB."))
return fileName;
// Make sure we use the correct file name as it differs depending on the game variant
fileName = _datafilePrefix;
fileName += name + 9;
return fileName;
}
bool DreamWebEngine::hasSpeech() { bool DreamWebEngine::hasSpeech() {
return isCD() && _hasSpeech; return isCD() && _hasSpeech;

View file

@ -149,6 +149,7 @@ public:
Common::Language getLanguage() const; Common::Language getLanguage() const;
uint8 modifyChar(uint8 c) const; uint8 modifyChar(uint8 c) const;
Common::String modifyFileName(const char *);
void stopSound(uint8 channel); void stopSound(uint8 channel);

View file

@ -2090,8 +2090,8 @@ void DreamWebEngine::getRidOfAll() {
void DreamWebEngine::loadRoomData(const Room &room, bool skipDat) { void DreamWebEngine::loadRoomData(const Room &room, bool skipDat) {
processEvents(); processEvents();
Common::File file; Common::File file;
if (!file.open(room.name)) if (!file.open(modifyFileName(room.name)))
error("cannot open file %s", room.name); error("cannot open file %s", modifyFileName(room.name).c_str());
FileHeader header; FileHeader header;
file.read((uint8 *)&header, sizeof(FileHeader)); file.read((uint8 *)&header, sizeof(FileHeader));
@ -2176,8 +2176,8 @@ void DreamWebEngine::restoreReels() {
processEvents(); processEvents();
Common::File file; Common::File file;
if (!file.open(room.name)) if (!file.open(modifyFileName(room.name)))
error("cannot open file %s", room.name); error("cannot open file %s", modifyFileName(room.name).c_str());
FileHeader header; FileHeader header;
file.read((uint8 *)&header, sizeof(FileHeader)); file.read((uint8 *)&header, sizeof(FileHeader));

View file

@ -437,9 +437,9 @@ bool ROQPlayer::processBlockStill(ROQBlockHeader &blockHeader) {
Graphics::JPEGDecoder *jpg = new Graphics::JPEGDecoder(); Graphics::JPEGDecoder *jpg = new Graphics::JPEGDecoder();
jpg->loadStream(*_file); jpg->loadStream(*_file);
byte *y = (byte *)jpg->getComponent(1)->getBasePtr(0, 0); const byte *y = (const byte *)jpg->getComponent(1)->getBasePtr(0, 0);
byte *u = (byte *)jpg->getComponent(2)->getBasePtr(0, 0); const byte *u = (const byte *)jpg->getComponent(2)->getBasePtr(0, 0);
byte *v = (byte *)jpg->getComponent(3)->getBasePtr(0, 0); const byte *v = (const byte *)jpg->getComponent(3)->getBasePtr(0, 0);
byte *ptr = (byte *)_currBuf->getBasePtr(0, 0); byte *ptr = (byte *)_currBuf->getBasePtr(0, 0);
for (int i = 0; i < _currBuf->w * _currBuf->h; i++) { for (int i = 0; i < _currBuf->w * _currBuf->h; i++) {

View file

@ -1258,9 +1258,9 @@ void KyraEngine_LoK::seq_playCredits() {
do { do {
currentString = nextString; currentString = nextString;
nextString = (uint8 *)strpbrk((const char *)currentString, stringTerms); nextString = (uint8 *)strpbrk((char *)currentString, stringTerms);
if (!nextString) if (!nextString)
nextString = (uint8 *)strchr((const char *)currentString, 0); nextString = (uint8 *)strchr((char *)currentString, 0);
CreditsLine line; CreditsLine line;

View file

@ -133,14 +133,8 @@ void Intro::introMovies_run() {
case 6: case 6:
_introStep = 7; _introStep = 7;
if (!(_vm->getFeatures() & GF_DEMO)) { // The demo doesn't have the intro video if (!(_vm->getFeatures() & GF_DEMO)) // The demo doesn't have the intro video
if ((_vm->getFeatures() & GF_ME) && _vm->getPlatform() == Common::kPlatformMacintosh) _vm->_video->playMovie(_vm->wrapMovieFilename("intro", kIntroStack));
// intro.mov uses Sorenson, introc uses Cinepak. Otherwise, they're the same.
// TODO: Switch back to the SVQ version when we support it
_vm->_video->playMovie(_vm->wrapMovieFilename("introc", kIntroStack));
else
_vm->_video->playMovie(_vm->wrapMovieFilename("intro", kIntroStack));
}
break; break;
case 7: case 7:
if (!_vm->_video->isVideoPlaying()) if (!_vm->_video->isVideoPlaying())

View file

@ -62,7 +62,7 @@ class NSArchive : public Common::Archive {
Common::SeekableReadStream *_stream; Common::SeekableReadStream *_stream;
char _archiveDir[MAX_ARCHIVE_ENTRIES][32]; char _archiveDir[MAX_ARCHIVE_ENTRIES][32];
uint32 _archiveLenghts[MAX_ARCHIVE_ENTRIES]; uint32 _archiveLengths[MAX_ARCHIVE_ENTRIES];
uint32 _archiveOffsets[MAX_ARCHIVE_ENTRIES]; uint32 _archiveOffsets[MAX_ARCHIVE_ENTRIES];
uint32 _numFiles; uint32 _numFiles;
@ -103,8 +103,8 @@ NSArchive::NSArchive(Common::SeekableReadStream *stream, Common::Platform platfo
uint32 dataOffset = (isSmallArchive) ? SMALL_ARCHIVE_DATA_OFS : NORMAL_ARCHIVE_DATA_OFS; uint32 dataOffset = (isSmallArchive) ? SMALL_ARCHIVE_DATA_OFS : NORMAL_ARCHIVE_DATA_OFS;
for (uint16 i = 0; i < _numFiles; i++) { for (uint16 i = 0; i < _numFiles; i++) {
_archiveOffsets[i] = dataOffset; _archiveOffsets[i] = dataOffset;
_archiveLenghts[i] = _stream->readUint32BE(); _archiveLengths[i] = _stream->readUint32BE();
dataOffset += _archiveLenghts[i]; dataOffset += _archiveLengths[i];
} }
} }
@ -133,7 +133,7 @@ Common::SeekableReadStream *NSArchive::createReadStreamForMember(const Common::S
debugC(9, kDebugDisk, "NSArchive::createReadStreamForMember: '%s' found in slot %i", name.c_str(), index); debugC(9, kDebugDisk, "NSArchive::createReadStreamForMember: '%s' found in slot %i", name.c_str(), index);
int offset = _archiveOffsets[index]; int offset = _archiveOffsets[index];
int endOffset = _archiveOffsets[index] + _archiveLenghts[index]; int endOffset = _archiveOffsets[index] + _archiveLengths[index];
return new Common::SeekableSubReadStream(_stream, offset, endOffset, DisposeAfterUse::NO); return new Common::SeekableSubReadStream(_stream, offset, endOffset, DisposeAfterUse::NO);
} }

106
engines/plugins_table.h Normal file
View file

@ -0,0 +1,106 @@
// This file is being included by "base/plugins.cpp"
#if PLUGIN_ENABLED_STATIC(SCUMM)
LINK_PLUGIN(SCUMM)
#endif
#if PLUGIN_ENABLED_STATIC(AGI)
LINK_PLUGIN(AGI)
#endif
#if PLUGIN_ENABLED_STATIC(AGOS)
LINK_PLUGIN(AGOS)
#endif
#if PLUGIN_ENABLED_STATIC(CGE)
LINK_PLUGIN(CGE)
#endif
#if PLUGIN_ENABLED_STATIC(CINE)
LINK_PLUGIN(CINE)
#endif
#if PLUGIN_ENABLED_STATIC(COMPOSER)
LINK_PLUGIN(COMPOSER)
#endif
#if PLUGIN_ENABLED_STATIC(CRUISE)
LINK_PLUGIN(CRUISE)
#endif
#if PLUGIN_ENABLED_STATIC(DRACI)
LINK_PLUGIN(DRACI)
#endif
#if PLUGIN_ENABLED_STATIC(DRASCULA)
LINK_PLUGIN(DRASCULA)
#endif
#if PLUGIN_ENABLED_STATIC(DREAMWEB)
LINK_PLUGIN(DREAMWEB)
#endif
#if PLUGIN_ENABLED_STATIC(GOB)
LINK_PLUGIN(GOB)
#endif
#if PLUGIN_ENABLED_STATIC(GROOVIE)
LINK_PLUGIN(GROOVIE)
#endif
#if PLUGIN_ENABLED_STATIC(HUGO)
LINK_PLUGIN(HUGO)
#endif
#if PLUGIN_ENABLED_STATIC(KYRA)
LINK_PLUGIN(KYRA)
#endif
#if PLUGIN_ENABLED_STATIC(LASTEXPRESS)
LINK_PLUGIN(LASTEXPRESS)
#endif
#if PLUGIN_ENABLED_STATIC(LURE)
LINK_PLUGIN(LURE)
#endif
#if PLUGIN_ENABLED_STATIC(MADE)
LINK_PLUGIN(MADE)
#endif
#if PLUGIN_ENABLED_STATIC(MOHAWK)
LINK_PLUGIN(MOHAWK)
#endif
#if PLUGIN_ENABLED_STATIC(PARALLACTION)
LINK_PLUGIN(PARALLACTION)
#endif
#if PLUGIN_ENABLED_STATIC(PEGASUS)
LINK_PLUGIN(PEGASUS)
#endif
#if PLUGIN_ENABLED_STATIC(QUEEN)
LINK_PLUGIN(QUEEN)
#endif
#if PLUGIN_ENABLED_STATIC(SAGA)
LINK_PLUGIN(SAGA)
#endif
#if PLUGIN_ENABLED_STATIC(SCI)
LINK_PLUGIN(SCI)
#endif
#if PLUGIN_ENABLED_STATIC(SKY)
LINK_PLUGIN(SKY)
#endif
#if PLUGIN_ENABLED_STATIC(SWORD1)
LINK_PLUGIN(SWORD1)
#endif
#if PLUGIN_ENABLED_STATIC(SWORD2)
LINK_PLUGIN(SWORD2)
#endif
#if PLUGIN_ENABLED_STATIC(SWORD25)
LINK_PLUGIN(SWORD25)
#endif
#if PLUGIN_ENABLED_STATIC(TEENAGENT)
LINK_PLUGIN(TEENAGENT)
#endif
#if PLUGIN_ENABLED_STATIC(TESTBED)
LINK_PLUGIN(TESTBED)
#endif
#if PLUGIN_ENABLED_STATIC(TINSEL)
LINK_PLUGIN(TINSEL)
#endif
#if PLUGIN_ENABLED_STATIC(TOLTECS)
LINK_PLUGIN(TOLTECS)
#endif
#if PLUGIN_ENABLED_STATIC(TOON)
LINK_PLUGIN(TOON)
#endif
#if PLUGIN_ENABLED_STATIC(TSAGE)
LINK_PLUGIN(TSAGE)
#endif
#if PLUGIN_ENABLED_STATIC(TOUCHE)
LINK_PLUGIN(TOUCHE)
#endif
#if PLUGIN_ENABLED_STATIC(TUCKER)
LINK_PLUGIN(TUCKER)
#endif

View file

@ -250,9 +250,9 @@ const SciWorkaroundEntry kDoSoundFade_workarounds[] = {
// gameID, room,script,lvl, object-name, method-name, call,index, workaround // gameID, room,script,lvl, object-name, method-name, call,index, workaround
const SciWorkaroundEntry kGetAngle_workarounds[] = { const SciWorkaroundEntry kGetAngle_workarounds[] = {
{ GID_FANMADE, 516, 992, 0, "Motion", "init", -1, 0, { WORKAROUND_IGNORE, 0 } }, // The Legend of the Lost Jewel Demo (fan made): called with third/fourth parameters as objects { GID_FANMADE, 516, 992, 0, "Motion", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // The Legend of the Lost Jewel Demo (fan made): called with third/fourth parameters as objects
{ GID_KQ6, -1, 752, 0, "throwDazzle", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // room 740/790 after the Genie is exposed in the Palace (short and long ending), it starts shooting lightning bolts around. An extra 5th parameter is passed - bug #3034610 & #3041734 { GID_KQ6, -1, 752, 0, "throwDazzle", "changeState", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // room 740/790 after the Genie is exposed in the Palace (short and long ending), it starts shooting lightning bolts around. An extra 5th parameter is passed - bug #3034610 & #3041734
{ GID_SQ1, -1, 927, 0, "PAvoider", "doit", -1, 0, { WORKAROUND_IGNORE, 0 } }, // all rooms in Ulence Flats after getting the Pilot Droid: called with a single parameter when the droid is in Roger's path - bug #3513207 { GID_SQ1, -1, 927, 0, "PAvoider", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // all rooms in Ulence Flats after getting the Pilot Droid: called with a single parameter when the droid is in Roger's path - bug #3513207
SCI_WORKAROUNDENTRY_TERMINATOR SCI_WORKAROUNDENTRY_TERMINATOR
}; };

View file

@ -563,7 +563,7 @@ void MidiPlayer_Midi::readMt32GmPatch(const byte *data, int size) {
switch (command & 0xf0) { switch (command & 0xf0) {
case 0xf0: { case 0xf0: {
byte *sysExEnd = (byte *)memchr(midi + i, 0xf7, midiSize - i); const byte *sysExEnd = (const byte *)memchr(midi + i, 0xf7, midiSize - i);
if (!sysExEnd) if (!sysExEnd)
error("Failed to find end of sysEx"); error("Failed to find end of sysEx");

View file

@ -47,7 +47,7 @@ public:
private: private:
struct Region { struct Region {
int32 offset; // offset of region int32 offset; // offset of region
int32 length; // lenght of region int32 length; // length of region
}; };
struct Jump { struct Jump {

View file

@ -153,6 +153,7 @@ _ClassicProc3RendererShadowARM:
STR r12,[r13,#height] STR r12,[r13,#height]
STR r14,[r13,#len] STR r14,[r13,#len]
LDR r12,[r13,#pitch] LDR r12,[r13,#pitch]
LDR r11,[r13,#_numStrips]
B startpos B startpos
outerloop: outerloop:
@ -231,13 +232,13 @@ innerloop:
CMPLE r0,r14 @ || _scaleY >= r14 CMPLE r0,r14 @ || _scaleY >= r14
BLE startpos BLE startpos
LDRB r14,[r10],r11 @ r14 = mask[0] mask += _numStrips
ADDS r4,r4,#1 @ y >= 0 (equiv to y>-1,y+1>0) ADDS r4,r4,#1 @ y >= 0 (equiv to y>-1,y+1>0)
CMPGT r1,#0 @ && color > 0 CMPGT r1,#0 @ && color > 0
CMPGT r6,r4 @ && _out.h+1 > y+1 CMPGT r6,r4 @ && _out.h+1 > y+1
CMNGT r3,#1 @ && x >= 0 (equiv to x>-1,x+1>0) CMNGT r3,#1 @ && x >= 0 (equiv to x>-1,x+1>0)
CMPGT r7,r3 @ && _out.w > x CMPGT r7,r3 @ && _out.w > x
BLE masked BLE masked
LDRB r14,[r10] @ r14 = mask[0]
TST r14,r8 @ && !(mask[0] && maskbit) TST r14,r8 @ && !(mask[0] && maskbit)
LDREQ r14,[r13,#_palette] LDREQ r14,[r13,#_palette]
BNE masked BNE masked
@ -256,6 +257,7 @@ innerloop:
@ stallEQ @ stallEQ
STRB r14,[r9] @ *dst = pcolor STRB r14,[r9] @ *dst = pcolor
masked: masked:
ADD r10,r10,r11 @ mask += _numStrips
ADD r9,r9,r12 @ dst += _out.pitch ADD r9,r9,r12 @ dst += _out.pitch
startpos: startpos:
SUBS r5,r5,#1 @ loopCount -=1 SUBS r5,r5,#1 @ loopCount -=1

View file

@ -471,7 +471,7 @@ void ScummEngine_v0::drawSentenceLine() {
actorName = " "; actorName = " ";
} else { } else {
Actor *a = derefActor(actorId, "drawSentenceLine"); Actor *a = derefActor(actorId, "drawSentenceLine");
actorName = (char *)a->getActorName(); actorName = (const char *)a->getActorName();
} }
_sentenceBuf += Common::String::format("%-13s", actorName); _sentenceBuf += Common::String::format("%-13s", actorName);
} }

View file

@ -1,5 +1,5 @@
/* /*
This file was generated by the md5table tool on Tue Mar 20 19:59:40 2012 This file was generated by the md5table tool on Mon Apr 9 12:23:48 2012
DO NOT EDIT MANUALLY! DO NOT EDIT MANUALLY!
*/ */
@ -431,6 +431,7 @@ static const MD5Table md5table[] = {
{ "a0a7dea72003933b8b3f8b99b9f7ddeb", "loom", "No AdLib", "EGA", -1, Common::EN_ANY, Common::kPlatformAtariST }, { "a0a7dea72003933b8b3f8b99b9f7ddeb", "loom", "No AdLib", "EGA", -1, Common::EN_ANY, Common::kPlatformAtariST },
{ "a194f15f51ee62badab74b9e7da97693", "baseball2001", "", "Demo", 20507, Common::EN_ANY, Common::kPlatformUnknown }, { "a194f15f51ee62badab74b9e7da97693", "baseball2001", "", "Demo", 20507, Common::EN_ANY, Common::kPlatformUnknown },
{ "a197a87ae77f3b3333f09a7a2c448fe2", "freddi", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows }, { "a197a87ae77f3b3333f09a7a2c448fe2", "freddi", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "a22af0ad0e3126d19d22707b0267a37d", "balloon", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "a2386da005672cbd5136f4f27a626c5f", "farm", "", "", 87061, Common::NL_NLD, Common::kPlatformWindows }, { "a2386da005672cbd5136f4f27a626c5f", "farm", "", "", 87061, Common::NL_NLD, Common::kPlatformWindows },
{ "a28135a7ade38cc0208b04507c46efd1", "spyfox", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "a28135a7ade38cc0208b04507c46efd1", "spyfox", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "a2bb6aa0537402c1b3c2ea899ccef64b", "lost", "HE 99", "Demo", 15540, Common::EN_ANY, Common::kPlatformWindows }, { "a2bb6aa0537402c1b3c2ea899ccef64b", "lost", "HE 99", "Demo", 15540, Common::EN_ANY, Common::kPlatformWindows },

View file

@ -129,7 +129,7 @@ void MoviePlayer::update() {
assert(s->format.bytesPerPixel == 4); assert(s->format.bytesPerPixel == 4);
#ifdef THEORA_INDIRECT_RENDERING #ifdef THEORA_INDIRECT_RENDERING
byte *frameData = (byte *)s->getBasePtr(0, 0); const byte *frameData = (const byte *)s->getBasePtr(0, 0);
_outputBitmap->setContent(frameData, s->pitch * s->h, 0, s->pitch); _outputBitmap->setContent(frameData, s->pitch * s->h, 0, s->pitch);
#else #else
g_system->copyRectToScreen((byte *)s->getBasePtr(0, 0), s->pitch, _outX, _outY, MIN(s->w, _backSurface->w), MIN(s->h, _backSurface->h)); g_system->copyRectToScreen((byte *)s->getBasePtr(0, 0), s->pitch, _outX, _outY, MIN(s->w, _backSurface->w), MIN(s->h, _backSurface->h));

View file

@ -19,6 +19,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
/**
* @file
* Image decoder used in engines:
* - hugo
* - mohawk
*/
#ifndef GRAPHICS_DECODERS_BMP_H #ifndef GRAPHICS_DECODERS_BMP_H
#define GRAPHICS_DECODERS_BMP_H #define GRAPHICS_DECODERS_BMP_H

View file

@ -20,6 +20,13 @@
* *
*/ */
/**
* @file
* Image decoder used in engines:
* - groovie
* - mohawk
*/
#ifndef GRAPHICS_JPEG_H #ifndef GRAPHICS_JPEG_H
#define GRAPHICS_JPEG_H #define GRAPHICS_JPEG_H

View file

@ -20,6 +20,13 @@
* *
*/ */
/**
* @file
* Image decoder used in engines:
* - mohawk
* - sci
*/
#ifndef GRAPHICS_PICT_H #ifndef GRAPHICS_PICT_H
#define GRAPHICS_PICT_H #define GRAPHICS_PICT_H

View file

@ -306,7 +306,7 @@ Graphics::Surface *Surface::convertTo(const PixelFormat &dstFormat, const byte *
assert(palette); assert(palette);
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
const byte *srcRow = (byte *)getBasePtr(0, y); const byte *srcRow = (const byte *)getBasePtr(0, y);
byte *dstRow = (byte *)surface->getBasePtr(0, y); byte *dstRow = (byte *)surface->getBasePtr(0, y);
for (int x = 0; x < w; x++) { for (int x = 0; x < w; x++) {
@ -328,7 +328,7 @@ Graphics::Surface *Surface::convertTo(const PixelFormat &dstFormat, const byte *
} else { } else {
// Converting from high color to high color // Converting from high color to high color
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
const byte *srcRow = (byte *)getBasePtr(0, y); const byte *srcRow = (const byte *)getBasePtr(0, y);
byte *dstRow = (byte *)surface->getBasePtr(0, y); byte *dstRow = (byte *)surface->getBasePtr(0, y);
for (int x = 0; x < w; x++) { for (int x = 0; x < w; x++) {

View file

@ -300,4 +300,89 @@ void convertYUV420ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uS
convertYUV420ToRGB<uint32>((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); convertYUV420ToRGB<uint32>((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
} }
#define READ_QUAD(ptr, prefix) \
byte prefix##A = ptr[index]; \
byte prefix##B = ptr[index + 1]; \
byte prefix##C = ptr[index + uvPitch]; \
byte prefix##D = ptr[index + uvPitch + 1]
#define DO_INTERPOLATION(out) \
out = (out##A * (4 - xDiff) * (4 - yDiff) + out##B * xDiff * (4 - yDiff) + \
out##C * yDiff * (4 - xDiff) + out##D * xDiff * yDiff) >> 4
#define DO_YUV410_PIXEL() \
DO_INTERPOLATION(u); \
DO_INTERPOLATION(v); \
\
cr_r = Cr_r_tab[v]; \
crb_g = Cr_g_tab[v] + Cb_g_tab[u]; \
cb_b = Cb_b_tab[u]; \
\
PUT_PIXEL(*ySrc, dstPtr); \
dstPtr += sizeof(PixelInt); \
\
ySrc++; \
xDiff++
template<typename PixelInt>
void convertYUV410ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) {
// Keep the tables in pointers here to avoid a dereference on each pixel
const int16 *Cr_r_tab = lookup->_colorTab;
const int16 *Cr_g_tab = Cr_r_tab + 256;
const int16 *Cb_g_tab = Cr_g_tab + 256;
const int16 *Cb_b_tab = Cb_g_tab + 256;
const uint32 *rgbToPix = lookup->_rgbToPix;
int quarterWidth = yWidth >> 2;
for (int y = 0; y < yHeight; y++) {
for (int x = 0; x < quarterWidth; x++) {
// Perform bilinear interpolation on the the chroma values
// Based on the algorithm found here: http://tech-algorithm.com/articles/bilinear-image-scaling/
// Feel free to optimize further
int targetY = y >> 2;
int xDiff = 0;
int yDiff = y & 3;
int index = targetY * uvPitch + x;
// Declare some variables for the following macros
byte u, v;
int16 cr_r, crb_g, cb_b;
register const uint32 *L;
READ_QUAD(uSrc, u);
READ_QUAD(vSrc, v);
DO_YUV410_PIXEL();
DO_YUV410_PIXEL();
DO_YUV410_PIXEL();
DO_YUV410_PIXEL();
}
dstPtr += dstPitch - yWidth * sizeof(PixelInt);
ySrc += yPitch - yWidth;
}
}
#undef READ_QUAD
#undef DO_INTERPOLATION
#undef DO_YUV410_PIXEL
void convertYUV410ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) {
// Sanity checks
assert(dst && dst->pixels);
assert(dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4);
assert(ySrc && uSrc && vSrc);
assert((yWidth & 3) == 0);
assert((yHeight & 3) == 0);
const YUVToRGBLookup *lookup = YUVToRGBMan.getLookup(dst->format);
// Use a templated function to avoid an if check on every pixel
if (dst->format.bytesPerPixel == 2)
convertYUV410ToRGB<uint16>((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
else
convertYUV410ToRGB<uint32>((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
}
} // End of namespace Graphics } // End of namespace Graphics

View file

@ -64,6 +64,25 @@ void convertYUV444ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uS
*/ */
void convertYUV420ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch); void convertYUV420ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch);
/**
* Convert a YUV410 image to an RGB surface
*
* Since the chroma has a very low resolution in 410, we perform bilinear scaling
* on the two chroma planes to produce the image. The chroma planes must have
* at least one extra row that can be read from in order to produce a proper
* image (filled with 0x80). This is required in order to speed up this function.
*
* @param dst the destination surface
* @param ySrc the source of the y component
* @param uSrc the source of the u component
* @param vSrc the source of the v component
* @param yWidth the width of the y surface (must be divisible by 4)
* @param yHeight the height of the y surface (must be divisible by 4)
* @param yPitch the pitch of the y surface
* @param uvPitch the pitch of the u and v surfaces
*/
void convertYUV410ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch);
} // End of namespace Graphics } // End of namespace Graphics
#endif #endif

Binary file not shown.

View file

@ -1373,24 +1373,23 @@ msgstr "Voces y sub."
#: engines/scumm/dialogs.cpp:653 #: engines/scumm/dialogs.cpp:653
msgid "Select a Proficiency Level." msgid "Select a Proficiency Level."
msgstr "" msgstr "Selecciona un nivel de dificultad."
#: engines/scumm/dialogs.cpp:655 #: engines/scumm/dialogs.cpp:655
msgid "Refer to your Loom(TM) manual for help." msgid "Refer to your Loom(TM) manual for help."
msgstr "" msgstr "Mira en el Manual para mayor información."
#: engines/scumm/dialogs.cpp:658 #: engines/scumm/dialogs.cpp:658
#, fuzzy
msgid "Standard" msgid "Standard"
msgstr "Estándar (16bpp)" msgstr "Estándar"
#: engines/scumm/dialogs.cpp:659 #: engines/scumm/dialogs.cpp:659
msgid "Practice" msgid "Practice"
msgstr "" msgstr "Práctica"
#: engines/scumm/dialogs.cpp:660 #: engines/scumm/dialogs.cpp:660
msgid "Expert" msgid "Expert"
msgstr "" msgstr "Experto"
#: engines/scumm/help.cpp:73 #: engines/scumm/help.cpp:73
msgid "Common keyboard commands:" msgid "Common keyboard commands:"

View file

@ -1380,23 +1380,23 @@ msgstr "Voix & ST"
#: engines/scumm/dialogs.cpp:653 #: engines/scumm/dialogs.cpp:653
msgid "Select a Proficiency Level." msgid "Select a Proficiency Level."
msgstr "" msgstr "Sélectionnez un niveau de compétence."
#: engines/scumm/dialogs.cpp:655 #: engines/scumm/dialogs.cpp:655
msgid "Refer to your Loom(TM) manual for help." msgid "Refer to your Loom(TM) manual for help."
msgstr "" msgstr "Reportez-vous à votre manuel d'instruction."
#: engines/scumm/dialogs.cpp:658 #: engines/scumm/dialogs.cpp:658
msgid "Standard" msgid "Standard"
msgstr "Standard" msgstr "Normal"
#: engines/scumm/dialogs.cpp:659 #: engines/scumm/dialogs.cpp:659
msgid "Practice" msgid "Practice"
msgstr "" msgstr "Essai"
#: engines/scumm/dialogs.cpp:660 #: engines/scumm/dialogs.cpp:660
msgid "Expert" msgid "Expert"
msgstr "" msgstr "Expert"
#: engines/scumm/help.cpp:73 #: engines/scumm/help.cpp:73
msgid "Common keyboard commands:" msgid "Common keyboard commands:"

View file

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n" "Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n" "Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
"POT-Creation-Date: 2012-03-07 22:09+0000\n" "POT-Creation-Date: 2012-03-07 22:09+0000\n"
"PO-Revision-Date: 2012-02-17 07:10+0100\n" "PO-Revision-Date: 2012-04-18 08:20+0100\n"
"Last-Translator: Gruby <grubycza@hotmail.com>\n" "Last-Translator: Gruby <grubycza@hotmail.com>\n"
"Language-Team: Hungarian\n" "Language-Team: Hungarian\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -1158,13 +1158,13 @@ msgstr ""
"README-t az alap információkról, és hogy hogyan segíthetsz a késõbbiekben." "README-t az alap információkról, és hogy hogyan segíthetsz a késõbbiekben."
#: engines/dialogs.cpp:243 #: engines/dialogs.cpp:243
#, fuzzy, c-format #, c-format
msgid "" msgid ""
"Gamestate save failed (%s)! Please consult the README for basic information, " "Gamestate save failed (%s)! Please consult the README for basic information, "
"and for instructions on how to obtain further assistance." "and for instructions on how to obtain further assistance."
msgstr "" msgstr ""
"Sajnálom, a motor jelenleg nem tartalmaz játék közbeni súgót. Olvassd el a " "(%s) játékmentés nem sikerült!. Olvassd el a README-t az alap "
"README-t az alap információkról, és hogy hogyan segíthetsz a későbbiekben." "információkról, és hogy hogyan segíthetsz a későbbiekben."
#: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109 #: engines/dialogs.cpp:321 engines/mohawk/dialogs.cpp:109
#: engines/mohawk/dialogs.cpp:174 #: engines/mohawk/dialogs.cpp:174
@ -1225,13 +1225,13 @@ msgstr ""
"Nézd meg a README fájlt a részletekért." "Nézd meg a README fájlt a részletekért."
#: engines/engine.cpp:426 #: engines/engine.cpp:426
#, fuzzy, c-format #, c-format
msgid "" msgid ""
"Gamestate load failed (%s)! Please consult the README for basic information, " "Gamestate load failed (%s)! Please consult the README for basic information, "
"and for instructions on how to obtain further assistance." "and for instructions on how to obtain further assistance."
msgstr "" msgstr ""
"Sajnálom, a motor jelenleg nem tartalmaz játék közbeni súgót. Olvassd el a " "(%s) játékállás betöltése nem sikerült!. Olvassd el a README-t az alap "
"README-t az alap információkról, és hogy hogyan segíthetsz a későbbiekben." "információkról, és hogy hogyan segíthetsz a későbbiekben."
#: engines/engine.cpp:439 #: engines/engine.cpp:439
msgid "" msgid ""
@ -2083,7 +2083,7 @@ msgstr ""
#: engines/sword1/animation.cpp:539 #: engines/sword1/animation.cpp:539
#, c-format #, c-format
msgid "PSX stream cutscene '%s' cannot be played in paletted mode" msgid "PSX stream cutscene '%s' cannot be played in paletted mode"
msgstr "" msgstr "'%s' PSX stream átvezető nem játszható le paletta módban"
#: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455 #: engines/sword1/animation.cpp:560 engines/sword2/animation.cpp:455
msgid "DXA cutscenes found but ScummVM has been built without zlib support" msgid "DXA cutscenes found but ScummVM has been built without zlib support"
@ -2138,10 +2138,11 @@ msgid "This is the end of the Broken Sword 1 Demo"
msgstr "Ez a Broken Sword 1 Demo vége" msgstr "Ez a Broken Sword 1 Demo vége"
#: engines/sword2/animation.cpp:435 #: engines/sword2/animation.cpp:435
#, fuzzy
msgid "" msgid ""
"PSX cutscenes found but ScummVM has been built without RGB color support" "PSX cutscenes found but ScummVM has been built without RGB color support"
msgstr "DXA átvezető elérhető, de a ScummVM zlib támogatás nincs lefordítva" msgstr ""
"PSX átvezetőfilmet találtam, de ez a ScummVM RGB színtámogatás nélkül van "
"lefordítva"
#: engines/parallaction/saveload.cpp:133 #: engines/parallaction/saveload.cpp:133
#, c-format #, c-format
@ -2289,7 +2290,7 @@ msgstr " (Akt
#: backends/keymapper/remap-dialog.cpp:106 #: backends/keymapper/remap-dialog.cpp:106
msgid " (Blocked)" msgid " (Blocked)"
msgstr "" msgstr " (Blokkolt)"
#: backends/keymapper/remap-dialog.cpp:119 #: backends/keymapper/remap-dialog.cpp:119
msgid " (Global)" msgid " (Global)"

View file

@ -1374,24 +1374,23 @@ msgstr "Voci e testo"
#: engines/scumm/dialogs.cpp:653 #: engines/scumm/dialogs.cpp:653
msgid "Select a Proficiency Level." msgid "Select a Proficiency Level."
msgstr "" msgstr "Selezionate un livello di difficoltà."
#: engines/scumm/dialogs.cpp:655 #: engines/scumm/dialogs.cpp:655
msgid "Refer to your Loom(TM) manual for help." msgid "Refer to your Loom(TM) manual for help."
msgstr "" msgstr "Consultate il manuale delle istruzioni."
#: engines/scumm/dialogs.cpp:658 #: engines/scumm/dialogs.cpp:658
#, fuzzy
msgid "Standard" msgid "Standard"
msgstr "Standard (16bpp)" msgstr "Medio"
#: engines/scumm/dialogs.cpp:659 #: engines/scumm/dialogs.cpp:659
msgid "Practice" msgid "Practice"
msgstr "" msgstr "Base"
#: engines/scumm/dialogs.cpp:660 #: engines/scumm/dialogs.cpp:660
msgid "Expert" msgid "Expert"
msgstr "" msgstr "Expert"
#: engines/scumm/help.cpp:73 #: engines/scumm/help.cpp:73
msgid "Common keyboard commands:" msgid "Common keyboard commands:"

782
video/codecs/svq1.cpp Normal file
View file

@ -0,0 +1,782 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
// Sorenson Video 1 Codec
// Based off FFmpeg's SVQ1 decoder (written by Arpi and Nick Kurshev)
#include "video/codecs/svq1.h"
#include "video/codecs/svq1_cb.h"
#include "video/codecs/svq1_vlc.h"
#include "common/stream.h"
#include "common/bitstream.h"
#include "common/rect.h"
#include "common/system.h"
#include "common/debug.h"
#include "common/textconsole.h"
#include "common/huffman.h"
#include "graphics/yuv_to_rgb.h"
namespace Video {
#define SVQ1_BLOCK_SKIP 0
#define SVQ1_BLOCK_INTER 1
#define SVQ1_BLOCK_INTER_4V 2
#define SVQ1_BLOCK_INTRA 3
SVQ1Decoder::SVQ1Decoder(uint16 width, uint16 height) {
debug(1, "SVQ1Decoder::SVQ1Decoder(width:%d, height:%d)", width, height);
_width = width;
_height = height;
_frameWidth = _frameHeight = 0;
_surface = 0;
_last[0] = 0;
_last[1] = 0;
_last[2] = 0;
// Setup Variable Length Code Tables
_blockType = new Common::Huffman(0, 4, s_svq1BlockTypeCodes, s_svq1BlockTypeLengths);
for (int i = 0; i < 6; i++) {
_intraMultistage[i] = new Common::Huffman(0, 8, s_svq1IntraMultistageCodes[i], s_svq1IntraMultistageLengths[i]);
_interMultistage[i] = new Common::Huffman(0, 8, s_svq1InterMultistageCodes[i], s_svq1InterMultistageLengths[i]);
}
_intraMean = new Common::Huffman(0, 256, s_svq1IntraMeanCodes, s_svq1IntraMeanLengths);
_interMean = new Common::Huffman(0, 512, s_svq1InterMeanCodes, s_svq1InterMeanLengths);
_motionComponent = new Common::Huffman(0, 33, s_svq1MotionComponentCodes, s_svq1MotionComponentLengths);
}
SVQ1Decoder::~SVQ1Decoder() {
if (_surface) {
_surface->free();
delete _surface;
}
delete[] _last[0];
delete[] _last[1];
delete[] _last[2];
delete _blockType;
delete _intraMean;
delete _interMean;
delete _motionComponent;
for (int i = 0; i < 6; i++) {
delete _intraMultistage[i];
delete _interMultistage[i];
}
}
#define ALIGN(x, a) (((x)+(a)-1)&~((a)-1))
const Graphics::Surface *SVQ1Decoder::decodeImage(Common::SeekableReadStream *stream) {
debug(1, "SVQ1Decoder::decodeImage()");
Common::BitStream32BEMSB frameData(*stream);
uint32 frameCode = frameData.getBits(22);
debug(1, " frameCode: %d", frameCode);
if ((frameCode & ~0x70) || !(frameCode & 0x60)) { // Invalid
warning("Invalid Image at frameCode");
return _surface;
}
byte temporalReference = frameData.getBits(8);
debug(1, " temporalReference: %d", temporalReference);
static const char *const types[4] = { "I (Key)", "P (Delta from Previous)", "B (Delta from Next)", "Invalid" };
byte frameType = frameData.getBits(2);
debug(1, " frameType: %d = %s Frame", frameType, types[frameType]);
if (frameType == 0) { // I Frame
// TODO: Validate checksum if present
if (frameCode == 0x50 || frameCode == 0x60) {
uint32 checksum = frameData.getBits(16);
debug(1, " checksum:0x%02x", checksum);
// We're currently just ignoring the checksum
}
if ((frameCode ^ 0x10) >= 0x50) {
// Skip embedded string
byte stringLen = frameData.getBits(8);
for (uint16 i = 0; i < stringLen-1; i++)
frameData.skip(8);
}
frameData.skip(5); // Unknown
static const struct { uint w, h; } standardFrameSizes[7] = {
{ 160, 120 }, // 0
{ 128, 96 }, // 1
{ 176, 144 }, // 2
{ 352, 288 }, // 3
{ 704, 576 }, // 4
{ 240, 180 }, // 5
{ 320, 240 } // 6
};
byte frameSizeCode = frameData.getBits(3);
debug(1, " frameSizeCode: %d", frameSizeCode);
if (frameSizeCode == 7) {
_frameWidth = frameData.getBits(12);
_frameHeight = frameData.getBits(12);
} else {
_frameWidth = standardFrameSizes[frameSizeCode].w;
_frameHeight = standardFrameSizes[frameSizeCode].h;
}
debug(1, " frameWidth: %d", _frameWidth);
debug(1, " frameHeight: %d", _frameHeight);
} else if (frameType == 2) { // B Frame
warning("B Frames not supported by SVQ1 decoder (yet)");
return _surface;
} else if (frameType == 3) { // Invalid
warning("Invalid Frame Type");
return _surface;
}
bool checksumPresent = frameData.getBit() != 0;
debug(1, " checksumPresent: %d", checksumPresent);
if (checksumPresent) {
bool usePacketChecksum = frameData.getBit() != 0;
debug(1, " usePacketChecksum: %d", usePacketChecksum);
bool componentChecksumsAfterImageData = frameData.getBit() != 0;
debug(1, " componentChecksumsAfterImageData: %d", componentChecksumsAfterImageData);
byte unk4 = frameData.getBits(2);
debug(1, " unk4: %d", unk4);
if (unk4 != 0)
warning("Invalid Frame Header in SVQ1 Frame Decode");
}
// Some more unknown data
bool unk5 = frameData.getBit() != 0;
if (unk5) {
frameData.skip(8);
while (frameData.getBit() != 0)
frameData.skip(8);
}
int yWidth = ALIGN(_frameWidth, 16);
int yHeight = ALIGN(_frameHeight, 16);
int uvWidth = ALIGN(yWidth / 4, 16);
int uvHeight = ALIGN(yHeight / 4, 16);
byte *current[3];
// Decode Y, U and V component planes
for (int i = 0; i < 3; i++) {
int width, height;
if (i == 0) {
width = yWidth;
height = yHeight;
current[i] = new byte[width * height];
} else {
width = uvWidth;
height = uvHeight;
// Add an extra row's worth of data to not go out-of-bounds in the
// color conversion. Then fill that with "empty" data.
current[i] = new byte[width * (height + 1)];
memset(current[i] + width * height, 0x80, width);
}
if (frameType == 0) { // I Frame
// Keyframe (I)
byte *currentP = current[i];
for (uint16 y = 0; y < height; y += 16) {
for (uint16 x = 0; x < width; x += 16) {
if (!svq1DecodeBlockIntra(&frameData, &currentP[x], width)) {
warning("svq1DecodeBlockIntra decode failure");
return _surface;
}
}
currentP += 16 * width;
}
} else {
// Delta frame (P or B)
// Prediction Motion Vector
Common::Point *pmv = new Common::Point[(width / 8) + 3];
byte *previous;
if (frameType == 2) { // B Frame
warning("B Frame not supported currently");
//previous = _next[i];
} else {
previous = _last[i];
}
byte *currentP = current[i];
for (uint16 y = 0; y < height; y += 16) {
for (uint16 x = 0; x < width; x += 16) {
if (!svq1DecodeDeltaBlock(&frameData, &currentP[x], previous, width, pmv, x, y)) {
warning("svq1DecodeDeltaBlock decode failure");
return _surface;
}
}
pmv[0].x = pmv[0].y = 0;
currentP += 16 * width;
}
delete[] pmv;
}
}
// Now we'll create the surface
if (!_surface) {
_surface = new Graphics::Surface();
_surface->create(yWidth, yHeight, g_system->getScreenFormat());
_surface->w = _width;
_surface->h = _height;
}
convertYUV410ToRGB(_surface, current[0], current[1], current[2], yWidth, yHeight, yWidth, uvWidth);
// Store the current surfaces for later and free the old ones
for (int i = 0; i < 3; i++) {
delete[] _last[i];
_last[i] = current[i];
}
return _surface;
}
bool SVQ1Decoder::svq1DecodeBlockIntra(Common::BitStream *s, byte *pixels, int pitch) {
// initialize list for breadth first processing of vectors
byte *list[63];
list[0] = pixels;
// recursively process vector
for (int i = 0, m = 1, n = 1, level = 5; i < n; i++) {
for (; level > 0; i++) {
// process next depth
if (i == m) {
m = n;
if (--level == 0)
break;
}
// divide block if next bit set
if (s->getBit() == 0)
break;
// add child nodes
list[n++] = list[i];
list[n++] = list[i] + (((level & 1) ? pitch : 1) << ((level / 2) + 1));
}
// destination address and vector size
uint32 *dst = (uint32 *)list[i];
uint width = 1 << ((level + 4) / 2);
uint height = 1 << ((level + 3) / 2);
// get number of stages (-1 skips vector, 0 for mean only)
int stages = _intraMultistage[level]->getSymbol(*s) - 1;
if (stages == -1) {
for (uint y = 0; y < height; y++)
memset(&dst[y * (pitch / 4)], 0, width);
continue; // skip vector
}
if (stages > 0 && level >= 4) {
warning("Error (svq1_decode_block_intra): invalid vector: stages = %d, level = %d", stages, level);
return false; // error - invalid vector
}
int mean = _intraMean->getSymbol(*s);
if (stages == 0) {
for (uint y = 0; y < height; y++)
memset(&dst[y * (pitch / 4)], mean, width);
} else {
const uint32 *codebook = s_svq1IntraCodebooks[level];
uint32 bitCache = s->getBits(stages * 4);
// calculate codebook entries for this vector
int entries[6];
for (int j = 0; j < stages; j++)
entries[j] = (((bitCache >> ((stages - j - 1) * 4)) & 0xF) + j * 16) << (level + 1);
mean -= stages * 128;
uint32 n4 = ((mean + (mean >> 31)) << 16) | (mean & 0xFFFF);
for (uint y = 0; y < height; y++) {
for (uint x = 0; x < (width / 4); x++, codebook++) {
uint32 n1 = n4;
uint32 n2 = n4;
uint32 n3;
// add codebook entries to vector
for (int j = 0; j < stages; j++) {
n3 = codebook[entries[j]] ^ 0x80808080;
n1 += (n3 & 0xFF00FF00) >> 8;
n2 += n3 & 0x00FF00FF;
}
// clip to [0..255]
if (n1 & 0xFF00FF00) {
n3 = (((n1 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;
n1 += 0x7F007F00;
n1 |= (((~n1 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;
n1 &= n3 & 0x00FF00FF;
}
if (n2 & 0xFF00FF00) {
n3 = (((n2 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;
n2 += 0x7F007F00;
n2 |= (((~n2 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;
n2 &= n3 & 0x00FF00FF;
}
// store result
dst[x] = (n1 << 8) | n2;
}
dst += pitch / 4;
}
}
}
return true;
}
bool SVQ1Decoder::svq1DecodeBlockNonIntra(Common::BitStream *s, byte *pixels, int pitch) {
// initialize list for breadth first processing of vectors
byte *list[63];
list[0] = pixels;
// recursively process vector
for (int i = 0, m = 1, n = 1, level = 5; i < n; i++) {
for (; level > 0; i++) {
// process next depth
if (i == m) {
m = n;
if (--level == 0)
break;
}
// divide block if next bit set
if (s->getBit() == 0)
break;
// add child nodes
list[n++] = list[i];
list[n++] = list[i] + (((level & 1) ? pitch : 1) << ((level / 2) + 1));
}
// destination address and vector size
uint32 *dst = (uint32 *)list[i];
int width = 1 << ((level + 4) / 2);
int height = 1 << ((level + 3) / 2);
// get number of stages (-1 skips vector, 0 for mean only)
int stages = _interMultistage[level]->getSymbol(*s) - 1;
if (stages == -1)
continue; // skip vector
if (stages > 0 && level >= 4) {
warning("Error (svq1_decode_block_non_intra): invalid vector: stages = %d, level = %d", stages, level);
return false; // error - invalid vector
}
int mean = _interMean->getSymbol(*s) - 256;
const uint32 *codebook = s_svq1InterCodebooks[level];
uint32 bitCache = s->getBits(stages * 4);
// calculate codebook entries for this vector
int entries[6];
for (int j = 0; j < stages; j++)
entries[j] = (((bitCache >> ((stages - j - 1) * 4)) & 0xF) + j * 16) << (level + 1);
mean -= stages * 128;
uint32 n4 = ((mean + (mean >> 31)) << 16) | (mean & 0xFFFF);
for (int y = 0; y < height; y++) {
for (int x = 0; x < (width / 4); x++, codebook++) {
uint32 n3 = dst[x];
// add mean value to vector
uint32 n1 = ((n3 & 0xFF00FF00) >> 8) + n4;
uint32 n2 = (n3 & 0x00FF00FF) + n4;
// add codebook entries to vector
for (int j = 0; j < stages; j++) {
n3 = codebook[entries[j]] ^ 0x80808080;
n1 += (n3 & 0xFF00FF00) >> 8;
n2 += n3 & 0x00FF00FF;
}
// clip to [0..255]
if (n1 & 0xFF00FF00) {
n3 = ((( n1 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;
n1 += 0x7F007F00;
n1 |= (((~n1 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;
n1 &= n3 & 0x00FF00FF;
}
if (n2 & 0xFF00FF00) {
n3 = ((( n2 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;
n2 += 0x7F007F00;
n2 |= (((~n2 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;
n2 &= n3 & 0x00FF00FF;
}
// store result
dst[x] = (n1 << 8) | n2;
}
dst += pitch / 4;
}
}
return true;
}
// median of 3
static inline int midPred(int a, int b, int c) {
if (a > b) {
if (c > b) {
if (c > a)
b = a;
else
b = c;
}
} else {
if (b > c) {
if (c > a)
b = c;
else
b = a;
}
}
return b;
}
bool SVQ1Decoder::svq1DecodeMotionVector(Common::BitStream *s, Common::Point *mv, Common::Point **pmv) {
for (int i = 0; i < 2; i++) {
// get motion code
int diff = _motionComponent->getSymbol(*s);
if (diff < 0)
return false; // error - invalid motion code
else if (diff && s->getBit() != 0)
diff = -diff;
// add median of motion vector predictors and clip result
if (i == 1)
mv->y = ((diff + midPred(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26;
else
mv->x = ((diff + midPred(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26;
}
return true;
}
void SVQ1Decoder::svq1SkipBlock(byte *current, byte *previous, int pitch, int x, int y) {
const byte *src = &previous[x + y * pitch];
byte *dst = current;
for (int i = 0; i < 16; i++) {
memcpy(dst, src, 16);
src += pitch;
dst += pitch;
}
}
void SVQ1Decoder::putPixels8C(byte *block, const byte *pixels, int lineSize, int h) {
for (int i = 0; i < h; i++) {
*((uint32 *)block) = READ_UINT32(pixels);
*((uint32 *)(block + 4)) = READ_UINT32(pixels + 4);
pixels += lineSize;
block += lineSize;
}
}
static inline uint32 rndAvg32(uint32 a, uint32 b) {
return (a | b) - (((a ^ b) & ~0x01010101) >> 1);
}
void SVQ1Decoder::putPixels8L2(byte *dst, const byte *src1, const byte *src2,
int dstStride, int srcStride1, int srcStride2, int h) {
for (int i = 0; i < h; i++) {
uint32 a = READ_UINT32(&src1[srcStride1 * i]);
uint32 b = READ_UINT32(&src2[srcStride2 * i]);
*((uint32 *)&dst[dstStride * i]) = rndAvg32(a, b);
a = READ_UINT32(&src1[srcStride1 * i + 4]);
b = READ_UINT32(&src2[srcStride2 * i + 4]);
*((uint32 *)&dst[dstStride * i + 4]) = rndAvg32(a, b);
}
}
void SVQ1Decoder::putPixels8X2C(byte *block, const byte *pixels, int lineSize, int h) {
putPixels8L2(block, pixels, pixels + 1, lineSize, lineSize, lineSize, h);
}
void SVQ1Decoder::putPixels8Y2C(byte *block, const byte *pixels, int lineSize, int h) {
putPixels8L2(block, pixels, pixels + lineSize, lineSize, lineSize, lineSize, h);
}
void SVQ1Decoder::putPixels8XY2C(byte *block, const byte *pixels, int lineSize, int h) {
for (int j = 0; j < 2; j++) {
uint32 a = READ_UINT32(pixels);
uint32 b = READ_UINT32(pixels + 1);
uint32 l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x02020202UL;
uint32 h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
pixels += lineSize;
for (int i = 0; i < h; i += 2) {
a = READ_UINT32(pixels);
b = READ_UINT32(pixels + 1);
uint32 l1 = (a & 0x03030303UL) + (b & 0x03030303UL);
uint32 h1 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
*((uint32 *)block) = h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
pixels += lineSize;
block += lineSize;
a = READ_UINT32(pixels);
b = READ_UINT32(pixels + 1);
l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x02020202UL;
h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);
*((uint32 *)block) = h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
pixels += lineSize;
block += lineSize;
}
pixels += 4 - lineSize * (h + 1);
block += 4 - lineSize * h;
}
}
void SVQ1Decoder::putPixels16C(byte *block, const byte *pixels, int lineSize, int h) {
putPixels8C(block, pixels, lineSize, h);
putPixels8C(block + 8, pixels + 8, lineSize, h);
}
void SVQ1Decoder::putPixels16X2C(byte *block, const byte *pixels, int lineSize, int h) {
putPixels8X2C(block, pixels, lineSize, h);
putPixels8X2C(block + 8, pixels + 8, lineSize, h);
}
void SVQ1Decoder::putPixels16Y2C(byte *block, const byte *pixels, int lineSize, int h) {
putPixels8Y2C(block, pixels, lineSize, h);
putPixels8Y2C(block + 8, pixels + 8, lineSize, h);
}
void SVQ1Decoder::putPixels16XY2C(byte *block, const byte *pixels, int lineSize, int h) {
putPixels8XY2C(block, pixels, lineSize, h);
putPixels8XY2C(block + 8, pixels + 8, lineSize, h);
}
bool SVQ1Decoder::svq1MotionInterBlock(Common::BitStream *ss, byte *current, byte *previous, int pitch,
Common::Point *motion, int x, int y) {
// predict and decode motion vector
Common::Point *pmv[3];
pmv[0] = &motion[0];
if (y == 0) {
pmv[1] = pmv[2] = pmv[0];
} else {
pmv[1] = &motion[(x / 8) + 2];
pmv[2] = &motion[(x / 8) + 4];
}
Common::Point mv;
bool resultValid = svq1DecodeMotionVector(ss, &mv, pmv);
if (!resultValid)
return false;
motion[0].x = motion[(x / 8) + 2].x = motion[(x / 8) + 3].x = mv.x;
motion[0].y = motion[(x / 8) + 2].y = motion[(x / 8) + 3].y = mv.y;
if (y + (mv.y >> 1) < 0)
mv.y = 0;
if (x + (mv.x >> 1) < 0)
mv.x = 0;
const byte *src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1)) * pitch];
byte *dst = current;
// Halfpel motion compensation with rounding (a + b + 1) >> 1.
// 4 motion compensation functions for the 4 halfpel positions
// for 16x16 blocks
switch(((mv.y & 1) << 1) + (mv.x & 1)) {
case 0:
putPixels16C(dst, src, pitch, 16);
break;
case 1:
putPixels16X2C(dst, src, pitch, 16);
break;
case 2:
putPixels16Y2C(dst, src, pitch, 16);
break;
case 3:
putPixels16XY2C(dst, src, pitch, 16);
break;
}
return true;
}
bool SVQ1Decoder::svq1MotionInter4vBlock(Common::BitStream *ss, byte *current, byte *previous, int pitch,
Common::Point *motion, int x, int y) {
// predict and decode motion vector (0)
Common::Point *pmv[4];
pmv[0] = &motion[0];
if (y == 0) {
pmv[1] = pmv[2] = pmv[0];
} else {
pmv[1] = &motion[(x / 8) + 2];
pmv[2] = &motion[(x / 8) + 4];
}
Common::Point mv;
bool resultValid = svq1DecodeMotionVector(ss, &mv, pmv);
if (!resultValid)
return false;
// predict and decode motion vector (1)
pmv[0] = &mv;
if (y == 0)
pmv[1] = pmv[2] = pmv[0];
else
pmv[1] = &motion[(x / 8) + 3];
resultValid = svq1DecodeMotionVector(ss, &motion[0], pmv);
if (!resultValid)
return false;
// predict and decode motion vector (2)
pmv[1] = &motion[0];
pmv[2] = &motion[(x / 8) + 1];
resultValid = svq1DecodeMotionVector(ss, &motion[(x / 8) + 2], pmv);
if (!resultValid)
return false;
// predict and decode motion vector (3)
pmv[2] = &motion[(x / 8) + 2];
pmv[3] = &motion[(x / 8) + 3];
resultValid = svq1DecodeMotionVector(ss, pmv[3], pmv);
if (!resultValid)
return false;
// form predictions
for (int i = 0; i < 4; i++) {
int mvx = pmv[i]->x + (i & 1) * 16;
int mvy = pmv[i]->y + (i >> 1) * 16;
// FIXME: clipping or padding?
if (y + (mvy >> 1) < 0)
mvy = 0;
if (x + (mvx >> 1) < 0)
mvx = 0;
const byte *src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1)) * pitch];
byte *dst = current;
// Halfpel motion compensation with rounding (a + b + 1) >> 1.
// 4 motion compensation functions for the 4 halfpel positions
// for 8x8 blocks
switch(((mvy & 1) << 1) + (mvx & 1)) {
case 0:
putPixels8C(dst, src, pitch, 8);
break;
case 1:
putPixels8X2C(dst, src, pitch, 8);
break;
case 2:
putPixels8Y2C(dst, src, pitch, 8);
break;
case 3:
putPixels8XY2C(dst, src, pitch, 8);
break;
}
// select next block
if (i & 1)
current += (pitch - 1) * 8;
else
current += 8;
}
return true;
}
bool SVQ1Decoder::svq1DecodeDeltaBlock(Common::BitStream *ss, byte *current, byte *previous, int pitch,
Common::Point *motion, int x, int y) {
// get block type
uint32 blockType = _blockType->getSymbol(*ss);
// reset motion vectors
if (blockType == SVQ1_BLOCK_SKIP || blockType == SVQ1_BLOCK_INTRA) {
motion[0].x =
motion[0].y =
motion[(x / 8) + 2].x =
motion[(x / 8) + 2].y =
motion[(x / 8) + 3].x =
motion[(x / 8) + 3].y = 0;
}
bool resultValid = true;
switch (blockType) {
case SVQ1_BLOCK_SKIP:
svq1SkipBlock(current, previous, pitch, x, y);
break;
case SVQ1_BLOCK_INTER:
resultValid = svq1MotionInterBlock(ss, current, previous, pitch, motion, x, y);
if (!resultValid) {
warning("svq1MotionInterBlock decode failure");
break;
}
resultValid = svq1DecodeBlockNonIntra(ss, current, pitch);
break;
case SVQ1_BLOCK_INTER_4V:
resultValid = svq1MotionInter4vBlock(ss, current, previous, pitch, motion, x, y);
if (!resultValid) {
warning("svq1MotionInter4vBlock decode failure");
break;
}
resultValid = svq1DecodeBlockNonIntra(ss, current, pitch);
break;
case SVQ1_BLOCK_INTRA:
resultValid = svq1DecodeBlockIntra(ss, current, pitch);
break;
}
return resultValid;
}
} // End of namespace Video

82
video/codecs/svq1.h Normal file
View file

@ -0,0 +1,82 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef VIDEO_CODECS_SVQ1_H
#define VIDEO_CODECS_SVQ1_H
#include "video/codecs/codec.h"
namespace Common {
class BitStream;
class Huffman;
struct Point;
}
namespace Video {
class SVQ1Decoder : public Codec {
public:
SVQ1Decoder(uint16 width, uint16 height);
~SVQ1Decoder();
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
Graphics::PixelFormat getPixelFormat() const { return _surface->format; }
private:
Graphics::Surface *_surface;
uint16 _width, _height;
uint16 _frameWidth, _frameHeight;
byte *_last[3];
Common::Huffman *_blockType;
Common::Huffman *_intraMultistage[6];
Common::Huffman *_interMultistage[6];
Common::Huffman *_intraMean;
Common::Huffman *_interMean;
Common::Huffman *_motionComponent;
bool svq1DecodeBlockIntra(Common::BitStream *s, byte *pixels, int pitch);
bool svq1DecodeBlockNonIntra(Common::BitStream *s, byte *pixels, int pitch);
bool svq1DecodeMotionVector(Common::BitStream *s, Common::Point *mv, Common::Point **pmv);
void svq1SkipBlock(byte *current, byte *previous, int pitch, int x, int y);
bool svq1MotionInterBlock(Common::BitStream *ss, byte *current, byte *previous, int pitch,
Common::Point *motion, int x, int y);
bool svq1MotionInter4vBlock(Common::BitStream *ss, byte *current, byte *previous, int pitch,
Common::Point *motion, int x, int y);
bool svq1DecodeDeltaBlock(Common::BitStream *ss, byte *current, byte *previous, int pitch,
Common::Point *motion, int x, int y);
void putPixels8C(byte *block, const byte *pixels, int lineSize, int h);
void putPixels8L2(byte *dst, const byte *src1, const byte *src2, int dstStride, int srcStride1, int srcStride2, int h);
void putPixels8X2C(byte *block, const byte *pixels, int lineSize, int h);
void putPixels8Y2C(byte *block, const byte *pixels, int lineSize, int h);
void putPixels8XY2C(byte *block, const byte *pixels, int lineSize, int h);
void putPixels16C(byte *block, const byte *pixels, int lineSize, int h);
void putPixels16X2C(byte *block, const byte *pixels, int lineSize, int h);
void putPixels16Y2C(byte *block, const byte *pixels, int lineSize, int h);
void putPixels16XY2C(byte *block, const byte *pixels, int lineSize, int h);
};
} // End of namespace Video
#endif

1511
video/codecs/svq1_cb.h Normal file

File diff suppressed because it is too large Load diff

341
video/codecs/svq1_vlc.h Normal file
View file

@ -0,0 +1,341 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
// These tables are modified versions of the FFmpeg ones so that they
// will work with our BitStream class directly.
#ifndef VIDEO_CODECS_SVQ1_VLC_H
#define VIDEO_CODECS_SVQ1_VLC_H
#include "common/scummsys.h"
namespace Video {
static const byte s_svq1BlockTypeLengths[4] = {
1, 2, 3, 3
};
static const uint32 s_svq1BlockTypeCodes[4] = {
1, 1, 1, 0
};
static const byte s_svq1IntraMultistageLengths0[8] = {
5, 1, 3, 3, 4, 4, 5, 4
};
static const uint32 s_svq1IntraMultistageCodes0[8] = {
1, 1, 3, 2, 3, 2, 0, 1
};
static const byte s_svq1IntraMultistageLengths1[8] = {
4, 2, 3, 3, 3, 3, 4, 3
};
static const uint32 s_svq1IntraMultistageCodes1[8] = {
1, 3, 5, 4, 3, 2, 0, 1
};
static const byte s_svq1IntraMultistageLengths2[8] = {
5, 1, 3, 5, 4, 3, 4, 4
};
static const uint32 s_svq1IntraMultistageCodes2[8] = {
1, 1, 3, 0, 3, 2, 2, 1
};
static const byte s_svq1IntraMultistageLengths3[8] = {
6, 1, 2, 6, 4, 4, 5, 4
};
static const uint32 s_svq1IntraMultistageCodes3[8] = {
1, 1, 1, 0, 3, 2, 1, 1
};
static const byte s_svq1IntraMultistageLengths4[8] = {
6, 1, 2, 5, 5, 6, 5, 3
};
static const uint32 s_svq1IntraMultistageCodes4[8] = {
1, 1, 1, 3, 2, 0, 1, 1
};
static const byte s_svq1IntraMultistageLengths5[8] = {
7, 1, 2, 3, 4, 6, 7, 5
};
static const uint32 s_svq1IntraMultistageCodes5[8] = {
1, 1, 1, 1, 1, 1, 0, 1
};
static const byte *s_svq1IntraMultistageLengths[6] = {
s_svq1IntraMultistageLengths0, s_svq1IntraMultistageLengths1, s_svq1IntraMultistageLengths2,
s_svq1IntraMultistageLengths3, s_svq1IntraMultistageLengths4, s_svq1IntraMultistageLengths5
};
static const uint32 *s_svq1IntraMultistageCodes[6] = {
s_svq1IntraMultistageCodes0, s_svq1IntraMultistageCodes1, s_svq1IntraMultistageCodes2,
s_svq1IntraMultistageCodes3, s_svq1IntraMultistageCodes4, s_svq1IntraMultistageCodes5
};
static const byte s_svq1InterMultistageLengths0[8] = {
2, 3, 3, 3, 3, 3, 4, 4
};
static const uint32 s_svq1InterMultistageCodes0[8] = {
3, 5, 4, 3, 2, 1, 1, 0
};
static const byte s_svq1InterMultistageLengths1[8] = {
2, 3, 3, 3, 3, 3, 4, 4
};
static const uint32 s_svq1InterMultistageCodes1[8] = {
3, 5, 4, 3, 2, 1, 1, 0
};
static const byte s_svq1InterMultistageLengths2[8] = {
1, 3, 3, 4, 4, 4, 5, 5
};
static const uint32 s_svq1InterMultistageCodes2[8] = {
1, 3, 2, 3, 2, 1, 1, 0
};
static const byte s_svq1InterMultistageLengths3[8] = {
1, 3, 3, 4, 4, 4, 5, 5
};
static const uint32 s_svq1InterMultistageCodes3[8] = {
1, 3, 2, 3, 2, 1, 1, 0
};
static const byte s_svq1InterMultistageLengths4[8] = {
1, 3, 3, 4, 4, 4, 5, 5
};
static const uint32 s_svq1InterMultistageCodes4[8] = {
1, 3, 2, 3, 2, 1, 1, 0
};
static const byte s_svq1InterMultistageLengths5[8] = {
1, 2, 3, 5, 5, 5, 6, 6
};
static const uint32 s_svq1InterMultistageCodes5[8] = {
1, 1, 1, 3, 2, 1, 1, 0
};
static const byte *s_svq1InterMultistageLengths[6] = {
s_svq1InterMultistageLengths0, s_svq1InterMultistageLengths1, s_svq1InterMultistageLengths2,
s_svq1InterMultistageLengths3, s_svq1InterMultistageLengths4, s_svq1InterMultistageLengths5
};
static const uint32 *s_svq1InterMultistageCodes[6] = {
s_svq1InterMultistageCodes0, s_svq1InterMultistageCodes1, s_svq1InterMultistageCodes2,
s_svq1InterMultistageCodes3, s_svq1InterMultistageCodes4, s_svq1InterMultistageCodes5
};
static const byte s_svq1IntraMeanLengths[256] = {
6, 7, 17, 20, 20, 20, 20, 20, 20, 19,
11, 9, 11, 14, 14, 15, 16, 12, 10, 11,
11, 9, 8, 8, 7, 4, 4, 6, 7, 8,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 7, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 7, 8, 8, 7, 8,
8, 8, 8, 8, 7, 8, 7, 7, 8, 7,
7, 8, 7, 8, 8, 8, 7, 7, 8, 7,
8, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 6, 6,
7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
9, 9, 9, 9, 8, 8, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 11, 11, 11, 10, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 14
};
static const uint32 s_svq1IntraMeanCodes[256] = {
55, 86, 1, 1, 2, 3, 0, 4, 5, 3,
21, 66, 20, 3, 2, 1, 1, 1, 43, 24,
12, 65, 120, 108, 85, 15, 14, 52, 81, 114,
110, 64, 63, 62, 61, 60, 59, 58, 57, 56,
55, 67, 70, 71, 69, 68, 73, 72, 74, 121,
118, 119, 113, 117, 116, 115, 106, 85, 112, 111,
82, 109, 76, 107, 64, 105, 104, 103, 102, 101,
100, 99, 98, 97, 96, 95, 94, 93, 92, 91,
90, 89, 88, 87, 86, 61, 84, 83, 63, 81,
80, 79, 78, 77, 65, 75, 83, 62, 72, 79,
82, 69, 80, 67, 66, 65, 66, 67, 62, 68,
60, 69, 70, 71, 72, 73, 74, 75, 76, 77,
78, 88, 89, 90, 91, 92, 93, 68, 73, 41,
63, 61, 59, 44, 40, 37, 38, 94, 87, 84,
95, 98, 99, 100, 97, 101, 103, 102, 53, 54,
96, 57, 58, 56, 55, 54, 53, 52, 51, 50,
49, 48, 45, 43, 42, 39, 64, 70, 71, 38,
37, 36, 35, 34, 46, 47, 31, 54, 29, 33,
27, 28, 25, 26, 24, 23, 22, 30, 32, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 53,
49, 50, 51, 52, 25, 42, 23, 22, 21, 40,
38, 37, 34, 33, 24, 20, 41, 18, 13, 14,
15, 16, 17, 26, 27, 28, 29, 30, 31, 32,
19, 35, 36, 9, 8, 7, 39, 5, 11, 6,
4, 3, 2, 1, 10, 22, 25, 23, 13, 14,
15, 16, 17, 18, 19, 1
};
static const byte s_svq1InterMeanLengths[512] = {
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 21, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 21,
22, 22, 22, 22, 22, 22, 20, 21, 22, 21,
22, 22, 20, 22, 22, 21, 19, 18, 20, 22,
22, 21, 20, 19, 20, 20, 19, 19, 19, 18,
19, 18, 19, 20, 19, 19, 18, 18, 18, 19,
18, 18, 18, 17, 19, 18, 18, 17, 18, 18,
18, 17, 17, 17, 17, 16, 16, 16, 16, 16,
16, 16, 16, 16, 15, 16, 15, 15, 15, 15,
15, 15, 15, 15, 14, 14, 14, 14, 14, 14,
14, 14, 14, 13, 13, 13, 13, 13, 13, 13,
13, 12, 12, 12, 12, 12, 12, 11, 11, 11,
11, 11, 11, 10, 10, 10, 10, 10, 10, 9,
9, 9, 9, 9, 8, 8, 8, 8, 7, 7,
7, 6, 6, 5, 5, 4, 1, 3, 5, 5,
6, 6, 7, 7, 7, 7, 8, 8, 8, 9,
9, 9, 9, 9, 10, 10, 10, 10, 11, 11,
11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
12, 13, 13, 13, 13, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 17, 17,
17, 17, 17, 17, 17, 17, 18, 17, 17, 17,
17, 17, 17, 17, 19, 18, 18, 19, 18, 18,
19, 18, 18, 18, 19, 18, 19, 19, 18, 20,
20, 19, 19, 19, 19, 19, 19, 18, 19, 20,
19, 19, 21, 20, 19, 20, 19, 19, 20, 20,
22, 20, 22, 22, 21, 22, 22, 21, 21, 22,
22, 20, 22, 22, 21, 22, 22, 22, 20, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 21, 21, 22, 22, 22, 21,
22, 21, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22
};
static const uint32 s_svq1InterMeanCodes[512] = {
90, 212, 213, 214, 215, 216, 217, 218, 219, 220,
221, 222, 223, 224, 225, 226, 227, 228, 229, 230,
232, 203, 233, 234, 231, 236, 237, 238, 239, 240,
241, 242, 243, 244, 245, 246, 247, 248, 258, 235,
249, 252, 253, 254, 256, 92, 96, 257, 113, 260,
261, 251, 255, 134, 250, 124, 117, 259, 120, 211,
123, 130, 210, 209, 208, 207, 206, 205, 204, 195,
202, 201, 200, 199, 198, 197, 139, 196, 194, 193,
192, 191, 190, 189, 188, 187, 186, 185, 97, 132,
133, 134, 135, 136, 137, 138, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
154, 155, 156, 157, 158, 159, 160, 161, 162, 163,
164, 165, 166, 167, 168, 169, 170, 171, 127, 143,
172, 173, 174, 175, 176, 177, 83, 144, 178, 145,
179, 180, 84, 181, 182, 140, 52, 61, 85, 183,
184, 139, 86, 61, 87, 88, 64, 67, 71, 42,
46, 44, 70, 89, 73, 45, 56, 54, 57, 69,
40, 48, 53, 32, 68, 50, 49, 31, 47, 46,
45, 33, 34, 35, 36, 39, 35, 32, 29, 37,
30, 36, 42, 38, 33, 41, 34, 35, 36, 27,
26, 29, 31, 39, 23, 24, 25, 27, 28, 30,
37, 32, 33, 19, 20, 21, 22, 23, 24, 25,
26, 24, 23, 21, 20, 19, 18, 15, 16, 18,
19, 27, 26, 14, 19, 15, 16, 17, 18, 13,
20, 21, 12, 19, 15, 14, 16, 17, 12, 9,
10, 8, 9, 9, 8, 5, 1, 3, 7, 6,
11, 10, 14, 15, 11, 13, 11, 13, 12, 15,
16, 17, 14, 18, 23, 20, 22, 21, 25, 24,
23, 22, 21, 20, 17, 25, 26, 22, 29, 27,
28, 32, 28, 35, 34, 33, 31, 30, 27, 29,
36, 22, 26, 34, 29, 31, 21, 35, 24, 32,
41, 40, 38, 37, 25, 28, 30, 23, 44, 43,
28, 33, 45, 40, 31, 27, 26, 34, 45, 50,
44, 39, 49, 51, 47, 43, 55, 42, 46, 48,
41, 40, 38, 37, 47, 51, 52, 48, 58, 59,
49, 60, 43, 41, 72, 39, 66, 65, 38, 82,
81, 63, 62, 57, 60, 59, 58, 37, 56, 80,
55, 54, 135, 79, 53, 78, 51, 50, 77, 76,
131, 75, 129, 128, 142, 126, 125, 132, 141, 122,
121, 74, 119, 118, 137, 116, 115, 114, 73, 112,
111, 110, 109, 108, 107, 106, 105, 104, 103, 102,
101, 100, 99, 98, 138, 136, 95, 94, 93, 133,
91, 131, 89, 88, 87, 86, 85, 84, 83, 82,
81, 80, 79, 78, 77, 76, 75, 74, 73, 72,
71, 70, 69, 68, 67, 66, 65, 64, 63, 62,
61, 60, 59, 58, 57, 56, 55, 54, 53, 52,
51, 50, 49, 48, 47, 46, 45, 44, 43, 42,
41, 40, 39, 38, 37, 36, 35, 34, 33, 32,
31, 30, 29, 28, 27, 26, 25, 24, 23, 22,
21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
1, 0
};
static const byte s_svq1MotionComponentLengths[33] = {
1, 2, 3, 4, 6, 7, 7, 7, 9, 9,
9, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 11, 11, 11, 11, 11,
11, 12, 12
};
static const uint32 s_svq1MotionComponentCodes[33] = {
1, 1, 1, 1, 3, 5, 4, 3, 11, 10,
9, 17, 16, 15, 14, 13, 12, 11, 10, 9,
8, 7, 6, 5, 4, 7, 6, 5, 4, 3,
2, 3, 2
};
} // End of namespace Video
#endif

View file

@ -18,6 +18,7 @@ MODULE_OBJS := \
codecs/qtrle.o \ codecs/qtrle.o \
codecs/rpza.o \ codecs/rpza.o \
codecs/smc.o \ codecs/smc.o \
codecs/svq1.o \
codecs/truemotion1.o codecs/truemotion1.o
ifdef USE_BINK ifdef USE_BINK

View file

@ -47,7 +47,7 @@
#include "video/codecs/rpza.h" #include "video/codecs/rpza.h"
#include "video/codecs/smc.h" #include "video/codecs/smc.h"
#include "video/codecs/cdtoons.h" #include "video/codecs/cdtoons.h"
#include "video/codecs/svq1.h"
namespace Video { namespace Video {
@ -152,7 +152,13 @@ const Graphics::Surface *QuickTimeDecoder::decodeNextFrame() {
// (needs to be done after we find the next track) // (needs to be done after we find the next track)
updateAudioBuffer(); updateAudioBuffer();
if (_scaledSurface) { // We have to initialize the scaled surface
if (frame && (_scaleFactorX != 1 || _scaleFactorY != 1)) {
if (!_scaledSurface) {
_scaledSurface = new Graphics::Surface();
_scaledSurface->create(_width, _height, getPixelFormat());
}
scaleSurface(frame, _scaledSurface, _scaleFactorX, _scaleFactorY); scaleSurface(frame, _scaledSurface, _scaleFactorX, _scaleFactorY);
return _scaledSurface; return _scaledSurface;
} }
@ -258,14 +264,10 @@ void QuickTimeDecoder::init() {
_nextVideoTrack = findNextVideoTrack(); _nextVideoTrack = findNextVideoTrack();
if (_nextVideoTrack) { if (_nextVideoTrack) {
// Initialize the scaled surface
if (_scaleFactorX != 1 || _scaleFactorY != 1) { if (_scaleFactorX != 1 || _scaleFactorY != 1) {
// We have to initialize the scaled surface // We have to take the scale into consideration when setting width/height
_scaledSurface = new Graphics::Surface(); _width = (_nextVideoTrack->getWidth() / _scaleFactorX).toInt();
_scaledSurface->create((_nextVideoTrack->getWidth() / _scaleFactorX).toInt(), _height = (_nextVideoTrack->getHeight() / _scaleFactorY).toInt();
(_nextVideoTrack->getHeight() / _scaleFactorY).toInt(), getPixelFormat());
_width = _scaledSurface->w;
_height = _scaledSurface->h;
} else { } else {
_width = _nextVideoTrack->getWidth().toInt(); _width = _nextVideoTrack->getWidth().toInt();
_height = _nextVideoTrack->getHeight().toInt(); _height = _nextVideoTrack->getHeight().toInt();
@ -471,7 +473,7 @@ void QuickTimeDecoder::VideoSampleDesc::initCodec() {
break; break;
case MKTAG('S','V','Q','1'): case MKTAG('S','V','Q','1'):
// Sorenson Video 1: Used by some Myst ME videos. // Sorenson Video 1: Used by some Myst ME videos.
warning("Sorenson Video 1 not yet supported"); _videoCodec = new SVQ1Decoder(_parentTrack->width, _parentTrack->height);
break; break;
case MKTAG('S','V','Q','3'): case MKTAG('S','V','Q','3'):
// Sorenson Video 3: Used by some Myst ME videos. // Sorenson Video 3: Used by some Myst ME videos.
@ -527,19 +529,12 @@ void QuickTimeDecoder::AudioTrackHandler::seekToTime(Audio::Timestamp time) {
} }
QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent) : TrackHandler(decoder, parent) { QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent) : TrackHandler(decoder, parent) {
if (_parent->scaleFactorX != 1 || _parent->scaleFactorY != 1) {
_scaledSurface = new Graphics::Surface();
_scaledSurface->create(getWidth().toInt(), getHeight().toInt(), getPixelFormat());
} else {
_scaledSurface = 0;
}
enterNewEditList(false); enterNewEditList(false);
_holdNextFrameStartTime = false; _holdNextFrameStartTime = false;
_curFrame = -1; _curFrame = -1;
_durationOverride = -1; _durationOverride = -1;
_scaledSurface = 0;
} }
QuickTimeDecoder::VideoTrackHandler::~VideoTrackHandler() { QuickTimeDecoder::VideoTrackHandler::~VideoTrackHandler() {
@ -576,7 +571,12 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame()
enterNewEditList(true); enterNewEditList(true);
} }
if (_scaledSurface) { if (frame && (_parent->scaleFactorX != 1 || _parent->scaleFactorY != 1)) {
if (!_scaledSurface) {
_scaledSurface = new Graphics::Surface();
_scaledSurface->create(getWidth().toInt(), getHeight().toInt(), getPixelFormat());
}
_decoder->scaleSurface(frame, _scaledSurface, _parent->scaleFactorX, _parent->scaleFactorY); _decoder->scaleSurface(frame, _scaledSurface, _parent->scaleFactorX, _parent->scaleFactorY);
return _scaledSurface; return _scaledSurface;
} }

View file

@ -709,14 +709,14 @@ void SmackerDecoder::queueCompressedBuffer(byte *buffer, uint32 bufferSize,
if (isStereo) { if (isStereo) {
if (is16Bits) { if (is16Bits) {
bases[1] = FROM_BE_16(audioBS.getBits(16)); bases[1] = SWAP_BYTES_16(audioBS.getBits(16));
} else { } else {
bases[1] = audioBS.getBits(8); bases[1] = audioBS.getBits(8);
} }
} }
if (is16Bits) { if (is16Bits) {
bases[0] = FROM_BE_16(audioBS.getBits(16)); bases[0] = SWAP_BYTES_16(audioBS.getBits(16));
} else { } else {
bases[0] = audioBS.getBits(8); bases[0] = audioBS.getBits(8);
} }