Skip to content

Commit

Permalink
Merge branch 'scummvm:master' into traceLog
Browse files Browse the repository at this point in the history
  • Loading branch information
r41k0u committed Jun 21, 2022
2 parents d44ba66 + 0dc0a24 commit e7f3955
Show file tree
Hide file tree
Showing 405 changed files with 38,150 additions and 3,224 deletions.
21 changes: 17 additions & 4 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@ For a more comprehensive changelog of the latest experimental code, see:

#### 2.7.0 (XXXX-XX-XX)

New games:
- Added support for Soldier Boyz.

General:
- Reduced amount of false positives in Mass Add.

Kyra:
- Added support for the Korean version of Legend of Kyrandia 1.

SCUMM:
- Marked a workaround in Monkey Island 2 (FM-Towns version) as an
enhancement; this workaround originally restored a section a portion
of the map chasing puzzle in Booty Island which had been cut in the
FM-Towns version of the game.
enhancement; this workaround originally restored a portion of the
map chasing puzzle in Booty Island which had been cut in the
FM-Towns version of the game.
- Made the sentence line in Maniac Mansion work like the manual says, i.e.
you can click on it to execute the command.

Toon:
- Made game menus behave like in the original.
Expand Down Expand Up @@ -201,6 +206,14 @@ For a more comprehensive changelog of the latest experimental code, see:
- Added "Portable Mode" in which the executable's directory is used to store
application files if a scummvm.ini file is present, instead of the user's
profile directory.
- Fixed detection of the Application Data path on Windows 95/98/ME.

RISC OS port:
- Added support for dynamic plugins.
- Added a native MIDI driver.

Nintendo DS port:
- Fixed screen scrolling when using the Load and Save dialogs.

#### 2.5.1 (2022-01-02)

Expand Down
76 changes: 45 additions & 31 deletions audio/decoders/aiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static const uint32 kVersionAIFC = MKTAG('A', 'I', 'F', 'C');
// Codecs
static const uint32 kCodecPCM = MKTAG('N', 'O', 'N', 'E'); // very original

RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
AIFFHeader *AIFFHeader::readAIFFHeader(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
if (stream->readUint32BE() != MKTAG('F', 'O', 'R', 'M')) {
warning("makeAIFFStream: No 'FORM' header");

Expand Down Expand Up @@ -100,10 +100,8 @@ RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, Dispos
bool foundCOMM = false;
bool foundSSND = false;

uint16 channels = 0, bitsPerSample = 0;
uint32 rate = 0;
uint32 codec = kCodecPCM; // AIFF default
Common::SeekableReadStream *dataStream = nullptr;
AIFFHeader *aiffHeader = new AIFFHeader;
aiffHeader->_codec = kCodecPCM; // AIFF Default;

while (!(foundCOMM && foundSSND) && !stream->err() && !stream->eos()) {
uint32 tag = stream->readUint32BE();
Expand All @@ -116,21 +114,20 @@ RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, Dispos
switch (tag) {
case MKTAG('C', 'O', 'M', 'M'):
foundCOMM = true;
channels = stream->readUint16BE();
/* frameCount = */ stream->readUint32BE();
bitsPerSample = stream->readUint16BE();
rate = readExtended(*stream);
aiffHeader->_channels = stream->readUint16BE();
aiffHeader->_frameCount = stream->readUint32BE();
aiffHeader->_bitsPerSample = stream->readUint16BE();
aiffHeader->_rate = readExtended(*stream);

if (version == kVersionAIFC)
codec = stream->readUint32BE();
aiffHeader->_codec = stream->readUint32BE();
break;
case MKTAG('S', 'S', 'N', 'D'):
foundSSND = true;
/* uint32 offset = */ stream->readUint32BE();
/* uint32 blockAlign = */ stream->readUint32BE();
if (dataStream)
delete dataStream;
dataStream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->pos() + length - 8, disposeAfterUse);
delete aiffHeader->_dataStream;
aiffHeader->_dataStream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->pos() + length - 8, disposeAfterUse);
break;
case MKTAG('F', 'V', 'E', 'R'):
switch (stream->readUint32BE()) {
Expand All @@ -148,10 +145,10 @@ RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, Dispos
case MKTAG('w', 'a', 'v', 'e'):
warning("Found unhandled AIFF-C extra data chunk");

if (!dataStream && disposeAfterUse == DisposeAfterUse::YES)
if (!aiffHeader->_dataStream && disposeAfterUse == DisposeAfterUse::YES)
delete stream;

delete dataStream;
delete aiffHeader->_dataStream;
return nullptr;
default:
debug(1, "Skipping AIFF '%s' chunk", tag2str(tag));
Expand All @@ -168,10 +165,10 @@ RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, Dispos
if (!foundCOMM) {
warning("makeAIFFStream: Could not find 'COMM' chunk");

if (!dataStream && disposeAfterUse == DisposeAfterUse::YES)
if (!aiffHeader->_dataStream && disposeAfterUse == DisposeAfterUse::YES)
delete stream;

delete dataStream;
delete aiffHeader;
return nullptr;
}

Expand All @@ -181,34 +178,39 @@ RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, Dispos
if (disposeAfterUse == DisposeAfterUse::YES)
delete stream;

delete aiffHeader;
return nullptr;
}

return aiffHeader;
}

RewindableAudioStream *AIFFHeader::makeAIFFStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
// We only implement a subset of the AIFF standard.

if (channels < 1 || channels > 2) {
warning("makeAIFFStream: Only 1 or 2 channels are supported, not %d", channels);
delete dataStream;
if (_channels < 1 || _channels > 2) {
warning("makeAIFFStream: Only 1 or 2 channels are supported, not %d", _channels);
delete _dataStream;
return nullptr;
}

// Seek to the start of dataStream, required for at least FileStream
dataStream->seek(0);
// Seek to the start of _dataStream, required for at least FileStream
_dataStream->seek(0);

switch (codec) {
switch (_codec) {
case kCodecPCM:
case MKTAG('t', 'w', 'o', 's'):
case MKTAG('s', 'o', 'w', 't'): {
// PCM samples are always signed.
byte rawFlags = 0;
if (bitsPerSample == 16)
if (_bitsPerSample == 16)
rawFlags |= Audio::FLAG_16BITS;
if (channels == 2)
if (_channels == 2)
rawFlags |= Audio::FLAG_STEREO;
if (codec == MKTAG('s', 'o', 'w', 't'))
if (_codec == MKTAG('s', 'o', 'w', 't'))
rawFlags |= Audio::FLAG_LITTLE_ENDIAN;

return makeRawStream(dataStream, rate, rawFlags);
return makeRawStream(_dataStream, _rate, rawFlags);
}
case MKTAG('i', 'm', 'a', '4'):
// TODO: Use QT IMA ADPCM
Expand All @@ -221,16 +223,28 @@ RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, Dispos
break;
case MKTAG('A', 'D', 'P', '4'):
// ADP4 on 3DO
return make3DO_ADP4AudioStream(dataStream, rate, channels == 2);
return make3DO_ADP4AudioStream(_dataStream, _rate, _channels == 2);
case MKTAG('S', 'D', 'X', '2'):
// SDX2 on 3DO
return make3DO_SDX2AudioStream(dataStream, rate, channels == 2);
return make3DO_SDX2AudioStream(_dataStream, _rate, _channels == 2);
default:
warning("Unhandled AIFF-C compression tag '%s'", tag2str(codec));
warning("Unhandled AIFF-C compression tag '%s'", tag2str(_codec));
}

delete dataStream;
delete _dataStream;
return nullptr;
}

AIFFHeader::~AIFFHeader() {
delete _dataStream;
}

RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
AIFFHeader *aiffHeader = AIFFHeader::readAIFFHeader(stream, disposeAfterUse);
if (aiffHeader == nullptr) {
return nullptr;
}
return aiffHeader->makeAIFFStream(stream, disposeAfterUse);
}

} // End of namespace Audio
18 changes: 18 additions & 0 deletions audio/decoders/aiff.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,24 @@ namespace Audio {

class RewindableAudioStream;

class AIFFHeader {
public:
~AIFFHeader();
static AIFFHeader *readAIFFHeader(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse);
RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse);

uint32 getFrameCount() const { return _frameCount; }
uint32 getFrameRate() const { return _rate; }

private:
uint16 _channels = 0;
uint32 _frameCount = 0;
uint16 _bitsPerSample = 0;
uint32 _rate = 0;
uint32 _codec = 0;
Common::SeekableReadStream *_dataStream = nullptr;
};

/**
* Try to load an AIFF from the given seekable stream and create an AudioStream
* from that data.
Expand Down
87 changes: 4 additions & 83 deletions audio/decoders/voc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
*
*/

#include "audio/decoders/voc.h"

#include "common/debug.h"
#include "common/endian.h"
#include "common/util.h"
Expand All @@ -32,8 +34,6 @@

namespace Audio {

namespace {

bool checkVOCHeader(Common::ReadStream &stream) {
VocFileHeader fileHeader;

Expand Down Expand Up @@ -73,83 +73,6 @@ bool checkVOCHeader(Common::ReadStream &stream) {
return true;
}

class VocStream : public SeekableAudioStream {
public:
VocStream(Common::SeekableReadStream *stream, bool isUnsigned, DisposeAfterUse::Flag disposeAfterUse);
~VocStream();

int readBuffer(int16 *buffer, const int numSamples) override;

bool isStereo() const override { return false; }

int getRate() const override { return _rate; }

bool endOfData() const override { return (_curBlock == _blocks.end()) && (_blockLeft == 0); }

bool seek(const Timestamp &where) override;

Timestamp getLength() const override { return _length; }
private:
void preProcess();

Common::SeekableReadStream *const _stream;
const DisposeAfterUse::Flag _disposeAfterUse;

const bool _isUnsigned;

int _rate;
Timestamp _length;

struct Block {
uint8 code;
uint32 length;

union {
struct {
uint32 offset;
int rate;
int samples;
} sampleBlock;

struct {
int count;
} loopBlock;
};
};

typedef Common::List<Block> BlockList;
BlockList _blocks;

BlockList::const_iterator _curBlock;
uint32 _blockLeft;

/**
* Advance one block in the stream in case
* the current one is empty.
*/
void updateBlockIfNeeded();

// Do some internal buffering for systems with really slow slow disk i/o
enum {
/**
* How many samples we can buffer at once.
*
* TODO: Check whether this size suffices
* for systems with slow disk I/O.
*/
kSampleBufferLength = 2048
};
byte _buffer[kSampleBufferLength];

/**
* Fill the temporary sample buffer used in readBuffer.
*
* @param maxSamples Maximum samples to read.
* @return actual count of samples read.
*/
int fillBuffer(int maxSamples);
};

VocStream::VocStream(Common::SeekableReadStream *stream, bool isUnsigned, DisposeAfterUse::Flag disposeAfterUse)
: _stream(stream), _disposeAfterUse(disposeAfterUse), _isUnsigned(isUnsigned), _rate(0),
_length(), _blocks(), _curBlock(_blocks.end()), _blockLeft(0), _buffer() {
Expand Down Expand Up @@ -245,9 +168,9 @@ int VocStream::fillBuffer(int maxSamples) {
maxSamples -= samplesRead;
_blockLeft -= samplesRead;

// In case of an error we will stop
// In case of an error or end of stream we will stop
// stream playback.
if (_stream->err()) {
if (_stream->err() || _stream->eos()) {
_blockLeft = 0;
_curBlock = _blocks.end();
break;
Expand Down Expand Up @@ -533,8 +456,6 @@ void VocStream::preProcess() {
rewind();
}

} // End of anonymous namespace

int getSampleRateFromVOCRate(int vocSR) {
if (vocSR == 0xa5 || vocSR == 0xa6) {
return 11025;
Expand Down
Loading

0 comments on commit e7f3955

Please sign in to comment.